re2 2.0.0.beta1-x64-mingw32
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 +7 -0
- data/.rspec +2 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +28 -0
- data/README.md +239 -0
- data/Rakefile +155 -0
- data/dependencies.yml +9 -0
- data/ext/re2/extconf.rb +384 -0
- data/ext/re2/re2.cc +1889 -0
- data/ext/re2/recipes.rb +43 -0
- data/lib/2.7/re2.so +0 -0
- data/lib/3.0/re2.so +0 -0
- data/lib/re2/scanner.rb +15 -0
- data/lib/re2/string.rb +85 -0
- data/lib/re2/version.rb +5 -0
- data/lib/re2.rb +14 -0
- data/re2.gemspec +43 -0
- data/spec/kernel_spec.rb +13 -0
- data/spec/re2/match_data_spec.rb +302 -0
- data/spec/re2/regexp_spec.rb +456 -0
- data/spec/re2/scanner_spec.rb +204 -0
- data/spec/re2/set_spec.rb +168 -0
- data/spec/re2/string_spec.rb +56 -0
- data/spec/re2_spec.rb +75 -0
- data/spec/spec_helper.rb +19 -0
- metadata +119 -0
@@ -0,0 +1,456 @@
|
|
1
|
+
RSpec.describe RE2::Regexp do
|
2
|
+
describe "#initialize" do
|
3
|
+
it "returns an instance given only a pattern" do
|
4
|
+
re = RE2::Regexp.new('woo')
|
5
|
+
expect(re).to be_a(RE2::Regexp)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns an instance given a pattern and options" do
|
9
|
+
re = RE2::Regexp.new('woo', :case_sensitive => false)
|
10
|
+
expect(re).to be_a(RE2::Regexp)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "raises an error if given an inappropriate type" do
|
14
|
+
expect { RE2::Regexp.new(nil) }.to raise_error(TypeError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows invalid patterns to be created" do
|
18
|
+
re = RE2::Regexp.new('???', :log_errors => false)
|
19
|
+
expect(re).to be_a(RE2::Regexp)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#compile" do
|
24
|
+
it "returns an instance given only a pattern" do
|
25
|
+
re = RE2::Regexp.compile('woo')
|
26
|
+
expect(re).to be_a(RE2::Regexp)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns an instance given a pattern and options" do
|
30
|
+
re = RE2::Regexp.compile('woo', :case_sensitive => false)
|
31
|
+
expect(re).to be_a(RE2::Regexp)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "allows invalid patterns to be created" do
|
35
|
+
re = RE2::Regexp.compile('???', :log_errors => false)
|
36
|
+
expect(re).to be_a(RE2::Regexp)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#options" do
|
41
|
+
it "returns a hash of options" do
|
42
|
+
options = RE2::Regexp.new('woo').options
|
43
|
+
expect(options).to be_a(Hash)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "is populated with default options when nothing has been set" do
|
47
|
+
options = RE2::Regexp.new('woo').options
|
48
|
+
expect(options).to include(:utf8 => true,
|
49
|
+
:posix_syntax => false,
|
50
|
+
:longest_match => false,
|
51
|
+
:log_errors => true,
|
52
|
+
:literal => false,
|
53
|
+
:never_nl => false,
|
54
|
+
:case_sensitive => true,
|
55
|
+
:perl_classes => false,
|
56
|
+
:word_boundary => false,
|
57
|
+
:one_line => false)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "is populated with overridden options when specified" do
|
61
|
+
options = RE2::Regexp.new('woo', :case_sensitive => false).options
|
62
|
+
expect(options[:case_sensitive]).to eq(false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#error" do
|
67
|
+
it "returns nil if there is no error" do
|
68
|
+
error = RE2::Regexp.new('woo').error
|
69
|
+
expect(error).to be_nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# Use log_errors => false to suppress RE2's logging to STDERR.
|
73
|
+
it "contains the error string if there is an error" do
|
74
|
+
error = RE2::Regexp.new('wo(o', :log_errors => false).error
|
75
|
+
expect(error).to eq("missing ): wo(o")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#error_arg" do
|
80
|
+
it "returns nil if there is no error" do
|
81
|
+
error_arg = RE2::Regexp.new('woo').error_arg
|
82
|
+
expect(error_arg).to be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the offending portin of the regexp if there is an error" do
|
86
|
+
error_arg = RE2::Regexp.new('wo(o', :log_errors => false).error_arg
|
87
|
+
expect(error_arg).to eq("wo(o")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#program_size" do
|
92
|
+
it "returns a numeric value" do
|
93
|
+
program_size = RE2::Regexp.new('w(o)(o)').program_size
|
94
|
+
|
95
|
+
expect(program_size).to be_an(Integer)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns -1 for an invalid pattern" do
|
99
|
+
program_size = RE2::Regexp.new('???', :log_errors => false).program_size
|
100
|
+
expect(program_size).to eq(-1)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#to_str" do
|
105
|
+
it "returns the original pattern" do
|
106
|
+
string = RE2::Regexp.new('w(o)(o)').to_str
|
107
|
+
expect(string).to eq("w(o)(o)")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#pattern" do
|
112
|
+
it "returns the original pattern" do
|
113
|
+
pattern = RE2::Regexp.new('w(o)(o)').pattern
|
114
|
+
expect(pattern).to eq("w(o)(o)")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns the pattern even if invalid" do
|
118
|
+
pattern = RE2::Regexp.new('???', :log_errors => false).pattern
|
119
|
+
expect(pattern).to eq("???")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#inspect" do
|
124
|
+
it "shows the class name and original pattern" do
|
125
|
+
string = RE2::Regexp.new('w(o)(o)').inspect
|
126
|
+
expect(string).to eq("#<RE2::Regexp /w(o)(o)/>")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#utf8?" do
|
131
|
+
it "returns true by default" do
|
132
|
+
expect(RE2::Regexp.new('woo')).to be_utf8
|
133
|
+
end
|
134
|
+
|
135
|
+
it "can be overridden on initialization" do
|
136
|
+
re = RE2::Regexp.new('woo', :utf8 => false)
|
137
|
+
expect(re).to_not be_utf8
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#posix_syntax?" do
|
142
|
+
it "returns false by default" do
|
143
|
+
expect(RE2::Regexp.new('woo')).to_not be_posix_syntax
|
144
|
+
end
|
145
|
+
|
146
|
+
it "can be overridden on initialization" do
|
147
|
+
re = RE2::Regexp.new('woo', :posix_syntax => true)
|
148
|
+
expect(re).to be_posix_syntax
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#literal?" do
|
153
|
+
it "returns false by default" do
|
154
|
+
expect(RE2::Regexp.new('woo')).to_not be_literal
|
155
|
+
end
|
156
|
+
|
157
|
+
it "can be overridden on initialization" do
|
158
|
+
re = RE2::Regexp.new('woo', :literal => true)
|
159
|
+
expect(re).to be_literal
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#never_nl?" do
|
164
|
+
it "returns false by default" do
|
165
|
+
expect(RE2::Regexp.new('woo')).to_not be_never_nl
|
166
|
+
end
|
167
|
+
|
168
|
+
it "can be overridden on initialization" do
|
169
|
+
re = RE2::Regexp.new('woo', :never_nl => true)
|
170
|
+
expect(re).to be_never_nl
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#case_sensitive?" do
|
175
|
+
it "returns true by default" do
|
176
|
+
expect(RE2::Regexp.new('woo')).to be_case_sensitive
|
177
|
+
end
|
178
|
+
|
179
|
+
it "can be overridden on initialization" do
|
180
|
+
re = RE2::Regexp.new('woo', :case_sensitive => false)
|
181
|
+
expect(re).to_not be_case_sensitive
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "#case_insensitive?" do
|
186
|
+
it "returns false by default" do
|
187
|
+
expect(RE2::Regexp.new('woo')).to_not be_case_insensitive
|
188
|
+
end
|
189
|
+
|
190
|
+
it "can be overridden on initialization" do
|
191
|
+
re = RE2::Regexp.new('woo', :case_sensitive => false)
|
192
|
+
expect(re).to be_case_insensitive
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#casefold?" do
|
197
|
+
it "returns true by default" do
|
198
|
+
expect(RE2::Regexp.new('woo')).to_not be_casefold
|
199
|
+
end
|
200
|
+
|
201
|
+
it "can be overridden on initialization" do
|
202
|
+
re = RE2::Regexp.new('woo', :case_sensitive => false)
|
203
|
+
expect(re).to be_casefold
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "#longest_match?" do
|
208
|
+
it "returns false by default" do
|
209
|
+
expect(RE2::Regexp.new('woo')).to_not be_casefold
|
210
|
+
end
|
211
|
+
|
212
|
+
it "can be overridden on initialization" do
|
213
|
+
re = RE2::Regexp.new('woo', :longest_match => true)
|
214
|
+
expect(re).to be_longest_match
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "#log_errors?" do
|
219
|
+
it "returns true by default" do
|
220
|
+
expect(RE2::Regexp.new('woo')).to be_log_errors
|
221
|
+
end
|
222
|
+
|
223
|
+
it "can be overridden on initialization" do
|
224
|
+
re = RE2::Regexp.new('woo', :log_errors => false)
|
225
|
+
expect(re).to_not be_log_errors
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe "#perl_classes?" do
|
230
|
+
it "returns false by default" do
|
231
|
+
expect(RE2::Regexp.new('woo')).to_not be_perl_classes
|
232
|
+
end
|
233
|
+
|
234
|
+
it "can be overridden on initialization" do
|
235
|
+
re = RE2::Regexp.new('woo', :perl_classes => true)
|
236
|
+
expect(re).to be_perl_classes
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "#word_boundary?" do
|
241
|
+
it "returns false by default" do
|
242
|
+
expect(RE2::Regexp.new('woo')).to_not be_word_boundary
|
243
|
+
end
|
244
|
+
|
245
|
+
it "can be overridden on initialization" do
|
246
|
+
re = RE2::Regexp.new('woo', :word_boundary => true)
|
247
|
+
expect(re).to be_word_boundary
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "#one_line?" do
|
252
|
+
it "returns false by default" do
|
253
|
+
expect(RE2::Regexp.new('woo')).to_not be_one_line
|
254
|
+
end
|
255
|
+
|
256
|
+
it "can be overridden on initialization" do
|
257
|
+
re = RE2::Regexp.new('woo', :one_line => true)
|
258
|
+
expect(re).to be_one_line
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "#max_mem" do
|
263
|
+
it "returns the default max memory" do
|
264
|
+
expect(RE2::Regexp.new('woo').max_mem).to eq(8388608)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "can be overridden on initialization" do
|
268
|
+
re = RE2::Regexp.new('woo', :max_mem => 1024)
|
269
|
+
expect(re.max_mem).to eq(1024)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe "#match" do
|
274
|
+
let(:re) { RE2::Regexp.new('My name is (\S+) (\S+)') }
|
275
|
+
|
276
|
+
it "returns match data given only text" do
|
277
|
+
md = re.match("My name is Robert Paulson")
|
278
|
+
expect(md).to be_a(RE2::MatchData)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "returns nil if there is no match for the given text" do
|
282
|
+
expect(re.match("My age is 99")).to be_nil
|
283
|
+
end
|
284
|
+
|
285
|
+
it "returns only true or false if no matches are requested" do
|
286
|
+
expect(re.match("My name is Robert Paulson", 0)).to eq(true)
|
287
|
+
expect(re.match("My age is 99", 0)).to eq(false)
|
288
|
+
end
|
289
|
+
|
290
|
+
it "raises an exception when given nil" do
|
291
|
+
expect { re.match(nil) }.to raise_error(TypeError)
|
292
|
+
end
|
293
|
+
|
294
|
+
it "raises an exception when given an inappropriate number of matches" do
|
295
|
+
expect { re.match("My name is Robert Paulson", {}) }.to raise_error(TypeError)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "raises an exception when given a negative number of matches" do
|
299
|
+
expect { re.match("My name is Robert Paulson", -1) }.to raise_error(ArgumentError, "number of matches should be >= 0")
|
300
|
+
end
|
301
|
+
|
302
|
+
it "returns nil with an invalid pattern" do
|
303
|
+
re = RE2::Regexp.new('???', :log_errors => false)
|
304
|
+
expect(re.match('My name is Robert Paulson')).to be_nil
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "with a specific number of matches under the total in the pattern" do
|
308
|
+
subject { re.match("My name is Robert Paulson", 1) }
|
309
|
+
|
310
|
+
it "returns a match data object" do
|
311
|
+
expect(subject).to be_a(RE2::MatchData)
|
312
|
+
end
|
313
|
+
|
314
|
+
it "has the whole match and only the specified number of matches" do
|
315
|
+
expect(subject.size).to eq(2)
|
316
|
+
end
|
317
|
+
|
318
|
+
it "populates any specified matches" do
|
319
|
+
expect(subject[1]).to eq("Robert")
|
320
|
+
end
|
321
|
+
|
322
|
+
it "does not populate any matches that weren't included" do
|
323
|
+
expect(subject[2]).to be_nil
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe "with a number of matches over the total in the pattern" do
|
328
|
+
subject { re.match("My name is Robert Paulson", 5) }
|
329
|
+
|
330
|
+
it "returns a match data object" do
|
331
|
+
expect(subject).to be_a(RE2::MatchData)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "has the whole match the specified number of matches" do
|
335
|
+
expect(subject.size).to eq(6)
|
336
|
+
end
|
337
|
+
|
338
|
+
it "populates any specified matches" do
|
339
|
+
expect(subject[1]).to eq("Robert")
|
340
|
+
expect(subject[2]).to eq("Paulson")
|
341
|
+
end
|
342
|
+
|
343
|
+
it "pads the remaining matches with nil" do
|
344
|
+
expect(subject[3]).to be_nil
|
345
|
+
expect(subject[4]).to be_nil
|
346
|
+
expect(subject[5]).to be_nil
|
347
|
+
expect(subject[6]).to be_nil
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
describe "#match?" do
|
353
|
+
it "returns only true or false if no matches are requested" do
|
354
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
355
|
+
expect(re.match?("My name is Robert Paulson")).to eq(true)
|
356
|
+
expect(re.match?("My age is 99")).to eq(false)
|
357
|
+
end
|
358
|
+
|
359
|
+
it "returns false if the pattern is invalid" do
|
360
|
+
re = RE2::Regexp.new('???', :log_errors => false)
|
361
|
+
expect(re.match?("My name is Robert Paulson")).to eq(false)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "#=~" do
|
366
|
+
it "returns only true or false if no matches are requested" do
|
367
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
368
|
+
expect(re =~ "My name is Robert Paulson").to eq(true)
|
369
|
+
expect(re =~ "My age is 99").to eq(false)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "#!~" do
|
374
|
+
it "returns only true or false if no matches are requested" do
|
375
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
376
|
+
expect(re !~ "My name is Robert Paulson").to eq(false)
|
377
|
+
expect(re !~ "My age is 99").to eq(true)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe "#===" do
|
382
|
+
it "returns only true or false if no matches are requested" do
|
383
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
384
|
+
expect(re === "My name is Robert Paulson").to eq(true)
|
385
|
+
expect(re === "My age is 99").to eq(false)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe "#ok?" do
|
390
|
+
it "returns true for valid regexps" do
|
391
|
+
expect(RE2::Regexp.new('woo')).to be_ok
|
392
|
+
expect(RE2::Regexp.new('wo(o)')).to be_ok
|
393
|
+
expect(RE2::Regexp.new('((\d)\w+){3,}')).to be_ok
|
394
|
+
end
|
395
|
+
|
396
|
+
it "returns false for invalid regexps" do
|
397
|
+
expect(RE2::Regexp.new('wo(o', :log_errors => false)).to_not be_ok
|
398
|
+
expect(RE2::Regexp.new('wo[o', :log_errors => false)).to_not be_ok
|
399
|
+
expect(RE2::Regexp.new('*', :log_errors => false)).to_not be_ok
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
describe ".escape" do
|
404
|
+
it "transforms a string into a regexp" do
|
405
|
+
expect(RE2::Regexp.escape("1.5-2.0?")).to eq('1\.5\-2\.0\?')
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe ".quote" do
|
410
|
+
it "transforms a string into a regexp" do
|
411
|
+
expect(RE2::Regexp.quote("1.5-2.0?")).to eq('1\.5\-2\.0\?')
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "#number_of_capturing_groups" do
|
416
|
+
it "returns the number of groups in a regexp" do
|
417
|
+
expect(RE2::Regexp.new('(a)(b)(c)').number_of_capturing_groups).to eq(3)
|
418
|
+
expect(RE2::Regexp.new('abc').number_of_capturing_groups).to eq(0)
|
419
|
+
expect(RE2::Regexp.new('a((b)c)').number_of_capturing_groups).to eq(2)
|
420
|
+
end
|
421
|
+
|
422
|
+
it "returns -1 for an invalid regexp" do
|
423
|
+
expect(RE2::Regexp.new('???', :log_errors => false).number_of_capturing_groups).to eq(-1)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe "#named_capturing_groups" do
|
428
|
+
it "returns a hash of names to indices" do
|
429
|
+
expect(RE2::Regexp.new('(?P<bob>a)').named_capturing_groups).to be_a(Hash)
|
430
|
+
end
|
431
|
+
|
432
|
+
it "maps names to indices with only one group" do
|
433
|
+
groups = RE2::Regexp.new('(?P<bob>a)').named_capturing_groups
|
434
|
+
expect(groups["bob"]).to eq(1)
|
435
|
+
end
|
436
|
+
|
437
|
+
it "maps names to indices with several groups" do
|
438
|
+
groups = RE2::Regexp.new('(?P<bob>a)(o)(?P<rob>e)').named_capturing_groups
|
439
|
+
expect(groups["bob"]).to eq(1)
|
440
|
+
expect(groups["rob"]).to eq(3)
|
441
|
+
end
|
442
|
+
|
443
|
+
it "returns an empty hash for an invalid regexp" do
|
444
|
+
expect(RE2::Regexp.new('???', :log_errors => false).named_capturing_groups).to be_empty
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "#scan" do
|
449
|
+
it "returns a scanner" do
|
450
|
+
r = RE2::Regexp.new('(\w+)')
|
451
|
+
scanner = r.scan("It is a truth universally acknowledged")
|
452
|
+
|
453
|
+
expect(scanner).to be_a(RE2::Scanner)
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe RE2::Scanner do
|
4
|
+
describe "#regexp" do
|
5
|
+
it "returns the original pattern for the scanner" do
|
6
|
+
re = RE2::Regexp.new('(\w+)')
|
7
|
+
scanner = re.scan("It is a truth")
|
8
|
+
|
9
|
+
expect(scanner.regexp).to equal(re)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#string" do
|
14
|
+
it "returns the original text for the scanner" do
|
15
|
+
re = RE2::Regexp.new('(\w+)')
|
16
|
+
text = "It is a truth"
|
17
|
+
scanner = re.scan(text)
|
18
|
+
|
19
|
+
expect(scanner.string).to equal(text)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#scan" do
|
24
|
+
it "returns the next array of matches" do
|
25
|
+
r = RE2::Regexp.new('(\w+)')
|
26
|
+
scanner = r.scan("It is a truth universally acknowledged")
|
27
|
+
expect(scanner.scan).to eq(["It"])
|
28
|
+
expect(scanner.scan).to eq(["is"])
|
29
|
+
expect(scanner.scan).to eq(["a"])
|
30
|
+
expect(scanner.scan).to eq(["truth"])
|
31
|
+
expect(scanner.scan).to eq(["universally"])
|
32
|
+
expect(scanner.scan).to eq(["acknowledged"])
|
33
|
+
expect(scanner.scan).to be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns an empty array if there are no capturing groups" do
|
37
|
+
r = RE2::Regexp.new('\w+')
|
38
|
+
scanner = r.scan("Foo bar")
|
39
|
+
expect(scanner.scan).to eq([])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns nil if there is no match" do
|
43
|
+
r = RE2::Regexp.new('\d+')
|
44
|
+
scanner = r.scan("Foo bar")
|
45
|
+
expect(scanner.scan).to be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns nil if the regexp is invalid" do
|
49
|
+
r = RE2::Regexp.new('???', :log_errors => false)
|
50
|
+
scanner = r.scan("Foo bar")
|
51
|
+
expect(scanner.scan).to be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns an empty array if the input is empty" do
|
55
|
+
r = RE2::Regexp.new("")
|
56
|
+
scanner = r.scan("")
|
57
|
+
expect(scanner.scan).to eq([])
|
58
|
+
expect(scanner.scan).to be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns an array of nil with an empty input and capture" do
|
62
|
+
r = RE2::Regexp.new("()")
|
63
|
+
scanner = r.scan("")
|
64
|
+
expect(scanner.scan).to eq([nil])
|
65
|
+
expect(scanner.scan).to be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns an empty array for every match if the pattern is empty" do
|
69
|
+
r = RE2::Regexp.new("")
|
70
|
+
scanner = r.scan("Foo")
|
71
|
+
expect(scanner.scan).to eq([])
|
72
|
+
expect(scanner.scan).to eq([])
|
73
|
+
expect(scanner.scan).to eq([])
|
74
|
+
expect(scanner.scan).to eq([])
|
75
|
+
expect(scanner.scan).to be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns an array of nil if the pattern is an empty capturing group" do
|
79
|
+
r = RE2::Regexp.new("()")
|
80
|
+
scanner = r.scan("Foo")
|
81
|
+
expect(scanner.scan).to eq([nil])
|
82
|
+
expect(scanner.scan).to eq([nil])
|
83
|
+
expect(scanner.scan).to eq([nil])
|
84
|
+
expect(scanner.scan).to eq([nil])
|
85
|
+
expect(scanner.scan).to be_nil
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns array of nils with multiple empty capturing groups" do
|
89
|
+
r = RE2::Regexp.new("()()()")
|
90
|
+
scanner = r.scan("Foo")
|
91
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
92
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
93
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
94
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
95
|
+
expect(scanner.scan).to be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "supports empty groups with multibyte characters" do
|
99
|
+
r = RE2::Regexp.new("()€")
|
100
|
+
scanner = r.scan("€")
|
101
|
+
expect(scanner.scan).to eq([nil])
|
102
|
+
expect(scanner.scan).to be_nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "is enumerable" do
|
107
|
+
r = RE2::Regexp.new('(\d)')
|
108
|
+
scanner = r.scan("There are 1 some 2 numbers 3")
|
109
|
+
expect(scanner).to be_a(Enumerable)
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#each" do
|
113
|
+
it "yields each match" do
|
114
|
+
r = RE2::Regexp.new('(\d)')
|
115
|
+
scanner = r.scan("There are 1 some 2 numbers 3")
|
116
|
+
matches = []
|
117
|
+
scanner.each do |match|
|
118
|
+
matches << match
|
119
|
+
end
|
120
|
+
|
121
|
+
expect(matches).to eq([["1"], ["2"], ["3"]])
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns an enumerator when not given a block" do
|
125
|
+
r = RE2::Regexp.new('(\d)')
|
126
|
+
scanner = r.scan("There are 1 some 2 numbers 3")
|
127
|
+
|
128
|
+
# Prior to Ruby 1.9, Enumerator was within Enumerable.
|
129
|
+
if defined?(Enumerator)
|
130
|
+
expect(scanner.each).to be_a(Enumerator)
|
131
|
+
elsif defined?(Enumerable::Enumerator)
|
132
|
+
expect(scanner.each).to be_a(Enumerable::Enumerator)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#rewind" do
|
138
|
+
it "resets any consumption" do
|
139
|
+
r = RE2::Regexp.new('(\d)')
|
140
|
+
scanner = r.scan("There are 1 some 2 numbers 3")
|
141
|
+
expect(scanner.to_enum.first).to eq(["1"])
|
142
|
+
expect(scanner.to_enum.first).to eq(["2"])
|
143
|
+
scanner.rewind
|
144
|
+
expect(scanner.to_enum.first).to eq(["1"])
|
145
|
+
end
|
146
|
+
|
147
|
+
it "resets the eof? check" do
|
148
|
+
r = RE2::Regexp.new('(\d)')
|
149
|
+
scanner = r.scan("1")
|
150
|
+
scanner.scan
|
151
|
+
expect(scanner.eof?).to be_truthy
|
152
|
+
scanner.rewind
|
153
|
+
expect(scanner.eof?).to be_falsey
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#eof?" do
|
158
|
+
it "returns false if the input has not been consumed" do
|
159
|
+
r = RE2::Regexp.new('(\d)')
|
160
|
+
scanner = r.scan("1 2 3")
|
161
|
+
|
162
|
+
expect(scanner.eof?).to be_falsey
|
163
|
+
end
|
164
|
+
|
165
|
+
it "returns true if the input has been consumed" do
|
166
|
+
r = RE2::Regexp.new('(\d)')
|
167
|
+
scanner = r.scan("1")
|
168
|
+
scanner.scan
|
169
|
+
|
170
|
+
expect(scanner.eof?).to be_truthy
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns false if no match is made" do
|
174
|
+
r = RE2::Regexp.new('(\d)')
|
175
|
+
scanner = r.scan("a")
|
176
|
+
scanner.scan
|
177
|
+
|
178
|
+
expect(scanner.eof?).to be_falsey
|
179
|
+
end
|
180
|
+
|
181
|
+
it "returns false with an empty input that has not been scanned" do
|
182
|
+
r = RE2::Regexp.new("")
|
183
|
+
scanner = r.scan("")
|
184
|
+
|
185
|
+
expect(scanner.eof?).to be_falsey
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns false with an empty input that has not been matched" do
|
189
|
+
r = RE2::Regexp.new('(\d)')
|
190
|
+
scanner = r.scan("")
|
191
|
+
scanner.scan
|
192
|
+
|
193
|
+
expect(scanner.eof?).to be_falsey
|
194
|
+
end
|
195
|
+
|
196
|
+
it "returns true with an empty input that has been matched" do
|
197
|
+
r = RE2::Regexp.new("")
|
198
|
+
scanner = r.scan("")
|
199
|
+
scanner.scan
|
200
|
+
|
201
|
+
expect(scanner.eof?).to be_truthy
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|