re2 2.4.3-x86-linux → 2.6.0.rc1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,11 +2,13 @@ RSpec.describe RE2::Regexp do
2
2
  describe "#initialize" do
3
3
  it "returns an instance given only a pattern" do
4
4
  re = RE2::Regexp.new('woo')
5
+
5
6
  expect(re).to be_a(RE2::Regexp)
6
7
  end
7
8
 
8
9
  it "returns an instance given a pattern and options" do
9
- re = RE2::Regexp.new('woo', :case_sensitive => false)
10
+ re = RE2::Regexp.new('woo', case_sensitive: false)
11
+
10
12
  expect(re).to be_a(RE2::Regexp)
11
13
  end
12
14
 
@@ -15,7 +17,8 @@ RSpec.describe RE2::Regexp do
15
17
  end
16
18
 
17
19
  it "allows invalid patterns to be created" do
18
- re = RE2::Regexp.new('???', :log_errors => false)
20
+ re = RE2::Regexp.new('???', log_errors: false)
21
+
19
22
  expect(re).to be_a(RE2::Regexp)
20
23
  end
21
24
 
@@ -29,11 +32,12 @@ RSpec.describe RE2::Regexp do
29
32
  describe ".compile" do
30
33
  it "returns an instance given only a pattern" do
31
34
  re = RE2::Regexp.compile('woo')
35
+
32
36
  expect(re).to be_a(RE2::Regexp)
33
37
  end
34
38
 
35
39
  it "returns an instance given a pattern and options" do
36
- re = RE2::Regexp.compile('woo', :case_sensitive => false)
40
+ re = RE2::Regexp.compile('woo', case_sensitive: false)
37
41
  expect(re).to be_a(RE2::Regexp)
38
42
  end
39
43
 
@@ -42,7 +46,8 @@ RSpec.describe RE2::Regexp do
42
46
  end
43
47
 
44
48
  it "allows invalid patterns to be created" do
45
- re = RE2::Regexp.compile('???', :log_errors => false)
49
+ re = RE2::Regexp.compile('???', log_errors: false)
50
+
46
51
  expect(re).to be_a(RE2::Regexp)
47
52
  end
48
53
 
@@ -60,34 +65,38 @@ RSpec.describe RE2::Regexp do
60
65
  end
61
66
 
62
67
  it "is populated with default options when nothing has been set" do
63
- options = RE2::Regexp.new('woo').options
64
- expect(options).to include(:utf8 => true,
65
- :posix_syntax => false,
66
- :longest_match => false,
67
- :log_errors => true,
68
- :literal => false,
69
- :never_nl => false,
70
- :case_sensitive => true,
71
- :perl_classes => false,
72
- :word_boundary => false,
73
- :one_line => false)
68
+ expect(RE2::Regexp.new('woo').options).to include(
69
+ utf8: true,
70
+ posix_syntax: false,
71
+ longest_match: false,
72
+ log_errors: true,
73
+ literal: false,
74
+ never_nl: false,
75
+ case_sensitive: true,
76
+ perl_classes: false,
77
+ word_boundary: false,
78
+ one_line: false
79
+ )
74
80
  end
75
81
 
76
82
  it "is populated with overridden options when specified" do
77
- options = RE2::Regexp.new('woo', :case_sensitive => false).options
78
- expect(options).to include(:case_sensitive => false)
83
+ options = RE2::Regexp.new('woo', case_sensitive: false).options
84
+
85
+ expect(options).to include(case_sensitive: false)
79
86
  end
80
87
  end
81
88
 
82
89
  describe "#error" do
83
90
  it "returns nil if there is no error" do
84
91
  error = RE2::Regexp.new('woo').error
92
+
85
93
  expect(error).to be_nil
86
94
  end
87
95
 
88
- # Use log_errors => false to suppress RE2's logging to STDERR.
96
+ # Use log_errors: false to suppress RE2's logging to STDERR.
89
97
  it "contains the error string if there is an error" do
90
- error = RE2::Regexp.new('wo(o', :log_errors => false).error
98
+ error = RE2::Regexp.new('wo(o', log_errors: false).error
99
+
91
100
  expect(error).to eq("missing ): wo(o")
92
101
  end
93
102
  end
@@ -95,11 +104,13 @@ RSpec.describe RE2::Regexp do
95
104
  describe "#error_arg" do
96
105
  it "returns nil if there is no error" do
97
106
  error_arg = RE2::Regexp.new('woo').error_arg
107
+
98
108
  expect(error_arg).to be_nil
99
109
  end
100
110
 
101
- it "returns the offending portion of the regexp if there is an error" do
102
- error_arg = RE2::Regexp.new('wo(o', :log_errors => false).error_arg
111
+ it "returns the offending portion of the pattern if there is an error" do
112
+ error_arg = RE2::Regexp.new('wo(o', log_errors: false).error_arg
113
+
103
114
  expect(error_arg).to eq("wo(o")
