regexador 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2928 @@
1
+ require './spec/testing'
2
+
3
+ describe Regexador do
4
+
5
+ before(:all) do
6
+ @parser = Regexador::Parser.new
7
+ @pattern = @parser.pattern
8
+ end
9
+
10
+ after(:each) do # FIXME There must be a better way?
11
+ if example.exception != nil
12
+ puts "\n--- Failed to parse:"
13
+ puts $prog
14
+ puts "--- Result is:"
15
+ puts @parser.parse_with_debug($prog) # Why doesn't this work?
16
+ puts "--- END"
17
+ end
18
+ end
19
+
20
+ def self.program &block
21
+ let(:code, &block)
22
+ let(:program) { Program.new(code) }
23
+ let(:regexp) { program.regexp }
24
+
25
+ subject { program }
26
+ end
27
+
28
+
29
+ ### Test 1: Single char
30
+
31
+ describe "Single char:" do
32
+ $prog = prog = %q<match `x end>
33
+ program { prog }
34
+
35
+ good = ["abcx", "xyzb", "x"]
36
+ bad = ["yz", "", "ABC"]
37
+ wanted = /x/
38
+
39
+ it { should be_parseable }
40
+
41
+ rx = nil
42
+ it "can be converted to a regex" do
43
+ rx = regexp
44
+ rx.class.should == Regexp
45
+ rx.to_s.should == wanted.to_s
46
+ end
47
+
48
+ # Check sanity: Is test valid?
49
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
50
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
51
+
52
+ # Is compiled result valid?
53
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
54
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
55
+ end # end of test
56
+
57
+
58
+ ### Test 2: Unicode codepoint
59
+
60
+ describe "Unicode codepoint:" do
61
+ $prog = prog = %q<match &20ac end>
62
+ program { prog }
63
+
64
+ good = ["€", "xyz€", "x€yz"]
65
+ bad = ["yz", "", "ABC"]
66
+ wanted = /€/
67
+
68
+ it { should be_parseable }
69
+
70
+ rx = nil
71
+ it "can be converted to a regex" do
72
+ rx = regexp
73
+ rx.class.should == Regexp
74
+ rx.to_s.should == wanted.to_s
75
+ end
76
+
77
+ # Check sanity: Is test valid?
78
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
79
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
80
+
81
+ # Is compiled result valid?
82
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
83
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
84
+ end # end of test
85
+
86
+
87
+ ### Test 3: Manual international characters
88
+
89
+ describe "Manual international characters:" do
90
+ $prog = prog = %q<match "ö" end>
91
+ program { prog }
92
+
93
+ good = ["öffnen", "xyzö", "xöyz"]
94
+ bad = ["offnen", "yz", "", "ABC"]
95
+ wanted = /ö/
96
+
97
+ it { should be_parseable }
98
+
99
+ rx = nil
100
+ it "can be converted to a regex" do
101
+ rx = regexp
102
+ rx.class.should == Regexp
103
+ rx.to_s.should == wanted.to_s
104
+ end
105
+
106
+ # Check sanity: Is test valid?
107
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
108
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
109
+
110
+ # Is compiled result valid?
111
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
112
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
113
+ end # end of test
114
+
115
+
116
+ ### Test 4: Simple range
117
+
118
+ describe "Simple range:" do
119
+ $prog = prog = %q<match `a-`f end>
120
+ program { prog }
121
+
122
+ good = ["alpha", "xyzb", "c"]
123
+ bad = ["xyz", "", "ABC"]
124
+ wanted = /[a-f]/
125
+
126
+ it { should be_parseable }
127
+
128
+ rx = nil
129
+ it "can be converted to a regex" do
130
+ rx = regexp
131
+ rx.class.should == Regexp
132
+ rx.to_s.should == wanted.to_s
133
+ end
134
+
135
+ # Check sanity: Is test valid?
136
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
137
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
138
+
139
+ # Is compiled result valid?
140
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
141
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
142
+ end # end of test
143
+
144
+
145
+ ### Test 5: Negated range
146
+
147
+ describe "Negated range:" do
148
+ $prog = prog = %q<match `c~`p end>
149
+ program { prog }
150
+
151
+ good = ["ab", "rst"]
152
+ bad = ["def", "mno", ""]
153
+ wanted = /[^c-p]/
154
+
155
+ it { should be_parseable }
156
+
157
+ rx = nil
158
+ it "can be converted to a regex" do
159
+ rx = regexp
160
+ rx.class.should == Regexp
161
+ rx.to_s.should == wanted.to_s
162
+ end
163
+
164
+ # Check sanity: Is test valid?
165
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
166
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
167
+
168
+ # Is compiled result valid?
169
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
170
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
171
+ end # end of test
172
+
173
+
174
+ ### Test 6: Negated char
175
+
176
+ describe "Negated char:" do
177
+ $prog = prog = %q<match ~`d end>
178
+ program { prog }
179
+
180
+ good = ["xyz", "123"]
181
+ bad = ["d", "dd"]
182
+ wanted = /[^d]/
183
+
184
+ it { should be_parseable }
185
+
186
+ rx = nil
187
+ it "can be converted to a regex" do
188
+ rx = regexp
189
+ rx.class.should == Regexp
190
+ rx.to_s.should == wanted.to_s
191
+ end
192
+
193
+ # Check sanity: Is test valid?
194
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
195
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
196
+
197
+ # Is compiled result valid?
198
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
199
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
200
+ end # end of test
201
+
202
+
203
+ ### Test 7: POSIX class
204
+
205
+ describe "POSIX class:" do
206
+ $prog = prog = %q<match %alnum end>
207
+ program { prog }
208
+
209
+ good = ["abc365", "237", "xyz"]
210
+ bad = ["---", ":,.-"]
211
+ wanted = /[[:alnum:]]/
212
+
213
+ it { should be_parseable }
214
+
215
+ rx = nil
216
+ it "can be converted to a regex" do
217
+ rx = regexp
218
+ rx.class.should == Regexp
219
+ rx.to_s.should == wanted.to_s
220
+ end
221
+
222
+ # Check sanity: Is test valid?
223
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
224
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
225
+
226
+ # Is compiled result valid?
227
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
228
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
229
+ end # end of test
230
+
231
+
232
+ ### Test 8: Simple char class
233
+
234
+ describe "Simple char class:" do
235
+ $prog = prog = %q<match 'prstu' end>
236
+ program { prog }
237
+
238
+ good = ["du", "ppp", "sr"]
239
+ bad = ["abc", "xyz"]
240
+ wanted = /[prstu]/
241
+
242
+ it { should be_parseable }
243
+
244
+ rx = nil
245
+ it "can be converted to a regex" do
246
+ rx = regexp
247
+ rx.class.should == Regexp
248
+ rx.to_s.should == wanted.to_s
249
+ end
250
+
251
+ # Check sanity: Is test valid?
252
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
253
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
254
+
255
+ # Is compiled result valid?
256
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
257
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
258
+ end # end of test
259
+
260
+
261
+ ### Test 9: Negated char class
262
+
263
+ describe "Negated char class:" do
264
+ $prog = prog = %q<match ~'ilmnop' end>
265
+ program { prog }
266
+
267
+ good = ["abacus", "peccata", "hydrogen"]
268
+ bad = ["oil", "pill"]
269
+ wanted = /[^ilmnop]/
270
+
271
+ it { should be_parseable }
272
+
273
+ rx = nil
274
+ it "can be converted to a regex" do
275
+ rx = regexp
276
+ rx.class.should == Regexp
277
+ rx.to_s.should == wanted.to_s
278
+ end
279
+
280
+ # Check sanity: Is test valid?
281
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
282
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
283
+
284
+ # Is compiled result valid?
285
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
286
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
287
+ end # end of test
288
+
289
+
290
+ ### Test 10: Predef Beginning of string
291
+
292
+ describe "Predef Beginning of string:" do
293
+ $prog = prog = %q<match BOS end>
294
+ program { prog }
295
+
296
+ good = [""]
297
+ bad = []
298
+ wanted = /^/
299
+
300
+ it { should be_parseable }
301
+
302
+ rx = nil
303
+ it "can be converted to a regex" do
304
+ rx = regexp
305
+ rx.class.should == Regexp
306
+ rx.to_s.should == wanted.to_s
307
+ end
308
+
309
+ # Check sanity: Is test valid?
310
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
311
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
312
+
313
+ # Is compiled result valid?
314
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
315
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
316
+ end # end of test
317
+
318
+
319
+ ### Test 11: Predef End of string
320
+
321
+ describe "Predef End of string:" do
322
+ $prog = prog = %q<match EOS end>
323
+ program { prog }
324
+
325
+ good = [""]
326
+ bad = []
327
+ wanted = /$/
328
+
329
+ it { should be_parseable }
330
+
331
+ rx = nil
332
+ it "can be converted to a regex" do
333
+ rx = regexp
334
+ rx.class.should == Regexp
335
+ rx.to_s.should == wanted.to_s
336
+ end
337
+
338
+ # Check sanity: Is test valid?
339
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
340
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
341
+
342
+ # Is compiled result valid?
343
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
344
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
345
+ end # end of test
346
+
347
+
348
+ ### Test 12: Predef Word boundary
349
+
350
+ describe "Predef Word boundary:" do
351
+ $prog = prog = %q<match WB end>
352
+ program { prog }
353
+
354
+ good = ["xyz"]
355
+ bad = ["", "---"]
356
+ wanted = /\b/
357
+
358
+ it { should be_parseable }
359
+
360
+ rx = nil
361
+ it "can be converted to a regex" do
362
+ rx = regexp
363
+ rx.class.should == Regexp
364
+ rx.to_s.should == wanted.to_s
365
+ end
366
+
367
+ # Check sanity: Is test valid?
368
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
369
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
370
+
371
+ # Is compiled result valid?
372
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
373
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
374
+ end # end of test
375
+
376
+
377
+ ### Test 13: Simple string
378
+
379
+ describe "Simple string:" do
380
+ $prog = prog = %q<match "xyz" end>
381
+ program { prog }
382
+
383
+ good = ["xyz", "abcxyzdef"]
384
+ bad = ["abc", "xydefz"]
385
+ wanted = /xyz/
386
+
387
+ it { should be_parseable }
388
+
389
+ rx = nil
390
+ it "can be converted to a regex" do
391
+ rx = regexp
392
+ rx.class.should == Regexp
393
+ rx.to_s.should == wanted.to_s
394
+ end
395
+
396
+ # Check sanity: Is test valid?
397
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
398
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
399
+
400
+ # Is compiled result valid?
401
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
402
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
403
+ end # end of test
404
+
405
+
406
+ ### Test 14: Single-bounded repetition
407
+
408
+ describe "Single-bounded repetition:" do
409
+ $prog = prog = %q<match 5 * "xyz" end>
410
+ program { prog }
411
+
412
+ good = ["xyzxyzxyzxyzxyz"]
413
+ bad = ["xyzxyzxyzxyz"]
414
+ wanted = /(xyz){5}/
415
+
416
+ it { should be_parseable }
417
+
418
+ rx = nil
419
+ it "can be converted to a regex" do
420
+ rx = regexp
421
+ rx.class.should == Regexp
422
+ rx.to_s.should == wanted.to_s
423
+ end
424
+
425
+ # Check sanity: Is test valid?
426
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
427
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
428
+
429
+ # Is compiled result valid?
430
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
431
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
432
+ end # end of test
433
+
434
+
435
+ ### Test 15: Double-bounded repetition
436
+
437
+ describe "Double-bounded repetition:" do
438
+ $prog = prog = %q<match 3,4 * %alpha end>
439
+ program { prog }
440
+
441
+ good = ["abc", "abcd"]
442
+ bad = ["ab", "x"]
443
+ wanted = /([[:alpha:]]){3,4}/
444
+
445
+ it { should be_parseable }
446
+
447
+ rx = nil
448
+ it "can be converted to a regex" do
449
+ rx = regexp
450
+ rx.class.should == Regexp
451
+ rx.to_s.should == wanted.to_s
452
+ end
453
+
454
+ # Check sanity: Is test valid?
455
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
456
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
457
+
458
+ # Is compiled result valid?
459
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
460
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
461
+ end # end of test
462
+
463
+
464
+ ### Test 16: any-qualifier
465
+
466
+ describe "any-qualifier:" do
467
+ $prog = prog = %q<match any "abc" end>
468
+ program { prog }
469
+
470
+ good = ["", "abc", "abcabc", "xyz"]
471
+ bad = []
472
+ wanted = /(abc)*/
473
+
474
+ it { should be_parseable }
475
+
476
+ rx = nil
477
+ it "can be converted to a regex" do
478
+ rx = regexp
479
+ rx.class.should == Regexp
480
+ rx.to_s.should == wanted.to_s
481
+ end
482
+
483
+ # Check sanity: Is test valid?
484
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
485
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
486
+
487
+ # Is compiled result valid?
488
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
489
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
490
+ end # end of test
491
+
492
+
493
+ ### Test 17: many-qualifier
494
+
495
+ describe "many-qualifier:" do
496
+ $prog = prog = %q<match many "def" end>
497
+ program { prog }
498
+
499
+ good = ["def", "defdef", "defdefdef"]
500
+ bad = ["", "de", "xyz"]
501
+ wanted = /(def)+/
502
+
503
+ it { should be_parseable }
504
+
505
+ rx = nil
506
+ it "can be converted to a regex" do
507
+ rx = regexp
508
+ rx.class.should == Regexp
509
+ rx.to_s.should == wanted.to_s
510
+ end
511
+
512
+ # Check sanity: Is test valid?
513
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
514
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
515
+
516
+ # Is compiled result valid?
517
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
518
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
519
+ end # end of test
520
+
521
+
522
+ ### Test 18: nocase-qualifier
523
+
524
+ describe "nocase-qualifier:" do
525
+ $prog = prog = %q<match nocase "ghi" end>
526
+ program { prog }
527
+
528
+ good = ["ghi", "GHI", "abGhicd"]
529
+ bad = ["", "gh", "abc"]
530
+ wanted = /((?i)ghi)/
531
+
532
+ it { should be_parseable }
533
+
534
+ rx = nil
535
+ it "can be converted to a regex" do
536
+ rx = regexp
537
+ rx.class.should == Regexp
538
+ rx.to_s.should == wanted.to_s
539
+ end
540
+
541
+ # Check sanity: Is test valid?
542
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
543
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
544
+
545
+ # Is compiled result valid?
546
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
547
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
548
+ end # end of test
549
+
550
+
551
+ ### Test 19: maybe-qualifier
552
+
553
+ describe "maybe-qualifier:" do
554
+ $prog = prog = %q<match maybe "ghi" end>
555
+ program { prog }
556
+
557
+ good = ["", "ghi", "abghicd", "gh"]
558
+ bad = []
559
+ wanted = /(ghi)?/
560
+
561
+ it { should be_parseable }
562
+
563
+ rx = nil
564
+ it "can be converted to a regex" do
565
+ rx = regexp
566
+ rx.class.should == Regexp
567
+ rx.to_s.should == wanted.to_s
568
+ end
569
+
570
+ # Check sanity: Is test valid?
571
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
572
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
573
+
574
+ # Is compiled result valid?
575
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
576
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
577
+ end # end of test
578
+
579
+
580
+ ### Test 20: Simple concatenation of two strings
581
+
582
+ describe "Simple concatenation of two strings:" do
583
+ $prog = prog = %q<match "abc" "def" end>
584
+ program { prog }
585
+
586
+ good = ["abcdefghi", "xyzabcdef"]
587
+ bad = ["", "abcxyzdef"]
588
+ wanted = /abcdef/
589
+
590
+ it { should be_parseable }
591
+
592
+ rx = nil
593
+ it "can be converted to a regex" do
594
+ rx = regexp
595
+ rx.class.should == Regexp
596
+ rx.to_s.should == wanted.to_s
597
+ end
598
+
599
+ # Check sanity: Is test valid?
600
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
601
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
602
+
603
+ # Is compiled result valid?
604
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
605
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
606
+ end # end of test
607
+
608
+
609
+ ### Test 21: Concat of string and char class
610
+
611
+ describe "Concat of string and char class:" do
612
+ $prog = prog = %q<match "abc"'def' end>
613
+ program { prog }
614
+
615
+ good = ["abcd", "abce"]
616
+ bad = ["", "abcx"]
617
+ wanted = /abc[def]/
618
+
619
+ it { should be_parseable }
620
+
621
+ rx = nil
622
+ it "can be converted to a regex" do
623
+ rx = regexp
624
+ rx.class.should == Regexp
625
+ rx.to_s.should == wanted.to_s
626
+ end
627
+
628
+ # Check sanity: Is test valid?
629
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
630
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
631
+
632
+ # Is compiled result valid?
633
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
634
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
635
+ end # end of test
636
+
637
+
638
+ ### Test 22: Simple alternation
639
+
640
+ describe "Simple alternation:" do
641
+ $prog = prog = %q<match "abc" | "def" end>
642
+ program { prog }
643
+
644
+ good = ["abc", "xyzabc123", "xdefy"]
645
+ bad = ["", "abde", "ab c d ef"]
646
+ wanted = /(abc|def)/
647
+
648
+ it { should be_parseable }
649
+
650
+ rx = nil
651
+ it "can be converted to a regex" do
652
+ rx = regexp
653
+ rx.class.should == Regexp
654
+ rx.to_s.should == wanted.to_s
655
+ end
656
+
657
+ # Check sanity: Is test valid?
658
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
659
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
660
+
661
+ # Is compiled result valid?
662
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
663
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
664
+ end # end of test
665
+
666
+
667
+ ### Test 23: Alternation of concatenations
668
+
669
+ describe "Alternation of concatenations:" do
670
+ $prog = prog = %q<match "ab" "c" | "d" "ef" end>
671
+ program { prog }
672
+
673
+ good = ["abc", "xyzabc123", "xdefy"]
674
+ bad = ["", "abde", "ab c d ef"]
675
+ wanted = /(abc|def)/
676
+
677
+ it { should be_parseable }
678
+
679
+ rx = nil
680
+ it "can be converted to a regex" do
681
+ rx = regexp
682
+ rx.class.should == Regexp
683
+ rx.to_s.should == wanted.to_s
684
+ end
685
+
686
+ # Check sanity: Is test valid?
687
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
688
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
689
+
690
+ # Is compiled result valid?
691
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
692
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
693
+ end # end of test
694
+
695
+
696
+ ### Test 24: Precedence of concatenation over alternation
697
+
698
+ describe "Precedence of concatenation over alternation:" do
699
+ $prog = prog = %q<match "a" "b" | "c" end>
700
+ program { prog }
701
+
702
+ good = ["ab", "c"]
703
+ bad = ["b", "a", "d"]
704
+ wanted = /(ab|c)/
705
+
706
+ it { should be_parseable }
707
+
708
+ rx = nil
709
+ it "can be converted to a regex" do
710
+ rx = regexp
711
+ rx.class.should == Regexp
712
+ rx.to_s.should == wanted.to_s
713
+ end
714
+
715
+ # Check sanity: Is test valid?
716
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
717
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
718
+
719
+ # Is compiled result valid?
720
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
721
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
722
+ end # end of test
723
+
724
+
725
+ ### Test 25: Precedence of parens over concatenation
726
+
727
+ describe "Precedence of parens over concatenation:" do
728
+ $prog = prog = %q<match "a" ("b" | "c") end>
729
+ program { prog }
730
+
731
+ good = ["ab", "ac"]
732
+ bad = ["a", "b", "c"]
733
+ wanted = /a(b|c)/
734
+
735
+ it { should be_parseable }
736
+
737
+ rx = nil
738
+ it "can be converted to a regex" do
739
+ rx = regexp
740
+ rx.class.should == Regexp
741
+ rx.to_s.should == wanted.to_s
742
+ end
743
+
744
+ # Check sanity: Is test valid?
745
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
746
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
747
+
748
+ # Is compiled result valid?
749
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
750
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
751
+ end # end of test
752
+
753
+
754
+ ### Test 26: Anchors and alternation
755
+
756
+ describe "Anchors and alternation:" do
757
+ $prog = prog = %q<match BOS "x" | "y" EOS end>
758
+ program { prog }
759
+
760
+ good = ["xabc", "abcy"]
761
+ bad = ["abc", "abcx", "yabc", "axb", "ayb", "axyb"]
762
+ wanted = /(^x|y$)/
763
+
764
+ it { should be_parseable }
765
+
766
+ rx = nil
767
+ it "can be converted to a regex" do
768
+ rx = regexp
769
+ rx.class.should == Regexp
770
+ rx.to_s.should == wanted.to_s
771
+ end
772
+
773
+ # Check sanity: Is test valid?
774
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
775
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
776
+
777
+ # Is compiled result valid?
778
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
779
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
780
+ end # end of test
781
+
782
+
783
+ ### Test 27: Anchors, alternation, parens
784
+
785
+ describe "Anchors, alternation, parens:" do
786
+ $prog = prog = %q<match BOS ("x" | "y") EOS end>
787
+ program { prog }
788
+
789
+ good = ["x", "y"]
790
+ bad = ["abc", "abcx", "yabc", "xabc", "abcy"]
791
+ wanted = /^(x|y)$/
792
+
793
+ it { should be_parseable }
794
+
795
+ rx = nil
796
+ it "can be converted to a regex" do
797
+ rx = regexp
798
+ rx.class.should == Regexp
799
+ rx.to_s.should == wanted.to_s
800
+ end
801
+
802
+ # Check sanity: Is test valid?
803
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
804
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
805
+
806
+ # Is compiled result valid?
807
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
808
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
809
+ end # end of test
810
+
811
+
812
+ ### Test 28: Parens, concatenation, alternation
813
+
814
+ describe "Parens, concatenation, alternation:" do
815
+ $prog = prog = %q<match BOS ((maybe `0) `1-`9 | `1 D2) EOS end>
816
+ program { prog }
817
+
818
+ good = ["01", "09", "12"]
819
+ bad = ["0", "00", "13"]
820
+ wanted = /^((0)?[1-9]|1[0-2])$/
821
+
822
+ it { should be_parseable }
823
+
824
+ rx = nil
825
+ it "can be converted to a regex" do
826
+ rx = regexp
827
+ rx.class.should == Regexp
828
+ rx.to_s.should == wanted.to_s
829
+ end
830
+
831
+ # Check sanity: Is test valid?
832
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
833
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
834
+
835
+ # Is compiled result valid?
836
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
837
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
838
+ end # end of test
839
+
840
+
841
+ ### Test 29: Single backtick char
842
+
843
+ describe "Single backtick char:" do
844
+ $prog = prog = %q<match `` end>
845
+ program { prog }
846
+
847
+ good = ["`", "this is a tick: `", "tock ` tock"]
848
+ bad = ["", "abc"]
849
+ wanted = /`/
850
+
851
+ it { should be_parseable }
852
+
853
+ rx = nil
854
+ it "can be converted to a regex" do
855
+ rx = regexp
856
+ rx.class.should == Regexp
857
+ rx.to_s.should == wanted.to_s
858
+ end
859
+
860
+ # Check sanity: Is test valid?
861
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
862
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
863
+
864
+ # Is compiled result valid?
865
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
866
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
867
+ end # end of test
868
+
869
+
870
+ ### Test 30: Single backslash char
871
+
872
+ describe "Single backslash char:" do
873
+ $prog = prog = %q<match `\ end>
874
+ program { prog }
875
+
876
+ good = ["\\", "trying \\n", "and \\b also"]
877
+ bad = ["\n", "\b", "neither \r nor \t"]
878
+ wanted = /\\/
879
+
880
+ it { should be_parseable }
881
+
882
+ rx = nil
883
+ it "can be converted to a regex" do
884
+ rx = regexp
885
+ rx.class.should == Regexp
886
+ rx.to_s.should == wanted.to_s
887
+ end
888
+
889
+ # Check sanity: Is test valid?
890
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
891
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
892
+
893
+ # Is compiled result valid?
894
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
895
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
896
+ end # end of test
897
+
898
+
899
+ ### Test 31: Empty string
900
+
901
+ describe "Empty string:" do
902
+ $prog = prog = %q<match "" end>
903
+ program { prog }
904
+
905
+ good = ["", "abc"]
906
+ bad = []
907
+ wanted = //
908
+
909
+ it { should be_parseable }
910
+
911
+ rx = nil
912
+ it "can be converted to a regex" do
913
+ rx = regexp
914
+ rx.class.should == Regexp
915
+ rx.to_s.should == wanted.to_s
916
+ end
917
+
918
+ # Check sanity: Is test valid?
919
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
920
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
921
+
922
+ # Is compiled result valid?
923
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
924
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
925
+ end # end of test
926
+
927
+
928
+ ### Test 32: Simple char class
929
+
930
+ describe "Simple char class:" do
931
+ $prog = prog = %q<match 'abcdef' end>
932
+ program { prog }
933
+
934
+ good = ["there's a cat here", "item c"]
935
+ bad = ["", "proton"]
936
+ wanted = /[abcdef]/
937
+
938
+ it { should be_parseable }
939
+
940
+ rx = nil
941
+ it "can be converted to a regex" do
942
+ rx = regexp
943
+ rx.class.should == Regexp
944
+ rx.to_s.should == wanted.to_s
945
+ end
946
+
947
+ # Check sanity: Is test valid?
948
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
949
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
950
+
951
+ # Is compiled result valid?
952
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
953
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
954
+ end # end of test
955
+
956
+
957
+ ### Test 33: Simple one-char class
958
+
959
+ describe "Simple one-char class:" do
960
+ $prog = prog = %q<match 'x' end>
961
+ program { prog }
962
+
963
+ good = ["x", "uvwxyz"]
964
+ bad = ["", "abc"]
965
+ wanted = /[x]/
966
+
967
+ it { should be_parseable }
968
+
969
+ rx = nil
970
+ it "can be converted to a regex" do
971
+ rx = regexp
972
+ rx.class.should == Regexp
973
+ rx.to_s.should == wanted.to_s
974
+ end
975
+
976
+ # Check sanity: Is test valid?
977
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
978
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
979
+
980
+ # Is compiled result valid?
981
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
982
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
983
+ end # end of test
984
+
985
+
986
+ ### Test 34: Alternation of range and class
987
+
988
+ describe "Alternation of range and class:" do
989
+ $prog = prog = %q<match `a-`f | 'xyz' end>
990
+ program { prog }
991
+
992
+ good = ["a", "x", "z", "c"]
993
+ bad = ["", "jkl", "gw"]
994
+ wanted = /([a-f]|[xyz])/
995
+
996
+ it { should be_parseable }
997
+
998
+ rx = nil
999
+ it "can be converted to a regex" do
1000
+ rx = regexp
1001
+ rx.class.should == Regexp
1002
+ rx.to_s.should == wanted.to_s
1003
+ end
1004
+
1005
+ # Check sanity: Is test valid?
1006
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1007
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1008
+
1009
+ # Is compiled result valid?
1010
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1011
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1012
+ end # end of test
1013
+
1014
+
1015
+ ### Test 35: Alternation of range and maybe-clause
1016
+
1017
+ describe "Alternation of range and maybe-clause:" do
1018
+ $prog = prog = %q<match `1-`6| maybe "#" end>
1019
+ program { prog }
1020
+
1021
+ good = ["", "1#", "1", " 2# abc"]
1022
+ bad = []
1023
+ wanted = /([1-6]|(\#)?)/
1024
+
1025
+ it { should be_parseable }
1026
+
1027
+ rx = nil
1028
+ it "can be converted to a regex" do
1029
+ rx = regexp
1030
+ rx.class.should == Regexp
1031
+ rx.to_s.should == wanted.to_s
1032
+ end
1033
+
1034
+ # Check sanity: Is test valid?
1035
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1036
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1037
+
1038
+ # Is compiled result valid?
1039
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1040
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1041
+ end # end of test
1042
+
1043
+
1044
+ ### Test 36: Four-way alternation
1045
+
1046
+ describe "Four-way alternation:" do
1047
+ $prog = prog = %q<match `a | `b|`c|`d end>
1048
+ program { prog }
1049
+
1050
+ good = ["xyza", "xybz", "xcyz", "dxyz"]
1051
+ bad = ["", "every", "ghijk"]
1052
+ wanted = /(a|b|c|d)/
1053
+
1054
+ it { should be_parseable }
1055
+
1056
+ rx = nil
1057
+ it "can be converted to a regex" do
1058
+ rx = regexp
1059
+ rx.class.should == Regexp
1060
+ rx.to_s.should == wanted.to_s
1061
+ end
1062
+
1063
+ # Check sanity: Is test valid?
1064
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1065
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1066
+
1067
+ # Is compiled result valid?
1068
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1069
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1070
+ end # end of test
1071
+
1072
+
1073
+ ### Test 37: Concatenation of range and class
1074
+
1075
+ describe "Concatenation of range and class:" do
1076
+ $prog = prog = %q<match `a-`f 'xyz' end>
1077
+ program { prog }
1078
+
1079
+ good = ["ax", "fz", "cy"]
1080
+ bad = ["zf", "xa", "gz", "hp", "mx"]
1081
+ wanted = /[a-f][xyz]/
1082
+
1083
+ it { should be_parseable }
1084
+
1085
+ rx = nil
1086
+ it "can be converted to a regex" do
1087
+ rx = regexp
1088
+ rx.class.should == Regexp
1089
+ rx.to_s.should == wanted.to_s
1090
+ end
1091
+
1092
+ # Check sanity: Is test valid?
1093
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1094
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1095
+
1096
+ # Is compiled result valid?
1097
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1098
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1099
+ end # end of test
1100
+
1101
+
1102
+ ### Test 38: Concat of strings and maybe-clause
1103
+
1104
+ describe "Concat of strings and maybe-clause:" do
1105
+ $prog = prog = %q<match "this" "that" maybe "other" end>
1106
+ program { prog }
1107
+
1108
+ good = ["thisthat", "thisthatother", "abc thisthat xyz", "abc thisthatother xyz"]
1109
+ bad = ["", "abc", "this that", "this that other"]
1110
+ wanted = /thisthat(other)?/
1111
+
1112
+ it { should be_parseable }
1113
+
1114
+ rx = nil
1115
+ it "can be converted to a regex" do
1116
+ rx = regexp
1117
+ rx.class.should == Regexp
1118
+ rx.to_s.should == wanted.to_s
1119
+ end
1120
+
1121
+ # Check sanity: Is test valid?
1122
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1123
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1124
+
1125
+ # Is compiled result valid?
1126
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1127
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1128
+ end # end of test
1129
+
1130
+
1131
+ ### Test 39: Simple repetition of class
1132
+
1133
+ describe "Simple repetition of class:" do
1134
+ $prog = prog = %q<match 3 * 'xyz' end>
1135
+ program { prog }
1136
+
1137
+ good = ["xyz", "xxx", "yzy", "xyzzy123"]
1138
+ bad = ["", "abc", "xy", "axy", "xyb", "axyb"]
1139
+ wanted = /([xyz]){3}/
1140
+
1141
+ it { should be_parseable }
1142
+
1143
+ rx = nil
1144
+ it "can be converted to a regex" do
1145
+ rx = regexp
1146
+ rx.class.should == Regexp
1147
+ rx.to_s.should == wanted.to_s
1148
+ end
1149
+
1150
+ # Check sanity: Is test valid?
1151
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1152
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1153
+
1154
+ # Is compiled result valid?
1155
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1156
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1157
+ end # end of test
1158
+
1159
+
1160
+ ### Test 40: Simple repetition of range
1161
+
1162
+ describe "Simple repetition of range:" do
1163
+ $prog = prog = %q<match 4 * `1-`6 end>
1164
+ program { prog }
1165
+
1166
+ good = ["1111", "1234", "abc 6543 def"]
1167
+ bad = ["", "abc", "123", "123 4"]
1168
+ wanted = /([1-6]){4}/
1169
+
1170
+ it { should be_parseable }
1171
+
1172
+ rx = nil
1173
+ it "can be converted to a regex" do
1174
+ rx = regexp
1175
+ rx.class.should == Regexp
1176
+ rx.to_s.should == wanted.to_s
1177
+ end
1178
+
1179
+ # Check sanity: Is test valid?
1180
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1181
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1182
+
1183
+ # Is compiled result valid?
1184
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1185
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1186
+ end # end of test
1187
+
1188
+
1189
+ ### Test 41: Complex repetition of char
1190
+
1191
+ describe "Complex repetition of char:" do
1192
+ $prog = prog = %q<match 3,5 * (`a) end>
1193
+ program { prog }
1194
+
1195
+ good = ["aaa", "aaaa", "aaaaa", "xaaay", "aaaaaaa"]
1196
+ bad = ["", "abc", "aa"]
1197
+ wanted = /(a){3,5}/
1198
+
1199
+ it { should be_parseable }
1200
+
1201
+ rx = nil
1202
+ it "can be converted to a regex" do
1203
+ rx = regexp
1204
+ rx.class.should == Regexp
1205
+ rx.to_s.should == wanted.to_s
1206
+ end
1207
+
1208
+ # Check sanity: Is test valid?
1209
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1210
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1211
+
1212
+ # Is compiled result valid?
1213
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1214
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1215
+ end # end of test
1216
+
1217
+
1218
+ ### Test 42: Complex repetition of parenthesized class
1219
+
1220
+ describe "Complex repetition of parenthesized class:" do
1221
+ $prog = prog = %q<match 4,7 * ('xyz') end>
1222
+ program { prog }
1223
+
1224
+ good = ["xxxx", "yyyy", "xyzy", "xyzzy", "zyzzyva", "xyzxyz", "xyzxyzx", "xyzxyzxyzxyz"]
1225
+ bad = ["", "abc", "x", "xx", "xxx", "xyz xy"]
1226
+ wanted = /([xyz]){4,7}/
1227
+
1228
+ it { should be_parseable }
1229
+
1230
+ rx = nil
1231
+ it "can be converted to a regex" do
1232
+ rx = regexp
1233
+ rx.class.should == Regexp
1234
+ rx.to_s.should == wanted.to_s
1235
+ end
1236
+
1237
+ # Check sanity: Is test valid?
1238
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1239
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1240
+
1241
+ # Is compiled result valid?
1242
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1243
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1244
+ end # end of test
1245
+
1246
+
1247
+ ### Test 43: Complex repetition of parenthesized range
1248
+
1249
+ describe "Complex repetition of parenthesized range:" do
1250
+ $prog = prog = %q<match 0,3 * (`1-`6) end>
1251
+ program { prog }
1252
+
1253
+ good = ["", "1", "11", "111", "56", "654", "1111", "x123y", "x123456y"]
1254
+ bad = []
1255
+ wanted = /([1-6]){0,3}/
1256
+
1257
+ it { should be_parseable }
1258
+
1259
+ rx = nil
1260
+ it "can be converted to a regex" do
1261
+ rx = regexp
1262
+ rx.class.should == Regexp
1263
+ rx.to_s.should == wanted.to_s
1264
+ end
1265
+
1266
+ # Check sanity: Is test valid?
1267
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1268
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1269
+
1270
+ # Is compiled result valid?
1271
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1272
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1273
+ end # end of test
1274
+
1275
+
1276
+ ### Test 44: Single char (anchored)
1277
+
1278
+ describe "Single char (anchored):" do
1279
+ $prog = prog = %q<match BOS `x EOS end>
1280
+ program { prog }
1281
+
1282
+ good = ["x"]
1283
+ bad = ["yz", "", "ABC"]
1284
+ wanted = /^x$/
1285
+
1286
+ it { should be_parseable }
1287
+
1288
+ rx = nil
1289
+ it "can be converted to a regex" do
1290
+ rx = regexp
1291
+ rx.class.should == Regexp
1292
+ rx.to_s.should == wanted.to_s
1293
+ end
1294
+
1295
+ # Check sanity: Is test valid?
1296
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1297
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1298
+
1299
+ # Is compiled result valid?
1300
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1301
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1302
+ end # end of test
1303
+
1304
+
1305
+ ### Test 45: Simple range (anchored)
1306
+
1307
+ describe "Simple range (anchored):" do
1308
+ $prog = prog = %q<match BOS `a-`f EOS end>
1309
+ program { prog }
1310
+
1311
+ good = ["a", "b", "c", "d", "e", "f"]
1312
+ bad = ["xyz", "", "ABC"]
1313
+ wanted = /^[a-f]$/
1314
+
1315
+ it { should be_parseable }
1316
+
1317
+ rx = nil
1318
+ it "can be converted to a regex" do
1319
+ rx = regexp
1320
+ rx.class.should == Regexp
1321
+ rx.to_s.should == wanted.to_s
1322
+ end
1323
+
1324
+ # Check sanity: Is test valid?
1325
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1326
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1327
+
1328
+ # Is compiled result valid?
1329
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1330
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1331
+ end # end of test
1332
+
1333
+
1334
+ ### Test 46: Negated range (anchored)
1335
+
1336
+ describe "Negated range (anchored):" do
1337
+ $prog = prog = %q<match BOS `c~`p EOS end>
1338
+ program { prog }
1339
+
1340
+ good = ["a", "r"]
1341
+ bad = ["def", "mno", ""]
1342
+ wanted = /^[^c-p]$/
1343
+
1344
+ it { should be_parseable }
1345
+
1346
+ rx = nil
1347
+ it "can be converted to a regex" do
1348
+ rx = regexp
1349
+ rx.class.should == Regexp
1350
+ rx.to_s.should == wanted.to_s
1351
+ end
1352
+
1353
+ # Check sanity: Is test valid?
1354
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1355
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1356
+
1357
+ # Is compiled result valid?
1358
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1359
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1360
+ end # end of test
1361
+
1362
+
1363
+ ### Test 47: Negated char (anchored)
1364
+
1365
+ describe "Negated char (anchored):" do
1366
+ $prog = prog = %q<match BOS ~`d EOS end>
1367
+ program { prog }
1368
+
1369
+ good = ["x", "1"]
1370
+ bad = ["d", "dd", "abc"]
1371
+ wanted = /^[^d]$/
1372
+
1373
+ it { should be_parseable }
1374
+
1375
+ rx = nil
1376
+ it "can be converted to a regex" do
1377
+ rx = regexp
1378
+ rx.class.should == Regexp
1379
+ rx.to_s.should == wanted.to_s
1380
+ end
1381
+
1382
+ # Check sanity: Is test valid?
1383
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1384
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1385
+
1386
+ # Is compiled result valid?
1387
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1388
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1389
+ end # end of test
1390
+
1391
+
1392
+ ### Test 48: POSIX class (anchored)
1393
+
1394
+ describe "POSIX class (anchored):" do
1395
+ $prog = prog = %q<match BOS %alnum EOS end>
1396
+ program { prog }
1397
+
1398
+ good = ["c", "2"]
1399
+ bad = ["", "abc", "123", "-", ":", ",", "."]
1400
+ wanted = /^[[:alnum:]]$/
1401
+
1402
+ it { should be_parseable }
1403
+
1404
+ rx = nil
1405
+ it "can be converted to a regex" do
1406
+ rx = regexp
1407
+ rx.class.should == Regexp
1408
+ rx.to_s.should == wanted.to_s
1409
+ end
1410
+
1411
+ # Check sanity: Is test valid?
1412
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1413
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1414
+
1415
+ # Is compiled result valid?
1416
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1417
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1418
+ end # end of test
1419
+
1420
+
1421
+ ### Test 49: Simple char class (anchored)
1422
+
1423
+ describe "Simple char class (anchored):" do
1424
+ $prog = prog = %q<match BOS 'prstu' EOS end>
1425
+ program { prog }
1426
+
1427
+ good = ["u", "p", "s"]
1428
+ bad = ["", "abc", "x"]
1429
+ wanted = /^[prstu]$/
1430
+
1431
+ it { should be_parseable }
1432
+
1433
+ rx = nil
1434
+ it "can be converted to a regex" do
1435
+ rx = regexp
1436
+ rx.class.should == Regexp
1437
+ rx.to_s.should == wanted.to_s
1438
+ end
1439
+
1440
+ # Check sanity: Is test valid?
1441
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1442
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1443
+
1444
+ # Is compiled result valid?
1445
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1446
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1447
+ end # end of test
1448
+
1449
+
1450
+ ### Test 50: Negated char class (anchored)
1451
+
1452
+ describe "Negated char class (anchored):" do
1453
+ $prog = prog = %q<match BOS ~'ilmnop' EOS end>
1454
+ program { prog }
1455
+
1456
+ good = ["a", "e", "h"]
1457
+ bad = ["o", "i", "l"]
1458
+ wanted = /^[^ilmnop]$/
1459
+
1460
+ it { should be_parseable }
1461
+
1462
+ rx = nil
1463
+ it "can be converted to a regex" do
1464
+ rx = regexp
1465
+ rx.class.should == Regexp
1466
+ rx.to_s.should == wanted.to_s
1467
+ end
1468
+
1469
+ # Check sanity: Is test valid?
1470
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1471
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1472
+
1473
+ # Is compiled result valid?
1474
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1475
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1476
+ end # end of test
1477
+
1478
+
1479
+ ### Test 51: Simple string (anchored)
1480
+
1481
+ describe "Simple string (anchored):" do
1482
+ $prog = prog = %q<match BOS "xyz" EOS end>
1483
+ program { prog }
1484
+
1485
+ good = ["xyz"]
1486
+ bad = ["", "abc", "abcxyzdef", "xydefz"]
1487
+ wanted = /^xyz$/
1488
+
1489
+ it { should be_parseable }
1490
+
1491
+ rx = nil
1492
+ it "can be converted to a regex" do
1493
+ rx = regexp
1494
+ rx.class.should == Regexp
1495
+ rx.to_s.should == wanted.to_s
1496
+ end
1497
+
1498
+ # Check sanity: Is test valid?
1499
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1500
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1501
+
1502
+ # Is compiled result valid?
1503
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1504
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1505
+ end # end of test
1506
+
1507
+
1508
+ ### Test 52: Single-bounded repetition (anchored)
1509
+
1510
+ describe "Single-bounded repetition (anchored):" do
1511
+ $prog = prog = %q<match BOS 5 * "xyz" EOS end>
1512
+ program { prog }
1513
+
1514
+ good = ["xyzxyzxyzxyzxyz"]
1515
+ bad = ["xyzxyzxyzxyz", "abcxyzxyzxyzxyz", "xyzxyzxyzxyzabc"]
1516
+ wanted = /^(xyz){5}$/
1517
+
1518
+ it { should be_parseable }
1519
+
1520
+ rx = nil
1521
+ it "can be converted to a regex" do
1522
+ rx = regexp
1523
+ rx.class.should == Regexp
1524
+ rx.to_s.should == wanted.to_s
1525
+ end
1526
+
1527
+ # Check sanity: Is test valid?
1528
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1529
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1530
+
1531
+ # Is compiled result valid?
1532
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1533
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1534
+ end # end of test
1535
+
1536
+
1537
+ ### Test 53: Double-bounded repetition (anchored)
1538
+
1539
+ describe "Double-bounded repetition (anchored):" do
1540
+ $prog = prog = %q<match BOS 3,4 * %alpha EOS end>
1541
+ program { prog }
1542
+
1543
+ good = ["abc", "abcd"]
1544
+ bad = ["", "ab", "x", "abcde"]
1545
+ wanted = /^([[:alpha:]]){3,4}$/
1546
+
1547
+ it { should be_parseable }
1548
+
1549
+ rx = nil
1550
+ it "can be converted to a regex" do
1551
+ rx = regexp
1552
+ rx.class.should == Regexp
1553
+ rx.to_s.should == wanted.to_s
1554
+ end
1555
+
1556
+ # Check sanity: Is test valid?
1557
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1558
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1559
+
1560
+ # Is compiled result valid?
1561
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1562
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1563
+ end # end of test
1564
+
1565
+
1566
+ ### Test 54: any-qualifier (anchored)
1567
+
1568
+ describe "any-qualifier (anchored):" do
1569
+ $prog = prog = %q<match BOS any "abc" EOS end>
1570
+ program { prog }
1571
+
1572
+ good = ["", "abc", "abcabc", "abcabcabc"]
1573
+ bad = ["ab", "abcab", "xyz"]
1574
+ wanted = /^(abc)*$/
1575
+
1576
+ it { should be_parseable }
1577
+
1578
+ rx = nil
1579
+ it "can be converted to a regex" do
1580
+ rx = regexp
1581
+ rx.class.should == Regexp
1582
+ rx.to_s.should == wanted.to_s
1583
+ end
1584
+
1585
+ # Check sanity: Is test valid?
1586
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1587
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1588
+
1589
+ # Is compiled result valid?
1590
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1591
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1592
+ end # end of test
1593
+
1594
+
1595
+ ### Test 55: many-qualifier (anchored)
1596
+
1597
+ describe "many-qualifier (anchored):" do
1598
+ $prog = prog = %q<match BOS many "def" EOS end>
1599
+ program { prog }
1600
+
1601
+ good = ["def", "defdef", "defdefdef"]
1602
+ bad = ["", "d", "de", "defd", "xyz"]
1603
+ wanted = /^(def)+$/
1604
+
1605
+ it { should be_parseable }
1606
+
1607
+ rx = nil
1608
+ it "can be converted to a regex" do
1609
+ rx = regexp
1610
+ rx.class.should == Regexp
1611
+ rx.to_s.should == wanted.to_s
1612
+ end
1613
+
1614
+ # Check sanity: Is test valid?
1615
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1616
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1617
+
1618
+ # Is compiled result valid?
1619
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1620
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1621
+ end # end of test
1622
+
1623
+
1624
+ ### Test 56: maybe-qualifier (anchored)
1625
+
1626
+ describe "maybe-qualifier (anchored):" do
1627
+ $prog = prog = %q<match BOS maybe "ghi" EOS end>
1628
+ program { prog }
1629
+
1630
+ good = ["", "ghi"]
1631
+ bad = ["abghicd", "gh"]
1632
+ wanted = /^(ghi)?$/
1633
+
1634
+ it { should be_parseable }
1635
+
1636
+ rx = nil
1637
+ it "can be converted to a regex" do
1638
+ rx = regexp
1639
+ rx.class.should == Regexp
1640
+ rx.to_s.should == wanted.to_s
1641
+ end
1642
+
1643
+ # Check sanity: Is test valid?
1644
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1645
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1646
+
1647
+ # Is compiled result valid?
1648
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1649
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1650
+ end # end of test
1651
+
1652
+
1653
+ ### Test 57: Simple concatenation of two strings (anchored)
1654
+
1655
+ describe "Simple concatenation of two strings (anchored):" do
1656
+ $prog = prog = %q<match BOS "abc" "def" EOS end>
1657
+ program { prog }
1658
+
1659
+ good = ["abcdef"]
1660
+ bad = ["", "abcd", "xyzabcdef", "abcxyzdef", "abcdefxyz"]
1661
+ wanted = /^abcdef$/
1662
+
1663
+ it { should be_parseable }
1664
+
1665
+ rx = nil
1666
+ it "can be converted to a regex" do
1667
+ rx = regexp
1668
+ rx.class.should == Regexp
1669
+ rx.to_s.should == wanted.to_s
1670
+ end
1671
+
1672
+ # Check sanity: Is test valid?
1673
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1674
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1675
+
1676
+ # Is compiled result valid?
1677
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1678
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1679
+ end # end of test
1680
+
1681
+
1682
+ ### Test 58: Concat of string and char class (anchored)
1683
+
1684
+ describe "Concat of string and char class (anchored):" do
1685
+ $prog = prog = %q<match BOS "abc" 'def' EOS end>
1686
+ program { prog }
1687
+
1688
+ good = ["abcd", "abce", "abcf"]
1689
+ bad = ["", "ab", "abc", "abcx"]
1690
+ wanted = /^abc[def]$/
1691
+
1692
+ it { should be_parseable }
1693
+
1694
+ rx = nil
1695
+ it "can be converted to a regex" do
1696
+ rx = regexp
1697
+ rx.class.should == Regexp
1698
+ rx.to_s.should == wanted.to_s
1699
+ end
1700
+
1701
+ # Check sanity: Is test valid?
1702
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1703
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1704
+
1705
+ # Is compiled result valid?
1706
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1707
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1708
+ end # end of test
1709
+
1710
+
1711
+ ### Test 59: Simple alternation (anchored)
1712
+
1713
+ describe "Simple alternation (anchored):" do
1714
+ $prog = prog = %q<match BOS ("abc" | "def") EOS end>
1715
+ program { prog }
1716
+
1717
+ good = ["abc", "def"]
1718
+ bad = ["", "abde", "ab c d ef", "xdefy"]
1719
+ wanted = /^(abc|def)$/
1720
+
1721
+ it { should be_parseable }
1722
+
1723
+ rx = nil
1724
+ it "can be converted to a regex" do
1725
+ rx = regexp
1726
+ rx.class.should == Regexp
1727
+ rx.to_s.should == wanted.to_s
1728
+ end
1729
+
1730
+ # Check sanity: Is test valid?
1731
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1732
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1733
+
1734
+ # Is compiled result valid?
1735
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1736
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1737
+ end # end of test
1738
+
1739
+
1740
+ ### Test 60: Alternation of concatenations (anchored)
1741
+
1742
+ describe "Alternation of concatenations (anchored):" do
1743
+ $prog = prog = %q<match BOS ("ab" "c" | "d" "ef") EOS end>
1744
+ program { prog }
1745
+
1746
+ good = ["abc", "def"]
1747
+ bad = ["", "abde", "ab c d ef", "xdefy"]
1748
+ wanted = /^(abc|def)$/
1749
+
1750
+ it { should be_parseable }
1751
+
1752
+ rx = nil
1753
+ it "can be converted to a regex" do
1754
+ rx = regexp
1755
+ rx.class.should == Regexp
1756
+ rx.to_s.should == wanted.to_s
1757
+ end
1758
+
1759
+ # Check sanity: Is test valid?
1760
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1761
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1762
+
1763
+ # Is compiled result valid?
1764
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1765
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1766
+ end # end of test
1767
+
1768
+
1769
+ ### Test 61: Precedence of concatenation over alternation (anchored)
1770
+
1771
+ describe "Precedence of concatenation over alternation (anchored):" do
1772
+ $prog = prog = %q<match BOS ("a" "b" | "c") EOS end>
1773
+ program { prog }
1774
+
1775
+ good = ["ab", "c"]
1776
+ bad = ["", "b", "a", "d", "abc", "abcde"]
1777
+ wanted = /^(ab|c)$/
1778
+
1779
+ it { should be_parseable }
1780
+
1781
+ rx = nil
1782
+ it "can be converted to a regex" do
1783
+ rx = regexp
1784
+ rx.class.should == Regexp
1785
+ rx.to_s.should == wanted.to_s
1786
+ end
1787
+
1788
+ # Check sanity: Is test valid?
1789
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1790
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1791
+
1792
+ # Is compiled result valid?
1793
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1794
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1795
+ end # end of test
1796
+
1797
+
1798
+ ### Test 62: Precedence of parens over concatenation (anchored)
1799
+
1800
+ describe "Precedence of parens over concatenation (anchored):" do
1801
+ $prog = prog = %q<match BOS "a" ("b" | "c") EOS end>
1802
+ program { prog }
1803
+
1804
+ good = ["ab", "ac"]
1805
+ bad = ["a", "b", "c", "abc", "abx", "bac"]
1806
+ wanted = /^a(b|c)$/
1807
+
1808
+ it { should be_parseable }
1809
+
1810
+ rx = nil
1811
+ it "can be converted to a regex" do
1812
+ rx = regexp
1813
+ rx.class.should == Regexp
1814
+ rx.to_s.should == wanted.to_s
1815
+ end
1816
+
1817
+ # Check sanity: Is test valid?
1818
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1819
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1820
+
1821
+ # Is compiled result valid?
1822
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1823
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1824
+ end # end of test
1825
+
1826
+
1827
+ ### Test 63: Anchors and alternation (anchored)
1828
+
1829
+ describe "Anchors and alternation (anchored):" do
1830
+ $prog = prog = %q<match BOS "x" | "y" EOS end>
1831
+ program { prog }
1832
+
1833
+ good = ["xabc", "abcy"]
1834
+ bad = ["abc", "abcx", "yabc", "axb", "ayb", "axyb"]
1835
+ wanted = /(^x|y$)/
1836
+
1837
+ it { should be_parseable }
1838
+
1839
+ rx = nil
1840
+ it "can be converted to a regex" do
1841
+ rx = regexp
1842
+ rx.class.should == Regexp
1843
+ rx.to_s.should == wanted.to_s
1844
+ end
1845
+
1846
+ # Check sanity: Is test valid?
1847
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1848
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1849
+
1850
+ # Is compiled result valid?
1851
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1852
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1853
+ end # end of test
1854
+
1855
+
1856
+ ### Test 64: Parens, concatenation, alternation (anchored)
1857
+
1858
+ describe "Parens, concatenation, alternation (anchored):" do
1859
+ $prog = prog = %q<match BOS ((maybe `0) `1-`9 | `1 D2) EOS end>
1860
+ program { prog }
1861
+
1862
+ good = ["01", "09", "12"]
1863
+ bad = ["0", "00", "13"]
1864
+ wanted = /^((0)?[1-9]|1[0-2])$/
1865
+
1866
+ it { should be_parseable }
1867
+
1868
+ rx = nil
1869
+ it "can be converted to a regex" do
1870
+ rx = regexp
1871
+ rx.class.should == Regexp
1872
+ rx.to_s.should == wanted.to_s
1873
+ end
1874
+
1875
+ # Check sanity: Is test valid?
1876
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1877
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1878
+
1879
+ # Is compiled result valid?
1880
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1881
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1882
+ end # end of test
1883
+
1884
+
1885
+ ### Test 65: Single backtick char (anchored)
1886
+
1887
+ describe "Single backtick char (anchored):" do
1888
+ $prog = prog = %q<match BOS `` EOS end>
1889
+ program { prog }
1890
+
1891
+ good = ["`"]
1892
+ bad = ["", "abc", "this is a tick: `", "tock ` tock"]
1893
+ wanted = /^`$/
1894
+
1895
+ it { should be_parseable }
1896
+
1897
+ rx = nil
1898
+ it "can be converted to a regex" do
1899
+ rx = regexp
1900
+ rx.class.should == Regexp
1901
+ rx.to_s.should == wanted.to_s
1902
+ end
1903
+
1904
+ # Check sanity: Is test valid?
1905
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1906
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1907
+
1908
+ # Is compiled result valid?
1909
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1910
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1911
+ end # end of test
1912
+
1913
+
1914
+ ### Test 66: Single backslash char (anchored)
1915
+
1916
+ describe "Single backslash char (anchored):" do
1917
+ $prog = prog = %q<match BOS `\ EOS end>
1918
+ program { prog }
1919
+
1920
+ good = ["\\"]
1921
+ bad = ["\n", "\b", "neither \r nor \t", "trying \\n", "and \\b also"]
1922
+ wanted = /^\\$/
1923
+
1924
+ it { should be_parseable }
1925
+
1926
+ rx = nil
1927
+ it "can be converted to a regex" do
1928
+ rx = regexp
1929
+ rx.class.should == Regexp
1930
+ rx.to_s.should == wanted.to_s
1931
+ end
1932
+
1933
+ # Check sanity: Is test valid?
1934
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1935
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1936
+
1937
+ # Is compiled result valid?
1938
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1939
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1940
+ end # end of test
1941
+
1942
+
1943
+ ### Test 67: Empty string (anchored)
1944
+
1945
+ describe "Empty string (anchored):" do
1946
+ $prog = prog = %q<match BOS "" EOS end>
1947
+ program { prog }
1948
+
1949
+ good = [""]
1950
+ bad = ["abc"]
1951
+ wanted = /^$/
1952
+
1953
+ it { should be_parseable }
1954
+
1955
+ rx = nil
1956
+ it "can be converted to a regex" do
1957
+ rx = regexp
1958
+ rx.class.should == Regexp
1959
+ rx.to_s.should == wanted.to_s
1960
+ end
1961
+
1962
+ # Check sanity: Is test valid?
1963
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1964
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1965
+
1966
+ # Is compiled result valid?
1967
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1968
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1969
+ end # end of test
1970
+
1971
+
1972
+ ### Test 68: Simple one-char class (anchored)
1973
+
1974
+ describe "Simple one-char class (anchored):" do
1975
+ $prog = prog = %q<match BOS 'x' EOS end>
1976
+ program { prog }
1977
+
1978
+ good = ["x"]
1979
+ bad = ["", "abc", "uvwxyz"]
1980
+ wanted = /^[x]$/
1981
+
1982
+ it { should be_parseable }
1983
+
1984
+ rx = nil
1985
+ it "can be converted to a regex" do
1986
+ rx = regexp
1987
+ rx.class.should == Regexp
1988
+ rx.to_s.should == wanted.to_s
1989
+ end
1990
+
1991
+ # Check sanity: Is test valid?
1992
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
1993
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
1994
+
1995
+ # Is compiled result valid?
1996
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
1997
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
1998
+ end # end of test
1999
+
2000
+
2001
+ ### Test 69: Alternation of range and class (anchored)
2002
+
2003
+ describe "Alternation of range and class (anchored):" do
2004
+ $prog = prog = %q<match BOS (`a-`f | 'xyz') EOS end>
2005
+ program { prog }
2006
+
2007
+ good = ["a", "x", "z", "c"]
2008
+ bad = ["", "ab", "abc", "xy", "jkl", "gw"]
2009
+ wanted = /^([a-f]|[xyz])$/
2010
+
2011
+ it { should be_parseable }
2012
+
2013
+ rx = nil
2014
+ it "can be converted to a regex" do
2015
+ rx = regexp
2016
+ rx.class.should == Regexp
2017
+ rx.to_s.should == wanted.to_s
2018
+ end
2019
+
2020
+ # Check sanity: Is test valid?
2021
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2022
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2023
+
2024
+ # Is compiled result valid?
2025
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2026
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2027
+ end # end of test
2028
+
2029
+
2030
+ ### Test 70: Alternation of range and maybe-clause (anchored)
2031
+
2032
+ describe "Alternation of range and maybe-clause (anchored):" do
2033
+ $prog = prog = %q<match BOS (`1-`6| maybe "#") EOS end>
2034
+ program { prog }
2035
+
2036
+ good = ["", "1", "#", "6"]
2037
+ bad = ["55", "###"]
2038
+ wanted = /^([1-6]|(\#)?)$/
2039
+
2040
+ it { should be_parseable }
2041
+
2042
+ rx = nil
2043
+ it "can be converted to a regex" do
2044
+ rx = regexp
2045
+ rx.class.should == Regexp
2046
+ rx.to_s.should == wanted.to_s
2047
+ end
2048
+
2049
+ # Check sanity: Is test valid?
2050
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2051
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2052
+
2053
+ # Is compiled result valid?
2054
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2055
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2056
+ end # end of test
2057
+
2058
+
2059
+ ### Test 71: Four-way alternation (anchored)
2060
+
2061
+ describe "Four-way alternation (anchored):" do
2062
+ $prog = prog = %q<match BOS (`a | `b|`c|`d) EOS end>
2063
+ program { prog }
2064
+
2065
+ good = ["a", "b", "c", "d"]
2066
+ bad = ["", "ab", "every", "ghijk"]
2067
+ wanted = /^(a|b|c|d)$/
2068
+
2069
+ it { should be_parseable }
2070
+
2071
+ rx = nil
2072
+ it "can be converted to a regex" do
2073
+ rx = regexp
2074
+ rx.class.should == Regexp
2075
+ rx.to_s.should == wanted.to_s
2076
+ end
2077
+
2078
+ # Check sanity: Is test valid?
2079
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2080
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2081
+
2082
+ # Is compiled result valid?
2083
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2084
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2085
+ end # end of test
2086
+
2087
+
2088
+ ### Test 72: Concatenation of range and class (anchored)
2089
+
2090
+ describe "Concatenation of range and class (anchored):" do
2091
+ $prog = prog = %q<match BOS `a-`f 'xyz' EOS end>
2092
+ program { prog }
2093
+
2094
+ good = ["ax", "fz", "cy"]
2095
+ bad = ["axe", "fz123", "zf", "xa", "gz", "hp", "mx"]
2096
+ wanted = /^[a-f][xyz]$/
2097
+
2098
+ it { should be_parseable }
2099
+
2100
+ rx = nil
2101
+ it "can be converted to a regex" do
2102
+ rx = regexp
2103
+ rx.class.should == Regexp
2104
+ rx.to_s.should == wanted.to_s
2105
+ end
2106
+
2107
+ # Check sanity: Is test valid?
2108
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2109
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2110
+
2111
+ # Is compiled result valid?
2112
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2113
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2114
+ end # end of test
2115
+
2116
+
2117
+ ### Test 73: Concat of strings and maybe-clause (anchored)
2118
+
2119
+ describe "Concat of strings and maybe-clause (anchored):" do
2120
+ $prog = prog = %q<match BOS "this" "that" maybe "other" EOS end>
2121
+ program { prog }
2122
+
2123
+ good = ["thisthat", "thisthatother"]
2124
+ bad = ["", "abc", "this that", "this that other", "abc thisthat xyz", "abc thisthatother xyz"]
2125
+ wanted = /^thisthat(other)?$/
2126
+
2127
+ it { should be_parseable }
2128
+
2129
+ rx = nil
2130
+ it "can be converted to a regex" do
2131
+ rx = regexp
2132
+ rx.class.should == Regexp
2133
+ rx.to_s.should == wanted.to_s
2134
+ end
2135
+
2136
+ # Check sanity: Is test valid?
2137
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2138
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2139
+
2140
+ # Is compiled result valid?
2141
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2142
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2143
+ end # end of test
2144
+
2145
+
2146
+ ### Test 74: Simple repetition of class (anchored)
2147
+
2148
+ describe "Simple repetition of class (anchored):" do
2149
+ $prog = prog = %q<match BOS 3 * 'xyz' EOS end>
2150
+ program { prog }
2151
+
2152
+ good = ["xyz", "xxx", "yzy"]
2153
+ bad = ["", "abc", "xy", "axy", "xyb", "axyb", "xyzzy123"]
2154
+ wanted = /^([xyz]){3}$/
2155
+
2156
+ it { should be_parseable }
2157
+
2158
+ rx = nil
2159
+ it "can be converted to a regex" do
2160
+ rx = regexp
2161
+ rx.class.should == Regexp
2162
+ rx.to_s.should == wanted.to_s
2163
+ end
2164
+
2165
+ # Check sanity: Is test valid?
2166
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2167
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2168
+
2169
+ # Is compiled result valid?
2170
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2171
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2172
+ end # end of test
2173
+
2174
+
2175
+ ### Test 75: Simple repetition of range (anchored)
2176
+
2177
+ describe "Simple repetition of range (anchored):" do
2178
+ $prog = prog = %q<match BOS 4 * `1-`6 EOS end>
2179
+ program { prog }
2180
+
2181
+ good = ["1111", "1234"]
2182
+ bad = ["", "abc", "123", "123 4", "abc 6543 def"]
2183
+ wanted = /^([1-6]){4}$/
2184
+
2185
+ it { should be_parseable }
2186
+
2187
+ rx = nil
2188
+ it "can be converted to a regex" do
2189
+ rx = regexp
2190
+ rx.class.should == Regexp
2191
+ rx.to_s.should == wanted.to_s
2192
+ end
2193
+
2194
+ # Check sanity: Is test valid?
2195
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2196
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2197
+
2198
+ # Is compiled result valid?
2199
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2200
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2201
+ end # end of test
2202
+
2203
+
2204
+ ### Test 76: Complex repetition of char (anchored)
2205
+
2206
+ describe "Complex repetition of char (anchored):" do
2207
+ $prog = prog = %q<match BOS 3,5 * (`a) EOS end>
2208
+ program { prog }
2209
+
2210
+ good = ["aaa", "aaaa", "aaaaa"]
2211
+ bad = ["", "abc", "aa", "xaaay", "aaaaaaa"]
2212
+ wanted = /^(a){3,5}$/
2213
+
2214
+ it { should be_parseable }
2215
+
2216
+ rx = nil
2217
+ it "can be converted to a regex" do
2218
+ rx = regexp
2219
+ rx.class.should == Regexp
2220
+ rx.to_s.should == wanted.to_s
2221
+ end
2222
+
2223
+ # Check sanity: Is test valid?
2224
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2225
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2226
+
2227
+ # Is compiled result valid?
2228
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2229
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2230
+ end # end of test
2231
+
2232
+
2233
+ ### Test 77: Complex repetition of parenthesized class (anchored)
2234
+
2235
+ describe "Complex repetition of parenthesized class (anchored):" do
2236
+ $prog = prog = %q<match BOS 4,7 * ('xyz') EOS end>
2237
+ program { prog }
2238
+
2239
+ good = ["xxxx", "yyyy", "xyzy", "xyzzy", "xyzxyz", "xyzxyzx"]
2240
+ bad = ["", "abc", "x", "xx", "xxx", "xyz xy", "xyzxyzxyzxyz", "zyzzyva"]
2241
+ wanted = /^([xyz]){4,7}$/
2242
+
2243
+ it { should be_parseable }
2244
+
2245
+ rx = nil
2246
+ it "can be converted to a regex" do
2247
+ rx = regexp
2248
+ rx.class.should == Regexp
2249
+ rx.to_s.should == wanted.to_s
2250
+ end
2251
+
2252
+ # Check sanity: Is test valid?
2253
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2254
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2255
+
2256
+ # Is compiled result valid?
2257
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2258
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2259
+ end # end of test
2260
+
2261
+
2262
+ ### Test 78: Complex repetition of parenthesized range (anchored)
2263
+
2264
+ describe "Complex repetition of parenthesized range (anchored):" do
2265
+ $prog = prog = %q<match BOS 0,3 * (`1-`6) EOS end>
2266
+ program { prog }
2267
+
2268
+ good = ["", "1", "11", "111", "56", "654"]
2269
+ bad = ["1111", "x123y", "x123456y"]
2270
+ wanted = /^([1-6]){0,3}$/
2271
+
2272
+ it { should be_parseable }
2273
+
2274
+ rx = nil
2275
+ it "can be converted to a regex" do
2276
+ rx = regexp
2277
+ rx.class.should == Regexp
2278
+ rx.to_s.should == wanted.to_s
2279
+ end
2280
+
2281
+ # Check sanity: Is test valid?
2282
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2283
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2284
+
2285
+ # Is compiled result valid?
2286
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2287
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2288
+ end # end of test
2289
+
2290
+
2291
+ ### Test 79: Simple lookaround (pos-ahead)
2292
+
2293
+ describe "Simple lookaround (pos-ahead):" do
2294
+ $prog = prog = %q<match find "X" with "Y" end>
2295
+ program { prog }
2296
+
2297
+ good = ["XY"]
2298
+ bad = ["X", "Y", "YX"]
2299
+ wanted = /(?=XY)X/
2300
+
2301
+ it { should be_parseable }
2302
+
2303
+ rx = nil
2304
+ it "can be converted to a regex" do
2305
+ rx = regexp
2306
+ rx.class.should == Regexp
2307
+ rx.to_s.should == wanted.to_s
2308
+ end
2309
+
2310
+ # Check sanity: Is test valid?
2311
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2312
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2313
+
2314
+ # Is compiled result valid?
2315
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2316
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2317
+ end # end of test
2318
+
2319
+
2320
+ ### Test 80: Simple lookaround (neg-ahead)
2321
+
2322
+ describe "Simple lookaround (neg-ahead):" do
2323
+ $prog = prog = %q<match find "X" without "Y" end>
2324
+ program { prog }
2325
+
2326
+ good = ["X", "YX"]
2327
+ bad = ["XY", "Y"]
2328
+ wanted = /(?!XY)X/
2329
+
2330
+ it { should be_parseable }
2331
+
2332
+ rx = nil
2333
+ it "can be converted to a regex" do
2334
+ rx = regexp
2335
+ rx.class.should == Regexp
2336
+ rx.to_s.should == wanted.to_s
2337
+ end
2338
+
2339
+ # Check sanity: Is test valid?
2340
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2341
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2342
+
2343
+ # Is compiled result valid?
2344
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2345
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2346
+ end # end of test
2347
+
2348
+
2349
+ ### Test 81: Simple lookaround (pos-behind)
2350
+
2351
+ describe "Simple lookaround (pos-behind):" do
2352
+ $prog = prog = %q<match with "X" find "Y" end>
2353
+ program { prog }
2354
+
2355
+ good = ["XY"]
2356
+ bad = ["YX", "Y", "X"]
2357
+ wanted = /(?<=X)Y/
2358
+
2359
+ it { should be_parseable }
2360
+
2361
+ rx = nil
2362
+ it "can be converted to a regex" do
2363
+ rx = regexp
2364
+ rx.class.should == Regexp
2365
+ rx.to_s.should == wanted.to_s
2366
+ end
2367
+
2368
+ # Check sanity: Is test valid?
2369
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2370
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2371
+
2372
+ # Is compiled result valid?
2373
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2374
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2375
+ end # end of test
2376
+
2377
+
2378
+ ### Test 82: Simple lookaround (neg-behind)
2379
+
2380
+ describe "Simple lookaround (neg-behind):" do
2381
+ $prog = prog = %q<match without "X" find "Y" end>
2382
+ program { prog }
2383
+
2384
+ good = ["aY", "Y"]
2385
+ bad = ["XY", "X"]
2386
+ wanted = /(?<!X)Y/
2387
+
2388
+ it { should be_parseable }
2389
+
2390
+ rx = nil
2391
+ it "can be converted to a regex" do
2392
+ rx = regexp
2393
+ rx.class.should == Regexp
2394
+ rx.to_s.should == wanted.to_s
2395
+ end
2396
+
2397
+ # Check sanity: Is test valid?
2398
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2399
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2400
+
2401
+ # Is compiled result valid?
2402
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2403
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2404
+ end # end of test
2405
+
2406
+
2407
+ ### Test 83: Positive lookahead
2408
+
2409
+ describe "Positive lookahead:" do
2410
+ $prog = prog = %q<match find (3*D " dollars") with 3*D end>
2411
+ program { prog }
2412
+
2413
+ good = ["101 dollars"]
2414
+ bad = ["102 pesos"]
2415
+ wanted = /(?=\d{3} dollars)\d{3}/
2416
+
2417
+ it { should be_parseable }
2418
+
2419
+ rx = nil
2420
+ it "can be converted to a regex" do
2421
+ rx = regexp
2422
+ rx.class.should == Regexp
2423
+ rx.to_s.should == wanted.to_s
2424
+ end
2425
+
2426
+ # Check sanity: Is test valid?
2427
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2428
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2429
+
2430
+ # Is compiled result valid?
2431
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2432
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2433
+ end # end of test
2434
+
2435
+
2436
+ ### Test 84: Negative lookahead
2437
+
2438
+ describe "Negative lookahead:" do
2439
+ $prog = prog = %q<match find 3*D without " pesos" end>
2440
+ program { prog }
2441
+
2442
+ good = ["103 dollars", "104 euros"]
2443
+ bad = ["105 pesos"]
2444
+ wanted = /(?!\d{3} pesos)\d{3}/
2445
+
2446
+ it { should be_parseable }
2447
+
2448
+ rx = nil
2449
+ it "can be converted to a regex" do
2450
+ rx = regexp
2451
+ rx.class.should == Regexp
2452
+ rx.to_s.should == wanted.to_s
2453
+ end
2454
+
2455
+ # Check sanity: Is test valid?
2456
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2457
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2458
+
2459
+ # Is compiled result valid?
2460
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2461
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2462
+ end # end of test
2463
+
2464
+
2465
+ ### Test 85: Positive lookbehind
2466
+
2467
+ describe "Positive lookbehind:" do
2468
+ $prog = prog = %q<match with "USD" find 3*D end>
2469
+ program { prog }
2470
+
2471
+ good = ["USD106"]
2472
+ bad = ["EUR107"]
2473
+ wanted = /(?<=USD)\d{3}/
2474
+
2475
+ it { should be_parseable }
2476
+
2477
+ rx = nil
2478
+ it "can be converted to a regex" do
2479
+ rx = regexp
2480
+ rx.class.should == Regexp
2481
+ rx.to_s.should == wanted.to_s
2482
+ end
2483
+
2484
+ # Check sanity: Is test valid?
2485
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2486
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2487
+
2488
+ # Is compiled result valid?
2489
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2490
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2491
+ end # end of test
2492
+
2493
+
2494
+ ### Test 86: Negative lookbehind
2495
+
2496
+ describe "Negative lookbehind:" do
2497
+ $prog = prog = %q<match without "USD" find 3*D end>
2498
+ program { prog }
2499
+
2500
+ good = ["EUR108"]
2501
+ bad = ["USD109"]
2502
+ wanted = /(?<!USD)\d{3}/
2503
+
2504
+ it { should be_parseable }
2505
+
2506
+ rx = nil
2507
+ it "can be converted to a regex" do
2508
+ rx = regexp
2509
+ rx.class.should == Regexp
2510
+ rx.to_s.should == wanted.to_s
2511
+ end
2512
+
2513
+ # Check sanity: Is test valid?
2514
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2515
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2516
+
2517
+ # Is compiled result valid?
2518
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2519
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2520
+ end # end of test
2521
+
2522
+
2523
+ ### Test 87: Simple use of two vars
2524
+
2525
+ describe "Simple use of two vars:" do
2526
+ $prog = prog = <<-'END'
2527
+ var1 = "abc"
2528
+ var2 = "def"
2529
+ match var1 var2 end
2530
+ END
2531
+ program { prog }
2532
+
2533
+ good = ["abcdefghi", "xyzabcdef"]
2534
+ bad = ["", "abcxyzdef"]
2535
+ wanted = /abcdef/
2536
+
2537
+ it { should be_parseable }
2538
+
2539
+ rx = nil
2540
+ it "can be converted to a regex" do
2541
+ rx = regexp
2542
+ rx.class.should == Regexp
2543
+ rx.to_s.should == wanted.to_s
2544
+ end
2545
+
2546
+ # Check sanity: Is test valid?
2547
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2548
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2549
+
2550
+ # Is compiled result valid?
2551
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2552
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2553
+ end # end of test
2554
+
2555
+
2556
+ ### Test 88: Multiline match with two vars
2557
+
2558
+ describe "Multiline match with two vars:" do
2559
+ $prog = prog = <<-'END'
2560
+ var1 = "abc"
2561
+ var2 = "def"
2562
+
2563
+ # Test a blank line and comment as well.
2564
+
2565
+ match # multiline match with comment
2566
+ var1
2567
+ var2
2568
+ end
2569
+ END
2570
+ program { prog }
2571
+
2572
+ good = ["abcdefghi", "xyzabcdef"]
2573
+ bad = ["", "abcxyzdef"]
2574
+ wanted = /abcdef/
2575
+
2576
+ it { should be_parseable }
2577
+
2578
+ rx = nil
2579
+ it "can be converted to a regex" do
2580
+ rx = regexp
2581
+ rx.class.should == Regexp
2582
+ rx.to_s.should == wanted.to_s
2583
+ end
2584
+
2585
+ # Check sanity: Is test valid?
2586
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2587
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2588
+
2589
+ # Is compiled result valid?
2590
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2591
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2592
+ end # end of test
2593
+
2594
+
2595
+ ### Test 89: IPv4 address
2596
+
2597
+ describe "IPv4 address:" do
2598
+ $prog = prog = <<-'END'
2599
+ dot = "."
2600
+ num = "25" D5 | `2 D4 D | maybe D1 1,2*D
2601
+ match BOS num dot num dot num dot num EOS end
2602
+ END
2603
+ program { prog }
2604
+
2605
+ good = ["127.0.0.1", "255.254.93.22", "255.254.93.22"]
2606
+ bad = ["", "7.8.9", "3.4.5.6.7", "1.2.3.256"]
2607
+ wanted = /^(25[0-5]|2[0-4]\d|([01])?(\d){1,2})\.(25[0-5]|2[0-4]\d|([01])?(\d){1,2})\.(25[0-5]|2[0-4]\d|([01])?(\d){1,2})\.(25[0-5]|2[0-4]\d|([01])?(\d){1,2})$/
2608
+
2609
+ it { should be_parseable }
2610
+
2611
+ rx = nil
2612
+ it "can be converted to a regex" do
2613
+ rx = regexp
2614
+ rx.class.should == Regexp
2615
+ rx.to_s.should == wanted.to_s
2616
+ end
2617
+
2618
+ # Check sanity: Is test valid?
2619
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2620
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2621
+
2622
+ # Is compiled result valid?
2623
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2624
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2625
+ end # end of test
2626
+
2627
+
2628
+ ### Test 90: Identifying credit cards
2629
+
2630
+ describe "Identifying credit cards:" do
2631
+ $prog = prog = <<-'END'
2632
+ # Warning: This one may have errors!
2633
+ visa = `4 12*D maybe 3*D
2634
+ mc = `5 D5 14*D
2635
+ discover = `6 ("011" | `5 2*D) 12*D
2636
+ amex = `3 '47' 13*D
2637
+ diners = `3 (`0 D5 | '68' D) 11*D
2638
+ jcb = ("2131"|"1800"|"35" 3*D) 11*D
2639
+
2640
+ match visa | mc | discover | amex | diners | jcb end
2641
+ END
2642
+ program { prog }
2643
+
2644
+ good = []
2645
+ bad = []
2646
+ wanted = /(4(\d){12}((\d){3})?|5[0-5](\d){14}|6(011|5(\d){2})(\d){12}|3[47](\d){13}|3(0[0-5]|[68]\d)(\d){11}|(2131|1800|35(\d){3})(\d){11})/
2647
+
2648
+ it { should be_parseable }
2649
+
2650
+ rx = nil
2651
+ it "can be converted to a regex" do
2652
+ rx = regexp
2653
+ rx.class.should == Regexp
2654
+ rx.to_s.should == wanted.to_s
2655
+ end
2656
+
2657
+ # Check sanity: Is test valid?
2658
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2659
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2660
+
2661
+ # Is compiled result valid?
2662
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2663
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2664
+ end # end of test
2665
+
2666
+
2667
+ ### Test 91: Matching US phone num (with captures)
2668
+
2669
+ describe "Matching US phone num (with captures):" do
2670
+ $prog = prog = <<-'END'
2671
+ match
2672
+ @area_code = 3 * D
2673
+ `-
2674
+ @prefix = 3*D
2675
+ `-
2676
+ @last4 = 4*D
2677
+ end
2678
+ END
2679
+ program { prog }
2680
+
2681
+ good = ["601-555-2345", "call me at 888-425-9000"]
2682
+ bad = ["888-HAL-9000", "800.237.1234"]
2683
+ wanted = /(?<area_code>(\d){3})\-(?<prefix>(\d){3})\-(?<last4>(\d){4})/
2684
+
2685
+ it { should be_parseable }
2686
+
2687
+ rx = nil
2688
+ it "can be converted to a regex" do
2689
+ rx = regexp
2690
+ rx.class.should == Regexp
2691
+ rx.to_s.should == wanted.to_s
2692
+ end
2693
+
2694
+ # Check sanity: Is test valid?
2695
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2696
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2697
+
2698
+ # Is compiled result valid?
2699
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2700
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2701
+ end # end of test
2702
+
2703
+
2704
+ ### Test 92: Matching a clock time, 12/24 hrs
2705
+
2706
+ describe "Matching a clock time, 12/24 hrs:" do
2707
+ $prog = prog = <<-'END'
2708
+ hr12 = (maybe `0) `1-`9 | `1 D2
2709
+ hr24 = (maybe `0) D | `1 D | `2 D3
2710
+ sep = `: | `.
2711
+ min = D5 D9
2712
+ sec = D5 D9
2713
+ ampm = (maybe SPACE) ("am" | "pm")
2714
+ time12 = hr12 sep min maybe (sep sec) maybe ampm
2715
+ time24 = hr24 sep min maybe (sep sec)
2716
+ match BOS (time12 | time24) EOS end
2717
+ END
2718
+ program { prog }
2719
+
2720
+ good = ["12:34", "1:23", "5:14pm", "19:43", "1:23:45", "1:23:45 pm", "7:43 pm", "8:32:45", "8.34", "8.34 pm", "8.34.45"]
2721
+ bad = ["", "abc", "24:30", "25:30", "19:43 pm", "5:14 pm"]
2722
+ wanted = /^(((0)?[1-9]|1[0-2])(:|\.)[0-5]\d((:|\.)[0-5]\d)?(( )?(am|pm))?|((0)?\d|1\d|2[0-3])(:|\.)[0-5]\d((:|\.)[0-5]\d)?)$/
2723
+
2724
+ it { should be_parseable }
2725
+
2726
+ rx = nil
2727
+ it "can be converted to a regex" do
2728
+ rx = regexp
2729
+ rx.class.should == Regexp
2730
+ rx.to_s.should == wanted.to_s
2731
+ end
2732
+
2733
+ # Check sanity: Is test valid?
2734
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2735
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2736
+
2737
+ # Is compiled result valid?
2738
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2739
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2740
+ end # end of test
2741
+
2742
+
2743
+ ### Test 93: Using nocase
2744
+
2745
+ describe "Using nocase:" do
2746
+ $prog = prog = %q<match BOS "abc" nocase "def" "ghi" EOS end>
2747
+ program { prog }
2748
+
2749
+ good = ["abcdefghi", "abcDEFghi", "abcdEfghi"]
2750
+ bad = ["", "x", "xabcdefghi", "abcdefghix", "aBcdefghi", "abcdefGhi", "abCdefghI", "abCdEfghI"]
2751
+ wanted = /^abc((?i)def)ghi$/
2752
+
2753
+ it { should be_parseable }
2754
+
2755
+ rx = nil
2756
+ it "can be converted to a regex" do
2757
+ rx = regexp
2758
+ rx.class.should == Regexp
2759
+ rx.to_s.should == wanted.to_s
2760
+ end
2761
+
2762
+ # Check sanity: Is test valid?
2763
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2764
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2765
+
2766
+ # Is compiled result valid?
2767
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2768
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2769
+ end # end of test
2770
+
2771
+
2772
+ ### Test 94: Var used in simple repetition
2773
+
2774
+ describe "Var used in simple repetition:" do
2775
+ $prog = prog = <<-'END'
2776
+ n = 3
2777
+ match BOS n * `x EOS end
2778
+ END
2779
+ program { prog }
2780
+
2781
+ good = ["xxx"]
2782
+ bad = ["", "x", "xx x", "xxxx"]
2783
+ wanted = /^(x){3}$/
2784
+
2785
+ it { should be_parseable }
2786
+
2787
+ rx = nil
2788
+ it "can be converted to a regex" do
2789
+ rx = regexp
2790
+ rx.class.should == Regexp
2791
+ rx.to_s.should == wanted.to_s
2792
+ end
2793
+
2794
+ # Check sanity: Is test valid?
2795
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2796
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2797
+
2798
+ # Is compiled result valid?
2799
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2800
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2801
+ end # end of test
2802
+
2803
+
2804
+ ### Test 95: Var used in complex repetition
2805
+
2806
+ describe "Var used in complex repetition:" do
2807
+ $prog = prog = <<-'END'
2808
+ m = 4
2809
+ n = 6
2810
+ match BOS m,n * `x EOS end
2811
+ END
2812
+ program { prog }
2813
+
2814
+ good = ["xxxx", "xxxxx", "xxxxxx"]
2815
+ bad = ["", "x", "xx x", "xxx", "xxxxxxx"]
2816
+ wanted = /^(x){4,6}$/
2817
+
2818
+ it { should be_parseable }
2819
+
2820
+ rx = nil
2821
+ it "can be converted to a regex" do
2822
+ rx = regexp
2823
+ rx.class.should == Regexp
2824
+ rx.to_s.should == wanted.to_s
2825
+ end
2826
+
2827
+ # Check sanity: Is test valid?
2828
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2829
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2830
+
2831
+ # Is compiled result valid?
2832
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2833
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2834
+ end # end of test
2835
+
2836
+
2837
+ ### Test 96: Using Unicode codepoint again
2838
+
2839
+ describe "Using Unicode codepoint again:" do
2840
+ $prog = prog = <<-'END'
2841
+ euro = &20ac
2842
+ price = (euro | "$") SPACE many D maybe ("." 2*D)
2843
+ match BOS price EOS end
2844
+ END
2845
+ program { prog }
2846
+
2847
+ good = ["€ 237", "$ 237", "€ 23.45", "€ 0.25"]
2848
+ bad = ["", "x", "€", "€ ", "€ 237", "$ 237", "€ 23.456"]
2849
+ wanted = /^(€|\$) (\d)+(\.(\d){2})?$/
2850
+
2851
+ it { should be_parseable }
2852
+
2853
+ rx = nil
2854
+ it "can be converted to a regex" do
2855
+ rx = regexp
2856
+ rx.class.should == Regexp
2857
+ rx.to_s.should == wanted.to_s
2858
+ end
2859
+
2860
+ # Check sanity: Is test valid?
2861
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2862
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2863
+
2864
+ # Is compiled result valid?
2865
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2866
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2867
+ end # end of test
2868
+
2869
+
2870
+ ### Test 97: Using within (1)
2871
+
2872
+ describe "Using within (1):" do
2873
+ $prog = prog = %q<match within `/ end>
2874
+ program { prog }
2875
+
2876
+ good = ["There is a /slash-delimited string/ here."]
2877
+ bad = ["No such string here."]
2878
+ wanted = /(\/.*?\/)/
2879
+
2880
+ it { should be_parseable }
2881
+
2882
+ rx = nil
2883
+ it "can be converted to a regex" do
2884
+ rx = regexp
2885
+ rx.class.should == Regexp
2886
+ rx.to_s.should == wanted.to_s
2887
+ end
2888
+
2889
+ # Check sanity: Is test valid?
2890
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2891
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2892
+
2893
+ # Is compiled result valid?
2894
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2895
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2896
+ end # end of test
2897
+
2898
+
2899
+ ### Test 98: Using escaping (1)
2900
+
2901
+ describe "Using escaping (1):" do
2902
+ $prog = prog = %q<match escaping `/ end>
2903
+ program { prog }
2904
+
2905
+ good = ["This is /slash-delimited but \\/with embedded slashes \\/ also /."]
2906
+ bad = ["No such string here."]
2907
+ wanted = /\/|[^\/]*?\//
2908
+
2909
+ it { should be_parseable }
2910
+
2911
+ rx = nil
2912
+ it "can be converted to a regex" do
2913
+ rx = regexp
2914
+ rx.class.should == Regexp
2915
+ rx.to_s.should == wanted.to_s
2916
+ end
2917
+
2918
+ # Check sanity: Is test valid?
2919
+ good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
2920
+ bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
2921
+
2922
+ # Is compiled result valid?
2923
+ good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
2924
+ bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
2925
+ end # end of test
2926
+
2927
+
2928
+ end