regexador 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +54 -46
- data/lib/chars.rb +1 -0
- data/lib/keywords.rb +13 -11
- data/lib/regexador_parser.rb +3 -2
- data/spec/GENERATED_spec.rb +3347 -0
- data/spec/captures.yaml +85 -0
- data/spec/old_mkcode.rb +116 -0
- data/spec/oneliners.yaml +1036 -0
- data/spec/programs.yaml +201 -0
- data/spec/regexador_spec.rb +348 -0
- data/test/captures.yaml +85 -0
- data/test/mkcode.rb +122 -0
- data/test/oneliners.yaml +1036 -0
- data/test/programs.yaml +201 -0
- data/test/test.rb +147 -16
- metadata +30 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ef781dea6cb100272e9885a401b5710d8721eddd9280a262b34c15ba444a35a0
|
4
|
+
data.tar.gz: bab1c2a5a233e23a701be3a852340092cff4710de52580692a5a184e5bee71ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b01ba0354deb1aab96a3d1aa95447ec5af4764511bdd9f4a6ec73586eb22db619aedee35c05977d40fc18b9e6f9d73638f332efca5cd3967c1fee6fe50dc78d3
|
7
|
+
data.tar.gz: '0980bc439ced111c2ae822dcd9416bd290e8cf8f3d17ec00b70e24bb65961c458a3fcd5844fcbbfb620f2463f128861c6b2698ce4d8705c30adb2fd33d233182'
|
data/README.md
CHANGED
@@ -19,21 +19,25 @@ as [the wiki](http://github.com/Hal9000/regexador/wiki).
|
|
19
19
|
|
20
20
|
### The Basic Concept
|
21
21
|
|
22
|
-
Many people are intimidated or confused by regular expressions.
|
23
|
-
|
22
|
+
Many people are intimidated or confused by regular expressions. A large part of
|
23
|
+
this is the complex syntax.
|
24
24
|
|
25
|
-
Regexador is a mini-language purely for building regular expressions.
|
26
|
-
|
27
|
-
|
25
|
+
Regexador is a mini-language purely for building regular expressions. It's purely
|
26
|
+
a Ruby project at the moment, although there are tentative plans for ports to
|
27
|
+
Elixir and Python.
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
A traditional (or internal) Ruby DSL consists of creative use of methods and
|
30
|
+
operators to "fake" a language inside Ruby code. The internal DSL is itself
|
31
|
+
Ruby code that must obeu Ruby syntax.
|
32
|
+
|
33
|
+
But what is an external DSL? For an analogy, think of how we sometimes manipulate
|
34
|
+
databases by constructing SQL queries and passing them into the appropriate
|
31
35
|
methods. Regexador works much the same way.
|
32
36
|
|
33
37
|
### A Short Example
|
34
38
|
|
35
|
-
Suppose we want to match a string consisting of a single IP address.
|
36
|
-
|
39
|
+
Suppose we want to match a string consisting of a single IP address. (Remember that
|
40
|
+
the numbers can only range as high as 255.)
|
37
41
|
|
38
42
|
Here is traditional regular expression notation:
|
39
43
|
|
@@ -45,11 +49,10 @@ And here is Regexador notation:
|
|
45
49
|
num = "25" D5 | `2 D4 D | maybe D1 1,2*D
|
46
50
|
match BOS num dot num dot num dot num EOS end
|
47
51
|
|
48
|
-
In your Ruby code, you can create a Regexador "script" or "program"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
and more may be added.
|
52
|
+
In your Ruby code, you can create a Regexador "script" or "program" (probably
|
53
|
+
by means of a here-document) that you can then pass into the Regexador class.
|
54
|
+
At minimum, you can convert this into a "real" Ruby regular expression; there
|
55
|
+
are a few other features and functions, and more are being added.
|
53
56
|
|
54
57
|
So here is a complete Ruby program:
|
55
58
|
|
@@ -75,9 +78,7 @@ So here is a complete Ruby program:
|
|
75
78
|
end
|
76
79
|
|
77
80
|
|
78
|
-
|
79
81
|
**Traditional Syntax: Things I Personally Dislike**
|
80
|
-
|
81
82
|
- There are no keywords -- only punctuation.
|
82
83
|
These symbols all have special meanings: ^$.\[]()+\*? (and others)
|
83
84
|
- ^ has at least three different meanings
|
@@ -93,42 +94,39 @@ So here is a complete Ruby program:
|
|
93
94
|
|
94
95
|
### Regexador at a Glance
|
95
96
|
|
96
|
-
I'm attracted to old-fashioned line-oriented syntax; but I don't want
|
97
|
-
|
97
|
+
I'm attracted to old-fashioned line-oriented syntax; but I don't want to lock
|
98
|
+
myself into that completely.
|
98
99
|
|
99
|
-
In general, useful definitions (variables) will come first. Many things
|
100
|
-
|
101
|
-
|
100
|
+
In general, useful definitions (variables) will come first. Many things are
|
101
|
+
predefined already, such as all the usual anchors and the POSIX character
|
102
|
+
classes. These are in all caps and are considered constants.
|
102
103
|
|
103
|
-
At the end, a *match* clause drives the actual building of the final
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
At the end, a *match* clause drives the actual building of the final regular
|
105
|
+
expression. Within this clause, names may be assigned to the individual
|
106
|
+
sub-matches (using variables that start with "@"). These will naturally be
|
107
|
+
available externally as named captures.
|
107
108
|
|
108
|
-
Because this is really just a "builder," and because we don't have "hooks"
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
109
|
+
Because this is really just a "builder," and because we don't have "hooks" into
|
110
|
+
the regular expression engine itself, a Regexador script will not look or act
|
111
|
+
much like a "real program." There will be no arithmetic, no function calls, no
|
112
|
+
looping or branching. Also there can be no printing of debug information "at
|
113
|
+
matching time"; in principle, printing could be done during parsing/compilation,
|
114
|
+
but I don't see any value in this.
|
114
115
|
|
115
|
-
Of course, syntax errors in Regexador will be found and made available
|
116
|
-
|
116
|
+
Of course, syntax errors in Regexador will be found and made available to the
|
117
|
+
caller.
|
117
118
|
|
118
119
|
|
119
120
|
**Beginning at the Beginning**
|
120
121
|
|
121
|
-
I've tried to "think ahead" so as not to paint myself into a corner
|
122
|
-
too much.
|
122
|
+
I've tried to "think ahead" so as not to paint myself into a corner too much.
|
123
123
|
|
124
|
-
However, probably not all of this can be implemented in the
|
125
|
-
|
126
|
-
|
124
|
+
However, probably not all of this can be implemented in the earliest versions.
|
125
|
+
The original "working version" (0.2.7) was implemented over a period of nine
|
126
|
+
weeks.
|
127
127
|
|
128
|
-
Therefore some of the
|
129
|
-
|
130
|
-
|
131
|
-
Features still postponed:
|
128
|
+
Therefore some of the functionality described here is not yet fully implemented.
|
129
|
+
Features still postponed include:
|
132
130
|
- intra-line comments: #{...}
|
133
131
|
- case/end
|
134
132
|
- unsure about upto, thru
|
@@ -251,11 +249,13 @@ But data type matters, of course:
|
|
251
249
|
n = "foo"
|
252
250
|
m,n * "def" # Syntax error!
|
253
251
|
|
254
|
-
The "match clause" uses all previous definitions to finally build the regular
|
252
|
+
The "match clause" uses all previous definitions to finally build the regular
|
253
|
+
expression. It starts with "match" and ends with "end":
|
255
254
|
|
256
255
|
match "abc" | "def" | many `x end
|
257
256
|
|
258
|
-
Named matches are only used inside the match clause; anywhere a pattern may be
|
257
|
+
Named matches are only used inside the match clause; anywhere a pattern may be
|
258
|
+
used, "@var = pattern" may also be used.
|
259
259
|
|
260
260
|
match @first = (many %alpha) SPACES @last = (many %alpha) end
|
261
261
|
|
@@ -267,7 +267,7 @@ Multiple lines are fine (and more readable):
|
|
267
267
|
@last = many %alpha
|
268
268
|
end
|
269
269
|
|
270
|
-
A "case" may be used for more complex alternatives (needed
|
270
|
+
Planned: A "case" may be used for more complex alternatives. (Is this needed?)
|
271
271
|
|
272
272
|
case
|
273
273
|
when "abc" ...
|
@@ -275,7 +275,8 @@ Multiple lines are fine (and more readable):
|
|
275
275
|
when "xyz" ...
|
276
276
|
end
|
277
277
|
|
278
|
-
Multiple "programs" can be concatenated, assuming the initial ones are all
|
278
|
+
Multiple "programs" can be concatenated, assuming the initial ones are all
|
279
|
+
definitions and there is only one match clause at the end.
|
279
280
|
|
280
281
|
# Ruby code
|
281
282
|
defs = "..."
|
@@ -373,6 +374,13 @@ Determine whether a credit card number is valid Regex: /^(?:4[0-9]{12}(?:[0-9
|
|
373
374
|
|
374
375
|
This history has been maintained only since version 0.4.2
|
375
376
|
|
377
|
+
*0.4.6*
|
378
|
+
- Moving from rspec to minitest
|
379
|
+
- Verifying compatibility with Ruby 2.6, 2.7
|
380
|
+
- improving gemspec
|
381
|
+
- improving README
|
382
|
+
- working on railroad diagrams
|
383
|
+
|
376
384
|
*0.4.3*
|
377
385
|
- Experimenting with lookarounds (pos/neg lookahead/behind)
|
378
386
|
- Rearranged tests
|
data/lib/chars.rb
CHANGED
data/lib/keywords.rb
CHANGED
@@ -3,19 +3,21 @@ abort "Require out of order" if ! defined? Regexador
|
|
3
3
|
|
4
4
|
class Regexador::Parser
|
5
5
|
|
6
|
-
rule(:
|
7
|
-
rule(:kMANY) { str("many") }
|
8
|
-
rule(:kMAYBE) { str("maybe") }
|
9
|
-
rule(:kMATCH) { str("match") }
|
10
|
-
rule(:kEND) { str("end") }
|
11
|
-
rule(:kNOCASE) { str("nocase") }
|
6
|
+
rule(:non_alphanum) { lower.absent? >> upper.absent? >> cUNDERSCORE.absent? >> digit.absent? }
|
12
7
|
|
13
|
-
rule(:
|
14
|
-
rule(:
|
15
|
-
rule(:
|
8
|
+
rule(:kANY) { str("any") >> non_alphanum }
|
9
|
+
rule(:kMANY) { str("many") >> non_alphanum }
|
10
|
+
rule(:kMAYBE) { str("maybe") >> non_alphanum }
|
11
|
+
rule(:kMATCH) { str("match") >> non_alphanum }
|
12
|
+
rule(:kEND) { str("end") >> non_alphanum }
|
13
|
+
rule(:kNOCASE) { str("nocase") >> non_alphanum }
|
16
14
|
|
17
|
-
rule(:
|
18
|
-
rule(:
|
15
|
+
rule(:kWITH) { str("with") >> non_alphanum }
|
16
|
+
rule(:kWITHOUT) { str("without") >> non_alphanum }
|
17
|
+
rule(:kFIND) { str("find") >> non_alphanum }
|
18
|
+
|
19
|
+
rule(:kWITHIN) { str("within") >> non_alphanum }
|
20
|
+
rule(:kESCAPING) { str("escaping") >> non_alphanum }
|
19
21
|
|
20
22
|
rule(:keyword) { kANY | kMANY | kMAYBE | kMATCH | kEND | kNOCASE |
|
21
23
|
kWITH | kWITHOUT | kFIND | kWITHIN | kESCAPING }
|
data/lib/regexador_parser.rb
CHANGED
@@ -18,8 +18,9 @@ class Regexador::Parser
|
|
18
18
|
rule(:lower) { match('[a-z]') }
|
19
19
|
rule(:upper) { match('[A-Z]') }
|
20
20
|
|
21
|
-
rule(:comment) { cHASH >> space >> (cNEWLINE.absent? >> any).repeat(0) }
|
21
|
+
rule(:comment) { space? >> cHASH >> space >> (cNEWLINE.absent? >> any).repeat(0) >> cNEWLINE }
|
22
22
|
rule(:endofline) { space? >> comment.maybe >> cNEWLINE }
|
23
|
+
rule(:statement) { (assignment | comment) }
|
23
24
|
|
24
25
|
rule(:digit) { match('[0-9]') }
|
25
26
|
rule(:digits) { digit.repeat(1) }
|
@@ -95,7 +96,7 @@ class Regexador::Parser
|
|
95
96
|
|
96
97
|
rule(:assignment) { space? >> name.as(:var) >> space? >> cEQUAL >> space? >> rvalue.as(:rvalue) }
|
97
98
|
|
98
|
-
rule(:definitions) { (
|
99
|
+
rule(:definitions) { (statement >> endofline).repeat(0).maybe }
|
99
100
|
|
100
101
|
rule(:oneline_clause) { space? >> kMATCH >> space? >> pattern >> kEND >> endofline.maybe }
|
101
102
|
|
@@ -0,0 +1,3347 @@
|
|
1
|
+
require_relative '../lib/regexador'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
require 'parslet/convenience'
|
5
|
+
require 'parslet/rig/rspec'
|
6
|
+
|
7
|
+
describe Regexador do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
@parser = Regexador::Parser.new
|
11
|
+
@pattern = @parser.pattern
|
12
|
+
end
|
13
|
+
|
14
|
+
class Program
|
15
|
+
attr_accessor :description, :program, :regex, :good, :bad, :examples
|
16
|
+
|
17
|
+
def initialize(code)
|
18
|
+
@code = code
|
19
|
+
@parser = Regexador::Parser.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def parseable?
|
23
|
+
result = @parser.parse(@code) rescue nil # != nil
|
24
|
+
!! result
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_pattern # FIXME no longer used?
|
28
|
+
tree = @parser.pattern.parse(@code)
|
29
|
+
tree = tree[:alternation] if tree.size == 1 && tree.keys.first == :alternation
|
30
|
+
tree = tree[:sequence].first if tree.size == 1 && tree.keys.first == :sequence
|
31
|
+
tree
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse
|
35
|
+
tree = @parser.parse(@code)
|
36
|
+
end
|
37
|
+
|
38
|
+
def debug_bad_program_parse
|
39
|
+
@parser.parse(@code)
|
40
|
+
atree = nil
|
41
|
+
rescue Parslet::ParseFailed => error
|
42
|
+
atree = error.cause.ascii_tree.split("
|
43
|
+
")
|
44
|
+
lchar = /at line (d+) char (d+).$/
|
45
|
+
fname = rand(10**5).to_s + ".tree"
|
46
|
+
File.open(fname, "w") {|f| f.puts @code + "
|
47
|
+
" + atree.join("
|
48
|
+
") }
|
49
|
+
puts "See file: " + fname
|
50
|
+
return
|
51
|
+
# FIXME bad logic below
|
52
|
+
begin
|
53
|
+
atree.map! do |line|
|
54
|
+
line.gsub!(/`- ||- || /, " ")
|
55
|
+
_, ln, cn = line.match(lchar).to_a
|
56
|
+
line.sub!(lchar, "")
|
57
|
+
line.sub!(/ /, " ")
|
58
|
+
line = '%-5s' % (ln+':'+cn) + line
|
59
|
+
end
|
60
|
+
rescue
|
61
|
+
end
|
62
|
+
puts atree
|
63
|
+
end
|
64
|
+
|
65
|
+
def regexp
|
66
|
+
Regexador.new(@code).to_regex
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def self.program &block
|
72
|
+
let(:code, &block)
|
73
|
+
let(:program) { Program.new(code) }
|
74
|
+
let(:regexp) { program.regexp }
|
75
|
+
|
76
|
+
subject { program }
|
77
|
+
end
|
78
|
+
|
79
|
+
### Test 1: Single char
|
80
|
+
|
81
|
+
describe "A correct program (Single char)" do
|
82
|
+
prog = <<-'END'
|
83
|
+
match `x end
|
84
|
+
END
|
85
|
+
|
86
|
+
good = ["abcx", "xyzb", "x"]
|
87
|
+
bad = ["yz", "", "ABC"]
|
88
|
+
wanted = /x/
|
89
|
+
|
90
|
+
myprog = Program.new(prog)
|
91
|
+
parsed = nil
|
92
|
+
|
93
|
+
it "should parse correctly" do
|
94
|
+
parsed = myprog.parseable?
|
95
|
+
myprog.debug_bad_program_parse unless parsed
|
96
|
+
parsed.should == true
|
97
|
+
end
|
98
|
+
|
99
|
+
rx = nil
|
100
|
+
it "can be converted to a regex" do
|
101
|
+
rx = myprog.regexp
|
102
|
+
rx.class.should == Regexp
|
103
|
+
end
|
104
|
+
|
105
|
+
# Check sanity: Is test valid?
|
106
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
107
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
108
|
+
|
109
|
+
# Is compiled result valid?
|
110
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
111
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
112
|
+
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
### Test 2: Unicode codepoint
|
118
|
+
|
119
|
+
describe "A correct program (Unicode codepoint)" do
|
120
|
+
prog = <<-'END'
|
121
|
+
match &20ac end
|
122
|
+
END
|
123
|
+
|
124
|
+
good = ["€", "xyz€", "x€yz"]
|
125
|
+
bad = ["yz", "", "ABC"]
|
126
|
+
wanted = /€/
|
127
|
+
|
128
|
+
myprog = Program.new(prog)
|
129
|
+
parsed = nil
|
130
|
+
|
131
|
+
it "should parse correctly" do
|
132
|
+
parsed = myprog.parseable?
|
133
|
+
myprog.debug_bad_program_parse unless parsed
|
134
|
+
parsed.should == true
|
135
|
+
end
|
136
|
+
|
137
|
+
rx = nil
|
138
|
+
it "can be converted to a regex" do
|
139
|
+
rx = myprog.regexp
|
140
|
+
rx.class.should == Regexp
|
141
|
+
end
|
142
|
+
|
143
|
+
# Check sanity: Is test valid?
|
144
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
145
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
146
|
+
|
147
|
+
# Is compiled result valid?
|
148
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
149
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
150
|
+
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
### Test 3: Manual international characters
|
156
|
+
|
157
|
+
describe "A correct program (Manual international characters)" do
|
158
|
+
prog = <<-'END'
|
159
|
+
match "ö" end
|
160
|
+
END
|
161
|
+
|
162
|
+
good = ["öffnen", "xyzö", "xöyz"]
|
163
|
+
bad = ["offnen", "yz", "", "ABC"]
|
164
|
+
wanted = /ö/
|
165
|
+
|
166
|
+
myprog = Program.new(prog)
|
167
|
+
parsed = nil
|
168
|
+
|
169
|
+
it "should parse correctly" do
|
170
|
+
parsed = myprog.parseable?
|
171
|
+
myprog.debug_bad_program_parse unless parsed
|
172
|
+
parsed.should == true
|
173
|
+
end
|
174
|
+
|
175
|
+
rx = nil
|
176
|
+
it "can be converted to a regex" do
|
177
|
+
rx = myprog.regexp
|
178
|
+
rx.class.should == Regexp
|
179
|
+
end
|
180
|
+
|
181
|
+
# Check sanity: Is test valid?
|
182
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
183
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
184
|
+
|
185
|
+
# Is compiled result valid?
|
186
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
187
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
188
|
+
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
### Test 4: Simple range
|
194
|
+
|
195
|
+
describe "A correct program (Simple range)" do
|
196
|
+
prog = <<-'END'
|
197
|
+
match `a-`f end
|
198
|
+
END
|
199
|
+
|
200
|
+
good = ["alpha", "xyzb", "c"]
|
201
|
+
bad = ["xyz", "", "ABC"]
|
202
|
+
wanted = /[a-f]/
|
203
|
+
|
204
|
+
myprog = Program.new(prog)
|
205
|
+
parsed = nil
|
206
|
+
|
207
|
+
it "should parse correctly" do
|
208
|
+
parsed = myprog.parseable?
|
209
|
+
myprog.debug_bad_program_parse unless parsed
|
210
|
+
parsed.should == true
|
211
|
+
end
|
212
|
+
|
213
|
+
rx = nil
|
214
|
+
it "can be converted to a regex" do
|
215
|
+
rx = myprog.regexp
|
216
|
+
rx.class.should == Regexp
|
217
|
+
end
|
218
|
+
|
219
|
+
# Check sanity: Is test valid?
|
220
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
221
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
222
|
+
|
223
|
+
# Is compiled result valid?
|
224
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
225
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
226
|
+
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
### Test 5: Negated range
|
232
|
+
|
233
|
+
describe "A correct program (Negated range)" do
|
234
|
+
prog = <<-'END'
|
235
|
+
match `c~`p end
|
236
|
+
END
|
237
|
+
|
238
|
+
good = ["ab", "rst"]
|
239
|
+
bad = ["def", "mno", ""]
|
240
|
+
wanted = /[^c-p]/
|
241
|
+
|
242
|
+
myprog = Program.new(prog)
|
243
|
+
parsed = nil
|
244
|
+
|
245
|
+
it "should parse correctly" do
|
246
|
+
parsed = myprog.parseable?
|
247
|
+
myprog.debug_bad_program_parse unless parsed
|
248
|
+
parsed.should == true
|
249
|
+
end
|
250
|
+
|
251
|
+
rx = nil
|
252
|
+
it "can be converted to a regex" do
|
253
|
+
rx = myprog.regexp
|
254
|
+
rx.class.should == Regexp
|
255
|
+
end
|
256
|
+
|
257
|
+
# Check sanity: Is test valid?
|
258
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
259
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
260
|
+
|
261
|
+
# Is compiled result valid?
|
262
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
263
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
264
|
+
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
### Test 6: Negated char
|
270
|
+
|
271
|
+
describe "A correct program (Negated char)" do
|
272
|
+
prog = <<-'END'
|
273
|
+
match ~`d end
|
274
|
+
END
|
275
|
+
|
276
|
+
good = ["xyz", "123"]
|
277
|
+
bad = ["d", "dd"]
|
278
|
+
wanted = /[^d]/
|
279
|
+
|
280
|
+
myprog = Program.new(prog)
|
281
|
+
parsed = nil
|
282
|
+
|
283
|
+
it "should parse correctly" do
|
284
|
+
parsed = myprog.parseable?
|
285
|
+
myprog.debug_bad_program_parse unless parsed
|
286
|
+
parsed.should == true
|
287
|
+
end
|
288
|
+
|
289
|
+
rx = nil
|
290
|
+
it "can be converted to a regex" do
|
291
|
+
rx = myprog.regexp
|
292
|
+
rx.class.should == Regexp
|
293
|
+
end
|
294
|
+
|
295
|
+
# Check sanity: Is test valid?
|
296
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
297
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
298
|
+
|
299
|
+
# Is compiled result valid?
|
300
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
301
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
302
|
+
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
### Test 7: POSIX class
|
308
|
+
|
309
|
+
describe "A correct program (POSIX class)" do
|
310
|
+
prog = <<-'END'
|
311
|
+
match %alnum end
|
312
|
+
END
|
313
|
+
|
314
|
+
good = ["abc365", "237", "xyz"]
|
315
|
+
bad = ["---", ":,.-"]
|
316
|
+
wanted = /[[:alnum:]]/
|
317
|
+
|
318
|
+
myprog = Program.new(prog)
|
319
|
+
parsed = nil
|
320
|
+
|
321
|
+
it "should parse correctly" do
|
322
|
+
parsed = myprog.parseable?
|
323
|
+
myprog.debug_bad_program_parse unless parsed
|
324
|
+
parsed.should == true
|
325
|
+
end
|
326
|
+
|
327
|
+
rx = nil
|
328
|
+
it "can be converted to a regex" do
|
329
|
+
rx = myprog.regexp
|
330
|
+
rx.class.should == Regexp
|
331
|
+
end
|
332
|
+
|
333
|
+
# Check sanity: Is test valid?
|
334
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
335
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
336
|
+
|
337
|
+
# Is compiled result valid?
|
338
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
339
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
340
|
+
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
|
345
|
+
### Test 8: Simple char class
|
346
|
+
|
347
|
+
describe "A correct program (Simple char class)" do
|
348
|
+
prog = <<-'END'
|
349
|
+
match 'prstu' end
|
350
|
+
END
|
351
|
+
|
352
|
+
good = ["du", "ppp", "sr"]
|
353
|
+
bad = ["abc", "xyz"]
|
354
|
+
wanted = /[prstu]/
|
355
|
+
|
356
|
+
myprog = Program.new(prog)
|
357
|
+
parsed = nil
|
358
|
+
|
359
|
+
it "should parse correctly" do
|
360
|
+
parsed = myprog.parseable?
|
361
|
+
myprog.debug_bad_program_parse unless parsed
|
362
|
+
parsed.should == true
|
363
|
+
end
|
364
|
+
|
365
|
+
rx = nil
|
366
|
+
it "can be converted to a regex" do
|
367
|
+
rx = myprog.regexp
|
368
|
+
rx.class.should == Regexp
|
369
|
+
end
|
370
|
+
|
371
|
+
# Check sanity: Is test valid?
|
372
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
373
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
374
|
+
|
375
|
+
# Is compiled result valid?
|
376
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
377
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
378
|
+
|
379
|
+
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
### Test 9: Negated char class
|
384
|
+
|
385
|
+
describe "A correct program (Negated char class)" do
|
386
|
+
prog = <<-'END'
|
387
|
+
match ~'ilmnop' end
|
388
|
+
END
|
389
|
+
|
390
|
+
good = ["abacus", "peccata", "hydrogen"]
|
391
|
+
bad = ["oil", "pill"]
|
392
|
+
wanted = /[^ilmnop]/
|
393
|
+
|
394
|
+
myprog = Program.new(prog)
|
395
|
+
parsed = nil
|
396
|
+
|
397
|
+
it "should parse correctly" do
|
398
|
+
parsed = myprog.parseable?
|
399
|
+
myprog.debug_bad_program_parse unless parsed
|
400
|
+
parsed.should == true
|
401
|
+
end
|
402
|
+
|
403
|
+
rx = nil
|
404
|
+
it "can be converted to a regex" do
|
405
|
+
rx = myprog.regexp
|
406
|
+
rx.class.should == Regexp
|
407
|
+
end
|
408
|
+
|
409
|
+
# Check sanity: Is test valid?
|
410
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
411
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
412
|
+
|
413
|
+
# Is compiled result valid?
|
414
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
415
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
416
|
+
|
417
|
+
|
418
|
+
end
|
419
|
+
|
420
|
+
|
421
|
+
### Test 10: Predef Beginning of string
|
422
|
+
|
423
|
+
describe "A correct program (Predef Beginning of string)" do
|
424
|
+
prog = <<-'END'
|
425
|
+
match BOS end
|
426
|
+
END
|
427
|
+
|
428
|
+
good = [""]
|
429
|
+
bad = []
|
430
|
+
wanted = /^/
|
431
|
+
|
432
|
+
myprog = Program.new(prog)
|
433
|
+
parsed = nil
|
434
|
+
|
435
|
+
it "should parse correctly" do
|
436
|
+
parsed = myprog.parseable?
|
437
|
+
myprog.debug_bad_program_parse unless parsed
|
438
|
+
parsed.should == true
|
439
|
+
end
|
440
|
+
|
441
|
+
rx = nil
|
442
|
+
it "can be converted to a regex" do
|
443
|
+
rx = myprog.regexp
|
444
|
+
rx.class.should == Regexp
|
445
|
+
end
|
446
|
+
|
447
|
+
# Check sanity: Is test valid?
|
448
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
449
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
450
|
+
|
451
|
+
# Is compiled result valid?
|
452
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
453
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
454
|
+
|
455
|
+
|
456
|
+
end
|
457
|
+
|
458
|
+
|
459
|
+
### Test 11: Predef End of string
|
460
|
+
|
461
|
+
describe "A correct program (Predef End of string)" do
|
462
|
+
prog = <<-'END'
|
463
|
+
match EOS end
|
464
|
+
END
|
465
|
+
|
466
|
+
good = [""]
|
467
|
+
bad = []
|
468
|
+
wanted = /$/
|
469
|
+
|
470
|
+
myprog = Program.new(prog)
|
471
|
+
parsed = nil
|
472
|
+
|
473
|
+
it "should parse correctly" do
|
474
|
+
parsed = myprog.parseable?
|
475
|
+
myprog.debug_bad_program_parse unless parsed
|
476
|
+
parsed.should == true
|
477
|
+
end
|
478
|
+
|
479
|
+
rx = nil
|
480
|
+
it "can be converted to a regex" do
|
481
|
+
rx = myprog.regexp
|
482
|
+
rx.class.should == Regexp
|
483
|
+
end
|
484
|
+
|
485
|
+
# Check sanity: Is test valid?
|
486
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
487
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
488
|
+
|
489
|
+
# Is compiled result valid?
|
490
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
491
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
492
|
+
|
493
|
+
|
494
|
+
end
|
495
|
+
|
496
|
+
|
497
|
+
### Test 12: Predef Word boundary
|
498
|
+
|
499
|
+
describe "A correct program (Predef Word boundary)" do
|
500
|
+
prog = <<-'END'
|
501
|
+
match WB end
|
502
|
+
END
|
503
|
+
|
504
|
+
good = ["xyz"]
|
505
|
+
bad = ["", "---"]
|
506
|
+
wanted = /\b/
|
507
|
+
|
508
|
+
myprog = Program.new(prog)
|
509
|
+
parsed = nil
|
510
|
+
|
511
|
+
it "should parse correctly" do
|
512
|
+
parsed = myprog.parseable?
|
513
|
+
myprog.debug_bad_program_parse unless parsed
|
514
|
+
parsed.should == true
|
515
|
+
end
|
516
|
+
|
517
|
+
rx = nil
|
518
|
+
it "can be converted to a regex" do
|
519
|
+
rx = myprog.regexp
|
520
|
+
rx.class.should == Regexp
|
521
|
+
end
|
522
|
+
|
523
|
+
# Check sanity: Is test valid?
|
524
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
525
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
526
|
+
|
527
|
+
# Is compiled result valid?
|
528
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
529
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
530
|
+
|
531
|
+
|
532
|
+
end
|
533
|
+
|
534
|
+
|
535
|
+
### Test 13: Simple string
|
536
|
+
|
537
|
+
describe "A correct program (Simple string)" do
|
538
|
+
prog = <<-'END'
|
539
|
+
match "xyz" end
|
540
|
+
END
|
541
|
+
|
542
|
+
good = ["xyz", "abcxyzdef"]
|
543
|
+
bad = ["abc", "xydefz"]
|
544
|
+
wanted = /xyz/
|
545
|
+
|
546
|
+
myprog = Program.new(prog)
|
547
|
+
parsed = nil
|
548
|
+
|
549
|
+
it "should parse correctly" do
|
550
|
+
parsed = myprog.parseable?
|
551
|
+
myprog.debug_bad_program_parse unless parsed
|
552
|
+
parsed.should == true
|
553
|
+
end
|
554
|
+
|
555
|
+
rx = nil
|
556
|
+
it "can be converted to a regex" do
|
557
|
+
rx = myprog.regexp
|
558
|
+
rx.class.should == Regexp
|
559
|
+
end
|
560
|
+
|
561
|
+
# Check sanity: Is test valid?
|
562
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
563
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
564
|
+
|
565
|
+
# Is compiled result valid?
|
566
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
567
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
568
|
+
|
569
|
+
|
570
|
+
end
|
571
|
+
|
572
|
+
|
573
|
+
### Test 14: Single-bounded repetition
|
574
|
+
|
575
|
+
describe "A correct program (Single-bounded repetition)" do
|
576
|
+
prog = <<-'END'
|
577
|
+
match 5 * "xyz" end
|
578
|
+
END
|
579
|
+
|
580
|
+
good = ["xyzxyzxyzxyzxyz"]
|
581
|
+
bad = ["xyzxyzxyzxyz"]
|
582
|
+
wanted = /(xyz){5}/
|
583
|
+
|
584
|
+
myprog = Program.new(prog)
|
585
|
+
parsed = nil
|
586
|
+
|
587
|
+
it "should parse correctly" do
|
588
|
+
parsed = myprog.parseable?
|
589
|
+
myprog.debug_bad_program_parse unless parsed
|
590
|
+
parsed.should == true
|
591
|
+
end
|
592
|
+
|
593
|
+
rx = nil
|
594
|
+
it "can be converted to a regex" do
|
595
|
+
rx = myprog.regexp
|
596
|
+
rx.class.should == Regexp
|
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
|
+
|
607
|
+
|
608
|
+
end
|
609
|
+
|
610
|
+
|
611
|
+
### Test 15: Double-bounded repetition
|
612
|
+
|
613
|
+
describe "A correct program (Double-bounded repetition)" do
|
614
|
+
prog = <<-'END'
|
615
|
+
match 3,4 * %alpha end
|
616
|
+
END
|
617
|
+
|
618
|
+
good = ["abc", "abcd"]
|
619
|
+
bad = ["ab", "x"]
|
620
|
+
wanted = /([[:alpha:]]){3,4}/
|
621
|
+
|
622
|
+
myprog = Program.new(prog)
|
623
|
+
parsed = nil
|
624
|
+
|
625
|
+
it "should parse correctly" do
|
626
|
+
parsed = myprog.parseable?
|
627
|
+
myprog.debug_bad_program_parse unless parsed
|
628
|
+
parsed.should == true
|
629
|
+
end
|
630
|
+
|
631
|
+
rx = nil
|
632
|
+
it "can be converted to a regex" do
|
633
|
+
rx = myprog.regexp
|
634
|
+
rx.class.should == Regexp
|
635
|
+
end
|
636
|
+
|
637
|
+
# Check sanity: Is test valid?
|
638
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
639
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
640
|
+
|
641
|
+
# Is compiled result valid?
|
642
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
643
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
644
|
+
|
645
|
+
|
646
|
+
end
|
647
|
+
|
648
|
+
|
649
|
+
### Test 16: any-qualifier
|
650
|
+
|
651
|
+
describe "A correct program (any-qualifier)" do
|
652
|
+
prog = <<-'END'
|
653
|
+
match any "abc" end
|
654
|
+
END
|
655
|
+
|
656
|
+
good = ["", "abc", "abcabc", "xyz"]
|
657
|
+
bad = []
|
658
|
+
wanted = /(abc)*/
|
659
|
+
|
660
|
+
myprog = Program.new(prog)
|
661
|
+
parsed = nil
|
662
|
+
|
663
|
+
it "should parse correctly" do
|
664
|
+
parsed = myprog.parseable?
|
665
|
+
myprog.debug_bad_program_parse unless parsed
|
666
|
+
parsed.should == true
|
667
|
+
end
|
668
|
+
|
669
|
+
rx = nil
|
670
|
+
it "can be converted to a regex" do
|
671
|
+
rx = myprog.regexp
|
672
|
+
rx.class.should == Regexp
|
673
|
+
end
|
674
|
+
|
675
|
+
# Check sanity: Is test valid?
|
676
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
677
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
678
|
+
|
679
|
+
# Is compiled result valid?
|
680
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
681
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
682
|
+
|
683
|
+
|
684
|
+
end
|
685
|
+
|
686
|
+
|
687
|
+
### Test 17: many-qualifier
|
688
|
+
|
689
|
+
describe "A correct program (many-qualifier)" do
|
690
|
+
prog = <<-'END'
|
691
|
+
match many "def" end
|
692
|
+
END
|
693
|
+
|
694
|
+
good = ["def", "defdef", "defdefdef"]
|
695
|
+
bad = ["", "de", "xyz"]
|
696
|
+
wanted = /(def)+/
|
697
|
+
|
698
|
+
myprog = Program.new(prog)
|
699
|
+
parsed = nil
|
700
|
+
|
701
|
+
it "should parse correctly" do
|
702
|
+
parsed = myprog.parseable?
|
703
|
+
myprog.debug_bad_program_parse unless parsed
|
704
|
+
parsed.should == true
|
705
|
+
end
|
706
|
+
|
707
|
+
rx = nil
|
708
|
+
it "can be converted to a regex" do
|
709
|
+
rx = myprog.regexp
|
710
|
+
rx.class.should == Regexp
|
711
|
+
end
|
712
|
+
|
713
|
+
# Check sanity: Is test valid?
|
714
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
715
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
716
|
+
|
717
|
+
# Is compiled result valid?
|
718
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
719
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
720
|
+
|
721
|
+
|
722
|
+
end
|
723
|
+
|
724
|
+
|
725
|
+
### Test 18: nocase-qualifier
|
726
|
+
|
727
|
+
describe "A correct program (nocase-qualifier)" do
|
728
|
+
prog = <<-'END'
|
729
|
+
match nocase "ghi" end
|
730
|
+
END
|
731
|
+
|
732
|
+
good = ["ghi", "GHI", "abGhicd"]
|
733
|
+
bad = ["", "gh", "abc"]
|
734
|
+
wanted = /((?i)ghi)/
|
735
|
+
|
736
|
+
myprog = Program.new(prog)
|
737
|
+
parsed = nil
|
738
|
+
|
739
|
+
it "should parse correctly" do
|
740
|
+
parsed = myprog.parseable?
|
741
|
+
myprog.debug_bad_program_parse unless parsed
|
742
|
+
parsed.should == true
|
743
|
+
end
|
744
|
+
|
745
|
+
rx = nil
|
746
|
+
it "can be converted to a regex" do
|
747
|
+
rx = myprog.regexp
|
748
|
+
rx.class.should == Regexp
|
749
|
+
end
|
750
|
+
|
751
|
+
# Check sanity: Is test valid?
|
752
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
753
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
754
|
+
|
755
|
+
# Is compiled result valid?
|
756
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
757
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
758
|
+
|
759
|
+
|
760
|
+
end
|
761
|
+
|
762
|
+
|
763
|
+
### Test 19: maybe-qualifier
|
764
|
+
|
765
|
+
describe "A correct program (maybe-qualifier)" do
|
766
|
+
prog = <<-'END'
|
767
|
+
match maybe "ghi" end
|
768
|
+
END
|
769
|
+
|
770
|
+
good = ["", "ghi", "abghicd", "gh"]
|
771
|
+
bad = []
|
772
|
+
wanted = /(ghi)?/
|
773
|
+
|
774
|
+
myprog = Program.new(prog)
|
775
|
+
parsed = nil
|
776
|
+
|
777
|
+
it "should parse correctly" do
|
778
|
+
parsed = myprog.parseable?
|
779
|
+
myprog.debug_bad_program_parse unless parsed
|
780
|
+
parsed.should == true
|
781
|
+
end
|
782
|
+
|
783
|
+
rx = nil
|
784
|
+
it "can be converted to a regex" do
|
785
|
+
rx = myprog.regexp
|
786
|
+
rx.class.should == Regexp
|
787
|
+
end
|
788
|
+
|
789
|
+
# Check sanity: Is test valid?
|
790
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
791
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
792
|
+
|
793
|
+
# Is compiled result valid?
|
794
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
795
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
796
|
+
|
797
|
+
|
798
|
+
end
|
799
|
+
|
800
|
+
|
801
|
+
### Test 20: Simple concatenation of two strings
|
802
|
+
|
803
|
+
describe "A correct program (Simple concatenation of two strings)" do
|
804
|
+
prog = <<-'END'
|
805
|
+
match "abc" "def" end
|
806
|
+
END
|
807
|
+
|
808
|
+
good = ["abcdefghi", "xyzabcdef"]
|
809
|
+
bad = ["", "abcxyzdef"]
|
810
|
+
wanted = /abcdef/
|
811
|
+
|
812
|
+
myprog = Program.new(prog)
|
813
|
+
parsed = nil
|
814
|
+
|
815
|
+
it "should parse correctly" do
|
816
|
+
parsed = myprog.parseable?
|
817
|
+
myprog.debug_bad_program_parse unless parsed
|
818
|
+
parsed.should == true
|
819
|
+
end
|
820
|
+
|
821
|
+
rx = nil
|
822
|
+
it "can be converted to a regex" do
|
823
|
+
rx = myprog.regexp
|
824
|
+
rx.class.should == Regexp
|
825
|
+
end
|
826
|
+
|
827
|
+
# Check sanity: Is test valid?
|
828
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
829
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
830
|
+
|
831
|
+
# Is compiled result valid?
|
832
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
833
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
834
|
+
|
835
|
+
|
836
|
+
end
|
837
|
+
|
838
|
+
|
839
|
+
### Test 21: Concat of string and char class
|
840
|
+
|
841
|
+
describe "A correct program (Concat of string and char class)" do
|
842
|
+
prog = <<-'END'
|
843
|
+
match "abc"'def' end
|
844
|
+
END
|
845
|
+
|
846
|
+
good = ["abcd", "abce"]
|
847
|
+
bad = ["", "abcx"]
|
848
|
+
wanted = /abc[def]/
|
849
|
+
|
850
|
+
myprog = Program.new(prog)
|
851
|
+
parsed = nil
|
852
|
+
|
853
|
+
it "should parse correctly" do
|
854
|
+
parsed = myprog.parseable?
|
855
|
+
myprog.debug_bad_program_parse unless parsed
|
856
|
+
parsed.should == true
|
857
|
+
end
|
858
|
+
|
859
|
+
rx = nil
|
860
|
+
it "can be converted to a regex" do
|
861
|
+
rx = myprog.regexp
|
862
|
+
rx.class.should == Regexp
|
863
|
+
end
|
864
|
+
|
865
|
+
# Check sanity: Is test valid?
|
866
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
867
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
868
|
+
|
869
|
+
# Is compiled result valid?
|
870
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
871
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
872
|
+
|
873
|
+
|
874
|
+
end
|
875
|
+
|
876
|
+
|
877
|
+
### Test 22: Simple alternation
|
878
|
+
|
879
|
+
describe "A correct program (Simple alternation)" do
|
880
|
+
prog = <<-'END'
|
881
|
+
match "abc" | "def" end
|
882
|
+
END
|
883
|
+
|
884
|
+
good = ["abc", "xyzabc123", "xdefy"]
|
885
|
+
bad = ["", "abde", "ab c d ef"]
|
886
|
+
wanted = /(abc|def)/
|
887
|
+
|
888
|
+
myprog = Program.new(prog)
|
889
|
+
parsed = nil
|
890
|
+
|
891
|
+
it "should parse correctly" do
|
892
|
+
parsed = myprog.parseable?
|
893
|
+
myprog.debug_bad_program_parse unless parsed
|
894
|
+
parsed.should == true
|
895
|
+
end
|
896
|
+
|
897
|
+
rx = nil
|
898
|
+
it "can be converted to a regex" do
|
899
|
+
rx = myprog.regexp
|
900
|
+
rx.class.should == Regexp
|
901
|
+
end
|
902
|
+
|
903
|
+
# Check sanity: Is test valid?
|
904
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
905
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
906
|
+
|
907
|
+
# Is compiled result valid?
|
908
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
909
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
910
|
+
|
911
|
+
|
912
|
+
end
|
913
|
+
|
914
|
+
|
915
|
+
### Test 23: Alternation of concatenations
|
916
|
+
|
917
|
+
describe "A correct program (Alternation of concatenations)" do
|
918
|
+
prog = <<-'END'
|
919
|
+
match "ab" "c" | "d" "ef" end
|
920
|
+
END
|
921
|
+
|
922
|
+
good = ["abc", "xyzabc123", "xdefy"]
|
923
|
+
bad = ["", "abde", "ab c d ef"]
|
924
|
+
wanted = /(abc|def)/
|
925
|
+
|
926
|
+
myprog = Program.new(prog)
|
927
|
+
parsed = nil
|
928
|
+
|
929
|
+
it "should parse correctly" do
|
930
|
+
parsed = myprog.parseable?
|
931
|
+
myprog.debug_bad_program_parse unless parsed
|
932
|
+
parsed.should == true
|
933
|
+
end
|
934
|
+
|
935
|
+
rx = nil
|
936
|
+
it "can be converted to a regex" do
|
937
|
+
rx = myprog.regexp
|
938
|
+
rx.class.should == Regexp
|
939
|
+
end
|
940
|
+
|
941
|
+
# Check sanity: Is test valid?
|
942
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
943
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
944
|
+
|
945
|
+
# Is compiled result valid?
|
946
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
947
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
948
|
+
|
949
|
+
|
950
|
+
end
|
951
|
+
|
952
|
+
|
953
|
+
### Test 24: Precedence of concatenation over alternation
|
954
|
+
|
955
|
+
describe "A correct program (Precedence of concatenation over alternation)" do
|
956
|
+
prog = <<-'END'
|
957
|
+
match "a" "b" | "c" end
|
958
|
+
END
|
959
|
+
|
960
|
+
good = ["ab", "c"]
|
961
|
+
bad = ["b", "a", "d"]
|
962
|
+
wanted = /(ab|c)/
|
963
|
+
|
964
|
+
myprog = Program.new(prog)
|
965
|
+
parsed = nil
|
966
|
+
|
967
|
+
it "should parse correctly" do
|
968
|
+
parsed = myprog.parseable?
|
969
|
+
myprog.debug_bad_program_parse unless parsed
|
970
|
+
parsed.should == true
|
971
|
+
end
|
972
|
+
|
973
|
+
rx = nil
|
974
|
+
it "can be converted to a regex" do
|
975
|
+
rx = myprog.regexp
|
976
|
+
rx.class.should == Regexp
|
977
|
+
end
|
978
|
+
|
979
|
+
# Check sanity: Is test valid?
|
980
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
981
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
982
|
+
|
983
|
+
# Is compiled result valid?
|
984
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
985
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
986
|
+
|
987
|
+
|
988
|
+
end
|
989
|
+
|
990
|
+
|
991
|
+
### Test 25: Precedence of parens over concatenation
|
992
|
+
|
993
|
+
describe "A correct program (Precedence of parens over concatenation)" do
|
994
|
+
prog = <<-'END'
|
995
|
+
match "a" ("b" | "c") end
|
996
|
+
END
|
997
|
+
|
998
|
+
good = ["ab", "ac"]
|
999
|
+
bad = ["a", "b", "c"]
|
1000
|
+
wanted = /a(b|c)/
|
1001
|
+
|
1002
|
+
myprog = Program.new(prog)
|
1003
|
+
parsed = nil
|
1004
|
+
|
1005
|
+
it "should parse correctly" do
|
1006
|
+
parsed = myprog.parseable?
|
1007
|
+
myprog.debug_bad_program_parse unless parsed
|
1008
|
+
parsed.should == true
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
rx = nil
|
1012
|
+
it "can be converted to a regex" do
|
1013
|
+
rx = myprog.regexp
|
1014
|
+
rx.class.should == Regexp
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
# Check sanity: Is test valid?
|
1018
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1019
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1020
|
+
|
1021
|
+
# Is compiled result valid?
|
1022
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1023
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1024
|
+
|
1025
|
+
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
|
1029
|
+
### Test 26: Anchors and alternation
|
1030
|
+
|
1031
|
+
describe "A correct program (Anchors and alternation)" do
|
1032
|
+
prog = <<-'END'
|
1033
|
+
match BOS "x" | "y" EOS end
|
1034
|
+
END
|
1035
|
+
|
1036
|
+
good = ["xabc", "abcy"]
|
1037
|
+
bad = ["abc", "abcx", "yabc", "axb", "ayb", "axyb"]
|
1038
|
+
wanted = /(^x|y$)/
|
1039
|
+
|
1040
|
+
myprog = Program.new(prog)
|
1041
|
+
parsed = nil
|
1042
|
+
|
1043
|
+
it "should parse correctly" do
|
1044
|
+
parsed = myprog.parseable?
|
1045
|
+
myprog.debug_bad_program_parse unless parsed
|
1046
|
+
parsed.should == true
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
rx = nil
|
1050
|
+
it "can be converted to a regex" do
|
1051
|
+
rx = myprog.regexp
|
1052
|
+
rx.class.should == Regexp
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
# Check sanity: Is test valid?
|
1056
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1057
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1058
|
+
|
1059
|
+
# Is compiled result valid?
|
1060
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1061
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1062
|
+
|
1063
|
+
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
|
1067
|
+
### Test 27: Anchors, alternation, parens
|
1068
|
+
|
1069
|
+
describe "A correct program (Anchors, alternation, parens)" do
|
1070
|
+
prog = <<-'END'
|
1071
|
+
match BOS ("x" | "y") EOS end
|
1072
|
+
END
|
1073
|
+
|
1074
|
+
good = ["x", "y"]
|
1075
|
+
bad = ["abc", "abcx", "yabc", "xabc", "abcy"]
|
1076
|
+
wanted = /^(x|y)$/
|
1077
|
+
|
1078
|
+
myprog = Program.new(prog)
|
1079
|
+
parsed = nil
|
1080
|
+
|
1081
|
+
it "should parse correctly" do
|
1082
|
+
parsed = myprog.parseable?
|
1083
|
+
myprog.debug_bad_program_parse unless parsed
|
1084
|
+
parsed.should == true
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
rx = nil
|
1088
|
+
it "can be converted to a regex" do
|
1089
|
+
rx = myprog.regexp
|
1090
|
+
rx.class.should == Regexp
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
# Check sanity: Is test valid?
|
1094
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1095
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1096
|
+
|
1097
|
+
# Is compiled result valid?
|
1098
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1099
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1100
|
+
|
1101
|
+
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
|
1105
|
+
### Test 28: Parens, concatenation, alternation
|
1106
|
+
|
1107
|
+
describe "A correct program (Parens, concatenation, alternation)" do
|
1108
|
+
prog = <<-'END'
|
1109
|
+
match BOS ((maybe `0) `1-`9 | `1 D2) EOS end
|
1110
|
+
END
|
1111
|
+
|
1112
|
+
good = ["01", "09", "12"]
|
1113
|
+
bad = ["0", "00", "13"]
|
1114
|
+
wanted = /^((0)?[1-9]|1[0-2])$/
|
1115
|
+
|
1116
|
+
myprog = Program.new(prog)
|
1117
|
+
parsed = nil
|
1118
|
+
|
1119
|
+
it "should parse correctly" do
|
1120
|
+
parsed = myprog.parseable?
|
1121
|
+
myprog.debug_bad_program_parse unless parsed
|
1122
|
+
parsed.should == true
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
rx = nil
|
1126
|
+
it "can be converted to a regex" do
|
1127
|
+
rx = myprog.regexp
|
1128
|
+
rx.class.should == Regexp
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
# Check sanity: Is test valid?
|
1132
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1133
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1134
|
+
|
1135
|
+
# Is compiled result valid?
|
1136
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1137
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1138
|
+
|
1139
|
+
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
|
1143
|
+
### Test 29: Single backtick char
|
1144
|
+
|
1145
|
+
describe "A correct program (Single backtick char)" do
|
1146
|
+
prog = <<-'END'
|
1147
|
+
match `` end
|
1148
|
+
END
|
1149
|
+
|
1150
|
+
good = ["`", "this is a tick: `", "tock ` tock"]
|
1151
|
+
bad = ["", "abc"]
|
1152
|
+
wanted = /`/
|
1153
|
+
|
1154
|
+
myprog = Program.new(prog)
|
1155
|
+
parsed = nil
|
1156
|
+
|
1157
|
+
it "should parse correctly" do
|
1158
|
+
parsed = myprog.parseable?
|
1159
|
+
myprog.debug_bad_program_parse unless parsed
|
1160
|
+
parsed.should == true
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
rx = nil
|
1164
|
+
it "can be converted to a regex" do
|
1165
|
+
rx = myprog.regexp
|
1166
|
+
rx.class.should == Regexp
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
# Check sanity: Is test valid?
|
1170
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1171
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1172
|
+
|
1173
|
+
# Is compiled result valid?
|
1174
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1175
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1176
|
+
|
1177
|
+
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
|
1181
|
+
### Test 30: Single backslash char
|
1182
|
+
|
1183
|
+
describe "A correct program (Single backslash char)" do
|
1184
|
+
prog = <<-'END'
|
1185
|
+
match `\ end
|
1186
|
+
END
|
1187
|
+
|
1188
|
+
good = ["\\", "trying \\n", "and \\b also"]
|
1189
|
+
bad = ["\n", "\b", "neither \r nor \t"]
|
1190
|
+
wanted = /\\/
|
1191
|
+
|
1192
|
+
myprog = Program.new(prog)
|
1193
|
+
parsed = nil
|
1194
|
+
|
1195
|
+
it "should parse correctly" do
|
1196
|
+
parsed = myprog.parseable?
|
1197
|
+
myprog.debug_bad_program_parse unless parsed
|
1198
|
+
parsed.should == true
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
rx = nil
|
1202
|
+
it "can be converted to a regex" do
|
1203
|
+
rx = myprog.regexp
|
1204
|
+
rx.class.should == Regexp
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
# Check sanity: Is test valid?
|
1208
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1209
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1210
|
+
|
1211
|
+
# Is compiled result valid?
|
1212
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1213
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1214
|
+
|
1215
|
+
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
|
1219
|
+
### Test 31: Empty string
|
1220
|
+
|
1221
|
+
describe "A correct program (Empty string)" do
|
1222
|
+
prog = <<-'END'
|
1223
|
+
match "" end
|
1224
|
+
END
|
1225
|
+
|
1226
|
+
good = ["", "abc"]
|
1227
|
+
bad = []
|
1228
|
+
wanted = //
|
1229
|
+
|
1230
|
+
myprog = Program.new(prog)
|
1231
|
+
parsed = nil
|
1232
|
+
|
1233
|
+
it "should parse correctly" do
|
1234
|
+
parsed = myprog.parseable?
|
1235
|
+
myprog.debug_bad_program_parse unless parsed
|
1236
|
+
parsed.should == true
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
rx = nil
|
1240
|
+
it "can be converted to a regex" do
|
1241
|
+
rx = myprog.regexp
|
1242
|
+
rx.class.should == Regexp
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
# Check sanity: Is test valid?
|
1246
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1247
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1248
|
+
|
1249
|
+
# Is compiled result valid?
|
1250
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1251
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1252
|
+
|
1253
|
+
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
|
1257
|
+
### Test 32: Simple char class
|
1258
|
+
|
1259
|
+
describe "A correct program (Simple char class)" do
|
1260
|
+
prog = <<-'END'
|
1261
|
+
match 'abcdef' end
|
1262
|
+
END
|
1263
|
+
|
1264
|
+
good = ["there's a cat here", "item c"]
|
1265
|
+
bad = ["", "proton"]
|
1266
|
+
wanted = /[abcdef]/
|
1267
|
+
|
1268
|
+
myprog = Program.new(prog)
|
1269
|
+
parsed = nil
|
1270
|
+
|
1271
|
+
it "should parse correctly" do
|
1272
|
+
parsed = myprog.parseable?
|
1273
|
+
myprog.debug_bad_program_parse unless parsed
|
1274
|
+
parsed.should == true
|
1275
|
+
end
|
1276
|
+
|
1277
|
+
rx = nil
|
1278
|
+
it "can be converted to a regex" do
|
1279
|
+
rx = myprog.regexp
|
1280
|
+
rx.class.should == Regexp
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
# Check sanity: Is test valid?
|
1284
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1285
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1286
|
+
|
1287
|
+
# Is compiled result valid?
|
1288
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1289
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1290
|
+
|
1291
|
+
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
|
1295
|
+
### Test 33: Simple one-char class
|
1296
|
+
|
1297
|
+
describe "A correct program (Simple one-char class)" do
|
1298
|
+
prog = <<-'END'
|
1299
|
+
match 'x' end
|
1300
|
+
END
|
1301
|
+
|
1302
|
+
good = ["x", "uvwxyz"]
|
1303
|
+
bad = ["", "abc"]
|
1304
|
+
wanted = /[x]/
|
1305
|
+
|
1306
|
+
myprog = Program.new(prog)
|
1307
|
+
parsed = nil
|
1308
|
+
|
1309
|
+
it "should parse correctly" do
|
1310
|
+
parsed = myprog.parseable?
|
1311
|
+
myprog.debug_bad_program_parse unless parsed
|
1312
|
+
parsed.should == true
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
rx = nil
|
1316
|
+
it "can be converted to a regex" do
|
1317
|
+
rx = myprog.regexp
|
1318
|
+
rx.class.should == Regexp
|
1319
|
+
end
|
1320
|
+
|
1321
|
+
# Check sanity: Is test valid?
|
1322
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1323
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1324
|
+
|
1325
|
+
# Is compiled result valid?
|
1326
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1327
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1328
|
+
|
1329
|
+
|
1330
|
+
end
|
1331
|
+
|
1332
|
+
|
1333
|
+
### Test 34: Alternation of range and class
|
1334
|
+
|
1335
|
+
describe "A correct program (Alternation of range and class)" do
|
1336
|
+
prog = <<-'END'
|
1337
|
+
match `a-`f | 'xyz' end
|
1338
|
+
END
|
1339
|
+
|
1340
|
+
good = ["a", "x", "z", "c"]
|
1341
|
+
bad = ["", "jkl", "gw"]
|
1342
|
+
wanted = /([a-f]|[xyz])/
|
1343
|
+
|
1344
|
+
myprog = Program.new(prog)
|
1345
|
+
parsed = nil
|
1346
|
+
|
1347
|
+
it "should parse correctly" do
|
1348
|
+
parsed = myprog.parseable?
|
1349
|
+
myprog.debug_bad_program_parse unless parsed
|
1350
|
+
parsed.should == true
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
rx = nil
|
1354
|
+
it "can be converted to a regex" do
|
1355
|
+
rx = myprog.regexp
|
1356
|
+
rx.class.should == Regexp
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
# Check sanity: Is test valid?
|
1360
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1361
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1362
|
+
|
1363
|
+
# Is compiled result valid?
|
1364
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1365
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1366
|
+
|
1367
|
+
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
|
1371
|
+
### Test 35: Alternation of range and maybe-clause
|
1372
|
+
|
1373
|
+
describe "A correct program (Alternation of range and maybe-clause)" do
|
1374
|
+
prog = <<-'END'
|
1375
|
+
match `1-`6| maybe "#" end
|
1376
|
+
END
|
1377
|
+
|
1378
|
+
good = ["", "1#", "1", " 2# abc"]
|
1379
|
+
bad = []
|
1380
|
+
wanted = /([1-6]|(\#)?)/
|
1381
|
+
|
1382
|
+
myprog = Program.new(prog)
|
1383
|
+
parsed = nil
|
1384
|
+
|
1385
|
+
it "should parse correctly" do
|
1386
|
+
parsed = myprog.parseable?
|
1387
|
+
myprog.debug_bad_program_parse unless parsed
|
1388
|
+
parsed.should == true
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
rx = nil
|
1392
|
+
it "can be converted to a regex" do
|
1393
|
+
rx = myprog.regexp
|
1394
|
+
rx.class.should == Regexp
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
# Check sanity: Is test valid?
|
1398
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1399
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1400
|
+
|
1401
|
+
# Is compiled result valid?
|
1402
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1403
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1404
|
+
|
1405
|
+
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
|
1409
|
+
### Test 36: Four-way alternation
|
1410
|
+
|
1411
|
+
describe "A correct program (Four-way alternation)" do
|
1412
|
+
prog = <<-'END'
|
1413
|
+
match `a | `b|`c|`d end
|
1414
|
+
END
|
1415
|
+
|
1416
|
+
good = ["xyza", "xybz", "xcyz", "dxyz"]
|
1417
|
+
bad = ["", "every", "ghijk"]
|
1418
|
+
wanted = /(a|b|c|d)/
|
1419
|
+
|
1420
|
+
myprog = Program.new(prog)
|
1421
|
+
parsed = nil
|
1422
|
+
|
1423
|
+
it "should parse correctly" do
|
1424
|
+
parsed = myprog.parseable?
|
1425
|
+
myprog.debug_bad_program_parse unless parsed
|
1426
|
+
parsed.should == true
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
rx = nil
|
1430
|
+
it "can be converted to a regex" do
|
1431
|
+
rx = myprog.regexp
|
1432
|
+
rx.class.should == Regexp
|
1433
|
+
end
|
1434
|
+
|
1435
|
+
# Check sanity: Is test valid?
|
1436
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1437
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1438
|
+
|
1439
|
+
# Is compiled result valid?
|
1440
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1441
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1442
|
+
|
1443
|
+
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
|
1447
|
+
### Test 37: Concatenation of range and class
|
1448
|
+
|
1449
|
+
describe "A correct program (Concatenation of range and class)" do
|
1450
|
+
prog = <<-'END'
|
1451
|
+
match `a-`f 'xyz' end
|
1452
|
+
END
|
1453
|
+
|
1454
|
+
good = ["ax", "fz", "cy"]
|
1455
|
+
bad = ["zf", "xa", "gz", "hp", "mx"]
|
1456
|
+
wanted = /[a-f][xyz]/
|
1457
|
+
|
1458
|
+
myprog = Program.new(prog)
|
1459
|
+
parsed = nil
|
1460
|
+
|
1461
|
+
it "should parse correctly" do
|
1462
|
+
parsed = myprog.parseable?
|
1463
|
+
myprog.debug_bad_program_parse unless parsed
|
1464
|
+
parsed.should == true
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
rx = nil
|
1468
|
+
it "can be converted to a regex" do
|
1469
|
+
rx = myprog.regexp
|
1470
|
+
rx.class.should == Regexp
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
# Check sanity: Is test valid?
|
1474
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1475
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1476
|
+
|
1477
|
+
# Is compiled result valid?
|
1478
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1479
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1480
|
+
|
1481
|
+
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
|
1485
|
+
### Test 38: Concat of strings and maybe-clause
|
1486
|
+
|
1487
|
+
describe "A correct program (Concat of strings and maybe-clause)" do
|
1488
|
+
prog = <<-'END'
|
1489
|
+
match "this" "that" maybe "other" end
|
1490
|
+
END
|
1491
|
+
|
1492
|
+
good = ["thisthat", "thisthatother", "abc thisthat xyz", "abc thisthatother xyz"]
|
1493
|
+
bad = ["", "abc", "this that", "this that other"]
|
1494
|
+
wanted = /thisthat(other)?/
|
1495
|
+
|
1496
|
+
myprog = Program.new(prog)
|
1497
|
+
parsed = nil
|
1498
|
+
|
1499
|
+
it "should parse correctly" do
|
1500
|
+
parsed = myprog.parseable?
|
1501
|
+
myprog.debug_bad_program_parse unless parsed
|
1502
|
+
parsed.should == true
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
rx = nil
|
1506
|
+
it "can be converted to a regex" do
|
1507
|
+
rx = myprog.regexp
|
1508
|
+
rx.class.should == Regexp
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
# Check sanity: Is test valid?
|
1512
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1513
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1514
|
+
|
1515
|
+
# Is compiled result valid?
|
1516
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1517
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1518
|
+
|
1519
|
+
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
|
1523
|
+
### Test 39: Simple repetition of class
|
1524
|
+
|
1525
|
+
describe "A correct program (Simple repetition of class)" do
|
1526
|
+
prog = <<-'END'
|
1527
|
+
match 3 * 'xyz' end
|
1528
|
+
END
|
1529
|
+
|
1530
|
+
good = ["xyz", "xxx", "yzy", "xyzzy123"]
|
1531
|
+
bad = ["", "abc", "xy", "axy", "xyb", "axyb"]
|
1532
|
+
wanted = /([xyz]){3}/
|
1533
|
+
|
1534
|
+
myprog = Program.new(prog)
|
1535
|
+
parsed = nil
|
1536
|
+
|
1537
|
+
it "should parse correctly" do
|
1538
|
+
parsed = myprog.parseable?
|
1539
|
+
myprog.debug_bad_program_parse unless parsed
|
1540
|
+
parsed.should == true
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
rx = nil
|
1544
|
+
it "can be converted to a regex" do
|
1545
|
+
rx = myprog.regexp
|
1546
|
+
rx.class.should == Regexp
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
# Check sanity: Is test valid?
|
1550
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1551
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1552
|
+
|
1553
|
+
# Is compiled result valid?
|
1554
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1555
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1556
|
+
|
1557
|
+
|
1558
|
+
end
|
1559
|
+
|
1560
|
+
|
1561
|
+
### Test 40: Simple repetition of range
|
1562
|
+
|
1563
|
+
describe "A correct program (Simple repetition of range)" do
|
1564
|
+
prog = <<-'END'
|
1565
|
+
match 4 * `1-`6 end
|
1566
|
+
END
|
1567
|
+
|
1568
|
+
good = ["1111", "1234", "abc 6543 def"]
|
1569
|
+
bad = ["", "abc", "123", "123 4"]
|
1570
|
+
wanted = /([1-6]){4}/
|
1571
|
+
|
1572
|
+
myprog = Program.new(prog)
|
1573
|
+
parsed = nil
|
1574
|
+
|
1575
|
+
it "should parse correctly" do
|
1576
|
+
parsed = myprog.parseable?
|
1577
|
+
myprog.debug_bad_program_parse unless parsed
|
1578
|
+
parsed.should == true
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
rx = nil
|
1582
|
+
it "can be converted to a regex" do
|
1583
|
+
rx = myprog.regexp
|
1584
|
+
rx.class.should == Regexp
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
# Check sanity: Is test valid?
|
1588
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1589
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1590
|
+
|
1591
|
+
# Is compiled result valid?
|
1592
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1593
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1594
|
+
|
1595
|
+
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
|
1599
|
+
### Test 41: Complex repetition of char
|
1600
|
+
|
1601
|
+
describe "A correct program (Complex repetition of char)" do
|
1602
|
+
prog = <<-'END'
|
1603
|
+
match 3,5 * (`a) end
|
1604
|
+
END
|
1605
|
+
|
1606
|
+
good = ["aaa", "aaaa", "aaaaa", "xaaay", "aaaaaaa"]
|
1607
|
+
bad = ["", "abc", "aa"]
|
1608
|
+
wanted = /(a){3,5}/
|
1609
|
+
|
1610
|
+
myprog = Program.new(prog)
|
1611
|
+
parsed = nil
|
1612
|
+
|
1613
|
+
it "should parse correctly" do
|
1614
|
+
parsed = myprog.parseable?
|
1615
|
+
myprog.debug_bad_program_parse unless parsed
|
1616
|
+
parsed.should == true
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
rx = nil
|
1620
|
+
it "can be converted to a regex" do
|
1621
|
+
rx = myprog.regexp
|
1622
|
+
rx.class.should == Regexp
|
1623
|
+
end
|
1624
|
+
|
1625
|
+
# Check sanity: Is test valid?
|
1626
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1627
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1628
|
+
|
1629
|
+
# Is compiled result valid?
|
1630
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1631
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1632
|
+
|
1633
|
+
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
|
1637
|
+
### Test 42: Complex repetition of parenthesized class
|
1638
|
+
|
1639
|
+
describe "A correct program (Complex repetition of parenthesized class)" do
|
1640
|
+
prog = <<-'END'
|
1641
|
+
match 4,7 * ('xyz') end
|
1642
|
+
END
|
1643
|
+
|
1644
|
+
good = ["xxxx", "yyyy", "xyzy", "xyzzy", "zyzzyva", "xyzxyz", "xyzxyzx", "xyzxyzxyzxyz"]
|
1645
|
+
bad = ["", "abc", "x", "xx", "xxx", "xyz xy"]
|
1646
|
+
wanted = /([xyz]){4,7}/
|
1647
|
+
|
1648
|
+
myprog = Program.new(prog)
|
1649
|
+
parsed = nil
|
1650
|
+
|
1651
|
+
it "should parse correctly" do
|
1652
|
+
parsed = myprog.parseable?
|
1653
|
+
myprog.debug_bad_program_parse unless parsed
|
1654
|
+
parsed.should == true
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
rx = nil
|
1658
|
+
it "can be converted to a regex" do
|
1659
|
+
rx = myprog.regexp
|
1660
|
+
rx.class.should == Regexp
|
1661
|
+
end
|
1662
|
+
|
1663
|
+
# Check sanity: Is test valid?
|
1664
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1665
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1666
|
+
|
1667
|
+
# Is compiled result valid?
|
1668
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1669
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1670
|
+
|
1671
|
+
|
1672
|
+
end
|
1673
|
+
|
1674
|
+
|
1675
|
+
### Test 43: Complex repetition of parenthesized range
|
1676
|
+
|
1677
|
+
describe "A correct program (Complex repetition of parenthesized range)" do
|
1678
|
+
prog = <<-'END'
|
1679
|
+
match 0,3 * (`1-`6) end
|
1680
|
+
END
|
1681
|
+
|
1682
|
+
good = ["", "1", "11", "111", "56", "654", "1111", "x123y", "x123456y"]
|
1683
|
+
bad = []
|
1684
|
+
wanted = /([1-6]){0,3}/
|
1685
|
+
|
1686
|
+
myprog = Program.new(prog)
|
1687
|
+
parsed = nil
|
1688
|
+
|
1689
|
+
it "should parse correctly" do
|
1690
|
+
parsed = myprog.parseable?
|
1691
|
+
myprog.debug_bad_program_parse unless parsed
|
1692
|
+
parsed.should == true
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
rx = nil
|
1696
|
+
it "can be converted to a regex" do
|
1697
|
+
rx = myprog.regexp
|
1698
|
+
rx.class.should == Regexp
|
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
|
+
|
1709
|
+
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
|
1713
|
+
### Test 44: Single char (anchored)
|
1714
|
+
|
1715
|
+
describe "A correct program (Single char (anchored))" do
|
1716
|
+
prog = <<-'END'
|
1717
|
+
match BOS `x EOS end
|
1718
|
+
END
|
1719
|
+
|
1720
|
+
good = ["x"]
|
1721
|
+
bad = ["yz", "", "ABC"]
|
1722
|
+
wanted = /^x$/
|
1723
|
+
|
1724
|
+
myprog = Program.new(prog)
|
1725
|
+
parsed = nil
|
1726
|
+
|
1727
|
+
it "should parse correctly" do
|
1728
|
+
parsed = myprog.parseable?
|
1729
|
+
myprog.debug_bad_program_parse unless parsed
|
1730
|
+
parsed.should == true
|
1731
|
+
end
|
1732
|
+
|
1733
|
+
rx = nil
|
1734
|
+
it "can be converted to a regex" do
|
1735
|
+
rx = myprog.regexp
|
1736
|
+
rx.class.should == Regexp
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
# Check sanity: Is test valid?
|
1740
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1741
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1742
|
+
|
1743
|
+
# Is compiled result valid?
|
1744
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1745
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1746
|
+
|
1747
|
+
|
1748
|
+
end
|
1749
|
+
|
1750
|
+
|
1751
|
+
### Test 45: Simple range (anchored)
|
1752
|
+
|
1753
|
+
describe "A correct program (Simple range (anchored))" do
|
1754
|
+
prog = <<-'END'
|
1755
|
+
match BOS `a-`f EOS end
|
1756
|
+
END
|
1757
|
+
|
1758
|
+
good = ["a", "b", "c", "d", "e", "f"]
|
1759
|
+
bad = ["xyz", "", "ABC"]
|
1760
|
+
wanted = /^[a-f]$/
|
1761
|
+
|
1762
|
+
myprog = Program.new(prog)
|
1763
|
+
parsed = nil
|
1764
|
+
|
1765
|
+
it "should parse correctly" do
|
1766
|
+
parsed = myprog.parseable?
|
1767
|
+
myprog.debug_bad_program_parse unless parsed
|
1768
|
+
parsed.should == true
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
rx = nil
|
1772
|
+
it "can be converted to a regex" do
|
1773
|
+
rx = myprog.regexp
|
1774
|
+
rx.class.should == Regexp
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
# Check sanity: Is test valid?
|
1778
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1779
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1780
|
+
|
1781
|
+
# Is compiled result valid?
|
1782
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1783
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1784
|
+
|
1785
|
+
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
|
1789
|
+
### Test 46: Negated range (anchored)
|
1790
|
+
|
1791
|
+
describe "A correct program (Negated range (anchored))" do
|
1792
|
+
prog = <<-'END'
|
1793
|
+
match BOS `c~`p EOS end
|
1794
|
+
END
|
1795
|
+
|
1796
|
+
good = ["a", "r"]
|
1797
|
+
bad = ["def", "mno", ""]
|
1798
|
+
wanted = /^[^c-p]$/
|
1799
|
+
|
1800
|
+
myprog = Program.new(prog)
|
1801
|
+
parsed = nil
|
1802
|
+
|
1803
|
+
it "should parse correctly" do
|
1804
|
+
parsed = myprog.parseable?
|
1805
|
+
myprog.debug_bad_program_parse unless parsed
|
1806
|
+
parsed.should == true
|
1807
|
+
end
|
1808
|
+
|
1809
|
+
rx = nil
|
1810
|
+
it "can be converted to a regex" do
|
1811
|
+
rx = myprog.regexp
|
1812
|
+
rx.class.should == Regexp
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
# Check sanity: Is test valid?
|
1816
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1817
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1818
|
+
|
1819
|
+
# Is compiled result valid?
|
1820
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1821
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1822
|
+
|
1823
|
+
|
1824
|
+
end
|
1825
|
+
|
1826
|
+
|
1827
|
+
### Test 47: Negated char (anchored)
|
1828
|
+
|
1829
|
+
describe "A correct program (Negated char (anchored))" do
|
1830
|
+
prog = <<-'END'
|
1831
|
+
match BOS ~`d EOS end
|
1832
|
+
END
|
1833
|
+
|
1834
|
+
good = ["x", "1"]
|
1835
|
+
bad = ["d", "dd", "abc"]
|
1836
|
+
wanted = /^[^d]$/
|
1837
|
+
|
1838
|
+
myprog = Program.new(prog)
|
1839
|
+
parsed = nil
|
1840
|
+
|
1841
|
+
it "should parse correctly" do
|
1842
|
+
parsed = myprog.parseable?
|
1843
|
+
myprog.debug_bad_program_parse unless parsed
|
1844
|
+
parsed.should == true
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
rx = nil
|
1848
|
+
it "can be converted to a regex" do
|
1849
|
+
rx = myprog.regexp
|
1850
|
+
rx.class.should == Regexp
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
# Check sanity: Is test valid?
|
1854
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1855
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1856
|
+
|
1857
|
+
# Is compiled result valid?
|
1858
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1859
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1860
|
+
|
1861
|
+
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
|
1865
|
+
### Test 48: POSIX class (anchored)
|
1866
|
+
|
1867
|
+
describe "A correct program (POSIX class (anchored))" do
|
1868
|
+
prog = <<-'END'
|
1869
|
+
match BOS %alnum EOS end
|
1870
|
+
END
|
1871
|
+
|
1872
|
+
good = ["c", "2"]
|
1873
|
+
bad = ["", "abc", "123", "-", ":", ",", "."]
|
1874
|
+
wanted = /^[[:alnum:]]$/
|
1875
|
+
|
1876
|
+
myprog = Program.new(prog)
|
1877
|
+
parsed = nil
|
1878
|
+
|
1879
|
+
it "should parse correctly" do
|
1880
|
+
parsed = myprog.parseable?
|
1881
|
+
myprog.debug_bad_program_parse unless parsed
|
1882
|
+
parsed.should == true
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
rx = nil
|
1886
|
+
it "can be converted to a regex" do
|
1887
|
+
rx = myprog.regexp
|
1888
|
+
rx.class.should == Regexp
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
# Check sanity: Is test valid?
|
1892
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1893
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1894
|
+
|
1895
|
+
# Is compiled result valid?
|
1896
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1897
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1898
|
+
|
1899
|
+
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
|
1903
|
+
### Test 49: Simple char class (anchored)
|
1904
|
+
|
1905
|
+
describe "A correct program (Simple char class (anchored))" do
|
1906
|
+
prog = <<-'END'
|
1907
|
+
match BOS 'prstu' EOS end
|
1908
|
+
END
|
1909
|
+
|
1910
|
+
good = ["u", "p", "s"]
|
1911
|
+
bad = ["", "abc", "x"]
|
1912
|
+
wanted = /^[prstu]$/
|
1913
|
+
|
1914
|
+
myprog = Program.new(prog)
|
1915
|
+
parsed = nil
|
1916
|
+
|
1917
|
+
it "should parse correctly" do
|
1918
|
+
parsed = myprog.parseable?
|
1919
|
+
myprog.debug_bad_program_parse unless parsed
|
1920
|
+
parsed.should == true
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
rx = nil
|
1924
|
+
it "can be converted to a regex" do
|
1925
|
+
rx = myprog.regexp
|
1926
|
+
rx.class.should == Regexp
|
1927
|
+
end
|
1928
|
+
|
1929
|
+
# Check sanity: Is test valid?
|
1930
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1931
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1932
|
+
|
1933
|
+
# Is compiled result valid?
|
1934
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1935
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1936
|
+
|
1937
|
+
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
|
1941
|
+
### Test 50: Negated char class (anchored)
|
1942
|
+
|
1943
|
+
describe "A correct program (Negated char class (anchored))" do
|
1944
|
+
prog = <<-'END'
|
1945
|
+
match BOS ~'ilmnop' EOS end
|
1946
|
+
END
|
1947
|
+
|
1948
|
+
good = ["a", "e", "h"]
|
1949
|
+
bad = ["o", "i", "l"]
|
1950
|
+
wanted = /^[^ilmnop]$/
|
1951
|
+
|
1952
|
+
myprog = Program.new(prog)
|
1953
|
+
parsed = nil
|
1954
|
+
|
1955
|
+
it "should parse correctly" do
|
1956
|
+
parsed = myprog.parseable?
|
1957
|
+
myprog.debug_bad_program_parse unless parsed
|
1958
|
+
parsed.should == true
|
1959
|
+
end
|
1960
|
+
|
1961
|
+
rx = nil
|
1962
|
+
it "can be converted to a regex" do
|
1963
|
+
rx = myprog.regexp
|
1964
|
+
rx.class.should == Regexp
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
# Check sanity: Is test valid?
|
1968
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
1969
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
1970
|
+
|
1971
|
+
# Is compiled result valid?
|
1972
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
1973
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
1974
|
+
|
1975
|
+
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
|
1979
|
+
### Test 51: Simple string (anchored)
|
1980
|
+
|
1981
|
+
describe "A correct program (Simple string (anchored))" do
|
1982
|
+
prog = <<-'END'
|
1983
|
+
match BOS "xyz" EOS end
|
1984
|
+
END
|
1985
|
+
|
1986
|
+
good = ["xyz"]
|
1987
|
+
bad = ["", "abc", "abcxyzdef", "xydefz"]
|
1988
|
+
wanted = /^xyz$/
|
1989
|
+
|
1990
|
+
myprog = Program.new(prog)
|
1991
|
+
parsed = nil
|
1992
|
+
|
1993
|
+
it "should parse correctly" do
|
1994
|
+
parsed = myprog.parseable?
|
1995
|
+
myprog.debug_bad_program_parse unless parsed
|
1996
|
+
parsed.should == true
|
1997
|
+
end
|
1998
|
+
|
1999
|
+
rx = nil
|
2000
|
+
it "can be converted to a regex" do
|
2001
|
+
rx = myprog.regexp
|
2002
|
+
rx.class.should == Regexp
|
2003
|
+
end
|
2004
|
+
|
2005
|
+
# Check sanity: Is test valid?
|
2006
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2007
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2008
|
+
|
2009
|
+
# Is compiled result valid?
|
2010
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2011
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2012
|
+
|
2013
|
+
|
2014
|
+
end
|
2015
|
+
|
2016
|
+
|
2017
|
+
### Test 52: Single-bounded repetition (anchored)
|
2018
|
+
|
2019
|
+
describe "A correct program (Single-bounded repetition (anchored))" do
|
2020
|
+
prog = <<-'END'
|
2021
|
+
match BOS 5 * "xyz" EOS end
|
2022
|
+
END
|
2023
|
+
|
2024
|
+
good = ["xyzxyzxyzxyzxyz"]
|
2025
|
+
bad = ["xyzxyzxyzxyz", "abcxyzxyzxyzxyz", "xyzxyzxyzxyzabc"]
|
2026
|
+
wanted = /^(xyz){5}$/
|
2027
|
+
|
2028
|
+
myprog = Program.new(prog)
|
2029
|
+
parsed = nil
|
2030
|
+
|
2031
|
+
it "should parse correctly" do
|
2032
|
+
parsed = myprog.parseable?
|
2033
|
+
myprog.debug_bad_program_parse unless parsed
|
2034
|
+
parsed.should == true
|
2035
|
+
end
|
2036
|
+
|
2037
|
+
rx = nil
|
2038
|
+
it "can be converted to a regex" do
|
2039
|
+
rx = myprog.regexp
|
2040
|
+
rx.class.should == Regexp
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
# Check sanity: Is test valid?
|
2044
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2045
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2046
|
+
|
2047
|
+
# Is compiled result valid?
|
2048
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2049
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2050
|
+
|
2051
|
+
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
|
2055
|
+
### Test 53: Double-bounded repetition (anchored)
|
2056
|
+
|
2057
|
+
describe "A correct program (Double-bounded repetition (anchored))" do
|
2058
|
+
prog = <<-'END'
|
2059
|
+
match BOS 3,4 * %alpha EOS end
|
2060
|
+
END
|
2061
|
+
|
2062
|
+
good = ["abc", "abcd"]
|
2063
|
+
bad = ["", "ab", "x", "abcde"]
|
2064
|
+
wanted = /^([[:alpha:]]){3,4}$/
|
2065
|
+
|
2066
|
+
myprog = Program.new(prog)
|
2067
|
+
parsed = nil
|
2068
|
+
|
2069
|
+
it "should parse correctly" do
|
2070
|
+
parsed = myprog.parseable?
|
2071
|
+
myprog.debug_bad_program_parse unless parsed
|
2072
|
+
parsed.should == true
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
rx = nil
|
2076
|
+
it "can be converted to a regex" do
|
2077
|
+
rx = myprog.regexp
|
2078
|
+
rx.class.should == Regexp
|
2079
|
+
end
|
2080
|
+
|
2081
|
+
# Check sanity: Is test valid?
|
2082
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2083
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2084
|
+
|
2085
|
+
# Is compiled result valid?
|
2086
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2087
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2088
|
+
|
2089
|
+
|
2090
|
+
end
|
2091
|
+
|
2092
|
+
|
2093
|
+
### Test 54: any-qualifier (anchored)
|
2094
|
+
|
2095
|
+
describe "A correct program (any-qualifier (anchored))" do
|
2096
|
+
prog = <<-'END'
|
2097
|
+
match BOS any "abc" EOS end
|
2098
|
+
END
|
2099
|
+
|
2100
|
+
good = ["", "abc", "abcabc", "abcabcabc"]
|
2101
|
+
bad = ["ab", "abcab", "xyz"]
|
2102
|
+
wanted = /^(abc)*$/
|
2103
|
+
|
2104
|
+
myprog = Program.new(prog)
|
2105
|
+
parsed = nil
|
2106
|
+
|
2107
|
+
it "should parse correctly" do
|
2108
|
+
parsed = myprog.parseable?
|
2109
|
+
myprog.debug_bad_program_parse unless parsed
|
2110
|
+
parsed.should == true
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
rx = nil
|
2114
|
+
it "can be converted to a regex" do
|
2115
|
+
rx = myprog.regexp
|
2116
|
+
rx.class.should == Regexp
|
2117
|
+
end
|
2118
|
+
|
2119
|
+
# Check sanity: Is test valid?
|
2120
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2121
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2122
|
+
|
2123
|
+
# Is compiled result valid?
|
2124
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2125
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2126
|
+
|
2127
|
+
|
2128
|
+
end
|
2129
|
+
|
2130
|
+
|
2131
|
+
### Test 55: many-qualifier (anchored)
|
2132
|
+
|
2133
|
+
describe "A correct program (many-qualifier (anchored))" do
|
2134
|
+
prog = <<-'END'
|
2135
|
+
match BOS many "def" EOS end
|
2136
|
+
END
|
2137
|
+
|
2138
|
+
good = ["def", "defdef", "defdefdef"]
|
2139
|
+
bad = ["", "d", "de", "defd", "xyz"]
|
2140
|
+
wanted = /^(def)+$/
|
2141
|
+
|
2142
|
+
myprog = Program.new(prog)
|
2143
|
+
parsed = nil
|
2144
|
+
|
2145
|
+
it "should parse correctly" do
|
2146
|
+
parsed = myprog.parseable?
|
2147
|
+
myprog.debug_bad_program_parse unless parsed
|
2148
|
+
parsed.should == true
|
2149
|
+
end
|
2150
|
+
|
2151
|
+
rx = nil
|
2152
|
+
it "can be converted to a regex" do
|
2153
|
+
rx = myprog.regexp
|
2154
|
+
rx.class.should == Regexp
|
2155
|
+
end
|
2156
|
+
|
2157
|
+
# Check sanity: Is test valid?
|
2158
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2159
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2160
|
+
|
2161
|
+
# Is compiled result valid?
|
2162
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2163
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2164
|
+
|
2165
|
+
|
2166
|
+
end
|
2167
|
+
|
2168
|
+
|
2169
|
+
### Test 56: maybe-qualifier (anchored)
|
2170
|
+
|
2171
|
+
describe "A correct program (maybe-qualifier (anchored))" do
|
2172
|
+
prog = <<-'END'
|
2173
|
+
match BOS maybe "ghi" EOS end
|
2174
|
+
END
|
2175
|
+
|
2176
|
+
good = ["", "ghi"]
|
2177
|
+
bad = ["abghicd", "gh"]
|
2178
|
+
wanted = /^(ghi)?$/
|
2179
|
+
|
2180
|
+
myprog = Program.new(prog)
|
2181
|
+
parsed = nil
|
2182
|
+
|
2183
|
+
it "should parse correctly" do
|
2184
|
+
parsed = myprog.parseable?
|
2185
|
+
myprog.debug_bad_program_parse unless parsed
|
2186
|
+
parsed.should == true
|
2187
|
+
end
|
2188
|
+
|
2189
|
+
rx = nil
|
2190
|
+
it "can be converted to a regex" do
|
2191
|
+
rx = myprog.regexp
|
2192
|
+
rx.class.should == Regexp
|
2193
|
+
end
|
2194
|
+
|
2195
|
+
# Check sanity: Is test valid?
|
2196
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2197
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2198
|
+
|
2199
|
+
# Is compiled result valid?
|
2200
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2201
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2202
|
+
|
2203
|
+
|
2204
|
+
end
|
2205
|
+
|
2206
|
+
|
2207
|
+
### Test 57: Simple concatenation of two strings (anchored)
|
2208
|
+
|
2209
|
+
describe "A correct program (Simple concatenation of two strings (anchored))" do
|
2210
|
+
prog = <<-'END'
|
2211
|
+
match BOS "abc" "def" EOS end
|
2212
|
+
END
|
2213
|
+
|
2214
|
+
good = ["abcdef"]
|
2215
|
+
bad = ["", "abcd", "xyzabcdef", "abcxyzdef", "abcdefxyz"]
|
2216
|
+
wanted = /^abcdef$/
|
2217
|
+
|
2218
|
+
myprog = Program.new(prog)
|
2219
|
+
parsed = nil
|
2220
|
+
|
2221
|
+
it "should parse correctly" do
|
2222
|
+
parsed = myprog.parseable?
|
2223
|
+
myprog.debug_bad_program_parse unless parsed
|
2224
|
+
parsed.should == true
|
2225
|
+
end
|
2226
|
+
|
2227
|
+
rx = nil
|
2228
|
+
it "can be converted to a regex" do
|
2229
|
+
rx = myprog.regexp
|
2230
|
+
rx.class.should == Regexp
|
2231
|
+
end
|
2232
|
+
|
2233
|
+
# Check sanity: Is test valid?
|
2234
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2235
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2236
|
+
|
2237
|
+
# Is compiled result valid?
|
2238
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2239
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2240
|
+
|
2241
|
+
|
2242
|
+
end
|
2243
|
+
|
2244
|
+
|
2245
|
+
### Test 58: Concat of string and char class (anchored)
|
2246
|
+
|
2247
|
+
describe "A correct program (Concat of string and char class (anchored))" do
|
2248
|
+
prog = <<-'END'
|
2249
|
+
match BOS "abc" 'def' EOS end
|
2250
|
+
END
|
2251
|
+
|
2252
|
+
good = ["abcd", "abce", "abcf"]
|
2253
|
+
bad = ["", "ab", "abc", "abcx"]
|
2254
|
+
wanted = /^abc[def]$/
|
2255
|
+
|
2256
|
+
myprog = Program.new(prog)
|
2257
|
+
parsed = nil
|
2258
|
+
|
2259
|
+
it "should parse correctly" do
|
2260
|
+
parsed = myprog.parseable?
|
2261
|
+
myprog.debug_bad_program_parse unless parsed
|
2262
|
+
parsed.should == true
|
2263
|
+
end
|
2264
|
+
|
2265
|
+
rx = nil
|
2266
|
+
it "can be converted to a regex" do
|
2267
|
+
rx = myprog.regexp
|
2268
|
+
rx.class.should == Regexp
|
2269
|
+
end
|
2270
|
+
|
2271
|
+
# Check sanity: Is test valid?
|
2272
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2273
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2274
|
+
|
2275
|
+
# Is compiled result valid?
|
2276
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2277
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2278
|
+
|
2279
|
+
|
2280
|
+
end
|
2281
|
+
|
2282
|
+
|
2283
|
+
### Test 59: Simple alternation (anchored)
|
2284
|
+
|
2285
|
+
describe "A correct program (Simple alternation (anchored))" do
|
2286
|
+
prog = <<-'END'
|
2287
|
+
match BOS ("abc" | "def") EOS end
|
2288
|
+
END
|
2289
|
+
|
2290
|
+
good = ["abc", "def"]
|
2291
|
+
bad = ["", "abde", "ab c d ef", "xdefy"]
|
2292
|
+
wanted = /^(abc|def)$/
|
2293
|
+
|
2294
|
+
myprog = Program.new(prog)
|
2295
|
+
parsed = nil
|
2296
|
+
|
2297
|
+
it "should parse correctly" do
|
2298
|
+
parsed = myprog.parseable?
|
2299
|
+
myprog.debug_bad_program_parse unless parsed
|
2300
|
+
parsed.should == true
|
2301
|
+
end
|
2302
|
+
|
2303
|
+
rx = nil
|
2304
|
+
it "can be converted to a regex" do
|
2305
|
+
rx = myprog.regexp
|
2306
|
+
rx.class.should == Regexp
|
2307
|
+
end
|
2308
|
+
|
2309
|
+
# Check sanity: Is test valid?
|
2310
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2311
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2312
|
+
|
2313
|
+
# Is compiled result valid?
|
2314
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2315
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2316
|
+
|
2317
|
+
|
2318
|
+
end
|
2319
|
+
|
2320
|
+
|
2321
|
+
### Test 60: Alternation of concatenations (anchored)
|
2322
|
+
|
2323
|
+
describe "A correct program (Alternation of concatenations (anchored))" do
|
2324
|
+
prog = <<-'END'
|
2325
|
+
match BOS ("ab" "c" | "d" "ef") EOS end
|
2326
|
+
END
|
2327
|
+
|
2328
|
+
good = ["abc", "def"]
|
2329
|
+
bad = ["", "abde", "ab c d ef", "xdefy"]
|
2330
|
+
wanted = /^(abc|def)$/
|
2331
|
+
|
2332
|
+
myprog = Program.new(prog)
|
2333
|
+
parsed = nil
|
2334
|
+
|
2335
|
+
it "should parse correctly" do
|
2336
|
+
parsed = myprog.parseable?
|
2337
|
+
myprog.debug_bad_program_parse unless parsed
|
2338
|
+
parsed.should == true
|
2339
|
+
end
|
2340
|
+
|
2341
|
+
rx = nil
|
2342
|
+
it "can be converted to a regex" do
|
2343
|
+
rx = myprog.regexp
|
2344
|
+
rx.class.should == Regexp
|
2345
|
+
end
|
2346
|
+
|
2347
|
+
# Check sanity: Is test valid?
|
2348
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2349
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2350
|
+
|
2351
|
+
# Is compiled result valid?
|
2352
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2353
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2354
|
+
|
2355
|
+
|
2356
|
+
end
|
2357
|
+
|
2358
|
+
|
2359
|
+
### Test 61: Precedence of concatenation over alternation (anchored)
|
2360
|
+
|
2361
|
+
describe "A correct program (Precedence of concatenation over alternation (anchored))" do
|
2362
|
+
prog = <<-'END'
|
2363
|
+
match BOS ("a" "b" | "c") EOS end
|
2364
|
+
END
|
2365
|
+
|
2366
|
+
good = ["ab", "c"]
|
2367
|
+
bad = ["", "b", "a", "d", "abc", "abcde"]
|
2368
|
+
wanted = /^(ab|c)$/
|
2369
|
+
|
2370
|
+
myprog = Program.new(prog)
|
2371
|
+
parsed = nil
|
2372
|
+
|
2373
|
+
it "should parse correctly" do
|
2374
|
+
parsed = myprog.parseable?
|
2375
|
+
myprog.debug_bad_program_parse unless parsed
|
2376
|
+
parsed.should == true
|
2377
|
+
end
|
2378
|
+
|
2379
|
+
rx = nil
|
2380
|
+
it "can be converted to a regex" do
|
2381
|
+
rx = myprog.regexp
|
2382
|
+
rx.class.should == Regexp
|
2383
|
+
end
|
2384
|
+
|
2385
|
+
# Check sanity: Is test valid?
|
2386
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2387
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2388
|
+
|
2389
|
+
# Is compiled result valid?
|
2390
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2391
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2392
|
+
|
2393
|
+
|
2394
|
+
end
|
2395
|
+
|
2396
|
+
|
2397
|
+
### Test 62: Precedence of parens over concatenation (anchored)
|
2398
|
+
|
2399
|
+
describe "A correct program (Precedence of parens over concatenation (anchored))" do
|
2400
|
+
prog = <<-'END'
|
2401
|
+
match BOS "a" ("b" | "c") EOS end
|
2402
|
+
END
|
2403
|
+
|
2404
|
+
good = ["ab", "ac"]
|
2405
|
+
bad = ["a", "b", "c", "abc", "abx", "bac"]
|
2406
|
+
wanted = /^a(b|c)$/
|
2407
|
+
|
2408
|
+
myprog = Program.new(prog)
|
2409
|
+
parsed = nil
|
2410
|
+
|
2411
|
+
it "should parse correctly" do
|
2412
|
+
parsed = myprog.parseable?
|
2413
|
+
myprog.debug_bad_program_parse unless parsed
|
2414
|
+
parsed.should == true
|
2415
|
+
end
|
2416
|
+
|
2417
|
+
rx = nil
|
2418
|
+
it "can be converted to a regex" do
|
2419
|
+
rx = myprog.regexp
|
2420
|
+
rx.class.should == Regexp
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
# Check sanity: Is test valid?
|
2424
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2425
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2426
|
+
|
2427
|
+
# Is compiled result valid?
|
2428
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2429
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2430
|
+
|
2431
|
+
|
2432
|
+
end
|
2433
|
+
|
2434
|
+
|
2435
|
+
### Test 63: Anchors and alternation (anchored)
|
2436
|
+
|
2437
|
+
describe "A correct program (Anchors and alternation (anchored))" do
|
2438
|
+
prog = <<-'END'
|
2439
|
+
match BOS "x" | "y" EOS end
|
2440
|
+
END
|
2441
|
+
|
2442
|
+
good = ["xabc", "abcy"]
|
2443
|
+
bad = ["abc", "abcx", "yabc", "axb", "ayb", "axyb"]
|
2444
|
+
wanted = /(^x|y$)/
|
2445
|
+
|
2446
|
+
myprog = Program.new(prog)
|
2447
|
+
parsed = nil
|
2448
|
+
|
2449
|
+
it "should parse correctly" do
|
2450
|
+
parsed = myprog.parseable?
|
2451
|
+
myprog.debug_bad_program_parse unless parsed
|
2452
|
+
parsed.should == true
|
2453
|
+
end
|
2454
|
+
|
2455
|
+
rx = nil
|
2456
|
+
it "can be converted to a regex" do
|
2457
|
+
rx = myprog.regexp
|
2458
|
+
rx.class.should == Regexp
|
2459
|
+
end
|
2460
|
+
|
2461
|
+
# Check sanity: Is test valid?
|
2462
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2463
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2464
|
+
|
2465
|
+
# Is compiled result valid?
|
2466
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2467
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2468
|
+
|
2469
|
+
|
2470
|
+
end
|
2471
|
+
|
2472
|
+
|
2473
|
+
### Test 64: Parens, concatenation, alternation (anchored)
|
2474
|
+
|
2475
|
+
describe "A correct program (Parens, concatenation, alternation (anchored))" do
|
2476
|
+
prog = <<-'END'
|
2477
|
+
match BOS ((maybe `0) `1-`9 | `1 D2) EOS end
|
2478
|
+
END
|
2479
|
+
|
2480
|
+
good = ["01", "09", "12"]
|
2481
|
+
bad = ["0", "00", "13"]
|
2482
|
+
wanted = /^((0)?[1-9]|1[0-2])$/
|
2483
|
+
|
2484
|
+
myprog = Program.new(prog)
|
2485
|
+
parsed = nil
|
2486
|
+
|
2487
|
+
it "should parse correctly" do
|
2488
|
+
parsed = myprog.parseable?
|
2489
|
+
myprog.debug_bad_program_parse unless parsed
|
2490
|
+
parsed.should == true
|
2491
|
+
end
|
2492
|
+
|
2493
|
+
rx = nil
|
2494
|
+
it "can be converted to a regex" do
|
2495
|
+
rx = myprog.regexp
|
2496
|
+
rx.class.should == Regexp
|
2497
|
+
end
|
2498
|
+
|
2499
|
+
# Check sanity: Is test valid?
|
2500
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2501
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2502
|
+
|
2503
|
+
# Is compiled result valid?
|
2504
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2505
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2506
|
+
|
2507
|
+
|
2508
|
+
end
|
2509
|
+
|
2510
|
+
|
2511
|
+
### Test 65: Single backtick char (anchored)
|
2512
|
+
|
2513
|
+
describe "A correct program (Single backtick char (anchored))" do
|
2514
|
+
prog = <<-'END'
|
2515
|
+
match BOS `` EOS end
|
2516
|
+
END
|
2517
|
+
|
2518
|
+
good = ["`"]
|
2519
|
+
bad = ["", "abc", "this is a tick: `", "tock ` tock"]
|
2520
|
+
wanted = /^`$/
|
2521
|
+
|
2522
|
+
myprog = Program.new(prog)
|
2523
|
+
parsed = nil
|
2524
|
+
|
2525
|
+
it "should parse correctly" do
|
2526
|
+
parsed = myprog.parseable?
|
2527
|
+
myprog.debug_bad_program_parse unless parsed
|
2528
|
+
parsed.should == true
|
2529
|
+
end
|
2530
|
+
|
2531
|
+
rx = nil
|
2532
|
+
it "can be converted to a regex" do
|
2533
|
+
rx = myprog.regexp
|
2534
|
+
rx.class.should == Regexp
|
2535
|
+
end
|
2536
|
+
|
2537
|
+
# Check sanity: Is test valid?
|
2538
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2539
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2540
|
+
|
2541
|
+
# Is compiled result valid?
|
2542
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2543
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2544
|
+
|
2545
|
+
|
2546
|
+
end
|
2547
|
+
|
2548
|
+
|
2549
|
+
### Test 66: Single backslash char (anchored)
|
2550
|
+
|
2551
|
+
describe "A correct program (Single backslash char (anchored))" do
|
2552
|
+
prog = <<-'END'
|
2553
|
+
match BOS `\ EOS end
|
2554
|
+
END
|
2555
|
+
|
2556
|
+
good = ["\\"]
|
2557
|
+
bad = ["\n", "\b", "neither \r nor \t", "trying \\n", "and \\b also"]
|
2558
|
+
wanted = /^\\$/
|
2559
|
+
|
2560
|
+
myprog = Program.new(prog)
|
2561
|
+
parsed = nil
|
2562
|
+
|
2563
|
+
it "should parse correctly" do
|
2564
|
+
parsed = myprog.parseable?
|
2565
|
+
myprog.debug_bad_program_parse unless parsed
|
2566
|
+
parsed.should == true
|
2567
|
+
end
|
2568
|
+
|
2569
|
+
rx = nil
|
2570
|
+
it "can be converted to a regex" do
|
2571
|
+
rx = myprog.regexp
|
2572
|
+
rx.class.should == Regexp
|
2573
|
+
end
|
2574
|
+
|
2575
|
+
# Check sanity: Is test valid?
|
2576
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2577
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2578
|
+
|
2579
|
+
# Is compiled result valid?
|
2580
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2581
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2582
|
+
|
2583
|
+
|
2584
|
+
end
|
2585
|
+
|
2586
|
+
|
2587
|
+
### Test 67: Empty string (anchored)
|
2588
|
+
|
2589
|
+
describe "A correct program (Empty string (anchored))" do
|
2590
|
+
prog = <<-'END'
|
2591
|
+
match BOS "" EOS end
|
2592
|
+
END
|
2593
|
+
|
2594
|
+
good = [""]
|
2595
|
+
bad = ["abc"]
|
2596
|
+
wanted = /^$/
|
2597
|
+
|
2598
|
+
myprog = Program.new(prog)
|
2599
|
+
parsed = nil
|
2600
|
+
|
2601
|
+
it "should parse correctly" do
|
2602
|
+
parsed = myprog.parseable?
|
2603
|
+
myprog.debug_bad_program_parse unless parsed
|
2604
|
+
parsed.should == true
|
2605
|
+
end
|
2606
|
+
|
2607
|
+
rx = nil
|
2608
|
+
it "can be converted to a regex" do
|
2609
|
+
rx = myprog.regexp
|
2610
|
+
rx.class.should == Regexp
|
2611
|
+
end
|
2612
|
+
|
2613
|
+
# Check sanity: Is test valid?
|
2614
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2615
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2616
|
+
|
2617
|
+
# Is compiled result valid?
|
2618
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2619
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2620
|
+
|
2621
|
+
|
2622
|
+
end
|
2623
|
+
|
2624
|
+
|
2625
|
+
### Test 68: Simple one-char class (anchored)
|
2626
|
+
|
2627
|
+
describe "A correct program (Simple one-char class (anchored))" do
|
2628
|
+
prog = <<-'END'
|
2629
|
+
match BOS 'x' EOS end
|
2630
|
+
END
|
2631
|
+
|
2632
|
+
good = ["x"]
|
2633
|
+
bad = ["", "abc", "uvwxyz"]
|
2634
|
+
wanted = /^[x]$/
|
2635
|
+
|
2636
|
+
myprog = Program.new(prog)
|
2637
|
+
parsed = nil
|
2638
|
+
|
2639
|
+
it "should parse correctly" do
|
2640
|
+
parsed = myprog.parseable?
|
2641
|
+
myprog.debug_bad_program_parse unless parsed
|
2642
|
+
parsed.should == true
|
2643
|
+
end
|
2644
|
+
|
2645
|
+
rx = nil
|
2646
|
+
it "can be converted to a regex" do
|
2647
|
+
rx = myprog.regexp
|
2648
|
+
rx.class.should == Regexp
|
2649
|
+
end
|
2650
|
+
|
2651
|
+
# Check sanity: Is test valid?
|
2652
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2653
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2654
|
+
|
2655
|
+
# Is compiled result valid?
|
2656
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2657
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2658
|
+
|
2659
|
+
|
2660
|
+
end
|
2661
|
+
|
2662
|
+
|
2663
|
+
### Test 69: Alternation of range and class (anchored)
|
2664
|
+
|
2665
|
+
describe "A correct program (Alternation of range and class (anchored))" do
|
2666
|
+
prog = <<-'END'
|
2667
|
+
match BOS (`a-`f | 'xyz') EOS end
|
2668
|
+
END
|
2669
|
+
|
2670
|
+
good = ["a", "x", "z", "c"]
|
2671
|
+
bad = ["", "ab", "abc", "xy", "jkl", "gw"]
|
2672
|
+
wanted = /^([a-f]|[xyz])$/
|
2673
|
+
|
2674
|
+
myprog = Program.new(prog)
|
2675
|
+
parsed = nil
|
2676
|
+
|
2677
|
+
it "should parse correctly" do
|
2678
|
+
parsed = myprog.parseable?
|
2679
|
+
myprog.debug_bad_program_parse unless parsed
|
2680
|
+
parsed.should == true
|
2681
|
+
end
|
2682
|
+
|
2683
|
+
rx = nil
|
2684
|
+
it "can be converted to a regex" do
|
2685
|
+
rx = myprog.regexp
|
2686
|
+
rx.class.should == Regexp
|
2687
|
+
end
|
2688
|
+
|
2689
|
+
# Check sanity: Is test valid?
|
2690
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2691
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2692
|
+
|
2693
|
+
# Is compiled result valid?
|
2694
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2695
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2696
|
+
|
2697
|
+
|
2698
|
+
end
|
2699
|
+
|
2700
|
+
|
2701
|
+
### Test 70: Alternation of range and maybe-clause (anchored)
|
2702
|
+
|
2703
|
+
describe "A correct program (Alternation of range and maybe-clause (anchored))" do
|
2704
|
+
prog = <<-'END'
|
2705
|
+
match BOS (`1-`6| maybe "#") EOS end
|
2706
|
+
END
|
2707
|
+
|
2708
|
+
good = ["", "1", "#", "6"]
|
2709
|
+
bad = ["55", "###"]
|
2710
|
+
wanted = /^([1-6]|(\#)?)$/
|
2711
|
+
|
2712
|
+
myprog = Program.new(prog)
|
2713
|
+
parsed = nil
|
2714
|
+
|
2715
|
+
it "should parse correctly" do
|
2716
|
+
parsed = myprog.parseable?
|
2717
|
+
myprog.debug_bad_program_parse unless parsed
|
2718
|
+
parsed.should == true
|
2719
|
+
end
|
2720
|
+
|
2721
|
+
rx = nil
|
2722
|
+
it "can be converted to a regex" do
|
2723
|
+
rx = myprog.regexp
|
2724
|
+
rx.class.should == Regexp
|
2725
|
+
end
|
2726
|
+
|
2727
|
+
# Check sanity: Is test valid?
|
2728
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2729
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2730
|
+
|
2731
|
+
# Is compiled result valid?
|
2732
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2733
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2734
|
+
|
2735
|
+
|
2736
|
+
end
|
2737
|
+
|
2738
|
+
|
2739
|
+
### Test 71: Four-way alternation (anchored)
|
2740
|
+
|
2741
|
+
describe "A correct program (Four-way alternation (anchored))" do
|
2742
|
+
prog = <<-'END'
|
2743
|
+
match BOS (`a | `b|`c|`d) EOS end
|
2744
|
+
END
|
2745
|
+
|
2746
|
+
good = ["a", "b", "c", "d"]
|
2747
|
+
bad = ["", "ab", "every", "ghijk"]
|
2748
|
+
wanted = /^(a|b|c|d)$/
|
2749
|
+
|
2750
|
+
myprog = Program.new(prog)
|
2751
|
+
parsed = nil
|
2752
|
+
|
2753
|
+
it "should parse correctly" do
|
2754
|
+
parsed = myprog.parseable?
|
2755
|
+
myprog.debug_bad_program_parse unless parsed
|
2756
|
+
parsed.should == true
|
2757
|
+
end
|
2758
|
+
|
2759
|
+
rx = nil
|
2760
|
+
it "can be converted to a regex" do
|
2761
|
+
rx = myprog.regexp
|
2762
|
+
rx.class.should == Regexp
|
2763
|
+
end
|
2764
|
+
|
2765
|
+
# Check sanity: Is test valid?
|
2766
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2767
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2768
|
+
|
2769
|
+
# Is compiled result valid?
|
2770
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2771
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2772
|
+
|
2773
|
+
|
2774
|
+
end
|
2775
|
+
|
2776
|
+
|
2777
|
+
### Test 72: Concatenation of range and class (anchored)
|
2778
|
+
|
2779
|
+
describe "A correct program (Concatenation of range and class (anchored))" do
|
2780
|
+
prog = <<-'END'
|
2781
|
+
match BOS `a-`f 'xyz' EOS end
|
2782
|
+
END
|
2783
|
+
|
2784
|
+
good = ["ax", "fz", "cy"]
|
2785
|
+
bad = ["axe", "fz123", "zf", "xa", "gz", "hp", "mx"]
|
2786
|
+
wanted = /^[a-f][xyz]$/
|
2787
|
+
|
2788
|
+
myprog = Program.new(prog)
|
2789
|
+
parsed = nil
|
2790
|
+
|
2791
|
+
it "should parse correctly" do
|
2792
|
+
parsed = myprog.parseable?
|
2793
|
+
myprog.debug_bad_program_parse unless parsed
|
2794
|
+
parsed.should == true
|
2795
|
+
end
|
2796
|
+
|
2797
|
+
rx = nil
|
2798
|
+
it "can be converted to a regex" do
|
2799
|
+
rx = myprog.regexp
|
2800
|
+
rx.class.should == Regexp
|
2801
|
+
end
|
2802
|
+
|
2803
|
+
# Check sanity: Is test valid?
|
2804
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2805
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2806
|
+
|
2807
|
+
# Is compiled result valid?
|
2808
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2809
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2810
|
+
|
2811
|
+
|
2812
|
+
end
|
2813
|
+
|
2814
|
+
|
2815
|
+
### Test 73: Concat of strings and maybe-clause (anchored)
|
2816
|
+
|
2817
|
+
describe "A correct program (Concat of strings and maybe-clause (anchored))" do
|
2818
|
+
prog = <<-'END'
|
2819
|
+
match BOS "this" "that" maybe "other" EOS end
|
2820
|
+
END
|
2821
|
+
|
2822
|
+
good = ["thisthat", "thisthatother"]
|
2823
|
+
bad = ["", "abc", "this that", "this that other", "abc thisthat xyz", "abc thisthatother xyz"]
|
2824
|
+
wanted = /^thisthat(other)?$/
|
2825
|
+
|
2826
|
+
myprog = Program.new(prog)
|
2827
|
+
parsed = nil
|
2828
|
+
|
2829
|
+
it "should parse correctly" do
|
2830
|
+
parsed = myprog.parseable?
|
2831
|
+
myprog.debug_bad_program_parse unless parsed
|
2832
|
+
parsed.should == true
|
2833
|
+
end
|
2834
|
+
|
2835
|
+
rx = nil
|
2836
|
+
it "can be converted to a regex" do
|
2837
|
+
rx = myprog.regexp
|
2838
|
+
rx.class.should == Regexp
|
2839
|
+
end
|
2840
|
+
|
2841
|
+
# Check sanity: Is test valid?
|
2842
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2843
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2844
|
+
|
2845
|
+
# Is compiled result valid?
|
2846
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2847
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2848
|
+
|
2849
|
+
|
2850
|
+
end
|
2851
|
+
|
2852
|
+
|
2853
|
+
### Test 74: Simple repetition of class (anchored)
|
2854
|
+
|
2855
|
+
describe "A correct program (Simple repetition of class (anchored))" do
|
2856
|
+
prog = <<-'END'
|
2857
|
+
match BOS 3 * 'xyz' EOS end
|
2858
|
+
END
|
2859
|
+
|
2860
|
+
good = ["xyz", "xxx", "yzy"]
|
2861
|
+
bad = ["", "abc", "xy", "axy", "xyb", "axyb", "xyzzy123"]
|
2862
|
+
wanted = /^([xyz]){3}$/
|
2863
|
+
|
2864
|
+
myprog = Program.new(prog)
|
2865
|
+
parsed = nil
|
2866
|
+
|
2867
|
+
it "should parse correctly" do
|
2868
|
+
parsed = myprog.parseable?
|
2869
|
+
myprog.debug_bad_program_parse unless parsed
|
2870
|
+
parsed.should == true
|
2871
|
+
end
|
2872
|
+
|
2873
|
+
rx = nil
|
2874
|
+
it "can be converted to a regex" do
|
2875
|
+
rx = myprog.regexp
|
2876
|
+
rx.class.should == Regexp
|
2877
|
+
end
|
2878
|
+
|
2879
|
+
# Check sanity: Is test valid?
|
2880
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2881
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2882
|
+
|
2883
|
+
# Is compiled result valid?
|
2884
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2885
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2886
|
+
|
2887
|
+
|
2888
|
+
end
|
2889
|
+
|
2890
|
+
|
2891
|
+
### Test 75: Simple repetition of range (anchored)
|
2892
|
+
|
2893
|
+
describe "A correct program (Simple repetition of range (anchored))" do
|
2894
|
+
prog = <<-'END'
|
2895
|
+
match BOS 4 * `1-`6 EOS end
|
2896
|
+
END
|
2897
|
+
|
2898
|
+
good = ["1111", "1234"]
|
2899
|
+
bad = ["", "abc", "123", "123 4", "abc 6543 def"]
|
2900
|
+
wanted = /^([1-6]){4}$/
|
2901
|
+
|
2902
|
+
myprog = Program.new(prog)
|
2903
|
+
parsed = nil
|
2904
|
+
|
2905
|
+
it "should parse correctly" do
|
2906
|
+
parsed = myprog.parseable?
|
2907
|
+
myprog.debug_bad_program_parse unless parsed
|
2908
|
+
parsed.should == true
|
2909
|
+
end
|
2910
|
+
|
2911
|
+
rx = nil
|
2912
|
+
it "can be converted to a regex" do
|
2913
|
+
rx = myprog.regexp
|
2914
|
+
rx.class.should == Regexp
|
2915
|
+
end
|
2916
|
+
|
2917
|
+
# Check sanity: Is test valid?
|
2918
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2919
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2920
|
+
|
2921
|
+
# Is compiled result valid?
|
2922
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2923
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2924
|
+
|
2925
|
+
|
2926
|
+
end
|
2927
|
+
|
2928
|
+
|
2929
|
+
### Test 76: Complex repetition of char (anchored)
|
2930
|
+
|
2931
|
+
describe "A correct program (Complex repetition of char (anchored))" do
|
2932
|
+
prog = <<-'END'
|
2933
|
+
match BOS 3,5 * (`a) EOS end
|
2934
|
+
END
|
2935
|
+
|
2936
|
+
good = ["aaa", "aaaa", "aaaaa"]
|
2937
|
+
bad = ["", "abc", "aa", "xaaay", "aaaaaaa"]
|
2938
|
+
wanted = /^(a){3,5}$/
|
2939
|
+
|
2940
|
+
myprog = Program.new(prog)
|
2941
|
+
parsed = nil
|
2942
|
+
|
2943
|
+
it "should parse correctly" do
|
2944
|
+
parsed = myprog.parseable?
|
2945
|
+
myprog.debug_bad_program_parse unless parsed
|
2946
|
+
parsed.should == true
|
2947
|
+
end
|
2948
|
+
|
2949
|
+
rx = nil
|
2950
|
+
it "can be converted to a regex" do
|
2951
|
+
rx = myprog.regexp
|
2952
|
+
rx.class.should == Regexp
|
2953
|
+
end
|
2954
|
+
|
2955
|
+
# Check sanity: Is test valid?
|
2956
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2957
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2958
|
+
|
2959
|
+
# Is compiled result valid?
|
2960
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2961
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
2962
|
+
|
2963
|
+
|
2964
|
+
end
|
2965
|
+
|
2966
|
+
|
2967
|
+
### Test 77: Complex repetition of parenthesized class (anchored)
|
2968
|
+
|
2969
|
+
describe "A correct program (Complex repetition of parenthesized class (anchored))" do
|
2970
|
+
prog = <<-'END'
|
2971
|
+
match BOS 4,7 * ('xyz') EOS end
|
2972
|
+
END
|
2973
|
+
|
2974
|
+
good = ["xxxx", "yyyy", "xyzy", "xyzzy", "xyzxyz", "xyzxyzx"]
|
2975
|
+
bad = ["", "abc", "x", "xx", "xxx", "xyz xy", "xyzxyzxyzxyz", "zyzzyva"]
|
2976
|
+
wanted = /^([xyz]){4,7}$/
|
2977
|
+
|
2978
|
+
myprog = Program.new(prog)
|
2979
|
+
parsed = nil
|
2980
|
+
|
2981
|
+
it "should parse correctly" do
|
2982
|
+
parsed = myprog.parseable?
|
2983
|
+
myprog.debug_bad_program_parse unless parsed
|
2984
|
+
parsed.should == true
|
2985
|
+
end
|
2986
|
+
|
2987
|
+
rx = nil
|
2988
|
+
it "can be converted to a regex" do
|
2989
|
+
rx = myprog.regexp
|
2990
|
+
rx.class.should == Regexp
|
2991
|
+
end
|
2992
|
+
|
2993
|
+
# Check sanity: Is test valid?
|
2994
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
2995
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
2996
|
+
|
2997
|
+
# Is compiled result valid?
|
2998
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
2999
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3000
|
+
|
3001
|
+
|
3002
|
+
end
|
3003
|
+
|
3004
|
+
|
3005
|
+
### Test 78: Complex repetition of parenthesized range (anchored)
|
3006
|
+
|
3007
|
+
describe "A correct program (Complex repetition of parenthesized range (anchored))" do
|
3008
|
+
prog = <<-'END'
|
3009
|
+
match BOS 0,3 * (`1-`6) EOS end
|
3010
|
+
END
|
3011
|
+
|
3012
|
+
good = ["", "1", "11", "111", "56", "654"]
|
3013
|
+
bad = ["1111", "x123y", "x123456y"]
|
3014
|
+
wanted = /^([1-6]){0,3}$/
|
3015
|
+
|
3016
|
+
myprog = Program.new(prog)
|
3017
|
+
parsed = nil
|
3018
|
+
|
3019
|
+
it "should parse correctly" do
|
3020
|
+
parsed = myprog.parseable?
|
3021
|
+
myprog.debug_bad_program_parse unless parsed
|
3022
|
+
parsed.should == true
|
3023
|
+
end
|
3024
|
+
|
3025
|
+
rx = nil
|
3026
|
+
it "can be converted to a regex" do
|
3027
|
+
rx = myprog.regexp
|
3028
|
+
rx.class.should == Regexp
|
3029
|
+
end
|
3030
|
+
|
3031
|
+
# Check sanity: Is test valid?
|
3032
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3033
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3034
|
+
|
3035
|
+
# Is compiled result valid?
|
3036
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3037
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3038
|
+
|
3039
|
+
|
3040
|
+
end
|
3041
|
+
|
3042
|
+
|
3043
|
+
### Test 79: Simple lookaround (pos-ahead)
|
3044
|
+
|
3045
|
+
describe "A correct program (Simple lookaround (pos-ahead))" do
|
3046
|
+
prog = <<-'END'
|
3047
|
+
match find "X" with "Y" end
|
3048
|
+
END
|
3049
|
+
|
3050
|
+
good = ["XY"]
|
3051
|
+
bad = ["X", "Y", "YX"]
|
3052
|
+
wanted = /(?=XY)X/
|
3053
|
+
|
3054
|
+
myprog = Program.new(prog)
|
3055
|
+
parsed = nil
|
3056
|
+
|
3057
|
+
it "should parse correctly" do
|
3058
|
+
parsed = myprog.parseable?
|
3059
|
+
myprog.debug_bad_program_parse unless parsed
|
3060
|
+
parsed.should == true
|
3061
|
+
end
|
3062
|
+
|
3063
|
+
rx = nil
|
3064
|
+
it "can be converted to a regex" do
|
3065
|
+
rx = myprog.regexp
|
3066
|
+
rx.class.should == Regexp
|
3067
|
+
end
|
3068
|
+
|
3069
|
+
# Check sanity: Is test valid?
|
3070
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3071
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3072
|
+
|
3073
|
+
# Is compiled result valid?
|
3074
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3075
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3076
|
+
|
3077
|
+
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
|
3081
|
+
### Test 80: Simple lookaround (neg-ahead)
|
3082
|
+
|
3083
|
+
describe "A correct program (Simple lookaround (neg-ahead))" do
|
3084
|
+
prog = <<-'END'
|
3085
|
+
match find "X" without "Y" end
|
3086
|
+
END
|
3087
|
+
|
3088
|
+
good = ["X", "YX"]
|
3089
|
+
bad = ["XY", "Y"]
|
3090
|
+
wanted = /(?!XY)X/
|
3091
|
+
|
3092
|
+
myprog = Program.new(prog)
|
3093
|
+
parsed = nil
|
3094
|
+
|
3095
|
+
it "should parse correctly" do
|
3096
|
+
parsed = myprog.parseable?
|
3097
|
+
myprog.debug_bad_program_parse unless parsed
|
3098
|
+
parsed.should == true
|
3099
|
+
end
|
3100
|
+
|
3101
|
+
rx = nil
|
3102
|
+
it "can be converted to a regex" do
|
3103
|
+
rx = myprog.regexp
|
3104
|
+
rx.class.should == Regexp
|
3105
|
+
end
|
3106
|
+
|
3107
|
+
# Check sanity: Is test valid?
|
3108
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3109
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3110
|
+
|
3111
|
+
# Is compiled result valid?
|
3112
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3113
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3114
|
+
|
3115
|
+
|
3116
|
+
end
|
3117
|
+
|
3118
|
+
|
3119
|
+
### Test 81: Simple lookaround (pos-behind)
|
3120
|
+
|
3121
|
+
describe "A correct program (Simple lookaround (pos-behind))" do
|
3122
|
+
prog = <<-'END'
|
3123
|
+
match with "X" find "Y" end
|
3124
|
+
END
|
3125
|
+
|
3126
|
+
good = ["XY"]
|
3127
|
+
bad = ["YX", "Y", "X"]
|
3128
|
+
wanted = /(?<=X)Y/
|
3129
|
+
|
3130
|
+
myprog = Program.new(prog)
|
3131
|
+
parsed = nil
|
3132
|
+
|
3133
|
+
it "should parse correctly" do
|
3134
|
+
parsed = myprog.parseable?
|
3135
|
+
myprog.debug_bad_program_parse unless parsed
|
3136
|
+
parsed.should == true
|
3137
|
+
end
|
3138
|
+
|
3139
|
+
rx = nil
|
3140
|
+
it "can be converted to a regex" do
|
3141
|
+
rx = myprog.regexp
|
3142
|
+
rx.class.should == Regexp
|
3143
|
+
end
|
3144
|
+
|
3145
|
+
# Check sanity: Is test valid?
|
3146
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3147
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3148
|
+
|
3149
|
+
# Is compiled result valid?
|
3150
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3151
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3152
|
+
|
3153
|
+
|
3154
|
+
end
|
3155
|
+
|
3156
|
+
|
3157
|
+
### Test 82: Simple lookaround (neg-behind)
|
3158
|
+
|
3159
|
+
describe "A correct program (Simple lookaround (neg-behind))" do
|
3160
|
+
prog = <<-'END'
|
3161
|
+
match without "X" find "Y" end
|
3162
|
+
END
|
3163
|
+
|
3164
|
+
good = ["aY", "Y"]
|
3165
|
+
bad = ["XY", "X"]
|
3166
|
+
wanted = /(?<!X)Y/
|
3167
|
+
|
3168
|
+
myprog = Program.new(prog)
|
3169
|
+
parsed = nil
|
3170
|
+
|
3171
|
+
it "should parse correctly" do
|
3172
|
+
parsed = myprog.parseable?
|
3173
|
+
myprog.debug_bad_program_parse unless parsed
|
3174
|
+
parsed.should == true
|
3175
|
+
end
|
3176
|
+
|
3177
|
+
rx = nil
|
3178
|
+
it "can be converted to a regex" do
|
3179
|
+
rx = myprog.regexp
|
3180
|
+
rx.class.should == Regexp
|
3181
|
+
end
|
3182
|
+
|
3183
|
+
# Check sanity: Is test valid?
|
3184
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3185
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3186
|
+
|
3187
|
+
# Is compiled result valid?
|
3188
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3189
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3190
|
+
|
3191
|
+
|
3192
|
+
end
|
3193
|
+
|
3194
|
+
|
3195
|
+
### Test 83: Positive lookahead
|
3196
|
+
|
3197
|
+
describe "A correct program (Positive lookahead)" do
|
3198
|
+
prog = <<-'END'
|
3199
|
+
match find (3*D " dollars") with 3*D end
|
3200
|
+
END
|
3201
|
+
|
3202
|
+
good = ["101 dollars"]
|
3203
|
+
bad = ["102 pesos"]
|
3204
|
+
wanted = /(?=\d{3} dollars)\d{3}/
|
3205
|
+
|
3206
|
+
myprog = Program.new(prog)
|
3207
|
+
parsed = nil
|
3208
|
+
|
3209
|
+
it "should parse correctly" do
|
3210
|
+
parsed = myprog.parseable?
|
3211
|
+
myprog.debug_bad_program_parse unless parsed
|
3212
|
+
parsed.should == true
|
3213
|
+
end
|
3214
|
+
|
3215
|
+
rx = nil
|
3216
|
+
it "can be converted to a regex" do
|
3217
|
+
rx = myprog.regexp
|
3218
|
+
rx.class.should == Regexp
|
3219
|
+
end
|
3220
|
+
|
3221
|
+
# Check sanity: Is test valid?
|
3222
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3223
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3224
|
+
|
3225
|
+
# Is compiled result valid?
|
3226
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3227
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3228
|
+
|
3229
|
+
|
3230
|
+
end
|
3231
|
+
|
3232
|
+
|
3233
|
+
### Test 84: Negative lookahead
|
3234
|
+
|
3235
|
+
describe "A correct program (Negative lookahead)" do
|
3236
|
+
prog = <<-'END'
|
3237
|
+
match find 3*D without " pesos" end
|
3238
|
+
END
|
3239
|
+
|
3240
|
+
good = ["103 dollars", "104 euros"]
|
3241
|
+
bad = ["105 pesos"]
|
3242
|
+
wanted = /(?!\d{3} pesos)\d{3}/
|
3243
|
+
|
3244
|
+
myprog = Program.new(prog)
|
3245
|
+
parsed = nil
|
3246
|
+
|
3247
|
+
it "should parse correctly" do
|
3248
|
+
parsed = myprog.parseable?
|
3249
|
+
myprog.debug_bad_program_parse unless parsed
|
3250
|
+
parsed.should == true
|
3251
|
+
end
|
3252
|
+
|
3253
|
+
rx = nil
|
3254
|
+
it "can be converted to a regex" do
|
3255
|
+
rx = myprog.regexp
|
3256
|
+
rx.class.should == Regexp
|
3257
|
+
end
|
3258
|
+
|
3259
|
+
# Check sanity: Is test valid?
|
3260
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3261
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3262
|
+
|
3263
|
+
# Is compiled result valid?
|
3264
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3265
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3266
|
+
|
3267
|
+
|
3268
|
+
end
|
3269
|
+
|
3270
|
+
|
3271
|
+
### Test 85: Positive lookbehind
|
3272
|
+
|
3273
|
+
describe "A correct program (Positive lookbehind)" do
|
3274
|
+
prog = <<-'END'
|
3275
|
+
match with "USD" find 3*D end
|
3276
|
+
END
|
3277
|
+
|
3278
|
+
good = ["USD106"]
|
3279
|
+
bad = ["EUR107"]
|
3280
|
+
wanted = /(?<=USD)\d{3}/
|
3281
|
+
|
3282
|
+
myprog = Program.new(prog)
|
3283
|
+
parsed = nil
|
3284
|
+
|
3285
|
+
it "should parse correctly" do
|
3286
|
+
parsed = myprog.parseable?
|
3287
|
+
myprog.debug_bad_program_parse unless parsed
|
3288
|
+
parsed.should == true
|
3289
|
+
end
|
3290
|
+
|
3291
|
+
rx = nil
|
3292
|
+
it "can be converted to a regex" do
|
3293
|
+
rx = myprog.regexp
|
3294
|
+
rx.class.should == Regexp
|
3295
|
+
end
|
3296
|
+
|
3297
|
+
# Check sanity: Is test valid?
|
3298
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3299
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3300
|
+
|
3301
|
+
# Is compiled result valid?
|
3302
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3303
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3304
|
+
|
3305
|
+
|
3306
|
+
end
|
3307
|
+
|
3308
|
+
|
3309
|
+
### Test 86: Negative lookbehind
|
3310
|
+
|
3311
|
+
describe "A correct program (Negative lookbehind)" do
|
3312
|
+
prog = <<-'END'
|
3313
|
+
match without "USD" find 3*D end
|
3314
|
+
END
|
3315
|
+
|
3316
|
+
good = ["EUR108"]
|
3317
|
+
bad = ["USD109"]
|
3318
|
+
wanted = /(?<!USD)\d{3}/
|
3319
|
+
|
3320
|
+
myprog = Program.new(prog)
|
3321
|
+
parsed = nil
|
3322
|
+
|
3323
|
+
it "should parse correctly" do
|
3324
|
+
parsed = myprog.parseable?
|
3325
|
+
myprog.debug_bad_program_parse unless parsed
|
3326
|
+
parsed.should == true
|
3327
|
+
end
|
3328
|
+
|
3329
|
+
rx = nil
|
3330
|
+
it "can be converted to a regex" do
|
3331
|
+
rx = myprog.regexp
|
3332
|
+
rx.class.should == Regexp
|
3333
|
+
end
|
3334
|
+
|
3335
|
+
# Check sanity: Is test valid?
|
3336
|
+
good.each {|str| it('has expected regex matching ' + str.inspect) { wanted.should =~ str } }
|
3337
|
+
bad.each {|str| it('has expected regex NOT matching ' + str.inspect) { wanted.should_not =~ str } }
|
3338
|
+
|
3339
|
+
# Is compiled result valid?
|
3340
|
+
good.each {|str| it('should match ' + str.inspect) { rx.should =~ str } }
|
3341
|
+
bad.each {|str| it('should NOT match ' + str.inspect) { rx.should_not =~ str } }
|
3342
|
+
|
3343
|
+
|
3344
|
+
end
|
3345
|
+
|
3346
|
+
|
3347
|
+
end
|