re2 2.9.0 → 2.27.0
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/Gemfile +6 -0
- data/README.md +130 -22
- data/Rakefile +52 -90
- data/dependencies.yml +4 -4
- data/ext/re2/extconf.rb +256 -290
- data/ext/re2/re2.cc +1037 -318
- data/ext/re2/recipes.rb +24 -21
- data/lib/re2/regexp.rb +2 -0
- data/lib/re2/scanner.rb +2 -0
- data/lib/re2/string.rb +8 -6
- data/lib/re2/version.rb +1 -1
- data/lib/re2.rb +2 -0
- data/ports/archives/20260107.1.tar.gz +0 -0
- data/ports/archives/re2-2025-11-05.tar.gz +0 -0
- data/re2.gemspec +6 -4
- data/spec/kernel_spec.rb +2 -0
- data/spec/re2/match_data_spec.rb +520 -5
- data/spec/re2/regexp_spec.rb +342 -0
- data/spec/re2/scanner_spec.rb +185 -15
- data/spec/re2/set_spec.rb +123 -6
- data/spec/re2/string_spec.rb +2 -0
- data/spec/re2_spec.rb +219 -43
- data/spec/spec_helper.rb +2 -0
- metadata +17 -21
- data/ports/archives/20240116.1.tar.gz +0 -0
- data/ports/archives/re2-2024-03-01.tar.gz +0 -0
data/spec/re2/regexp_spec.rb
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rbconfig/sizeof"
|
|
4
|
+
|
|
1
5
|
RSpec.describe RE2::Regexp do
|
|
6
|
+
INT_MAX = 2**(RbConfig::SIZEOF.fetch("int") * 8 - 1) - 1
|
|
7
|
+
|
|
2
8
|
describe "#initialize" do
|
|
3
9
|
it "returns an instance given only a pattern" do
|
|
4
10
|
re = RE2::Regexp.new('woo')
|
|
@@ -33,6 +39,77 @@ RSpec.describe RE2::Regexp do
|
|
|
33
39
|
|
|
34
40
|
expect(re).to be_a(RE2::Regexp)
|
|
35
41
|
end
|
|
42
|
+
|
|
43
|
+
it "returns a frozen object" do
|
|
44
|
+
expect(RE2::Regexp.new('woo')).to be_frozen
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "cannot be re-initialized" do
|
|
48
|
+
re = RE2::Regexp.new('woo')
|
|
49
|
+
|
|
50
|
+
expect { re.send(:initialize, 'bar') }.to raise_error(FrozenError)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "#dup" do
|
|
55
|
+
it "returns a copy with the same pattern" do
|
|
56
|
+
re = described_class.new('(\d+)')
|
|
57
|
+
copy = re.dup
|
|
58
|
+
|
|
59
|
+
expect(copy.to_s).to eq('(\d+)')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "returns a different object" do
|
|
63
|
+
re = described_class.new('(\d+)')
|
|
64
|
+
copy = re.dup
|
|
65
|
+
|
|
66
|
+
expect(copy).to_not equal(re)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "returns a valid copy" do
|
|
70
|
+
re = described_class.new('(\d+)')
|
|
71
|
+
copy = re.dup
|
|
72
|
+
|
|
73
|
+
expect(copy.ok?).to eq(true)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "copies options from the original" do
|
|
77
|
+
re = described_class.new('(\d+)', case_sensitive: false)
|
|
78
|
+
copy = re.dup
|
|
79
|
+
|
|
80
|
+
expect(copy).to_not be_case_sensitive
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "returns a frozen copy" do
|
|
84
|
+
re = described_class.new('(\d+)')
|
|
85
|
+
copy = re.dup
|
|
86
|
+
|
|
87
|
+
expect(copy).to be_frozen
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "raises an error when called on an uninitialized object" do
|
|
91
|
+
expect { described_class.allocate.dup }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "#clone" do
|
|
96
|
+
it "returns a copy with the same pattern" do
|
|
97
|
+
re = described_class.new('woo')
|
|
98
|
+
copy = re.clone
|
|
99
|
+
|
|
100
|
+
expect(copy.to_s).to eq('woo')
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "returns a frozen copy" do
|
|
104
|
+
re = described_class.new('woo')
|
|
105
|
+
copy = re.clone
|
|
106
|
+
|
|
107
|
+
expect(copy).to be_frozen
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "raises an error when called on an uninitialized object" do
|
|
111
|
+
expect { described_class.allocate.clone }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
112
|
+
end
|
|
36
113
|
end
|
|
37
114
|
|
|
38
115
|
describe ".compile" do
|
|
@@ -96,6 +173,10 @@ RSpec.describe RE2::Regexp do
|
|
|
96
173
|
|
|
97
174
|
expect(options).to include(case_sensitive: false)
|
|
98
175
|
end
|
|
176
|
+
|
|
177
|
+
it "raises an error when called on an uninitialized object" do
|
|
178
|
+
expect { described_class.allocate.options }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
179
|
+
end
|
|
99
180
|
end
|
|
100
181
|
|
|
101
182
|
describe "#error" do
|
|
@@ -111,6 +192,10 @@ RSpec.describe RE2::Regexp do
|
|
|
111
192
|
|
|
112
193
|
expect(error).to eq("missing ): wo(o")
|
|
113
194
|
end
|
|
195
|
+
|
|
196
|
+
it "raises an error when called on an uninitialized object" do
|
|
197
|
+
expect { described_class.allocate.error }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
198
|
+
end
|
|
114
199
|
end
|
|
115
200
|
|
|
116
201
|
describe "#error_arg" do
|
|
@@ -125,6 +210,10 @@ RSpec.describe RE2::Regexp do
|
|
|
125
210
|
|
|
126
211
|
expect(error_arg).to eq("wo(o")
|
|
127
212
|
end
|
|
213
|
+
|
|
214
|
+
it "raises an error when called on an uninitialized object" do
|
|
215
|
+
expect { described_class.allocate.error_arg }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
216
|
+
end
|
|
128
217
|
end
|
|
129
218
|
|
|
130
219
|
describe "#program_size" do
|
|
@@ -139,6 +228,10 @@ RSpec.describe RE2::Regexp do
|
|
|
139
228
|
|
|
140
229
|
expect(program_size).to eq(-1)
|
|
141
230
|
end
|
|
231
|
+
|
|
232
|
+
it "raises an error when called on an uninitialized object" do
|
|
233
|
+
expect { described_class.allocate.program_size }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
234
|
+
end
|
|
142
235
|
end
|
|
143
236
|
|
|
144
237
|
describe "#to_str" do
|
|
@@ -153,6 +246,10 @@ RSpec.describe RE2::Regexp do
|
|
|
153
246
|
|
|
154
247
|
expect(string).to eq("???")
|
|
155
248
|
end
|
|
249
|
+
|
|
250
|
+
it "raises an error when called on an uninitialized object" do
|
|
251
|
+
expect { described_class.allocate.to_str }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
252
|
+
end
|
|
156
253
|
end
|
|
157
254
|
|
|
158
255
|
describe "#pattern" do
|
|
@@ -167,6 +264,10 @@ RSpec.describe RE2::Regexp do
|
|
|
167
264
|
|
|
168
265
|
expect(pattern).to eq("???")
|
|
169
266
|
end
|
|
267
|
+
|
|
268
|
+
it "raises an error when called on an uninitialized object" do
|
|
269
|
+
expect { described_class.allocate.pattern }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
270
|
+
end
|
|
170
271
|
end
|
|
171
272
|
|
|
172
273
|
describe "#inspect" do
|
|
@@ -181,6 +282,10 @@ RSpec.describe RE2::Regexp do
|
|
|
181
282
|
|
|
182
283
|
expect(string.encoding).to eq(Encoding::ISO_8859_1)
|
|
183
284
|
end
|
|
285
|
+
|
|
286
|
+
it "raises an error when called on an uninitialized object" do
|
|
287
|
+
expect { described_class.allocate.inspect }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
288
|
+
end
|
|
184
289
|
end
|
|
185
290
|
|
|
186
291
|
describe "#utf8?" do
|
|
@@ -193,6 +298,10 @@ RSpec.describe RE2::Regexp do
|
|
|
193
298
|
|
|
194
299
|
expect(re).to_not be_utf8
|
|
195
300
|
end
|
|
301
|
+
|
|
302
|
+
it "raises an error when called on an uninitialized object" do
|
|
303
|
+
expect { described_class.allocate.utf8? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
304
|
+
end
|
|
196
305
|
end
|
|
197
306
|
|
|
198
307
|
describe "#posix_syntax?" do
|
|
@@ -205,6 +314,10 @@ RSpec.describe RE2::Regexp do
|
|
|
205
314
|
|
|
206
315
|
expect(re).to be_posix_syntax
|
|
207
316
|
end
|
|
317
|
+
|
|
318
|
+
it "raises an error when called on an uninitialized object" do
|
|
319
|
+
expect { described_class.allocate.posix_syntax? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
320
|
+
end
|
|
208
321
|
end
|
|
209
322
|
|
|
210
323
|
describe "#literal?" do
|
|
@@ -217,6 +330,10 @@ RSpec.describe RE2::Regexp do
|
|
|
217
330
|
|
|
218
331
|
expect(re).to be_literal
|
|
219
332
|
end
|
|
333
|
+
|
|
334
|
+
it "raises an error when called on an uninitialized object" do
|
|
335
|
+
expect { described_class.allocate.literal? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
336
|
+
end
|
|
220
337
|
end
|
|
221
338
|
|
|
222
339
|
describe "#never_nl?" do
|
|
@@ -229,6 +346,10 @@ RSpec.describe RE2::Regexp do
|
|
|
229
346
|
|
|
230
347
|
expect(re).to be_never_nl
|
|
231
348
|
end
|
|
349
|
+
|
|
350
|
+
it "raises an error when called on an uninitialized object" do
|
|
351
|
+
expect { described_class.allocate.never_nl? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
352
|
+
end
|
|
232
353
|
end
|
|
233
354
|
|
|
234
355
|
describe "#case_sensitive?" do
|
|
@@ -240,6 +361,10 @@ RSpec.describe RE2::Regexp do
|
|
|
240
361
|
re = RE2::Regexp.new('woo', case_sensitive: false)
|
|
241
362
|
expect(re).to_not be_case_sensitive
|
|
242
363
|
end
|
|
364
|
+
|
|
365
|
+
it "raises an error when called on an uninitialized object" do
|
|
366
|
+
expect { described_class.allocate.case_sensitive? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
367
|
+
end
|
|
243
368
|
end
|
|
244
369
|
|
|
245
370
|
describe "#case_insensitive?" do
|
|
@@ -252,6 +377,10 @@ RSpec.describe RE2::Regexp do
|
|
|
252
377
|
|
|
253
378
|
expect(re).to be_case_insensitive
|
|
254
379
|
end
|
|
380
|
+
|
|
381
|
+
it "raises an error when called on an uninitialized object" do
|
|
382
|
+
expect { described_class.allocate.case_insensitive? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
383
|
+
end
|
|
255
384
|
end
|
|
256
385
|
|
|
257
386
|
describe "#casefold?" do
|
|
@@ -264,6 +393,10 @@ RSpec.describe RE2::Regexp do
|
|
|
264
393
|
|
|
265
394
|
expect(re).to be_casefold
|
|
266
395
|
end
|
|
396
|
+
|
|
397
|
+
it "raises an error when called on an uninitialized object" do
|
|
398
|
+
expect { described_class.allocate.casefold? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
399
|
+
end
|
|
267
400
|
end
|
|
268
401
|
|
|
269
402
|
describe "#longest_match?" do
|
|
@@ -276,6 +409,10 @@ RSpec.describe RE2::Regexp do
|
|
|
276
409
|
|
|
277
410
|
expect(re).to be_longest_match
|
|
278
411
|
end
|
|
412
|
+
|
|
413
|
+
it "raises an error when called on an uninitialized object" do
|
|
414
|
+
expect { described_class.allocate.longest_match? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
415
|
+
end
|
|
279
416
|
end
|
|
280
417
|
|
|
281
418
|
describe "#log_errors?" do
|
|
@@ -288,6 +425,10 @@ RSpec.describe RE2::Regexp do
|
|
|
288
425
|
|
|
289
426
|
expect(re).to_not be_log_errors
|
|
290
427
|
end
|
|
428
|
+
|
|
429
|
+
it "raises an error when called on an uninitialized object" do
|
|
430
|
+
expect { described_class.allocate.log_errors? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
431
|
+
end
|
|
291
432
|
end
|
|
292
433
|
|
|
293
434
|
describe "#perl_classes?" do
|
|
@@ -300,6 +441,10 @@ RSpec.describe RE2::Regexp do
|
|
|
300
441
|
|
|
301
442
|
expect(re).to be_perl_classes
|
|
302
443
|
end
|
|
444
|
+
|
|
445
|
+
it "raises an error when called on an uninitialized object" do
|
|
446
|
+
expect { described_class.allocate.perl_classes? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
447
|
+
end
|
|
303
448
|
end
|
|
304
449
|
|
|
305
450
|
describe "#word_boundary?" do
|
|
@@ -312,6 +457,10 @@ RSpec.describe RE2::Regexp do
|
|
|
312
457
|
|
|
313
458
|
expect(re).to be_word_boundary
|
|
314
459
|
end
|
|
460
|
+
|
|
461
|
+
it "raises an error when called on an uninitialized object" do
|
|
462
|
+
expect { described_class.allocate.word_boundary? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
463
|
+
end
|
|
315
464
|
end
|
|
316
465
|
|
|
317
466
|
describe "#one_line?" do
|
|
@@ -324,6 +473,10 @@ RSpec.describe RE2::Regexp do
|
|
|
324
473
|
|
|
325
474
|
expect(re).to be_one_line
|
|
326
475
|
end
|
|
476
|
+
|
|
477
|
+
it "raises an error when called on an uninitialized object" do
|
|
478
|
+
expect { described_class.allocate.one_line? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
479
|
+
end
|
|
327
480
|
end
|
|
328
481
|
|
|
329
482
|
describe "#max_mem" do
|
|
@@ -336,6 +489,10 @@ RSpec.describe RE2::Regexp do
|
|
|
336
489
|
|
|
337
490
|
expect(re.max_mem).to eq(1024)
|
|
338
491
|
end
|
|
492
|
+
|
|
493
|
+
it "raises an error when called on an uninitialized object" do
|
|
494
|
+
expect { described_class.allocate.max_mem }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
495
|
+
end
|
|
339
496
|
end
|
|
340
497
|
|
|
341
498
|
describe "#match" do
|
|
@@ -457,6 +614,24 @@ RSpec.describe RE2::Regexp do
|
|
|
457
614
|
expect { re.match("one two three", endpos: 3) }.to raise_error(RE2::Regexp::UnsupportedError)
|
|
458
615
|
end
|
|
459
616
|
|
|
617
|
+
it "does not truncate startpos to 32 bits" do
|
|
618
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
|
619
|
+
skip "size_t is not larger than a 32-bit int" if RbConfig::SIZEOF.fetch("size_t") <= (32 / 8)
|
|
620
|
+
|
|
621
|
+
re = RE2::Regexp.new('(\w+)', log_errors: false)
|
|
622
|
+
|
|
623
|
+
expect(re.match("one two three", startpos: 2_147_483_648, endpos: 2_147_483_649)).to be_nil
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
it "does not truncate endpos to 32 bits" do
|
|
627
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
|
628
|
+
skip "size_t is not larger than a 32-bit int" if RbConfig::SIZEOF.fetch("size_t") <= (32 / 8)
|
|
629
|
+
|
|
630
|
+
re = RE2::Regexp.new('(\w+)', log_errors: false)
|
|
631
|
+
|
|
632
|
+
expect(re.match("one two three", endpos: 2_147_483_648)).to be_nil
|
|
633
|
+
end
|
|
634
|
+
|
|
460
635
|
it "does not anchor matches by default when extracting submatches" do
|
|
461
636
|
re = RE2::Regexp.new('(two)')
|
|
462
637
|
|
|
@@ -564,6 +739,12 @@ RSpec.describe RE2::Regexp do
|
|
|
564
739
|
expect { re.match("one two three", submatches: :invalid) }.to raise_error(TypeError)
|
|
565
740
|
end
|
|
566
741
|
|
|
742
|
+
it "raises an exception when given too large a number of submatches" do
|
|
743
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
|
744
|
+
|
|
745
|
+
expect { re.match("one two three", submatches: INT_MAX) }.to raise_error(RangeError, "number of matches should be < #{INT_MAX}")
|
|
746
|
+
end
|
|
747
|
+
|
|
567
748
|
it "defaults to extracting all submatches when given nil", :aggregate_failures do
|
|
568
749
|
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
|
569
750
|
md = re.match("one two three", submatches: nil)
|
|
@@ -582,6 +763,12 @@ RSpec.describe RE2::Regexp do
|
|
|
582
763
|
expect(md[3]).to be_nil
|
|
583
764
|
end
|
|
584
765
|
|
|
766
|
+
it "raises an exception if given too large a number of submatches instead of options" do
|
|
767
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
|
768
|
+
|
|
769
|
+
expect { re.match("one two three", INT_MAX) }.to raise_error(RangeError, "number of matches should be < #{INT_MAX}")
|
|
770
|
+
end
|
|
771
|
+
|
|
585
772
|
it "raises an exception when given invalid options" do
|
|
586
773
|
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
|
587
774
|
|
|
@@ -593,6 +780,29 @@ RSpec.describe RE2::Regexp do
|
|
|
593
780
|
|
|
594
781
|
expect(re.match("one two three", nil)).to be_a(RE2::MatchData)
|
|
595
782
|
end
|
|
783
|
+
|
|
784
|
+
it "raises an error when startpos exceeds INT_MAX on old RE2 ABI" do
|
|
785
|
+
skip "Underlying RE2::Match does not take int startpos" if RE2::Regexp.match_has_endpos_argument?
|
|
786
|
+
skip "size_t is not larger than a 32-bit int" if RbConfig::SIZEOF.fetch("size_t") <= (32 / 8)
|
|
787
|
+
|
|
788
|
+
re = RE2::Regexp.new('(\w+)', log_errors: false)
|
|
789
|
+
|
|
790
|
+
expect { re.match("test", start_pos: 2_147_483_648) }.to raise_error(RangeError, /startpos should be <=/)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
it "raises an error when called on an uninitialized object" do
|
|
794
|
+
expect { described_class.allocate.match("test") }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
it "can be run concurrently" do
|
|
798
|
+
re = RE2::Regexp.new('(\w+)\s(\w+)')
|
|
799
|
+
|
|
800
|
+
threads = 10.times.map do
|
|
801
|
+
Thread.new { re.match("one two").values_at(1, 2) }
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
expect(threads.map(&:value)).to all(eq(["one", "two"]))
|
|
805
|
+
end
|
|
596
806
|
end
|
|
597
807
|
|
|
598
808
|
describe "#match?" do
|
|
@@ -614,6 +824,20 @@ RSpec.describe RE2::Regexp do
|
|
|
614
824
|
|
|
615
825
|
expect { re.match?(0) }.to raise_error(TypeError)
|
|
616
826
|
end
|
|
827
|
+
|
|
828
|
+
it "raises an error when called on an uninitialized object" do
|
|
829
|
+
expect { described_class.allocate.match?("test") }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
it "can be run concurrently" do
|
|
833
|
+
re = RE2::Regexp.new('(\w+)\s(\w+)')
|
|
834
|
+
|
|
835
|
+
threads = 10.times.map do
|
|
836
|
+
Thread.new { re.match?("one two") }
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
expect(threads.map(&:value)).to all(eq(true))
|
|
840
|
+
end
|
|
617
841
|
end
|
|
618
842
|
|
|
619
843
|
describe "#partial_match?" do
|
|
@@ -642,6 +866,20 @@ RSpec.describe RE2::Regexp do
|
|
|
642
866
|
|
|
643
867
|
expect { re.partial_match?(0) }.to raise_error(TypeError)
|
|
644
868
|
end
|
|
869
|
+
|
|
870
|
+
it "raises an error when called on an uninitialized object" do
|
|
871
|
+
expect { described_class.allocate.partial_match?("test") }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
it "can be run concurrently" do
|
|
875
|
+
re = RE2::Regexp.new('(\d+)')
|
|
876
|
+
|
|
877
|
+
threads = 10.times.map do
|
|
878
|
+
Thread.new { re.partial_match?("alice 123") }
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
expect(threads.map(&:value)).to all(eq(true))
|
|
882
|
+
end
|
|
645
883
|
end
|
|
646
884
|
|
|
647
885
|
describe "#=~" do
|
|
@@ -670,6 +908,10 @@ RSpec.describe RE2::Regexp do
|
|
|
670
908
|
|
|
671
909
|
expect { re =~ 0 }.to raise_error(TypeError)
|
|
672
910
|
end
|
|
911
|
+
|
|
912
|
+
it "raises an error when called on an uninitialized object" do
|
|
913
|
+
expect { described_class.allocate =~ "test" }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
914
|
+
end
|
|
673
915
|
end
|
|
674
916
|
|
|
675
917
|
describe "#===" do
|
|
@@ -691,6 +933,10 @@ RSpec.describe RE2::Regexp do
|
|
|
691
933
|
|
|
692
934
|
expect { re === 0 }.to raise_error(TypeError)
|
|
693
935
|
end
|
|
936
|
+
|
|
937
|
+
it "raises an error when called on an uninitialized object" do
|
|
938
|
+
expect { described_class.allocate === "test" }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
939
|
+
end
|
|
694
940
|
end
|
|
695
941
|
|
|
696
942
|
describe "#full_match?" do
|
|
@@ -719,6 +965,20 @@ RSpec.describe RE2::Regexp do
|
|
|
719
965
|
|
|
720
966
|
expect { re.full_match?(0) }.to raise_error(TypeError)
|
|
721
967
|
end
|
|
968
|
+
|
|
969
|
+
it "raises an error when called on an uninitialized object" do
|
|
970
|
+
expect { described_class.allocate.full_match?("test") }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
it "can be run concurrently" do
|
|
974
|
+
re = RE2::Regexp.new('(\w+) (\d+)')
|
|
975
|
+
|
|
976
|
+
threads = 10.times.map do
|
|
977
|
+
Thread.new { re.full_match?("alice 123") }
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
expect(threads.map(&:value)).to all(eq(true))
|
|
981
|
+
end
|
|
722
982
|
end
|
|
723
983
|
|
|
724
984
|
describe "#ok?" do
|
|
@@ -733,6 +993,10 @@ RSpec.describe RE2::Regexp do
|
|
|
733
993
|
expect(RE2::Regexp.new('wo[o', log_errors: false)).to_not be_ok
|
|
734
994
|
expect(RE2::Regexp.new('*', log_errors: false)).to_not be_ok
|
|
735
995
|
end
|
|
996
|
+
|
|
997
|
+
it "raises an error when called on an uninitialized object" do
|
|
998
|
+
expect { described_class.allocate.ok? }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
999
|
+
end
|
|
736
1000
|
end
|
|
737
1001
|
|
|
738
1002
|
describe ".escape" do
|
|
@@ -757,6 +1021,10 @@ RSpec.describe RE2::Regexp do
|
|
|
757
1021
|
it "returns -1 for an invalid pattern" do
|
|
758
1022
|
expect(RE2::Regexp.new('???', log_errors: false).number_of_capturing_groups).to eq(-1)
|
|
759
1023
|
end
|
|
1024
|
+
|
|
1025
|
+
it "raises an error when called on an uninitialized object" do
|
|
1026
|
+
expect { described_class.allocate.number_of_capturing_groups }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1027
|
+
end
|
|
760
1028
|
end
|
|
761
1029
|
|
|
762
1030
|
describe "#named_capturing_groups" do
|
|
@@ -779,6 +1047,68 @@ RSpec.describe RE2::Regexp do
|
|
|
779
1047
|
it "returns an empty hash for an invalid regexp" do
|
|
780
1048
|
expect(RE2::Regexp.new('???', log_errors: false).named_capturing_groups).to be_empty
|
|
781
1049
|
end
|
|
1050
|
+
|
|
1051
|
+
it "raises an error when called on an uninitialized object" do
|
|
1052
|
+
expect { described_class.allocate.named_capturing_groups }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1053
|
+
end
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
describe "#names" do
|
|
1057
|
+
it "returns an array of names of named capturing groups" do
|
|
1058
|
+
expect(RE2::Regexp.new('(?P<bob>a)(?P<rob>b)').names).to eq(["bob", "rob"])
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
it "returns an empty array if there are no named capturing groups" do
|
|
1062
|
+
expect(RE2::Regexp.new('(a)(b)').names).to be_empty
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
it "returns an empty array for a pattern with no capturing groups" do
|
|
1066
|
+
expect(RE2::Regexp.new('ab').names).to be_empty
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
it "returns an empty array for an invalid regexp" do
|
|
1070
|
+
expect(RE2::Regexp.new('???', log_errors: false).names).to be_empty
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
it "returns UTF-8 strings if the pattern is UTF-8" do
|
|
1074
|
+
names = RE2::Regexp.new('(?P<bob>a)').names
|
|
1075
|
+
|
|
1076
|
+
expect(names.first.encoding).to eq(Encoding::UTF_8)
|
|
1077
|
+
end
|
|
1078
|
+
|
|
1079
|
+
it "returns ISO-8859-1 strings if the pattern is not UTF-8" do
|
|
1080
|
+
names = RE2::Regexp.new('(?P<bob>a)', utf8: false).names
|
|
1081
|
+
|
|
1082
|
+
expect(names.first.encoding).to eq(Encoding::ISO_8859_1)
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
it "raises an error when called on an uninitialized object" do
|
|
1086
|
+
expect { described_class.allocate.names }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1087
|
+
end
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
describe "#named_captures" do
|
|
1091
|
+
it "returns a hash of names to indices" do
|
|
1092
|
+
expect(RE2::Regexp.new('(?P<bob>a)').named_captures).to eq("bob" => 1)
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
it "maps names to indices with several groups" do
|
|
1096
|
+
groups = RE2::Regexp.new('(?P<bob>a)(o)(?P<rob>e)').named_captures
|
|
1097
|
+
|
|
1098
|
+
expect(groups).to eq("bob" => 1, "rob" => 3)
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1101
|
+
it "returns an empty hash for a pattern with no named groups" do
|
|
1102
|
+
expect(RE2::Regexp.new('(a)(b)').named_captures).to be_empty
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1105
|
+
it "returns an empty hash for an invalid regexp" do
|
|
1106
|
+
expect(RE2::Regexp.new('???', log_errors: false).named_captures).to be_empty
|
|
1107
|
+
end
|
|
1108
|
+
|
|
1109
|
+
it "raises an error when called on an uninitialized object" do
|
|
1110
|
+
expect { described_class.allocate.named_captures }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1111
|
+
end
|
|
782
1112
|
end
|
|
783
1113
|
|
|
784
1114
|
describe "#scan" do
|
|
@@ -794,6 +1124,10 @@ RSpec.describe RE2::Regexp do
|
|
|
794
1124
|
|
|
795
1125
|
expect { r.scan(nil) }.to raise_error(TypeError)
|
|
796
1126
|
end
|
|
1127
|
+
|
|
1128
|
+
it "raises an error when called on an uninitialized object" do
|
|
1129
|
+
expect { described_class.allocate.scan("test") }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1130
|
+
end
|
|
797
1131
|
end
|
|
798
1132
|
|
|
799
1133
|
describe "#partial_match" do
|
|
@@ -849,6 +1183,10 @@ RSpec.describe RE2::Regexp do
|
|
|
849
1183
|
|
|
850
1184
|
expect(r.partial_match('ruby:1234', anchor: :anchor_both)).to be_a(RE2::MatchData)
|
|
851
1185
|
end
|
|
1186
|
+
|
|
1187
|
+
it "raises an error when called on an uninitialized object" do
|
|
1188
|
+
expect { described_class.allocate.partial_match('test') }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1189
|
+
end
|
|
852
1190
|
end
|
|
853
1191
|
|
|
854
1192
|
describe "#full_match" do
|
|
@@ -905,5 +1243,9 @@ RSpec.describe RE2::Regexp do
|
|
|
905
1243
|
|
|
906
1244
|
expect(r.full_match('ruby:1234', anchor: :unanchored)).to be_nil
|
|
907
1245
|
end
|
|
1246
|
+
|
|
1247
|
+
it "raises an error when called on an uninitialized object" do
|
|
1248
|
+
expect { described_class.allocate.full_match('test') }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
1249
|
+
end
|
|
908
1250
|
end
|
|
909
1251
|
end
|