regexp_parser 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -1
  3. data/Gemfile +1 -1
  4. data/README.md +9 -13
  5. data/lib/regexp_parser/expression.rb +33 -21
  6. data/lib/regexp_parser/expression/classes/backref.rb +18 -10
  7. data/lib/regexp_parser/expression/classes/conditional.rb +4 -0
  8. data/lib/regexp_parser/expression/classes/group.rb +4 -2
  9. data/lib/regexp_parser/expression/classes/keep.rb +1 -3
  10. data/lib/regexp_parser/expression/methods/match_length.rb +172 -0
  11. data/lib/regexp_parser/expression/quantifier.rb +2 -2
  12. data/lib/regexp_parser/expression/sequence.rb +0 -4
  13. data/lib/regexp_parser/expression/subexpression.rb +3 -5
  14. data/lib/regexp_parser/lexer.rb +31 -24
  15. data/lib/regexp_parser/parser.rb +25 -3
  16. data/lib/regexp_parser/syntax/tokens.rb +2 -10
  17. data/lib/regexp_parser/version.rb +1 -1
  18. data/regexp_parser.gemspec +2 -2
  19. data/spec/expression/base_spec.rb +80 -0
  20. data/spec/expression/clone_spec.rb +120 -0
  21. data/spec/expression/conditional_spec.rb +89 -0
  22. data/spec/expression/free_space_spec.rb +27 -0
  23. data/spec/expression/methods/match_length_spec.rb +141 -0
  24. data/spec/expression/methods/strfregexp_spec.rb +224 -0
  25. data/spec/expression/methods/tests_spec.rb +97 -0
  26. data/spec/expression/methods/traverse_spec.rb +140 -0
  27. data/spec/expression/subexpression_spec.rb +50 -0
  28. data/spec/expression/to_h_spec.rb +26 -0
  29. data/spec/expression/to_s_spec.rb +100 -0
  30. data/spec/lexer/all_spec.rb +22 -0
  31. data/{test/lexer/test_conditionals.rb → spec/lexer/conditionals_spec.rb} +31 -35
  32. data/spec/lexer/escapes_spec.rb +38 -0
  33. data/spec/lexer/keep_spec.rb +22 -0
  34. data/{test/lexer/test_literals.rb → spec/lexer/literals_spec.rb} +20 -24
  35. data/{test/lexer/test_nesting.rb → spec/lexer/nesting_spec.rb} +11 -13
  36. data/spec/lexer/refcalls_spec.rb +54 -0
  37. data/spec/parser/all_spec.rb +31 -0
  38. data/spec/parser/alternation_spec.rb +88 -0
  39. data/{test/parser/test_anchors.rb → spec/parser/anchors_spec.rb} +7 -10
  40. data/spec/parser/conditionals_spec.rb +179 -0
  41. data/spec/parser/errors_spec.rb +51 -0
  42. data/spec/parser/escapes_spec.rb +132 -0
  43. data/spec/parser/free_space_spec.rb +130 -0
  44. data/spec/parser/groups_spec.rb +267 -0
  45. data/spec/parser/keep_spec.rb +19 -0
  46. data/spec/parser/posix_classes_spec.rb +27 -0
  47. data/spec/parser/properties_spec.rb +127 -0
  48. data/spec/parser/quantifiers_spec.rb +293 -0
  49. data/spec/parser/refcalls_spec.rb +237 -0
  50. data/spec/parser/set/intersections_spec.rb +127 -0
  51. data/spec/parser/set/ranges_spec.rb +111 -0
  52. data/spec/parser/sets_spec.rb +178 -0
  53. data/{test/parser/test_types.rb → spec/parser/types_spec.rb} +13 -20
  54. data/spec/scanner/all_spec.rb +18 -0
  55. data/{test/scanner/test_anchors.rb → spec/scanner/anchors_spec.rb} +8 -10
  56. data/{test/scanner/test_conditionals.rb → spec/scanner/conditionals_spec.rb} +49 -53
  57. data/spec/scanner/errors_spec.rb +90 -0
  58. data/{test/scanner/test_escapes.rb → spec/scanner/escapes_spec.rb} +8 -10
  59. data/{test/scanner/test_free_space.rb → spec/scanner/free_space_spec.rb} +48 -52
  60. data/{test/scanner/test_groups.rb → spec/scanner/groups_spec.rb} +33 -41
  61. data/spec/scanner/keep_spec.rb +33 -0
  62. data/{test/scanner/test_literals.rb → spec/scanner/literals_spec.rb} +8 -12
  63. data/{test/scanner/test_meta.rb → spec/scanner/meta_spec.rb} +8 -10
  64. data/{test/scanner/test_properties.rb → spec/scanner/properties_spec.rb} +14 -19
  65. data/{test/scanner/test_quantifiers.rb → spec/scanner/quantifiers_spec.rb} +7 -9
  66. data/{test/scanner/test_refcalls.rb → spec/scanner/refcalls_spec.rb} +9 -9
  67. data/{test/scanner/test_scripts.rb → spec/scanner/scripts_spec.rb} +8 -12
  68. data/{test/scanner/test_sets.rb → spec/scanner/sets_spec.rb} +14 -17
  69. data/spec/scanner/types_spec.rb +29 -0
  70. data/spec/scanner/unicode_blocks_spec.rb +28 -0
  71. data/spec/spec_helper.rb +14 -0
  72. data/{test → spec}/support/runner.rb +9 -8
  73. data/{test → spec}/support/warning_extractor.rb +5 -7
  74. data/spec/syntax/syntax_spec.rb +44 -0
  75. data/spec/syntax/syntax_token_map_spec.rb +23 -0
  76. data/spec/syntax/versions/1.8.6_spec.rb +38 -0
  77. data/spec/syntax/versions/1.9.1_spec.rb +23 -0
  78. data/spec/syntax/versions/1.9.3_spec.rb +22 -0
  79. data/spec/syntax/versions/2.0.0_spec.rb +28 -0
  80. data/spec/syntax/versions/2.2.0_spec.rb +22 -0
  81. data/spec/syntax/versions/aliases_spec.rb +119 -0
  82. data/spec/token/token_spec.rb +85 -0
  83. metadata +131 -140
  84. data/test/expression/test_all.rb +0 -12
  85. data/test/expression/test_base.rb +0 -90
  86. data/test/expression/test_clone.rb +0 -89
  87. data/test/expression/test_conditionals.rb +0 -113
  88. data/test/expression/test_free_space.rb +0 -35
  89. data/test/expression/test_set.rb +0 -84
  90. data/test/expression/test_strfregexp.rb +0 -230
  91. data/test/expression/test_subexpression.rb +0 -58
  92. data/test/expression/test_tests.rb +0 -99
  93. data/test/expression/test_to_h.rb +0 -59
  94. data/test/expression/test_to_s.rb +0 -104
  95. data/test/expression/test_traverse.rb +0 -161
  96. data/test/helpers.rb +0 -10
  97. data/test/lexer/test_all.rb +0 -41
  98. data/test/lexer/test_keep.rb +0 -24
  99. data/test/lexer/test_refcalls.rb +0 -56
  100. data/test/parser/set/test_intersections.rb +0 -127
  101. data/test/parser/set/test_ranges.rb +0 -111
  102. data/test/parser/test_all.rb +0 -64
  103. data/test/parser/test_alternation.rb +0 -92
  104. data/test/parser/test_conditionals.rb +0 -187
  105. data/test/parser/test_errors.rb +0 -63
  106. data/test/parser/test_escapes.rb +0 -134
  107. data/test/parser/test_free_space.rb +0 -139
  108. data/test/parser/test_groups.rb +0 -289
  109. data/test/parser/test_keep.rb +0 -21
  110. data/test/parser/test_posix_classes.rb +0 -27
  111. data/test/parser/test_properties.rb +0 -134
  112. data/test/parser/test_quantifiers.rb +0 -301
  113. data/test/parser/test_refcalls.rb +0 -186
  114. data/test/parser/test_sets.rb +0 -179
  115. data/test/scanner/test_all.rb +0 -38
  116. data/test/scanner/test_errors.rb +0 -91
  117. data/test/scanner/test_keep.rb +0 -35
  118. data/test/scanner/test_types.rb +0 -35
  119. data/test/scanner/test_unicode_blocks.rb +0 -30
  120. data/test/support/disable_autotest.rb +0 -8
  121. data/test/syntax/test_all.rb +0 -6
  122. data/test/syntax/test_syntax.rb +0 -61
  123. data/test/syntax/test_syntax_token_map.rb +0 -25
  124. data/test/syntax/versions/test_1.8.rb +0 -55
  125. data/test/syntax/versions/test_1.9.1.rb +0 -36
  126. data/test/syntax/versions/test_1.9.3.rb +0 -32
  127. data/test/syntax/versions/test_2.0.0.rb +0 -37
  128. data/test/syntax/versions/test_2.2.0.rb +0 -32
  129. data/test/syntax/versions/test_aliases.rb +0 -129
  130. data/test/syntax/versions/test_all.rb +0 -5
  131. data/test/test_all.rb +0 -5
  132. data/test/token/test_all.rb +0 -2
  133. data/test/token/test_token.rb +0 -107