104
115
  end
105
116
  end
@@ -112,7 +123,8 @@ RSpec.describe RE2::Regexp do
112
123
  end
113
124
 
114
125
  it "returns -1 for an invalid pattern" do
115
- program_size = RE2::Regexp.new('???', :log_errors => false).program_size
126
+ program_size = RE2::Regexp.new('???', log_errors: false).program_size
127
+
116
128
  expect(program_size).to eq(-1)
117
129
  end
118
130
  end
@@ -120,18 +132,27 @@ RSpec.describe RE2::Regexp do
120
132
  describe "#to_str" do
121
133
  it "returns the original pattern" do
122
134
  string = RE2::Regexp.new('w(o)(o)').to_str
135
+
123
136
  expect(string).to eq("w(o)(o)")
124
137
  end
138
+
139
+ it "returns the pattern even if invalid" do
140
+ string = RE2::Regexp.new('???', log_errors: false).to_str
141
+
142
+ expect(string).to eq("???")
143
+ end
125
144
  end
126
145
 
127
146
  describe "#pattern" do
128
147
  it "returns the original pattern" do
129
148
  pattern = RE2::Regexp.new('w(o)(o)').pattern
149
+
130
150
  expect(pattern).to eq("w(o)(o)")
131
151
  end
132
152
 
133
153
  it "returns the pattern even if invalid" do
134
- pattern = RE2::Regexp.new('???', :log_errors => false).pattern
154
+ pattern = RE2::Regexp.new('???', log_errors: false).pattern
155
+
135
156
  expect(pattern).to eq("???")
136
157
  end
137
158
  end
@@ -139,8 +160,15 @@ RSpec.describe RE2::Regexp do
139
160
  describe "#inspect" do
140
161
  it "shows the class name and original pattern" do
141
162
  string = RE2::Regexp.new('w(o)(o)').inspect
163
+
142
164
  expect(string).to eq("#<RE2::Regexp /w(o)(o)/>")
143
165
  end
166
+
167
+ it "respects the pattern's original encoding" do
168
+ string = RE2::Regexp.new('w(o)(o)', utf8: false).inspect
169
+
170
+ expect(string.encoding).to eq(Encoding::ISO_8859_1)
171
+ end
144
172
  end
145
173
 
146
174
  describe "#utf8?" do
@@ -149,7 +177,8 @@ RSpec.describe RE2::Regexp do
149
177
  end
150
178
 
151
179
  it "can be overridden on initialization" do
152
- re = RE2::Regexp.new('woo', :utf8 => false)
180
+ re = RE2::Regexp.new('woo', utf8: false)
181
+
153
182
  expect(re).to_not be_utf8
154
183
  end
155
184
  end
@@ -160,7 +189,8 @@ RSpec.describe RE2::Regexp do
160
189
  end
161
190
 
162
191
  it "can be overridden on initialization" do
163
- re = RE2::Regexp.new('woo', :posix_syntax => true)
192
+ re = RE2::Regexp.new('woo', posix_syntax: true)
193
+
164
194
  expect(re).to be_posix_syntax
165
195
  end
166
196
  end
@@ -171,7 +201,8 @@ RSpec.describe RE2::Regexp do
171
201
  end
172
202
 
173
203
  it "can be overridden on initialization" do
174
- re = RE2::Regexp.new('woo', :literal => true)
204
+ re = RE2::Regexp.new('woo', literal: true)
205
+
175
206
  expect(re).to be_literal
176
207
  end
177
208
  end
@@ -182,7 +213,8 @@ RSpec.describe RE2::Regexp do
182
213
  end
183
214
 
184
215
  it "can be overridden on initialization" do
185
- re = RE2::Regexp.new('woo', :never_nl => true)
216
+ re = RE2::Regexp.new('woo', never_nl: true)
217
+
186
218
  expect(re).to be_never_nl
187
219
  end
188
220
  end
@@ -193,7 +225,7 @@ RSpec.describe RE2::Regexp do
193
225
  end
194
226
 
195
227
  it "can be overridden on initialization" do
196
- re = RE2::Regexp.new('woo', :case_sensitive => false)
228
+ re = RE2::Regexp.new('woo', case_sensitive: false)
197
229
  expect(re).to_not be_case_sensitive
198
230
  end
199
231
  end
@@ -204,7 +236,8 @@ RSpec.describe RE2::Regexp do
204
236
  end
205
237
 
206
238
  it "can be overridden on initialization" do
207
- re = RE2::Regexp.new('woo', :case_sensitive => false)
239
+ re = RE2::Regexp.new('woo', case_sensitive: false)
240
+
208
241
  expect(re).to be_case_insensitive
