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