regexp-examples 1.1.0 → 1.1.2
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 +9 -9
- data/Rakefile +3 -3
- data/db/unicode_ranges_2.0.pstore +0 -0
- data/db/unicode_ranges_2.1.pstore +0 -0
- data/db/unicode_ranges_2.2.pstore +0 -0
- data/lib/{regexp-examples/core_extensions → core_extensions}/regexp/examples.rb +3 -3
- data/lib/regexp-examples.rb +11 -2
- data/lib/regexp-examples/backreferences.rb +3 -4
- data/lib/regexp-examples/chargroup_parser.rb +14 -14
- data/lib/regexp-examples/constants.rb +5 -156
- data/lib/regexp-examples/groups.rb +20 -12
- data/lib/regexp-examples/helpers.rb +5 -5
- data/lib/regexp-examples/parser.rb +52 -42
- data/lib/regexp-examples/repeaters.rb +5 -5
- data/lib/regexp-examples/unicode_char_ranges.rb +45 -0
- data/lib/regexp-examples/version.rb +1 -1
- data/regexp-examples.gemspec +4 -4
- data/scripts/unicode_lister.rb +34 -150
- data/spec/regexp-examples_spec.rb +81 -59
- data/spec/regexp-random_example_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +8 -4
@@ -1,8 +1,8 @@
|
|
1
|
-
RSpec.describe Regexp,
|
1
|
+
RSpec.describe Regexp, '#examples' do
|
2
2
|
def self.examples_exist_and_match(*regexps)
|
3
3
|
regexps.each do |regexp|
|
4
4
|
it "examples for /#{regexp.source}/" do
|
5
|
-
regexp_examples = regexp.examples(max_group_results:
|
5
|
+
regexp_examples = regexp.examples(max_group_results: 99_999)
|
6
6
|
|
7
7
|
expect(regexp_examples).not_to be_empty, "No examples were generated for regexp: /#{regexp.source}/"
|
8
8
|
regexp_examples.each { |example| expect(example).to match(/\A(?:#{regexp.source})\z/) }
|
@@ -17,7 +17,7 @@ RSpec.describe Regexp, "#examples" do
|
|
17
17
|
def self.examples_raise_illegal_syntax_error(*regexps)
|
18
18
|
regexps.each do |regexp|
|
19
19
|
it "examples for /#{regexp.source}/" do
|
20
|
-
expect{regexp.examples}.to raise_error RegexpExamples::IllegalSyntaxError
|
20
|
+
expect { regexp.examples }.to raise_error RegexpExamples::IllegalSyntaxError
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -31,7 +31,7 @@ RSpec.describe Regexp, "#examples" do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'returns matching strings' do
|
34
|
-
context
|
34
|
+
context 'for basic repeaters' do
|
35
35
|
examples_exist_and_match(
|
36
36
|
/a/, # "one-time repeater"
|
37
37
|
/a*/, # greedy
|
@@ -58,7 +58,7 @@ RSpec.describe Regexp, "#examples" do
|
|
58
58
|
)
|
59
59
|
end
|
60
60
|
|
61
|
-
context
|
61
|
+
context 'for basic groups' do
|
62
62
|
examples_exist_and_match(
|
63
63
|
/[a]/,
|
64
64
|
/(a)/,
|
@@ -67,7 +67,7 @@ RSpec.describe Regexp, "#examples" do
|
|
67
67
|
)
|
68
68
|
end
|
69
69
|
|
70
|
-
context
|
70
|
+
context 'for complex char groups (square brackets)' do
|
71
71
|
examples_exist_and_match(
|
72
72
|
/[abc]/,
|
73
73
|
/[a-c]/,
|
@@ -93,7 +93,7 @@ RSpec.describe Regexp, "#examples" do
|
|
93
93
|
)
|
94
94
|
end
|
95
95
|
|
96
|
-
context
|
96
|
+
context 'for complex multi groups' do
|
97
97
|
examples_exist_and_match(
|
98
98
|
/(normal)/,
|
99
99
|
/(?:nocapture)/,
|
@@ -103,19 +103,19 @@ RSpec.describe Regexp, "#examples" do
|
|
103
103
|
)
|
104
104
|
end
|
105
105
|
|
106
|
-
context
|
106
|
+
context 'for escaped characters' do
|
107
107
|
all_letters = Array('a'..'z') | Array('A'..'Z')
|
108
108
|
special_letters = %w(b c g p u x z A B C G M P Z)
|
109
109
|
valid_letters = all_letters - special_letters
|
110
110
|
|
111
111
|
valid_letters.each do |char|
|
112
112
|
backslash_char = "\\#{char}"
|
113
|
-
examples_exist_and_match(
|
113
|
+
examples_exist_and_match(/#{backslash_char}/)
|
114
114
|
end
|
115
|
-
examples_exist_and_match(
|
115
|
+
examples_exist_and_match(/[\b]/)
|
116
116
|
end
|
117
117
|
|
118
|
-
context
|
118
|
+
context 'for backreferences' do
|
119
119
|
examples_exist_and_match(
|
120
120
|
/(repeat) \1/,
|
121
121
|
/(ref1) (ref2) \1 \2/,
|
@@ -130,14 +130,14 @@ RSpec.describe Regexp, "#examples" do
|
|
130
130
|
)
|
131
131
|
end
|
132
132
|
|
133
|
-
context
|
133
|
+
context 'for escaped octal characters' do
|
134
134
|
examples_exist_and_match(
|
135
135
|
/\10\20\30\40\50/,
|
136
136
|
/\177123/ # Should work for numbers up to 177
|
137
137
|
)
|
138
138
|
end
|
139
139
|
|
140
|
-
context
|
140
|
+
context 'for complex patterns' do
|
141
141
|
# Longer combinations of the above
|
142
142
|
examples_exist_and_match(
|
143
143
|
/https?:\/\/(www\.)github\.com/,
|
@@ -151,7 +151,7 @@ RSpec.describe Regexp, "#examples" do
|
|
151
151
|
)
|
152
152
|
end
|
153
153
|
|
154
|
-
context
|
154
|
+
context 'for illegal syntax' do
|
155
155
|
examples_raise_illegal_syntax_error(
|
156
156
|
/(?=lookahead)/,
|
157
157
|
/(?!neglookahead)/,
|
@@ -168,7 +168,7 @@ RSpec.describe Regexp, "#examples" do
|
|
168
168
|
)
|
169
169
|
end
|
170
170
|
|
171
|
-
context
|
171
|
+
context 'ignore start/end anchors if at start/end' do
|
172
172
|
examples_exist_and_match(
|
173
173
|
/\Astart/,
|
174
174
|
/\Glast-match/,
|
@@ -179,19 +179,42 @@ RSpec.describe Regexp, "#examples" do
|
|
179
179
|
)
|
180
180
|
end
|
181
181
|
|
182
|
-
context
|
182
|
+
context 'for named properties' do
|
183
183
|
examples_exist_and_match(
|
184
|
-
/\p{
|
185
|
-
/\p{
|
186
|
-
/\
|
187
|
-
/\
|
188
|
-
/\P{Ll}/,
|
189
|
-
/\P{^Ll}/ # Double negative!!
|
184
|
+
/\p{AlPhA}/, # Case insensitivity
|
185
|
+
/\p{^Ll}/, # Negation syntax type 1
|
186
|
+
/\P{Ll}/, # Negation syntax type 2
|
187
|
+
/\P{^Ll}/ # Double negation!! (Should cancel out)
|
190
188
|
)
|
189
|
+
# An exhaustive set of tests for all named properties!!!
|
190
|
+
# This is useful for verifying the PStore contains correct values for all ruby versions
|
191
|
+
%w(
|
192
|
+
Alnum Alpha Blank Cntrl Digit Graph Lower Print Punct Space Upper XDigit Word ASCII Any Assigned
|
193
|
+
L Ll Lm Lo Lt Lu M Mn Mc Me N Nd Nl No P Pc Pd Ps Pe Pi Pf Po S Sm Sc Sk So Z Zs Zl Zp C Cc Cf Cn Co
|
194
|
+
Arabic Armenian Balinese Bengali Bopomofo Braille Buginese Buhid Canadian_Aboriginal Cham Cherokee
|
195
|
+
Common Coptic Cyrillic Devanagari Ethiopic Georgian Glagolitic Greek Gujarati Gurmukhi Han Hangul
|
196
|
+
Hanunoo Hebrew Hiragana Inherited Kannada Katakana Kayah_Li Khmer Lao Latin Lepcha Limbu Malayalam
|
197
|
+
Mongolian Myanmar New_Tai_Lue Nko Ogham Ol_Chiki Oriya Phags_Pa Rejang Runic Saurashtra Sinhala
|
198
|
+
Sundanese Syloti_Nagri Syriac Tagalog Tagbanwa Tai_Le Tamil Telugu Thaana Thai Tibetan Tifinagh
|
199
|
+
Vai Yi
|
200
|
+
).each do |property|
|
201
|
+
it "examples for /\p{#{property}}/" do
|
202
|
+
regexp_examples = /\p{#{property}}/.examples(max_group_results: 99_999)
|
203
|
+
expect(regexp_examples).not_to be_empty, "No examples were generated for regexp: /\p{#{property}}/"
|
204
|
+
# Just do one big check, for test system performance (~30% faster)
|
205
|
+
# (Otherwise, we are doing up to 128 regex expectations for every single property!!)
|
206
|
+
expect(regexp_examples.join('')).to match(/\A\p{#{property}}+\z/)
|
207
|
+
end
|
208
|
+
end
|
191
209
|
|
210
|
+
# The following seem to genuinely have no matching examples (!!??!!?!)
|
211
|
+
%w(Cs Carian Cuneiform Cypriot Deseret Gothic Kharoshthi Linear_B Lycian
|
212
|
+
Lydian Old_Italic Old_Persian Osmanya Phoenician Shavian Ugaritic).each do |property|
|
213
|
+
examples_are_empty(/\p{#{property}}/)
|
214
|
+
end
|
192
215
|
end
|
193
216
|
|
194
|
-
context
|
217
|
+
context 'for control characters' do
|
195
218
|
examples_exist_and_match(
|
196
219
|
/\ca/,
|
197
220
|
/\cZ/,
|
@@ -204,7 +227,7 @@ RSpec.describe Regexp, "#examples" do
|
|
204
227
|
)
|
205
228
|
end
|
206
229
|
|
207
|
-
context
|
230
|
+
context 'for escape sequences' do
|
208
231
|
examples_exist_and_match(
|
209
232
|
/\x42/,
|
210
233
|
/\x1D/,
|
@@ -213,15 +236,15 @@ RSpec.describe Regexp, "#examples" do
|
|
213
236
|
)
|
214
237
|
end
|
215
238
|
|
216
|
-
context
|
239
|
+
context 'for unicode sequences' do
|
217
240
|
examples_exist_and_match(
|
218
|
-
|
219
|
-
|
220
|
-
|
241
|
+
/\u6829/,
|
242
|
+
/\uabcd/,
|
243
|
+
/\u{42}word/
|
221
244
|
)
|
222
245
|
end
|
223
246
|
|
224
|
-
context
|
247
|
+
context 'for empty character sets' do
|
225
248
|
examples_are_empty(
|
226
249
|
/[^\d\D]/,
|
227
250
|
/[^\w\W]/,
|
@@ -235,14 +258,14 @@ RSpec.describe Regexp, "#examples" do
|
|
235
258
|
)
|
236
259
|
end
|
237
260
|
|
238
|
-
context
|
261
|
+
context 'for comment groups' do
|
239
262
|
examples_exist_and_match(
|
240
263
|
/a(?#comment)b/,
|
241
264
|
/a(?#ugly backslashy\ comment\\\))b/
|
242
265
|
)
|
243
266
|
end
|
244
267
|
|
245
|
-
context
|
268
|
+
context 'for POSIX groups' do
|
246
269
|
examples_exist_and_match(
|
247
270
|
/[[:alnum:]]/,
|
248
271
|
/[[:alpha:]]/,
|
@@ -262,29 +285,29 @@ RSpec.describe Regexp, "#examples" do
|
|
262
285
|
)
|
263
286
|
end
|
264
287
|
|
265
|
-
context
|
288
|
+
context 'exact examples match' do
|
266
289
|
# More rigorous tests to assert that ALL examples are being listed
|
267
|
-
context
|
290
|
+
context 'default config options' do
|
268
291
|
# Simple examples
|
269
|
-
it { expect(/[ab]{2}/.examples).to
|
270
|
-
it { expect(/(a|b){2}/.examples).to
|
271
|
-
it { expect(/a+|b?/.examples).to
|
292
|
+
it { expect(/[ab]{2}/.examples).to match_array %w(aa ab ba bb) }
|
293
|
+
it { expect(/(a|b){2}/.examples).to match_array %w(aa ab ba bb) }
|
294
|
+
it { expect(/a+|b?/.examples).to match_array ['a', 'aa', 'aaa', '', 'b'] }
|
272
295
|
|
273
296
|
# a{1}? should be equivalent to (?:a{1})?, i.e. NOT a "non-greedy quantifier"
|
274
|
-
it { expect(/a{1}?/.examples).to
|
297
|
+
it { expect(/a{1}?/.examples).to match_array ['', 'a'] }
|
275
298
|
end
|
276
299
|
|
277
|
-
context
|
300
|
+
context 'backreferences and escaped octal combined' do
|
278
301
|
it do
|
279
302
|
expect(/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)? \10\9\8\7\6\5\4\3\2\1/.examples)
|
280
|
-
.to
|
303
|
+
.to match_array ["abcdefghi \x08ihgfedcba", 'abcdefghij jihgfedcba']
|
281
304
|
end
|
282
305
|
end
|
283
306
|
|
284
|
-
context
|
307
|
+
context 'max_repeater_variance config option' do
|
285
308
|
it do
|
286
309
|
expect(/a+/.examples(max_repeater_variance: 5))
|
287
|
-
.to
|
310
|
+
.to match_array %w(a aa aaa aaaa aaaaa aaaaaa)
|
288
311
|
end
|
289
312
|
it do
|
290
313
|
expect(/a{4,8}/.examples(max_repeater_variance: 0))
|
@@ -292,25 +315,25 @@ RSpec.describe Regexp, "#examples" do
|
|
292
315
|
end
|
293
316
|
end
|
294
317
|
|
295
|
-
context
|
318
|
+
context 'max_group_results config option' do
|
296
319
|
it do
|
297
320
|
expect(/\d/.examples(max_group_results: 10))
|
298
|
-
.to
|
321
|
+
.to match_array %w(0 1 2 3 4 5 6 7 8 9)
|
299
322
|
end
|
300
323
|
end
|
301
324
|
|
302
|
-
context
|
303
|
-
it { expect(/ab/i.examples).to
|
304
|
-
it { expect(/a+/i.examples).to
|
305
|
-
it { expect(/([ab])\1/i.examples).to
|
325
|
+
context 'case insensitive' do
|
326
|
+
it { expect(/ab/i.examples).to match_array %w(ab aB Ab AB) }
|
327
|
+
it { expect(/a+/i.examples).to match_array %w(a A aa aA Aa AA aaa aaA aAa aAA Aaa AaA AAa AAA) }
|
328
|
+
it { expect(/([ab])\1/i.examples).to match_array %w(aa bb AA BB) }
|
306
329
|
end
|
307
330
|
|
308
|
-
context
|
331
|
+
context 'multiline' do
|
309
332
|
it { expect(/./.examples(max_group_results: 999)).not_to include "\n" }
|
310
333
|
it { expect(/./m.examples(max_group_results: 999)).to include "\n" }
|
311
334
|
end
|
312
335
|
|
313
|
-
context
|
336
|
+
context 'exteded form' do
|
314
337
|
it { expect(/a b c/x.examples).to eq %w(abc) }
|
315
338
|
it { expect(/a#comment/x.examples).to eq %w(a) }
|
316
339
|
it do
|
@@ -323,20 +346,19 @@ RSpec.describe Regexp, "#examples" do
|
|
323
346
|
end
|
324
347
|
end
|
325
348
|
|
326
|
-
context
|
327
|
-
context
|
328
|
-
it { expect(/a(?i)b(?-i)c/.examples).to
|
329
|
-
it { expect(/a(?x) b(?-x) c/.examples).to eq %w
|
349
|
+
context 'options toggling' do
|
350
|
+
context 'rest of string' do
|
351
|
+
it { expect(/a(?i)b(?-i)c/.examples).to match_array %w(abc aBc) }
|
352
|
+
it { expect(/a(?x) b(?-x) c/.examples).to eq %w(ab\ c) }
|
330
353
|
it { expect(/(?m)./.examples(max_group_results: 999)).to include "\n" }
|
331
|
-
it { expect(/(?i)(a)-\1/.examples).to
|
354
|
+
it { expect(/(?i)(a)-\1/.examples).to match_array %w(a-a A-A) } # Toggle "groups" should not increase backref group count
|
332
355
|
end
|
333
|
-
context
|
334
|
-
it { expect(/a(?i:b)c/.examples).to
|
335
|
-
it { expect(/a(?i:b(?-i:c))/.examples).to
|
336
|
-
it { expect(/a(?-i:b)c/i.examples).to
|
356
|
+
context 'subexpression' do
|
357
|
+
it { expect(/a(?i:b)c/.examples).to match_array %w(abc aBc) }
|
358
|
+
it { expect(/a(?i:b(?-i:c))/.examples).to match_array %w(abc aBc) }
|
359
|
+
it { expect(/a(?-i:b)c/i.examples).to match_array %w(abc abC Abc AbC) }
|
337
360
|
end
|
338
361
|
end
|
339
362
|
end
|
340
|
-
|
341
363
|
end
|
342
364
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
RSpec.describe Regexp,
|
1
|
+
RSpec.describe Regexp, '#random_example' do
|
2
2
|
def self.random_example_matches(*regexps)
|
3
3
|
regexps.each do |regexp|
|
4
4
|
it "random example for /#{regexp.source}/" do
|
@@ -10,7 +10,7 @@ RSpec.describe Regexp, "#random_example" do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
context
|
13
|
+
context 'smoke tests' do
|
14
14
|
# Just a few "smoke tests", to ensure the basic method isn't broken.
|
15
15
|
# Testing of the RegexpExamples::Parser class is all covered by Regexp#examples test already.
|
16
16
|
random_example_matches(
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: regexp-examples
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Lord
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -51,15 +51,19 @@ files:
|
|
51
51
|
- LICENSE.txt
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
|
+
- db/unicode_ranges_2.0.pstore
|
55
|
+
- db/unicode_ranges_2.1.pstore
|
56
|
+
- db/unicode_ranges_2.2.pstore
|
57
|
+
- lib/core_extensions/regexp/examples.rb
|
54
58
|
- lib/regexp-examples.rb
|
55
59
|
- lib/regexp-examples/backreferences.rb
|
56
60
|
- lib/regexp-examples/chargroup_parser.rb
|
57
61
|
- lib/regexp-examples/constants.rb
|
58
|
-
- lib/regexp-examples/core_extensions/regexp/examples.rb
|
59
62
|
- lib/regexp-examples/groups.rb
|
60
63
|
- lib/regexp-examples/helpers.rb
|
61
64
|
- lib/regexp-examples/parser.rb
|
62
65
|
- lib/regexp-examples/repeaters.rb
|
66
|
+
- lib/regexp-examples/unicode_char_ranges.rb
|
63
67
|
- lib/regexp-examples/version.rb
|
64
68
|
- regexp-examples.gemspec
|
65
69
|
- scripts/unicode_lister.rb
|
@@ -86,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
90
|
version: '0'
|
87
91
|
requirements: []
|
88
92
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.4.
|
93
|
+
rubygems_version: 2.4.6
|
90
94
|
signing_key:
|
91
95
|
specification_version: 4
|
92
96
|
summary: Extends the Regexp class with '#examples'
|