209
242
  end
210
243
  end
@@ -215,7 +248,8 @@ RSpec.describe RE2::Regexp do
215
248
  end
216
249
 
217
250
  it "can be overridden on initialization" do
218
- re = RE2::Regexp.new('woo', :case_sensitive => false)
251
+ re = RE2::Regexp.new('woo', case_sensitive: false)
252
+
219
253
  expect(re).to be_casefold
220
254
  end
221
255
  end
@@ -226,7 +260,8 @@ RSpec.describe RE2::Regexp do
226
260
  end
227
261
 
228
262
  it "can be overridden on initialization" do
229
- re = RE2::Regexp.new('woo', :longest_match => true)
263
+ re = RE2::Regexp.new('woo', longest_match: true)
264
+
230
265
  expect(re).to be_longest_match
231
266
  end
232
267
  end
@@ -237,7 +272,8 @@ RSpec.describe RE2::Regexp do
237
272
  end
238
273
 
239
274
  it "can be overridden on initialization" do
240
- re = RE2::Regexp.new('woo', :log_errors => false)
275
+ re = RE2::Regexp.new('woo', log_errors: false)
276
+
241
277
  expect(re).to_not be_log_errors
242
278
  end
243
279
  end
@@ -248,7 +284,8 @@ RSpec.describe RE2::Regexp do
248
284
  end
249
285
 
250
286
  it "can be overridden on initialization" do
251
- re = RE2::Regexp.new('woo', :perl_classes => true)
287
+ re = RE2::Regexp.new('woo', perl_classes: true)
288
+
252
289
  expect(re).to be_perl_classes
253
290
  end
254
291
  end
@@ -259,7 +296,8 @@ RSpec.describe RE2::Regexp do
259
296
  end
260
297
 
261
298
  it "can be overridden on initialization" do
262
- re = RE2::Regexp.new('woo', :word_boundary => true)
299
+ re = RE2::Regexp.new('woo', word_boundary: true)
300
+
263
301
  expect(re).to be_word_boundary
264
302
  end
265
303
  end
@@ -270,7 +308,8 @@ RSpec.describe RE2::Regexp do
270
308
  end
271
309
 
272
310
  it "can be overridden on initialization" do
273
- re = RE2::Regexp.new('woo', :one_line => true)
311
+ re = RE2::Regexp.new('woo', one_line: true)
312
+
274
313
  expect(re).to be_one_line
275
314
  end
276
315
  end
@@ -281,144 +320,372 @@ RSpec.describe RE2::Regexp do
281
320
  end
282
321
 
283
322
  it "can be overridden on initialization" do
284
- re = RE2::Regexp.new('woo', :max_mem => 1024)
323
+ re = RE2::Regexp.new('woo', max_mem: 1024)
324
+
285
325
  expect(re.max_mem).to eq(1024)
286
326
  end
287
327
  end
288
328
 
289
329
  describe "#match" do
290
- let(:re) { RE2::Regexp.new('My name is (\S+) (\S+)') }
330
+ it "returns match data given only text if the pattern has capturing groups" do
331
+ re = RE2::Regexp.new('My name is (\w+) (\w+)')
291
332
 
292
- it "returns match data given only text" do
293
- md = re.match("My name is Robert Paulson")
294
- expect(md).to be_a(RE2::MatchData)
333
+ expect(re.match("My name is Alice Bloggs")).to be_a(RE2::MatchData)
295
334
  end
296
335
 
297
- it "returns nil if there is no match for the given text" do
298
- expect(re.match("My age is 99")).to be_nil
336
+ it "returns only true or false given only text if the pattern has no capturing groups" do
337
+ re = RE2::Regexp.new('My name is \w+ \w+')
338
+
339
+ expect(re.match("My name is Alice Bloggs")).to eq(true)
299
340
  end
300
341
 
301
- it "returns only true or false if no matches are requested" do
302
- expect(re.match("My name is Robert Paulson", 0)).to eq(true)
303
- expect(re.match("My age is 99", 0)).to eq(false)
342
+ it "returns nil if the text does not match the pattern" do
343
+ re = RE2::Regexp.new('My name is (\w+) (\w+)')
344
+
345
+ expect(re.match("My age is 99")).to be_nil
304
346
  end
305
347
 
306
- it "returns only true or false if the pattern has no capturing groups" do
307
- re = RE2::Regexp.new('My name is')
348
+ it "accepts text that can be coerced to a string" do
349
+ re = RE2::Regexp.new('My name is (\w+) (\w+)')
308
350
 
309
- expect(re.match('My name is Robert Paulson')).to eq(true)
351
+ expect(re.match(StringLike.new("My name is Alice Bloggs"))).to be_a(RE2::MatchData)
310
352
  end
311
353
 
