character_set 1.6.0-java → 1.8.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/gouteur.yml +1 -1
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/tests.yml +3 -1
- data/.rubocop.yml +3 -0
- data/BENCHMARK.md +32 -32
- data/CHANGELOG.md +24 -1
- data/Gemfile +7 -6
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/Rakefile +2 -123
- data/character_set.gemspec +0 -7
- data/ext/character_set/character_set.c +77 -43
- data/lib/character_set/core_ext/regexp_ext.rb +8 -0
- data/lib/character_set/expression_converter.rb +37 -54
- data/lib/character_set/parser.rb +8 -4
- data/lib/character_set/predefined_sets/assigned.cps +73 -52
- data/lib/character_set/predefined_sets/emoji.cps +10 -9
- data/lib/character_set/ruby_fallback/character_set_methods.rb +14 -17
- data/lib/character_set/ruby_fallback/set_methods.rb +6 -21
- data/lib/character_set/ruby_fallback/vendored_set_classes.rb +385 -0
- data/lib/character_set/ruby_fallback.rb +18 -6
- data/lib/character_set/set_method_adapters.rb +1 -1
- data/lib/character_set/shared_methods.rb +6 -2
- data/lib/character_set/version.rb +1 -1
- data/tasks/benchmark.rake +20 -0
- data/tasks/benchmarks/shared.rb +28 -0
- data/tasks/sync_casefold_data.rake +20 -0
- data/tasks/sync_predefined_sets.rake +9 -0
- data/tasks/sync_ruby_spec.rake +65 -0
- metadata +19 -28
- data/benchmarks/shared.rb +0 -30
- /data/{benchmarks → tasks/benchmarks}/count_in.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/cover.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/delete_in.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/keep_in.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/scan.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/used_by.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/z_add.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/z_delete.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/z_merge.rb +0 -0
- /data/{benchmarks → tasks/benchmarks}/z_minmax.rb +0 -0
@@ -0,0 +1,385 @@
|
|
1
|
+
# set, vendored from https://github.com/ruby/set/blob/master/lib/set.rb,
|
2
|
+
# with comments removed and linted.
|
3
|
+
class CharacterSet::RubyFallback::Set
|
4
|
+
Set = self
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def self.[](*ary)
|
8
|
+
new(ary)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(enum = nil, &block)
|
12
|
+
@hash = Hash.new(false)
|
13
|
+
|
14
|
+
enum.nil? and return
|
15
|
+
|
16
|
+
if block
|
17
|
+
do_with_enum(enum) { |o| add(block[o]) }
|
18
|
+
else
|
19
|
+
merge(enum)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def do_with_enum(enum, &block)
|
24
|
+
if enum.respond_to?(:each_entry)
|
25
|
+
enum.each_entry(&block) if block
|
26
|
+
elsif enum.respond_to?(:each)
|
27
|
+
enum.each(&block) if block
|
28
|
+
else
|
29
|
+
raise ArgumentError, "value must be enumerable"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
private :do_with_enum
|
33
|
+
|
34
|
+
def initialize_dup(orig)
|
35
|
+
super
|
36
|
+
@hash = orig.instance_variable_get(:@hash).dup
|
37
|
+
end
|
38
|
+
|
39
|
+
if Kernel.instance_method(:initialize_clone).arity != 1
|
40
|
+
def initialize_clone(orig, **options)
|
41
|
+
super
|
42
|
+
@hash = orig.instance_variable_get(:@hash).clone(**options)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
def initialize_clone(orig)
|
46
|
+
super
|
47
|
+
@hash = orig.instance_variable_get(:@hash).clone
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def freeze
|
52
|
+
@hash.freeze
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
def size
|
57
|
+
@hash.size
|
58
|
+
end
|
59
|
+
alias length size
|
60
|
+
|
61
|
+
def empty?
|
62
|
+
@hash.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear
|
66
|
+
@hash.clear
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_a
|
71
|
+
@hash.keys
|
72
|
+
end
|
73
|
+
|
74
|
+
def include?(o)
|
75
|
+
@hash[o]
|
76
|
+
end
|
77
|
+
alias member? include?
|
78
|
+
|
79
|
+
def superset?(set)
|
80
|
+
case
|
81
|
+
when set.instance_of?(self.class) && @hash.respond_to?(:>=)
|
82
|
+
@hash >= set.instance_variable_get(:@hash)
|
83
|
+
when set.is_a?(Set)
|
84
|
+
size >= set.size && set.all? { |o| include?(o) }
|
85
|
+
else
|
86
|
+
raise ArgumentError, "value must be a set"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
alias >= superset?
|
90
|
+
|
91
|
+
def proper_superset?(set)
|
92
|
+
case
|
93
|
+
when set.instance_of?(self.class) && @hash.respond_to?(:>)
|
94
|
+
@hash > set.instance_variable_get(:@hash)
|
95
|
+
when set.is_a?(Set)
|
96
|
+
size > set.size && set.all? { |o| include?(o) }
|
97
|
+
else
|
98
|
+
raise ArgumentError, "value must be a set"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
alias > proper_superset?
|
102
|
+
|
103
|
+
def subset?(set)
|
104
|
+
case
|
105
|
+
when set.instance_of?(self.class) && @hash.respond_to?(:<=)
|
106
|
+
@hash <= set.instance_variable_get(:@hash)
|
107
|
+
when set.is_a?(Set)
|
108
|
+
size <= set.size && all? { |o| set.include?(o) }
|
109
|
+
else
|
110
|
+
raise ArgumentError, "value must be a set"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
alias <= subset?
|
114
|
+
|
115
|
+
def proper_subset?(set)
|
116
|
+
case
|
117
|
+
when set.instance_of?(self.class) && @hash.respond_to?(:<)
|
118
|
+
@hash < set.instance_variable_get(:@hash)
|
119
|
+
when set.is_a?(Set)
|
120
|
+
size < set.size && all? { |o| set.include?(o) }
|
121
|
+
else
|
122
|
+
raise ArgumentError, "value must be a set"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
alias < proper_subset?
|
126
|
+
|
127
|
+
def <=>(set)
|
128
|
+
return unless set.is_a?(Set)
|
129
|
+
|
130
|
+
case size <=> set.size
|
131
|
+
when -1 then -1 if proper_subset?(set)
|
132
|
+
when +1 then +1 if proper_superset?(set)
|
133
|
+
else 0 if self.==(set)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def intersect?(set)
|
138
|
+
case set
|
139
|
+
when Set
|
140
|
+
if size < set.size
|
141
|
+
any? { |o| set.include?(o) }
|
142
|
+
else
|
143
|
+
set.any? { |o| include?(o) }
|
144
|
+
end
|
145
|
+
when Enumerable
|
146
|
+
set.any? { |o| include?(o) }
|
147
|
+
else
|
148
|
+
raise ArgumentError, "value must be enumerable"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def disjoint?(set)
|
153
|
+
!intersect?(set)
|
154
|
+
end
|
155
|
+
|
156
|
+
def each(&block)
|
157
|
+
block_given? or return enum_for(__method__) { size }
|
158
|
+
@hash.each_key(&block)
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
def add(o)
|
163
|
+
@hash[o] = true
|
164
|
+
self
|
165
|
+
end
|
166
|
+
alias << add
|
167
|
+
|
168
|
+
def add?(o)
|
169
|
+
add(o) unless include?(o)
|
170
|
+
end
|
171
|
+
|
172
|
+
def delete(o)
|
173
|
+
@hash.delete(o)
|
174
|
+
self
|
175
|
+
end
|
176
|
+
|
177
|
+
def delete?(o)
|
178
|
+
delete(o) if include?(o)
|
179
|
+
end
|
180
|
+
|
181
|
+
def delete_if
|
182
|
+
block_given? or return enum_for(__method__) { size }
|
183
|
+
select { |o| yield o }.each { |o| @hash.delete(o) }
|
184
|
+
self
|
185
|
+
end
|
186
|
+
|
187
|
+
def keep_if
|
188
|
+
block_given? or return enum_for(__method__) { size }
|
189
|
+
reject { |o| yield o }.each { |o| @hash.delete(o) }
|
190
|
+
self
|
191
|
+
end
|
192
|
+
|
193
|
+
def reject!(&block)
|
194
|
+
block_given? or return enum_for(__method__) { size }
|
195
|
+
n = size
|
196
|
+
delete_if(&block)
|
197
|
+
self if size != n
|
198
|
+
end
|
199
|
+
|
200
|
+
def select!(&block)
|
201
|
+
block_given? or return enum_for(__method__) { size }
|
202
|
+
n = size
|
203
|
+
keep_if(&block)
|
204
|
+
self if size != n
|
205
|
+
end
|
206
|
+
|
207
|
+
alias filter! select!
|
208
|
+
|
209
|
+
def merge(*enums, **_rest)
|
210
|
+
enums.each do |enum|
|
211
|
+
if enum.instance_of?(self.class)
|
212
|
+
@hash.update(enum.instance_variable_get(:@hash))
|
213
|
+
else
|
214
|
+
do_with_enum(enum) { |o| add(o) }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
self
|
219
|
+
end
|
220
|
+
|
221
|
+
def subtract(enum)
|
222
|
+
do_with_enum(enum) { |o| delete(o) }
|
223
|
+
self
|
224
|
+
end
|
225
|
+
|
226
|
+
def |(enum)
|
227
|
+
dup.merge(enum)
|
228
|
+
end
|
229
|
+
alias + |
|
230
|
+
alias union |
|
231
|
+
|
232
|
+
def -(enum)
|
233
|
+
dup.subtract(enum)
|
234
|
+
end
|
235
|
+
alias difference -
|
236
|
+
|
237
|
+
def &(enum)
|
238
|
+
n = self.class.new
|
239
|
+
if enum.is_a?(Set)
|
240
|
+
if enum.size > size
|
241
|
+
each { |o| n.add(o) if enum.include?(o) }
|
242
|
+
else
|
243
|
+
enum.each { |o| n.add(o) if include?(o) }
|
244
|
+
end
|
245
|
+
else
|
246
|
+
do_with_enum(enum) { |o| n.add(o) if include?(o) }
|
247
|
+
end
|
248
|
+
n
|
249
|
+
end
|
250
|
+
alias intersection &
|
251
|
+
|
252
|
+
def ^(enum)
|
253
|
+
n = Set.new(enum)
|
254
|
+
each { |o| n.add(o) unless n.delete?(o) }
|
255
|
+
n
|
256
|
+
end
|
257
|
+
|
258
|
+
def ==(other)
|
259
|
+
if self.equal?(other)
|
260
|
+
true
|
261
|
+
elsif other.instance_of?(self.class)
|
262
|
+
@hash == other.instance_variable_get(:@hash)
|
263
|
+
elsif other.is_a?(Set) && self.size == other.size
|
264
|
+
other.all? { |o| @hash.include?(o) }
|
265
|
+
else
|
266
|
+
false
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def hash
|
271
|
+
@hash.hash
|
272
|
+
end
|
273
|
+
|
274
|
+
def eql?(o)
|
275
|
+
return false unless o.is_a?(Set)
|
276
|
+
@hash.eql?(o.instance_variable_get(:@hash))
|
277
|
+
end
|
278
|
+
|
279
|
+
alias === include?
|
280
|
+
|
281
|
+
def classify
|
282
|
+
block_given? or return enum_for(__method__) { size }
|
283
|
+
|
284
|
+
h = {}
|
285
|
+
|
286
|
+
each { |i|
|
287
|
+
(h[yield(i)] ||= self.class.new).add(i)
|
288
|
+
}
|
289
|
+
|
290
|
+
h
|
291
|
+
end
|
292
|
+
|
293
|
+
def divide(&func)
|
294
|
+
func or return enum_for(__method__) { size }
|
295
|
+
|
296
|
+
if func.arity == 2
|
297
|
+
require 'tsort'
|
298
|
+
|
299
|
+
class << dig = {}
|
300
|
+
include TSort
|
301
|
+
|
302
|
+
alias tsort_each_node each_key
|
303
|
+
def tsort_each_child(node, &block)
|
304
|
+
fetch(node).each(&block)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
each { |u|
|
309
|
+
dig[u] = a = []
|
310
|
+
each{ |v| func.call(u, v) and a << v }
|
311
|
+
}
|
312
|
+
|
313
|
+
set = Set.new()
|
314
|
+
dig.each_strongly_connected_component { |css|
|
315
|
+
set.add(self.class.new(css))
|
316
|
+
}
|
317
|
+
set
|
318
|
+
else
|
319
|
+
Set.new(classify(&func).values)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
# sorted_set without rbtree dependency, vendored from
|
325
|
+
# https://github.com/ruby/set/blob/72f08c4/lib/set.rb#L731-L800
|
326
|
+
class CharacterSet::RubyFallback::SortedSet < CharacterSet::RubyFallback::Set
|
327
|
+
def initialize(*args)
|
328
|
+
@keys = nil
|
329
|
+
super
|
330
|
+
end
|
331
|
+
|
332
|
+
def clear
|
333
|
+
@keys = nil
|
334
|
+
super
|
335
|
+
end
|
336
|
+
|
337
|
+
def add(o)
|
338
|
+
@keys = nil
|
339
|
+
super
|
340
|
+
end
|
341
|
+
alias << add
|
342
|
+
|
343
|
+
def delete(o)
|
344
|
+
@keys = nil
|
345
|
+
@hash.delete(o)
|
346
|
+
self
|
347
|
+
end
|
348
|
+
|
349
|
+
def delete_if
|
350
|
+
block_given? or return enum_for(__method__) { size }
|
351
|
+
n = @hash.size
|
352
|
+
super
|
353
|
+
@keys = nil if @hash.size != n
|
354
|
+
self
|
355
|
+
end
|
356
|
+
|
357
|
+
def keep_if
|
358
|
+
block_given? or return enum_for(__method__) { size }
|
359
|
+
n = @hash.size
|
360
|
+
super
|
361
|
+
@keys = nil if @hash.size != n
|
362
|
+
self
|
363
|
+
end
|
364
|
+
|
365
|
+
def merge(enum)
|
366
|
+
@keys = nil
|
367
|
+
super
|
368
|
+
end
|
369
|
+
|
370
|
+
def each(&block)
|
371
|
+
block or return enum_for(__method__) { size }
|
372
|
+
to_a.each(&block)
|
373
|
+
self
|
374
|
+
end
|
375
|
+
|
376
|
+
def to_a
|
377
|
+
(@keys = @hash.keys).sort! unless @keys
|
378
|
+
@keys.dup
|
379
|
+
end
|
380
|
+
|
381
|
+
def freeze
|
382
|
+
to_a
|
383
|
+
super
|
384
|
+
end
|
385
|
+
end
|
@@ -1,8 +1,3 @@
|
|
1
|
-
if RUBY_VERSION.to_f >= 3.0 && !RUBY_PLATFORM[/java/i]
|
2
|
-
require 'sorted_set'
|
3
|
-
else
|
4
|
-
require 'set'
|
5
|
-
end
|
6
1
|
require 'character_set/ruby_fallback/set_methods'
|
7
2
|
require 'character_set/ruby_fallback/character_set_methods'
|
8
3
|
|
@@ -16,8 +11,25 @@ class CharacterSet
|
|
16
11
|
end
|
17
12
|
|
18
13
|
def initialize(enum = [])
|
19
|
-
@__set = SortedSet.new
|
14
|
+
@__set = CharacterSet::RubyFallback::SortedSet.new
|
20
15
|
super
|
21
16
|
end
|
22
17
|
end
|
23
18
|
end
|
19
|
+
|
20
|
+
if RUBY_PLATFORM[/java/i]
|
21
|
+
# JRuby has sorted_set in the stdlib.
|
22
|
+
require 'set'
|
23
|
+
CharacterSet::RubyFallback::Set = ::Set
|
24
|
+
CharacterSet::RubyFallback::SortedSet = ::SortedSet
|
25
|
+
else
|
26
|
+
# For other rubies, set/sorted_set are vendored due to dependency issues:
|
27
|
+
#
|
28
|
+
# - issues with default vs. installed gems such as [#2]
|
29
|
+
# - issues with the sorted_set dependency rb_tree
|
30
|
+
# - long-standing issues in recent versions of sorted_set
|
31
|
+
#
|
32
|
+
# The RubyFallback, and thus these set classes, are only used for testing,
|
33
|
+
# and for exotic rubies which use neither C nor Java.
|
34
|
+
require 'character_set/ruby_fallback/vendored_set_classes'
|
35
|
+
end
|
@@ -22,7 +22,7 @@ class CharacterSet
|
|
22
22
|
|
23
23
|
# Allow some methods to take an Enum just as well as another CharacterSet.
|
24
24
|
# Tested by ruby-spec.
|
25
|
-
%w[& + - ^ | difference disjoint? intersect? intersection
|
25
|
+
%w[& + - ^ | <=> difference disjoint? intersect? intersection
|
26
26
|
subtract union].each do |method|
|
27
27
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
28
28
|
def #{method}(arg)
|
@@ -165,8 +165,12 @@ class CharacterSet
|
|
165
165
|
end
|
166
166
|
|
167
167
|
def divide(&func)
|
168
|
-
|
169
|
-
Set.new(to_a).divide(&func)
|
168
|
+
require 'character_set/ruby_fallback'
|
169
|
+
CharacterSet::RubyFallback::Set.new(to_a).divide(&func)
|
170
|
+
end
|
171
|
+
|
172
|
+
def join(separator = '')
|
173
|
+
to_a(true).join(separator)
|
170
174
|
end
|
171
175
|
RUBY
|
172
176
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
desc 'Run all IPS benchmarks'
|
2
|
+
task :benchmark do
|
3
|
+
Dir["#{__dir__}/benchmarks/*.rb"].sort.each { |file| load(file) }
|
4
|
+
end
|
5
|
+
|
6
|
+
namespace :benchmark do
|
7
|
+
desc 'Run all IPS benchmarks and store the comparison results in BENCHMARK.md'
|
8
|
+
task :write_to_file do
|
9
|
+
Rake.application[:benchmark].invoke
|
10
|
+
|
11
|
+
# extract comparison results from reports
|
12
|
+
results = $benchmark_results
|
13
|
+
.map { |caption, report| "```\n#{caption}\n\n#{report[/(?<=Comparison:).+/m].strip}\n```" }
|
14
|
+
.join("\n")
|
15
|
+
.gsub(/ \(±[^)]+\) |(?<=same-ish).*/, '') # remove some noise
|
16
|
+
|
17
|
+
File.write "#{__dir__}/../BENCHMARK.md",
|
18
|
+
"Results of `rake:benchmark` on #{RUBY_DESCRIPTION}\n\n#{results}\n"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'benchmark/ips'
|
2
|
+
require_relative '../../lib/character_set'
|
3
|
+
if RUBY_VERSION.to_f >= 3.0 && !RUBY_PLATFORM[/java/i]
|
4
|
+
require 'sorted_set'
|
5
|
+
else
|
6
|
+
require 'set'
|
7
|
+
end
|
8
|
+
|
9
|
+
def benchmark(caption: nil, cases: {})
|
10
|
+
with_stdouts($stdout, string_io = StringIO.new) do
|
11
|
+
puts caption
|
12
|
+
Benchmark.ips do |x|
|
13
|
+
cases.each { |label, callable| x.report(label, &callable) }
|
14
|
+
x.compare!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
($benchmark_results ||= {})[caption] = string_io.string
|
18
|
+
end
|
19
|
+
|
20
|
+
def with_stdouts(*ios)
|
21
|
+
old_stdout = $stdout
|
22
|
+
ios.define_singleton_method(:method_missing) { |*args| each { |io| io.send(*args) } }
|
23
|
+
ios.define_singleton_method(:respond_to?) { |*args| IO.respond_to?(*args) }
|
24
|
+
$stdout = ios
|
25
|
+
yield
|
26
|
+
ensure
|
27
|
+
$stdout = old_stdout
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
desc 'Download unicode casefold data and write new C header file'
|
2
|
+
task :sync_casefold_data do
|
3
|
+
src_path = './CaseFolding.txt'
|
4
|
+
dst_path = "#{__dir__}/../ext/character_set/unicode_casefold_table.h"
|
5
|
+
|
6
|
+
`wget http://www.unicode.org/Public/UNIDATA/CaseFolding.txt`
|
7
|
+
|
8
|
+
mapping = File.foreach(src_path).each_with_object({}) do |line, hash|
|
9
|
+
from, type, to = line.split(/\s*;\s*/).first(3)
|
10
|
+
# type 'C' stands for 'common', excludes mappings to multiple chars
|
11
|
+
hash[from] = to if type == 'C'
|
12
|
+
end.sort
|
13
|
+
|
14
|
+
content = File.read(dst_path + '.tmpl')
|
15
|
+
.sub(/(CASEFOLD_COUNT )0/, "\\1#{mapping.count}")
|
16
|
+
.sub('{}', ['{', mapping.map { |a, b| "{0x#{a},0x#{b}}," }, '}'].join("\n"))
|
17
|
+
|
18
|
+
File.write(dst_path, content)
|
19
|
+
File.unlink(src_path)
|
20
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
desc 'Update codepoint data for predefined sets, based on Onigmo'
|
2
|
+
task :sync_predefined_sets do
|
3
|
+
%w[assigned emoji whitespace].each do |prop|
|
4
|
+
require 'regexp_property_values'
|
5
|
+
ranges = RegexpPropertyValues[prop].matched_ranges
|
6
|
+
str = ranges.map { |r| "#{r.min.to_s(16)},#{r.max.to_s(16)}\n" }.join.upcase
|
7
|
+
File.write("#{__dir__}/../lib/character_set/predefined_sets/#{prop}.cps", str, mode: 'w')
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
desc 'Download relevant ruby/spec tests, adapt to CharacterSet and its variants'
|
2
|
+
task :sync_ruby_spec do
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
variants = {
|
6
|
+
'CharacterSet' => "#{__dir__}/../spec/ruby-spec/library/character_set",
|
7
|
+
'CharacterSet::Pure' => "#{__dir__}/../spec/ruby-spec/library/character_set_pure",
|
8
|
+
}
|
9
|
+
|
10
|
+
# download fresh specs from ruby/spec repository
|
11
|
+
variants.each do |_, dir|
|
12
|
+
FileUtils.rm_rf(dir)
|
13
|
+
`svn export https://github.com/ruby/spec/trunk/library/set/sortedset #{dir}`
|
14
|
+
end
|
15
|
+
|
16
|
+
# make copies for each CharacterSet variant
|
17
|
+
base = variants.first[1]
|
18
|
+
variants.each_value { |dir| FileUtils.copy_entry(base, dir) unless dir == base }
|
19
|
+
|
20
|
+
# adapt specs to work with CharacterSet
|
21
|
+
variants.each do |class_name, dir|
|
22
|
+
Dir["#{dir}/**/*.rb"].each do |spec|
|
23
|
+
# ignore some tests that do not apply or are covered otherwise
|
24
|
+
if spec =~ %r{/(classify|divide|flatten|initialize|pretty_print)}
|
25
|
+
File.delete(spec)
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
adapted_content =
|
30
|
+
File.read(spec).
|
31
|
+
# adapt class name
|
32
|
+
gsub('SortedSet', (spec['/shared/'] ? 'variant' : class_name)).
|
33
|
+
gsub(/(it_behaves_like :[^,\n]+), (:[^,\n]+)/, "\\1, #{class_name}, \\2").
|
34
|
+
# get shared specs from a single shared dir at the parent level
|
35
|
+
gsub(/(require_relative ['"])(shared\/)/, '\1../\2').
|
36
|
+
# make 'mspec' syntax rspec-compatible
|
37
|
+
gsub(/describe (.*), shared.*$/, 'shared_examples \1 do |variant, method|').
|
38
|
+
gsub(/be_(false|true)/, 'be \1').
|
39
|
+
gsub('stub!', 'stub').
|
40
|
+
gsub('mock', 'double').
|
41
|
+
gsub('@method', 'method').
|
42
|
+
# remove unneeded requires
|
43
|
+
gsub(/require 'set'\n/, '').
|
44
|
+
gsub(/require.*spec_helper.*\n/, '').
|
45
|
+
gsub(/\A\n+/, '').
|
46
|
+
# make examples use Integers/codepoints
|
47
|
+
gsub(/1\.0|"cat"|"dog"|"hello"|"test"/, '0').
|
48
|
+
gsub('"one"', '1').
|
49
|
+
gsub('"two"', '2').
|
50
|
+
gsub('"three"', '3').
|
51
|
+
gsub('"four"', '4').
|
52
|
+
gsub('"five"', '5').
|
53
|
+
gsub(/x.(size|length) == 3/, 'x != 3').
|
54
|
+
gsub(/x.(size|length) != 3/, 'x == 3').
|
55
|
+
gsub(/(add)\(\d\)(\.to_a \}.should raise)/, '\1(:foo)\2')
|
56
|
+
|
57
|
+
File.open(spec, 'w') { |f| f.puts adapted_content }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# keep only one copy of the shared specs, at the parent level
|
62
|
+
FileUtils.rm_rf(base + '/../shared')
|
63
|
+
FileUtils.mv(base + '/shared', base + '/../')
|
64
|
+
variants.each_value { |dir| FileUtils.rm_rf(dir + '/shared') }
|
65
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: character_set
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Janosch Müller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: sorted_set
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: range_compressor
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,17 +45,6 @@ files:
|
|
59
45
|
- LICENSE.txt
|
60
46
|
- README.md
|
61
47
|
- Rakefile
|
62
|
-
- benchmarks/count_in.rb
|
63
|
-
- benchmarks/cover.rb
|
64
|
-
- benchmarks/delete_in.rb
|
65
|
-
- benchmarks/keep_in.rb
|
66
|
-
- benchmarks/scan.rb
|
67
|
-
- benchmarks/shared.rb
|
68
|
-
- benchmarks/used_by.rb
|
69
|
-
- benchmarks/z_add.rb
|
70
|
-
- benchmarks/z_delete.rb
|
71
|
-
- benchmarks/z_merge.rb
|
72
|
-
- benchmarks/z_minmax.rb
|
73
48
|
- bin/console
|
74
49
|
- bin/setup
|
75
50
|
- character_set.gemspec
|
@@ -105,10 +80,26 @@ files:
|
|
105
80
|
- lib/character_set/ruby_fallback.rb
|
106
81
|
- lib/character_set/ruby_fallback/character_set_methods.rb
|
107
82
|
- lib/character_set/ruby_fallback/set_methods.rb
|
83
|
+
- lib/character_set/ruby_fallback/vendored_set_classes.rb
|
108
84
|
- lib/character_set/set_method_adapters.rb
|
109
85
|
- lib/character_set/shared_methods.rb
|
110
86
|
- lib/character_set/version.rb
|
111
87
|
- lib/character_set/writer.rb
|
88
|
+
- tasks/benchmark.rake
|
89
|
+
- tasks/benchmarks/count_in.rb
|
90
|
+
- tasks/benchmarks/cover.rb
|
91
|
+
- tasks/benchmarks/delete_in.rb
|
92
|
+
- tasks/benchmarks/keep_in.rb
|
93
|
+
- tasks/benchmarks/scan.rb
|
94
|
+
- tasks/benchmarks/shared.rb
|
95
|
+
- tasks/benchmarks/used_by.rb
|
96
|
+
- tasks/benchmarks/z_add.rb
|
97
|
+
- tasks/benchmarks/z_delete.rb
|
98
|
+
- tasks/benchmarks/z_merge.rb
|
99
|
+
- tasks/benchmarks/z_minmax.rb
|
100
|
+
- tasks/sync_casefold_data.rake
|
101
|
+
- tasks/sync_predefined_sets.rake
|
102
|
+
- tasks/sync_ruby_spec.rake
|
112
103
|
homepage: https://github.com/jaynetics/character_set
|
113
104
|
licenses:
|
114
105
|
- MIT
|
@@ -128,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
119
|
- !ruby/object:Gem::Version
|
129
120
|
version: '0'
|
130
121
|
requirements: []
|
131
|
-
rubygems_version: 3.
|
122
|
+
rubygems_version: 3.5.0.dev
|
132
123
|
signing_key:
|
133
124
|
specification_version: 4
|
134
125
|
summary: Build, read, write and compare sets of Unicode codepoints.
|