@@ -0,0 +1,237 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('Refcall parsing') do
4
+ specify('parse traditional number backref') do
5
+ root = RP.parse('(abc)\\1', 'ruby/1.9')
6
+ exp = root[1]
7
+
8
+ expect(exp).to be_instance_of(Backreference::Number)
9
+ expect(exp.number).to eq 1
10
+ end
11
+
12
+ specify('parse backref named ab') do
13
+ root = RP.parse('(?<X>abc)\\k<X>', 'ruby/1.9')
14
+ exp = root[1]
15
+
16
+ expect(exp).to be_instance_of(Backreference::Name)
17
+ expect(exp.name).to eq 'X'
18
+ end
19
+
20
+ specify('parse backref named sq') do
21
+ root = RP.parse("(?<X>abc)\\k'X'", 'ruby/1.9')
22
+ exp = root[1]
23
+
24
+ expect(exp).to be_instance_of(Backreference::Name)
25
+ expect(exp.name).to eq 'X'
26
+ end
27
+
28
+ specify('parse backref number ab') do
29
+ root = RP.parse('(abc)\\k<1>', 'ruby/1.9')
30
+ exp = root[1]
31
+
32
+ expect(exp).to be_instance_of(Backreference::Number)
33
+ expect(exp.number).to eq 1
34
+ end
35
+
36
+ specify('parse backref number sq') do
37
+ root = RP.parse("(abc)\\k'1'", 'ruby/1.9')
38
+ exp = root[1]
39
+
40
+ expect(exp).to be_instance_of(Backreference::Number)
41
+ expect(exp.number).to eq 1
42
+ end
43
+
44
+ specify('parse backref number relative ab') do
45
+ root = RP.parse('(abc)\\k<-1>', 'ruby/1.9')
46
+ exp = root[1]
47
+
48
+ expect(exp).to be_instance_of(Backreference::NumberRelative)
49
+ expect(exp.number).to eq(-1)
50
+ end
51
+
52
+ specify('parse backref number relative sq') do
53
+ root = RP.parse("(abc)\\k'-1'", 'ruby/1.9')
54
+ exp = root[1]
55
+
56
+ expect(exp).to be_instance_of(Backreference::NumberRelative)
57
+ expect(exp.number).to eq(-1)
58
+ end
59
+
60
+ specify('parse backref effective_number') do
61
+ root = RP.parse('(abc)(def)\\k<-1>(ghi)\\k<-3>\\k<-1>', 'ruby/1.9')
62
+ exp1 = root[2]
63
+ exp2 = root[4]
64
+ exp3 = root[5]
65
+
66
+ expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberRelative)
67
+ expect(exp1.effective_number).to eq 2
68
+ expect(exp2.effective_number).to eq 1
69
+ expect(exp3.effective_number).to eq 3
70
+ end
71
+
72
+ specify('parse backref referenced_expression') do
73
+ root = RP.parse('(abc)(def)\\k<-1>(ghi)\\k<-3>\\k<-1>', 'ruby/1.9')
74
+ exp1 = root[2]
75
+ exp2 = root[4]
76
+ exp3 = root[5]
77
+
78
+ expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberRelative)
79
+
80
+ expect(exp1.referenced_expression.to_s).to eq '(def)'
81
+ expect(exp2.referenced_expression.to_s).to eq '(abc)'
82
+ expect(exp3.referenced_expression.to_s).to eq '(ghi)'
83
+ end
84
+
85
+ specify('parse backref name call ab') do
86
+ root = RP.parse('(?<X>abc)\\g<X>', 'ruby/1.9')
87
+ exp = root[1]
88
+
89
+ expect(exp).to be_instance_of(Backreference::NameCall)
90
+ expect(exp.name).to eq 'X'
91
+ end
92
+
93
+ specify('parse backref name call sq') do
94
+ root = RP.parse("(?<X>abc)\\g'X'", 'ruby/1.9')
95
+ exp = root[1]
96
+
97
+ expect(exp).to be_instance_of(Backreference::NameCall)
98
+ expect(exp.name).to eq 'X'
99
+ end
100
+
101
+ specify('parse backref number call ab') do
102
+ root = RP.parse('(abc)\\g<1>', 'ruby/1.9')
103
+ exp = root[1]
104
+
105
+ expect(exp).to be_instance_of(Backreference::NumberCall)
106
+ expect(exp.number).to eq 1
107
+ end
108
+
109
+ specify('parse backref number call sq') do
110
+ root = RP.parse("(abc)\\g'1'", 'ruby/1.9')
111
+ exp = root[1]
112
+
113
+ expect(exp).to be_instance_of(Backreference::NumberCall)
114
+ expect(exp.number).to eq 1
115
+ end
116
+
117
+ specify('parse backref number relative call ab') do
118
+ root = RP.parse('(abc)\\g<-1>', 'ruby/1.9')
119
+ exp = root[1]
120
+
121
+ expect(exp).to be_instance_of(Backreference::NumberCallRelative)
122
+ expect(exp.number).to eq(-1)
123
+ end
124
+
125
+ specify('parse backref number relative call sq') do
126
+ root = RP.parse("(abc)\\g'-1'", 'ruby/1.9')
127
+ exp = root[1]
128
+
129
+ expect(exp).to be_instance_of(Backreference::NumberCallRelative)
130
+ expect(exp.number).to eq(-1)
131
+ end
132
+
133
+ specify('parse backref number relative forward call ab') do
134
+ root = RP.parse('\\g<+1>(abc)', 'ruby/1.9')
135
+ exp = root[0]
136
+
137
+ expect(exp).to be_instance_of(Backreference::NumberCallRelative)
138
+ expect(exp.number).to eq 1
139
+ end
140
+
141
+ specify('parse backref number relative forward call sq') do
142
+ root = RP.parse("\\g'+1'(abc)", 'ruby/1.9')
143
+ exp = root[0]
144
+
145
+ expect(exp).to be_instance_of(Backreference::NumberCallRelative)
146
+ expect(exp.number).to eq 1
147
+ end
148
+
149
+ specify('parse backref call effective_number') do
150
+ root = RP.parse('\\g<+1>(abc)\\g<+2>(def)(ghi)\\g<-2>', 'ruby/1.9')
151
+ exp1 = root[0]
152
+ exp2 = root[2]
153
+ exp3 = root[5]
154
+
155
+ expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberCallRelative)
156
+
157
+ expect(exp1.effective_number).to eq 1
158
+ expect(exp2.effective_number).to eq 3
159
+ expect(exp3.effective_number).to eq 2
160
+ end
161
+
162
+ specify('parse backref call referenced_expression') do
163
+ root = RP.parse('\\g<+1>(abc)\\g<+2>(def)(ghi)\\g<-2>', 'ruby/1.9')
164
+ exp1 = root[0]
165
+ exp2 = root[2]
166
+ exp3 = root[5]
167
+
168
+ expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberCallRelative)
169
+
170
+ expect(exp1.referenced_expression.to_s).to eq '(abc)'
171
+ expect(exp2.referenced_expression.to_s).to eq '(ghi)'
172
+ expect(exp3.referenced_expression.to_s).to eq '(def)'
173
+ end
174
+
175
+ specify('parse backref name recursion level ab') do
176
+ root = RP.parse('(?<X>abc)\\k<X-0>', 'ruby/1.9')
177
+ exp = root[1]
178
+
179
+ expect(exp).to be_instance_of(Backreference::NameRecursionLevel)
180
+ expect(exp.name).to eq 'X'
181
+ expect(exp.recursion_level).to eq 0
182
+ end
183
+
184
+ specify('parse backref name recursion level sq') do
185
+ root = RP.parse("(?<X>abc)\\k'X-0'", 'ruby/1.9')
186
+ exp = root[1]
187
+
188
+ expect(exp).to be_instance_of(Backreference::NameRecursionLevel)
189
+ expect(exp.name).to eq 'X'
190
+ expect(exp.recursion_level).to eq 0
191
+ end
192
+
193
+ specify('parse backref number recursion level ab') do
194
+ root = RP.parse('(abc)\\k<1-0>', 'ruby/1.9')
195
+ exp = root[1]
196
+
197
+ expect(exp).to be_instance_of(Backreference::NumberRecursionLevel)
198
+ expect(exp.number).to eq 1
199
+ expect(exp.recursion_level).to eq 0
200
+ end
201
+
202
+ specify('parse backref number recursion level sq') do
203
+ root = RP.parse("(abc)\\k'1-0'", 'ruby/1.9')
204
+ exp = root[1]
205
+
206
+ expect(exp).to be_instance_of(Backreference::NumberRecursionLevel)
207
+ expect(exp.number).to eq 1
208
+ expect(exp.recursion_level).to eq 0
209
+ end
210
+
211
+ specify('parse backref negative number recursion level') do
212
+ root = RP.parse("(abc)\\k'-1+0'", 'ruby/1.9')
213
+ exp = root[1]
214
+
215
+ expect(exp).to be_instance_of(Backreference::NumberRecursionLevel)
216
+ expect(exp.number).to eq(-1)
217
+ expect(exp.recursion_level).to eq 0
218
+ end
219
+
220
+ specify('parse backref number positive recursion level') do
221
+ root = RP.parse("(abc)\\k'1+1'", 'ruby/1.9')
222
+ exp = root[1]
223
+
224
+ expect(exp).to be_instance_of(Backreference::NumberRecursionLevel)
225
+ expect(exp.number).to eq 1
226
+ expect(exp.recursion_level).to eq 1
227
+ end
228
+
229
+ specify('parse backref number negative recursion level') do
230
+ root = RP.parse("(abc)\\k'1-1'", 'ruby/1.9')
231
+ exp = root[1]
232
+
233
+ expect(exp).to be_instance_of(Backreference::NumberRecursionLevel)
234
+ expect(exp.number).to eq 1
235
+ expect(exp.recursion_level).to eq(-1)
236
+ end
237
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ # edge cases with `...-&&...` and `...&&-...` are checked in test_ranges.rb
4
+
5
+ RSpec.describe('SetIntersection parsing') do
6
+ specify('parse set intersection') do
7
+ root = RP.parse('[a&&z]')
8
+ set = root[0]
9
+ ints = set[0]
10
+
11
+ expect(set.count).to eq 1
12
+ expect(ints).to be_instance_of(CharacterSet::Intersection)
13
+ expect(ints.count).to eq 2
14
+
15
+ seq1, seq2 = ints.expressions
16
+ expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
17
+ expect(seq1.count).to eq 1
18
+ expect(seq1.first.to_s).to eq 'a'
19
+ expect(seq1.first).to be_instance_of(Literal)
20
+ expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
21
+ expect(seq2.count).to eq 1
22
+ expect(seq2.first.to_s).to eq 'z'
23
+ expect(seq2.first).to be_instance_of(Literal)
24
+
25
+ expect(set.matches?('a')).to be false
26
+ expect(set.matches?('&')).to be false
27
+ expect(set.matches?('z')).to be false
28
+ end
29
+
30
+ specify('parse set intersection range and subset') do
31
+ root = RP.parse('[a-z&&[^a]]')
32
+ set = root[0]
33
+ ints = set[0]
34
+
35
+ expect(set.count).to eq 1
36
+ expect(ints).to be_instance_of(CharacterSet::Intersection)
37
+ expect(ints.count).to eq 2
38
+
39
+ seq1, seq2 = ints.expressions
40
+ expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
41
+ expect(seq1.count).to eq 1
42
+ expect(seq1.first.to_s).to eq 'a-z'
43
+ expect(seq1.first).to be_instance_of(CharacterSet::Range)
44
+ expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
45
+ expect(seq2.count).to eq 1
46
+ expect(seq2.first.to_s).to eq '[^a]'
47
+ expect(seq2.first).to be_instance_of(CharacterSet)
48
+
49
+ expect(set.matches?('a')).to be false
50
+ expect(set.matches?('&')).to be false
51
+ expect(set.matches?('b')).to be true
52
+ end
53
+
54
+ specify('parse set intersection trailing range') do
55
+ root = RP.parse('[a&&a-z]')
56
+ set = root[0]
57
+ ints = set[0]
58
+
59
+ expect(set.count).to eq 1
60
+ expect(ints).to be_instance_of(CharacterSet::Intersection)
61
+ expect(ints.count).to eq 2
62
+
63
+ seq1, seq2 = ints.expressions
64
+ expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
65
+ expect(seq1.count).to eq 1
66
+ expect(seq1.first.to_s).to eq 'a'
67
+ expect(seq1.first).to be_instance_of(Literal)
68
+ expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
69
+ expect(seq2.count).to eq 1
70
+ expect(seq2.first.to_s).to eq 'a-z'
71
+ expect(seq2.first).to be_instance_of(CharacterSet::Range)
72
+
73
+ expect(set.matches?('a')).to be true
74
+ expect(set.matches?('&')).to be false
75
+ expect(set.matches?('b')).to be false
76
+ end
77
+
78
+ specify('parse set intersection type') do
79
+ root = RP.parse('[a&&\\w]')
80
+ set = root[0]
81
+ ints = set[0]
82
+
83
+ expect(set.count).to eq 1
84
+ expect(ints).to be_instance_of(CharacterSet::Intersection)
85
+ expect(ints.count).to eq 2
86
+
87
+ seq1, seq2 = ints.expressions
88
+ expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
89
+ expect(seq1.count).to eq 1
90
+ expect(seq1.first.to_s).to eq 'a'
91
+ expect(seq1.first).to be_instance_of(Literal)
92
+ expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
93
+ expect(seq2.count).to eq 1
94
+ expect(seq2.first.to_s).to eq '\\w'
95
+ expect(seq2.first).to be_instance_of(CharacterType::Word)
96
+
97
+ expect(set.matches?('a')).to be true
98
+ expect(set.matches?('&')).to be false
99
+ expect(set.matches?('b')).to be false
100
+ end
101
+
102
+ specify('parse set intersection multipart') do
103
+ root = RP.parse('[\\h&&\\w&&efg]')
104
+ set = root[0]
105
+ ints = set[0]
106
+
107
+ expect(set.count).to eq 1
108
+ expect(ints).to be_instance_of(CharacterSet::Intersection)
109
+ expect(ints.count).to eq 3
110
+
111
+ seq1, seq2, seq3 = ints.expressions
112
+ expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
113
+ expect(seq1.count).to eq 1
114
+ expect(seq1.first.to_s).to eq '\\h'
115
+ expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
116
+ expect(seq2.count).to eq 1
117
+ expect(seq2.first.to_s).to eq '\\w'
118
+ expect(seq3).to be_instance_of(CharacterSet::IntersectedSequence)
119
+ expect(seq3.count).to eq 3
120
+ expect(seq3.to_s).to eq 'efg'
121
+
122
+ expect(set.matches?('e')).to be true
123
+ expect(set.matches?('f')).to be true
124
+ expect(set.matches?('a')).to be false
125
+ expect(set.matches?('g')).to be false
126
+ end
127
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('SetRang parsing') do
4
+ specify('parse set range') do
5
+ root = RP.parse('[a-z]')
6
+ set = root[0]
7
+ range = set[0]
8
+
9
+ expect(set.count).to eq 1
10
+ expect(range).to be_instance_of(CharacterSet::Range)
11
+ expect(range.count).to eq 2
12
+ expect(range.first.to_s).to eq 'a'
13
+ expect(range.first).to be_instance_of(Literal)
14
+ expect(range.last.to_s).to eq 'z'
15
+ expect(range.last).to be_instance_of(Literal)
16
+ expect(set.matches?('m')).to be true
17
+ end
18
+
19
+ specify('parse set range hex') do
20
+ root = RP.parse('[\\x00-\\x99]')
21
+ set = root[0]
22
+ range = set[0]
23
+
24
+ expect(set.count).to eq 1
25
+ expect(range).to be_instance_of(CharacterSet::Range)
26
+ expect(range.count).to eq 2
27
+ expect(range.first.to_s).to eq '\\x00'
28
+ expect(range.first).to be_instance_of(EscapeSequence::Hex)
29
+ expect(range.last.to_s).to eq '\\x99'
30
+ expect(range.last).to be_instance_of(EscapeSequence::Hex)
31
+ expect(set.matches?('\\x50')).to be true
32
+ end
33
+
34
+ specify('parse set range unicode') do
35
+ root = RP.parse('[\\u{40 42}-\\u1234]')
36
+ set = root[0]
37
+ range = set[0]
38
+
39
+ expect(set.count).to eq 1
40
+ expect(range).to be_instance_of(CharacterSet::Range)
41
+ expect(range.count).to eq 2
42
+ expect(range.first.to_s).to eq '\\u{40 42}'
43
+ expect(range.first).to be_instance_of(EscapeSequence::CodepointList)
44
+ expect(range.last.to_s).to eq '\\u1234'
45
+ expect(range.last).to be_instance_of(EscapeSequence::Codepoint)
46
+ expect(set.matches?('\\u600')).to be true
47
+ end
48
+
49
+ specify('parse set range edge case leading dash') do
50
+ root = RP.parse('[--z]')
51
+ set = root[0]
52
+ range = set[0]
53
+
54
+ expect(set.count).to eq 1
55
+ expect(range.count).to eq 2
56
+ expect(set.matches?('a')).to be true
57
+ end
58
+
59
+ specify('parse set range edge case trailing dash') do
60
+ root = RP.parse('[!--]')
61
+ set = root[0]
62
+ range = set[0]
63
+
64
+ expect(set.count).to eq 1
65
+ expect(range.count).to eq 2
66
+ expect(set.matches?('$')).to be true
67
+ end
68
+
69
+ specify('parse set range edge case leading negate') do
70
+ root = RP.parse('[^-z]')
71
+ set = root[0]
72
+
73
+ expect(set.count).to eq 2
74
+ expect(set.matches?('a')).to be true
75
+ expect(set.matches?('z')).to be false
76
+ end
77
+
78
+ specify('parse set range edge case trailing negate') do
79
+ root = RP.parse('[!-^]')
80
+ set = root[0]
81
+ range = set[0]
82
+
83
+ expect(set.count).to eq 1
84
+ expect(range.count).to eq 2
85
+ expect(set.matches?('$')).to be true
86
+ end
87
+
88
+ specify('parse set range edge case leading intersection') do
89
+ root = RP.parse('[[\\-ab]&&-bc]')
90
+ set = root[0]
91
+
92
+ expect(set.count).to eq 1
93
+ expect(set.first.last.to_s).to eq '-bc'
94
+ expect(set.matches?('-')).to be true
95
+ expect(set.matches?('b')).to be true
96
+ expect(set.matches?('a')).to be false
97
+ expect(set.matches?('c')).to be false
98
+ end
99
+
100
+ specify('parse set range edge case trailing intersection') do
101
+ root = RP.parse('[bc-&&[\\-ab]]')
102
+ set = root[0]
103
+
104
+ expect(set.count).to eq 1
105
+ expect(set.first.first.to_s).to eq 'bc-'
106
+ expect(set.matches?('-')).to be true
107
+ expect(set.matches?('b')).to be true
108
+ expect(set.matches?('a')).to be false
109
+ expect(set.matches?('c')).to be false
110
+ end
111
+ end