312
- it "raises an exception when given nil" do
354
+ it "raises an exception when given text that cannot be coerced to a string" do
355
+ re = RE2::Regexp.new('My name is (\w+) (\w+)')
356
+
313
357
  expect { re.match(nil) }.to raise_error(TypeError)
314
358
  end
315
359
 
316
- it "raises an exception when given an inappropriate number of matches" do
317
- expect { re.match("My name is Robert Paulson", {}) }.to raise_error(TypeError)
360
+ it "returns nil with an invalid pattern" do
361
+ re = RE2::Regexp.new('???', log_errors: false)
362
+
363
+ expect(re.match("My name is Alice Bloggs")).to be_nil
364
+ end
365
+
366
+ it "returns nil with an invalid pattern and options" do
367
+ re = RE2::Regexp.new('???', log_errors: false)
368
+
369
+ expect(re.match('foo bar', startpos: 1)).to be_nil
318
370
  end
319
371
 
320
- it "raises an exception when given a negative number of matches" do
321
- expect { re.match("My name is Robert Paulson", -1) }.to raise_error(ArgumentError, "number of matches should be >= 0")
372
+ it "accepts an offset at which to start matching", :aggregate_failures do
373
+ re = RE2::Regexp.new('(\w+) (\w+)')
374
+ md = re.match("one two three", startpos: 4)
375
+
376
+ expect(md[1]).to eq("two")
377
+ expect(md[2]).to eq("three")
322
378
  end
323
379
 
324
- it "returns nil with an invalid pattern" do
325
- re = RE2::Regexp.new('???', :log_errors => false)
326
- expect(re.match('My name is Robert Paulson')).to be_nil
380
+ it "returns nil if using a starting offset past the end of the text" do
381
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
382
+
383
+ re = RE2::Regexp.new('(\w+) (\w+)', log_errors: false)
384
+
385
+ expect(re.match("one two three", startpos: 20, endpos: 21)).to be_nil
327
386
  end
328
387
 
329
- describe "with a specific number of matches under the total in the pattern" do
330
- subject { re.match("My name is Robert Paulson", 1) }
388
+ it "raises an exception when given a negative starting offset" do
389
+ re = RE2::Regexp.new('(\w+) (\w+)')
331
390
 
332
- it "returns a match data object" do
333
- expect(subject).to be_a(RE2::MatchData)
334
- end
391
+ expect { re.match("one two three", startpos: -1) }.to raise_error(ArgumentError, "startpos should be >= 0")
392
+ end
393
+
394
+ it "raises an exception when given a starting offset past the default ending offset" do
395
+ re = RE2::Regexp.new('(\w+) (\w+)')
396
+
397
+ expect { re.match("one two three", startpos: 30) }.to raise_error(ArgumentError, "startpos should be <= endpos")
398
+ end
335
399
 
336
- it "has the whole match and only the specified number of matches" do
337
- expect(subject.size).to eq(2)
338
- end
400
+ it "accepts an offset at which to end matching", :aggregate_failures do
401
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
339
402
 
340
- it "populates any specified matches" do
341
- expect(subject[1]).to eq("Robert")
342
- end
403
+ re = RE2::Regexp.new('(\w+) (\w+)')
404
+ md = re.match("one two three", endpos: 6)
343
405
 
344
- it "does not populate any matches that weren't included" do
345
- expect(subject[2]).to be_nil
346
- end
406
+ expect(md[1]).to eq("one")
407
+ expect(md[2]).to eq("tw")
347
408
  end
348
409
 
349
- describe "with a number of matches over the total in the pattern" do
350
- subject { re.match("My name is Robert Paulson", 5) }
410
+ it "returns nil if using a ending offset at the start of the text" do
411
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
412
+
413
+ re = RE2::Regexp.new('(\w+) (\w+)')
414
+
415
+ expect(re.match("one two three", endpos: 0)).to be_nil
416
+ end
351
417
 
352
- it "returns a match data object" do
353
- expect(subject).to be_a(RE2::MatchData)
354
- end
418
+ it "raises an exception when given a negative ending offset" do
419
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
355
420
 
356
- it "has the whole match the specified number of matches" do
357
- expect(subject.size).to eq(6)
358
- end
421
+ re = RE2::Regexp.new('(\w+) (\w+)')
422
+
423
+ expect { re.match("one two three", endpos: -1) }.to raise_error(ArgumentError, "endpos should be >= 0")
424
+ end
425
+
426
+ it "raises an exception when given an ending offset before the starting offset" do
427
+ skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
428
+
429
+ re = RE2::Regexp.new('(\w+) (\w+)')
430
+
431
+ expect { re.match("one two three", startpos: 3, endpos: 0) }.to raise_error(ArgumentError, "startpos should be <= endpos")
432
+ end
433
+
434
+ it "raises an error if given an ending offset and RE2 does not support it" do
435
+ skip "Underlying RE2::Match has endpos argument" if RE2::Regexp.match_has_endpos_argument?
436
+
437
+ re = RE2::Regexp.new('(\w+) (\w+)')
438
+
439
+ expect { re.match("one two three", endpos: 3) }.to raise_error(RE2::Regexp::UnsupportedError)
440
+ end
441
+
442
+ it "does not anchor matches by default when extracting submatches" do
443
+ re = RE2::Regexp.new('(two)')
444
+
445
+ expect(re.match("one two three")).to be_a(RE2::MatchData)
446
+ end
447
+
448
+ it "does not anchor matches by default without extracting submatches" do
449
+ re = RE2::Regexp.new('(two)')
450
+
451
+ expect(re.match("one two three", submatches: 0)).to eq(true)
452
+ end
453
+
454
+ it "can explicitly match without anchoring when extracting submatches" do
455
+ re = RE2::Regexp.new('(two)')
456
+
457
+ expect(re.match("one two three", anchor: :unanchored)).to be_a(RE2::MatchData)
458
+ end
459
+
460
+ it "can explicitly match with neither anchoring nor extracting submatches" do
461
+ re = RE2::Regexp.new('(two)')
462
+
463
+ expect(re.match("one two three", anchor: :unanchored, submatches: 0)).to eq(true)
464
+ end
465
+
466
+ it "can anchor matches at the start when extracting submatches", :aggregate_failures do
467
+ re = RE2::Regexp.new('(two)')
468
+
469
+ expect(re.match("two three", anchor: :anchor_start)).to be_a(RE2::MatchData)
470
+ expect(re.match("one two three", anchor: :anchor_start)).to be_nil
471
+ end
472
+
473
+ it "can anchor matches at the start without extracting submatches", :aggregate_failures do
474
+ re = RE2::Regexp.new('(two)')
475
+
476
+ expect(re.match("two three", anchor: :anchor_start, submatches: 0)).to eq(true)
477
+ expect(re.match("one two three", anchor: :anchor_start, submatches: 0)).to eq(false)
478
+ end
479
+
480
+ it "can anchor matches at both ends when extracting submatches", :aggregate_failures do
481
+ re = RE2::Regexp.new('(two)')
482
+
483
+ expect(re.match("two three", anchor: :anchor_both)).to be_nil
484
+ expect(re.match("two", anchor: :anchor_both)).to be_a(RE2::MatchData)
485
+ end
486
+
487
+ it "does not anchor matches when given a nil anchor" do
488
+ re = RE2::Regexp.new('(two)')
489
+
490
+ expect(re.match("one two three", anchor: nil)).to be_a(RE2::MatchData)
491
+ end
492
+
493
+ it "raises an exception when given an invalid anchor" do
494
+ re = RE2::Regexp.new('(two)')
495
+
496
+ expect { re.match("one two three", anchor: :invalid) }.to raise_error(ArgumentError, "anchor should be one of: :unanchored, :anchor_start, :anchor_both")
497
+ end
498
+
499
+ it "raises an exception when given a non-symbol anchor" do
500
+ re = RE2::Regexp.new('(two)')
501
+
502
+ expect { re.match("one two three", anchor: 0) }.to raise_error(TypeError)
503
+ end
504
+
505
+ it "extracts all submatches by default", :aggregate_failures do
506
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
507
+ md = re.match("one two three")
508
+
509
+ expect(md[1]).to eq("one")
510
+ expect(md[2]).to eq("two")
511
+ expect(md[3]).to eq("three")
512
+ end
513
+
514
+ it "extracts a specific number of submatches", :aggregate_failures do
515
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
516
+ md = re.match("one two three", submatches: 2)
517
+
518
+ expect(md[1]).to eq("one")
519
+ expect(md[2]).to eq("two")
520
+ expect(md[3]).to be_nil
521
+ end
522
+
523
+ it "pads submatches with nil when requesting more than the number of capturing groups" do
524
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
525
+ md = re.match("one two three", submatches: 5)
526
+
527
+ expect(md.to_a).to eq(["one two three", "one", "two", "three", nil, nil])
528
+ end
529
+
530
+ it "raises an exception when given a negative number of submatches" do
531
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
532
+
533
+ expect { re.match("one two three", submatches: -1) }.to raise_error(ArgumentError, "number of matches should be >= 0")
534
+ end
535
+
536
+ it "raises an exception when given a non-numeric number of submatches" do
537
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
538
+
539
+ expect { re.match("one two three", submatches: :invalid) }.to raise_error(TypeError)
540
+ end
359
541
 
360
- it "populates any specified matches" do
361
- expect(subject[1]).to eq("Robert")
362
- expect(subject[2]).to eq("Paulson")
363
- end
542
+ it "defaults to extracting all submatches when given nil", :aggregate_failures do
543
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
544
+ md = re.match("one two three", submatches: nil)
364
545
 
365
- it "pads the remaining matches with nil" do
366
- expect(subject[3]).to be_nil
367
- expect(subject[4]).to be_nil
368
- expect(subject[5]).to be_nil
369
- expect(subject[6]).to be_nil
370
- end
546
+ expect(md[1]).to eq("one")
547
+ expect(md[2]).to eq("two")
548
+ expect(md[3]).to eq("three")
549
+ end
550
+
551
+ it "accepts passing the number of submatches instead of options for backward compatibility", :aggregate_failures do
552
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
553
+ md = re.match("one two three", 2)
554
+
555
+ expect(md[1]).to eq("one")
556
+ expect(md[2]).to eq("two")
557
+ expect(md[3]).to be_nil
558
+ end
559
+
560
+ it "raises an exception when given invalid options" do
561
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
562
+
563
+ expect { re.match("one two three", :invalid) }.to raise_error(TypeError)
564
+ end
565
+
566
+ it "accepts anything that can be coerced to a hash as options", :aggregate_failures do
567
+ re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
568
+
569
+ expect(re.match("one two three", nil)).to be_a(RE2::MatchData)
371
570
  end
372
571
  end
373
572
 
374
573
  describe "#match?" do
375
- it "returns only true or false if no matches are requested" do
574
+ it "returns only true or false even if there are capturing groups", :aggregate_failures do
376
575
  re = RE2::Regexp.new('My name is (\S+) (\S+)')
377
- expect(re.match?("My name is Robert Paulson")).to eq(true)
576
+
577
+ expect(re.match?("My name is Alice Bloggs")).to eq(true)
378
578
  expect(re.match?("My age is 99")).to eq(false)
379
579
  end
380
580
 
381
581
  it "returns false if the pattern is invalid" do
382
- re = RE2::Regexp.new('???', :log_errors => false)
383
- expect(re.match?("My name is Robert Paulson")).to eq(false)
582
+ re = RE2::Regexp.new('???', log_errors: false)
583
+
584
+ expect(re.match?("My name is Alice Bloggs")).to eq(false)
585
+ end
586
+
587
+ it "raises an exception if text cannot be coerced to a string" do
588
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
589
+
590
+ expect { re.match?(0) }.to raise_error(TypeError)
591
+ end
592
+ end
593
+
594
+ describe "#partial_match?" do
595
+ it "returns only true or false even if there are capturing groups", :aggregate_failures do
596
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
597
+
598
+ expect(re.partial_match?("My name is Alice Bloggs")).to eq(true)
599
+ expect(re.partial_match?("My age is 99")).to eq(false)
600
+ end
601
+
602
+ it "returns false if the pattern is invalid" do
603
+ re = RE2::Regexp.new('???', log_errors: false)
604
+
605
+ expect(re.partial_match?("My name is Alice Bloggs")).to eq(false)
606
+ end
607
+
608
+ it "raises an exception if text cannot be coerced to a string" do
609
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
610
+
611
+ expect { re.partial_match?(0) }.to raise_error(TypeError)
384
612
  end
385
613
  end
386
614
 
387
615
  describe "#=~" do
388
- it "returns only true or false if no matches are requested" do
616
+ it "returns only true or false even if there are capturing groups", :aggregate_failures do
389
617
  re = RE2::Regexp.new('My name is (\S+) (\S+)')
390
- expect(re =~ "My name is Robert Paulson").to eq(true)
618
+
619
+ expect(re =~ "My name is Alice Bloggs").to eq(true)
391
620
  expect(re =~ "My age is 99").to eq(false)
392
621
  end
393
- end
394
622
 
395
- describe "#!~" do
396
- it "returns only true or false if no matches are requested" do
623
+ it "returns false if the pattern is invalid" do
624
+ re = RE2::Regexp.new('???', log_errors: false)
625
+
626
+ expect(re =~ "My name is Alice Bloggs").to eq(false)
627
+ end
628
+
629
+ it "raises an exception if text cannot be coerced to a string" do
397
630
  re = RE2::Regexp.new('My name is (\S+) (\S+)')
398
- expect(re !~ "My name is Robert Paulson").to eq(false)
399
- expect(re !~ "My age is 99").to eq(true)
631
+
632
+ expect { re =~ 0 }.to raise_error(TypeError)
400
633
  end
401
634
  end
402
635
 
403
636
  describe "#===" do
404
- it "returns only true or false if no matches are requested" do
637
+ it "returns only true or false even if there are capturing groups", :aggregate_failures do
405
638
  re = RE2::Regexp.new('My name is (\S+) (\S+)')
406
- expect(re === "My name is Robert Paulson").to eq(true)
639
+
640
+ expect(re === "My name is Alice Bloggs").to eq(true)
407
641
  expect(re === "My age is 99").to eq(false)
408
642
  end
643
+
644
+ it "returns false if the pattern is invalid" do
645
+ re = RE2::Regexp.new('???', log_errors: false)
646
+
647
+ expect(re === "My name is Alice Bloggs").to eq(false)
648
+ end
649
+
650
+ it "raises an exception if text cannot be coerced to a string" do
651
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
652
+
653
+ expect { re === 0 }.to raise_error(TypeError)
654
+ end
655
+ end
656
+
657
+ describe "#full_match?" do
658
+ it "returns only true or false even if there are capturing groups", :aggregate_failures do
659
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
660
+
661
+ expect(re.full_match?("My name is Alice Bloggs")).to eq(true)
662
+ expect(re.full_match?("My name is Alice Bloggs and I am 99")).to eq(false)
663
+ end
664
+
665
+ it "returns false if the pattern is invalid" do
666
+ re = RE2::Regexp.new('???', log_errors: false)
667
+
668
+ expect(re.full_match?("My name is Alice Bloggs")).to eq(false)
669
+ end
670
+
671
+ it "raises an exception if text cannot be coerced to a string" do
672
+ re = RE2::Regexp.new('My name is (\S+) (\S+)')
673
+
674
+ expect { re.full_match?(0) }.to raise_error(TypeError)
675
+ end
409
676
  end
410
677
 
411
678
  describe "#ok?" do
412
- it "returns true for valid regexps" do
679
+ it "returns true for valid patterns", :aggregate_failures do
413
680
  expect(RE2::Regexp.new('woo')).to be_ok
414
681
  expect(RE2::Regexp.new('wo(o)')).to be_ok
415
682
  expect(RE2::Regexp.new('((\d)\w+){3,}')).to be_ok
416
683
  end
417
684
 
418
- it "returns false for invalid regexps" do
419
- expect(RE2::Regexp.new('wo(o', :log_errors => false)).to_not be_ok
420
- expect(RE2::Regexp.new('wo[o', :log_errors => false)).to_not be_ok
421
- expect(RE2::Regexp.new('*', :log_errors => false)).to_not be_ok
685
+ it "returns false for invalid patterns", :aggregate_failures do
686
+ expect(RE2::Regexp.new('wo(o', log_errors: false)).to_not be_ok
687
+ expect(RE2::Regexp.new('wo[o', log_errors: false)).to_not be_ok
688
+ expect(RE2::Regexp.new('*', log_errors: false)).to_not be_ok
422
689
  end
423
690
  end
424
691
 
@@ -435,14 +702,14 @@ RSpec.describe RE2::Regexp do
435
702
  end
436
703
 
437
704
  describe "#number_of_capturing_groups" do
438
- it "returns the number of groups in a regexp" do
705
+ it "returns the number of groups in a pattern", :aggregate_failures do
439
706
  expect(RE2::Regexp.new('(a)(b)(c)').number_of_capturing_groups).to eq(3)
440
707
  expect(RE2::Regexp.new('abc').number_of_capturing_groups).to eq(0)
441
708
  expect(RE2::Regexp.new('a((b)c)').number_of_capturing_groups).to eq(2)
442
709
  end
443
710
 
444
- it "returns -1 for an invalid regexp" do
445
- expect(RE2::Regexp.new('???', :log_errors => false).number_of_capturing_groups).to eq(-1)
711
+ it "returns -1 for an invalid pattern" do
712
+ expect(RE2::Regexp.new('???', log_errors: false).number_of_capturing_groups).to eq(-1)
446
713
  end
447
714
  end
448
715
 
@@ -453,17 +720,18 @@ RSpec.describe RE2::Regexp do
453
720
 
454
721
  it "maps names to indices with only one group" do
455
722
  groups = RE2::Regexp.new('(?P<bob>a)').named_capturing_groups
456
- expect(groups["bob"]).to eq(1)
723
+
724
+ expect(groups).to eq("bob" => 1)
457
725
  end
458
726
 
459
727
  it "maps names to indices with several groups" do
460
728
  groups = RE2::Regexp.new('(?P<bob>a)(o)(?P<rob>e)').named_capturing_groups
461
- expect(groups["bob"]).to eq(1)
462
- expect(groups["rob"]).to eq(3)
729
+
730
+ expect(groups).to eq("bob" => 1, "rob" => 3)
463
731
  end
464
732
 
465
733
  it "returns an empty hash for an invalid regexp" do
466
- expect(RE2::Regexp.new('???', :log_errors => false).named_capturing_groups).to be_empty
734
+ expect(RE2::Regexp.new('???', log_errors: false).named_capturing_groups).to be_empty
467
735
  end
468
736
  end
469
737
 
@@ -475,4 +743,115 @@ RSpec.describe RE2::Regexp do
475
743
  expect(scanner).to be_a(RE2::Scanner)
476
744
  end
477
745
  end
746
+
747
+ describe "#partial_match" do
748
+ it "matches the pattern anywhere within the given text" do
749
+ r = RE2::Regexp.new('f(o+)')
750
+
751
+ expect(r.partial_match("foo bar")).to be_a(RE2::MatchData)
752
+ end
753
+
754
+ it "returns true or false if there are no capturing groups" do
755
+ r = RE2::Regexp.new('fo+')
756
+
757
+ expect(r.partial_match("foo bar")).to eq(true)
758
+ end
759
+
760
+ it "can set the number of submatches to extract", :aggregate_failures do
761
+ r = RE2::Regexp.new('f(o+)(a+)')
762
+ m = r.partial_match("fooaa bar", submatches: 1)
763
+
764
+ expect(m[1]).to eq("oo")
765
+ expect(m[2]).to be_nil
766
+
767
+ m = r.partial_match("fooaa bar", submatches: 2)
768
+
769
+ expect(m[1]).to eq("oo")
770
+ expect(m[2]).to eq("aa")
771
+ end
772
+
773
+ it "raises an error if given non-hash options" do
774
+ r = RE2::Regexp.new('f(o+)(a+)')
775
+
776
+ expect { r.partial_match("fooaa bar", "not a hash") }.to raise_error(TypeError)
777
+ end
778
+
779
+ it "accepts options that can be coerced to a hash", :aggregate_failures do
780
+ r = RE2::Regexp.new('f(o+)(a+)')
781
+
782
+ m = r.partial_match("fooaa bar", nil)
783
+ expect(m[1]).to eq('oo')
784
+
785
+ m = r.partial_match("fooaa bar", [])
786
+ expect(m[1]).to eq('oo')
787
+ end
788
+
789
+ it "accepts anything that can be coerced to a string" do
790
+ r = RE2::Regexp.new('f(o+)(a+)')
791
+
792
+ expect(r.partial_match(StringLike.new("fooaa bar"))).to be_a(RE2::MatchData)
793
+ end
794
+
795
+ it "does not allow the anchor to be overridden" do
796
+ r = RE2::Regexp.new('(\d+)')
797
+
798
+ expect(r.partial_match('ruby:1234', anchor: :anchor_both)).to be_a(RE2::MatchData)
799
+ end
800
+ end
801
+
802
+ describe "#full_match" do
803
+ it "only matches the pattern if all of the given text matches", :aggregate_failures do
804
+ r = RE2::Regexp.new('f(o+)')
805
+
806
+ expect(r.full_match("foo")).to be_a(RE2::MatchData)
807
+ expect(r.full_match("foo bar")).to be_nil
808
+ end
809
+
810
+ it "returns true or false if there are no capturing groups" do
811
+ r = RE2::Regexp.new('fo+')
812
+
813
+ expect(r.full_match("foo")).to eq(true)
814
+ end
815
+
816
+ it "can set the number of submatches to extract", :aggregate_failures do
817
+ r = RE2::Regexp.new('f(o+)(a+)')
818
+ m = r.full_match("fooaa", submatches: 1)
819
+
820
+ expect(m[1]).to eq("oo")
821
+ expect(m[2]).to be_nil
822
+
823
+ m = r.full_match("fooaa", submatches: 2)
824
+
825
+ expect(m[1]).to eq("oo")
826
+ expect(m[2]).to eq("aa")
827
+ end
828
+
829
+ it "raises an error if given non-hash options" do
830
+ r = RE2::Regexp.new('f(o+)(a+)')
831
+
832
+ expect { r.full_match("fooaa", "not a hash") }.to raise_error(TypeError)
833
+ end
834
+
835
+ it "accepts options that can be coerced to a hash", :aggregate_failures do
836
+ r = RE2::Regexp.new('f(o+)(a+)')
837
+
838
+ m = r.full_match("fooaa", nil)
839
+ expect(m[1]).to eq("oo")
840
+
841
+ m = r.full_match("fooaa", [])
842
+ expect(m[1]).to eq("oo")
843
+ end
844
+
845
+ it "accepts anything that can be coerced to a string" do
846
+ r = RE2::Regexp.new('f(o+)(a+)')
847
+
848
+ expect(r.full_match(StringLike.new("fooaa"), submatches: 0)).to eq(true)
849
+ end
850
+
851
+ it "does not allow the anchor to be overridden" do
852
+ r = RE2::Regexp.new('(\d+)')
853
+
854
+ expect(r.full_match('ruby:1234', anchor: :unanchored)).to be_nil
855
+ end
856
+ end
478
857
  end