regexp_parser 1.7.0 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -2
  3. data/LICENSE +1 -1
  4. data/Rakefile +6 -70
  5. data/lib/regexp_parser/error.rb +4 -0
  6. data/lib/regexp_parser/expression/base.rb +76 -0
  7. data/lib/regexp_parser/expression/classes/alternation.rb +1 -1
  8. data/lib/regexp_parser/expression/classes/anchor.rb +0 -2
  9. data/lib/regexp_parser/expression/classes/{backref.rb → backreference.rb} +22 -2
  10. data/lib/regexp_parser/expression/classes/{set → character_set}/range.rb +4 -8
  11. data/lib/regexp_parser/expression/classes/{set.rb → character_set.rb} +3 -4
  12. data/lib/regexp_parser/expression/classes/{type.rb → character_type.rb} +0 -2
  13. data/lib/regexp_parser/expression/classes/conditional.rb +11 -5
  14. data/lib/regexp_parser/expression/classes/{escape.rb → escape_sequence.rb} +15 -7
  15. data/lib/regexp_parser/expression/classes/free_space.rb +5 -5
  16. data/lib/regexp_parser/expression/classes/group.rb +28 -15
  17. data/lib/regexp_parser/expression/classes/keep.rb +2 -0
  18. data/lib/regexp_parser/expression/classes/literal.rb +1 -5
  19. data/lib/regexp_parser/expression/classes/posix_class.rb +5 -1
  20. data/lib/regexp_parser/expression/classes/root.rb +4 -19
  21. data/lib/regexp_parser/expression/classes/{property.rb → unicode_property.rb} +5 -3
  22. data/lib/regexp_parser/expression/methods/construct.rb +41 -0
  23. data/lib/regexp_parser/expression/methods/human_name.rb +43 -0
  24. data/lib/regexp_parser/expression/methods/match_length.rb +11 -7
  25. data/lib/regexp_parser/expression/methods/parts.rb +23 -0
  26. data/lib/regexp_parser/expression/methods/printing.rb +26 -0
  27. data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
  28. data/lib/regexp_parser/expression/methods/tests.rb +47 -1
  29. data/lib/regexp_parser/expression/methods/traverse.rb +34 -18
  30. data/lib/regexp_parser/expression/quantifier.rb +57 -17
  31. data/lib/regexp_parser/expression/sequence.rb +11 -47
  32. data/lib/regexp_parser/expression/sequence_operation.rb +4 -9
  33. data/lib/regexp_parser/expression/shared.rb +111 -0
  34. data/lib/regexp_parser/expression/subexpression.rb +27 -19
  35. data/lib/regexp_parser/expression.rb +14 -141
  36. data/lib/regexp_parser/lexer.rb +83 -41
  37. data/lib/regexp_parser/parser.rb +371 -429
  38. data/lib/regexp_parser/scanner/char_type.rl +11 -11
  39. data/lib/regexp_parser/scanner/errors/premature_end_error.rb +8 -0
  40. data/lib/regexp_parser/scanner/errors/scanner_error.rb +6 -0
  41. data/lib/regexp_parser/scanner/errors/validation_error.rb +63 -0
  42. data/lib/regexp_parser/scanner/properties/long.csv +633 -0
  43. data/lib/regexp_parser/scanner/properties/short.csv +248 -0
  44. data/lib/regexp_parser/scanner/property.rl +4 -4
  45. data/lib/regexp_parser/scanner/scanner.rl +303 -368
  46. data/lib/regexp_parser/scanner.rb +1423 -1674
  47. data/lib/regexp_parser/syntax/any.rb +2 -7
  48. data/lib/regexp_parser/syntax/base.rb +92 -67
  49. data/lib/regexp_parser/syntax/token/anchor.rb +15 -0
  50. data/lib/regexp_parser/syntax/{tokens → token}/assertion.rb +2 -2
  51. data/lib/regexp_parser/syntax/token/backreference.rb +33 -0
  52. data/lib/regexp_parser/syntax/token/character_set.rb +16 -0
  53. data/lib/regexp_parser/syntax/{tokens → token}/character_type.rb +3 -3
  54. data/lib/regexp_parser/syntax/{tokens → token}/conditional.rb +3 -3
  55. data/lib/regexp_parser/syntax/token/escape.rb +33 -0
  56. data/lib/regexp_parser/syntax/{tokens → token}/group.rb +7 -7
  57. data/lib/regexp_parser/syntax/{tokens → token}/keep.rb +1 -1
  58. data/lib/regexp_parser/syntax/token/meta.rb +20 -0
  59. data/lib/regexp_parser/syntax/{tokens → token}/posix_class.rb +3 -3
  60. data/lib/regexp_parser/syntax/token/quantifier.rb +35 -0
  61. data/lib/regexp_parser/syntax/token/unicode_property.rb +733 -0
  62. data/lib/regexp_parser/syntax/token/virtual.rb +11 -0
  63. data/lib/regexp_parser/syntax/token.rb +45 -0
  64. data/lib/regexp_parser/syntax/version_lookup.rb +19 -36
  65. data/lib/regexp_parser/syntax/versions/1.8.6.rb +13 -20
  66. data/lib/regexp_parser/syntax/versions/1.9.1.rb +10 -17
  67. data/lib/regexp_parser/syntax/versions/1.9.3.rb +3 -10
  68. data/lib/regexp_parser/syntax/versions/2.0.0.rb +8 -15
  69. data/lib/regexp_parser/syntax/versions/2.2.0.rb +3 -9
  70. data/lib/regexp_parser/syntax/versions/2.3.0.rb +3 -9
  71. data/lib/regexp_parser/syntax/versions/2.4.0.rb +3 -9
  72. data/lib/regexp_parser/syntax/versions/2.4.1.rb +2 -8
  73. data/lib/regexp_parser/syntax/versions/2.5.0.rb +3 -9
  74. data/lib/regexp_parser/syntax/versions/2.6.0.rb +3 -9
  75. data/lib/regexp_parser/syntax/versions/2.6.2.rb +3 -9
  76. data/lib/regexp_parser/syntax/versions/2.6.3.rb +3 -9
  77. data/lib/regexp_parser/syntax/versions/3.1.0.rb +4 -0
  78. data/lib/regexp_parser/syntax/versions/3.2.0.rb +4 -0
  79. data/lib/regexp_parser/syntax/versions.rb +3 -1
  80. data/lib/regexp_parser/syntax.rb +8 -6
  81. data/lib/regexp_parser/token.rb +9 -20
  82. data/lib/regexp_parser/version.rb +1 -1
  83. data/lib/regexp_parser.rb +0 -2
  84. data/regexp_parser.gemspec +19 -23
  85. metadata +52 -171
  86. data/CHANGELOG.md +0 -349
  87. data/README.md +0 -470
  88. data/lib/regexp_parser/scanner/properties/long.yml +0 -594
  89. data/lib/regexp_parser/scanner/properties/short.yml +0 -237
  90. data/lib/regexp_parser/syntax/tokens/anchor.rb +0 -15
  91. data/lib/regexp_parser/syntax/tokens/backref.rb +0 -24
  92. data/lib/regexp_parser/syntax/tokens/character_set.rb +0 -13
  93. data/lib/regexp_parser/syntax/tokens/escape.rb +0 -30
  94. data/lib/regexp_parser/syntax/tokens/meta.rb +0 -13
  95. data/lib/regexp_parser/syntax/tokens/quantifier.rb +0 -35
  96. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +0 -675
  97. data/lib/regexp_parser/syntax/tokens.rb +0 -45
  98. data/spec/expression/base_spec.rb +0 -94
  99. data/spec/expression/clone_spec.rb +0 -120
  100. data/spec/expression/conditional_spec.rb +0 -89
  101. data/spec/expression/free_space_spec.rb +0 -27
  102. data/spec/expression/methods/match_length_spec.rb +0 -161
  103. data/spec/expression/methods/match_spec.rb +0 -25
  104. data/spec/expression/methods/strfregexp_spec.rb +0 -224
  105. data/spec/expression/methods/tests_spec.rb +0 -99
  106. data/spec/expression/methods/traverse_spec.rb +0 -161
  107. data/spec/expression/options_spec.rb +0 -128
  108. data/spec/expression/root_spec.rb +0 -9
  109. data/spec/expression/sequence_spec.rb +0 -9
  110. data/spec/expression/subexpression_spec.rb +0 -50
  111. data/spec/expression/to_h_spec.rb +0 -26
  112. data/spec/expression/to_s_spec.rb +0 -100
  113. data/spec/lexer/all_spec.rb +0 -22
  114. data/spec/lexer/conditionals_spec.rb +0 -53
  115. data/spec/lexer/escapes_spec.rb +0 -14
  116. data/spec/lexer/keep_spec.rb +0 -10
  117. data/spec/lexer/literals_spec.rb +0 -89
  118. data/spec/lexer/nesting_spec.rb +0 -99
  119. data/spec/lexer/refcalls_spec.rb +0 -55
  120. data/spec/parser/all_spec.rb +0 -43
  121. data/spec/parser/alternation_spec.rb +0 -88
  122. data/spec/parser/anchors_spec.rb +0 -17
  123. data/spec/parser/conditionals_spec.rb +0 -179
  124. data/spec/parser/errors_spec.rb +0 -30
  125. data/spec/parser/escapes_spec.rb +0 -121
  126. data/spec/parser/free_space_spec.rb +0 -130
  127. data/spec/parser/groups_spec.rb +0 -108
  128. data/spec/parser/keep_spec.rb +0 -6
  129. data/spec/parser/posix_classes_spec.rb +0 -8
  130. data/spec/parser/properties_spec.rb +0 -115
  131. data/spec/parser/quantifiers_spec.rb +0 -51
  132. data/spec/parser/refcalls_spec.rb +0 -112
  133. data/spec/parser/set/intersections_spec.rb +0 -127
  134. data/spec/parser/set/ranges_spec.rb +0 -111
  135. data/spec/parser/sets_spec.rb +0 -178
  136. data/spec/parser/types_spec.rb +0 -18
  137. data/spec/scanner/all_spec.rb +0 -18
  138. data/spec/scanner/anchors_spec.rb +0 -21
  139. data/spec/scanner/conditionals_spec.rb +0 -128
  140. data/spec/scanner/errors_spec.rb +0 -68
  141. data/spec/scanner/escapes_spec.rb +0 -53
  142. data/spec/scanner/free_space_spec.rb +0 -133
  143. data/spec/scanner/groups_spec.rb +0 -52
  144. data/spec/scanner/keep_spec.rb +0 -10
  145. data/spec/scanner/literals_spec.rb +0 -49
  146. data/spec/scanner/meta_spec.rb +0 -18
  147. data/spec/scanner/properties_spec.rb +0 -64
  148. data/spec/scanner/quantifiers_spec.rb +0 -20
  149. data/spec/scanner/refcalls_spec.rb +0 -36
  150. data/spec/scanner/sets_spec.rb +0 -102
  151. data/spec/scanner/types_spec.rb +0 -14
  152. data/spec/spec_helper.rb +0 -15
  153. data/spec/support/runner.rb +0 -42
  154. data/spec/support/shared_examples.rb +0 -77
  155. data/spec/support/warning_extractor.rb +0 -60
  156. data/spec/syntax/syntax_spec.rb +0 -48
  157. data/spec/syntax/syntax_token_map_spec.rb +0 -23
  158. data/spec/syntax/versions/1.8.6_spec.rb +0 -17
  159. data/spec/syntax/versions/1.9.1_spec.rb +0 -10
  160. data/spec/syntax/versions/1.9.3_spec.rb +0 -9
  161. data/spec/syntax/versions/2.0.0_spec.rb +0 -13
  162. data/spec/syntax/versions/2.2.0_spec.rb +0 -9
  163. data/spec/syntax/versions/aliases_spec.rb +0 -37
  164. data/spec/token/token_spec.rb +0 -85
  165. /data/lib/regexp_parser/expression/classes/{set → character_set}/intersection.rb +0 -0
@@ -1,224 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Expression#strfregexp') do
4
- specify('#strfre alias') do
5
- expect(RP.parse(/a/)).to respond_to(:strfre)
6
- end
7
-
8
- specify('#strfregexp level') do
9
- root = RP.parse(/a(b(c))/)
10
-
11
- expect(root.strfregexp('%l')).to eq 'root'
12
-
13
- a = root.first
14
- expect(a.strfregexp('%%l')).to eq '%0'
15
-
16
- b = root[1].first
17
- expect(b.strfregexp('<%l>')).to eq '<1>'
18
-
19
- c = root[1][1].first
20
- expect(c.strfregexp('[at: %l]')).to eq '[at: 2]'
21
- end
22
-
23
- specify('#strfregexp start end') do
24
- root = RP.parse(/a(b(c))/)
25
-
26
- expect(root.strfregexp('%s')).to eq '0'
27
- expect(root.strfregexp('%e')).to eq '7'
28
-
29
- a = root.first
30
- expect(a.strfregexp('%%s')).to eq '%0'
31
- expect(a.strfregexp('%e')).to eq '1'
32
-
33
- group_1 = root[1]
34
- expect(group_1.strfregexp('GRP:%s')).to eq 'GRP:1'
35
- expect(group_1.strfregexp('%e')).to eq '7'
36
-
37
- b = group_1.first
38
- expect(b.strfregexp('<@%s>')).to eq '<@2>'
39
- expect(b.strfregexp('%e')).to eq '3'
40
-
41
- c = group_1.last.first
42
- expect(c.strfregexp('[at: %s]')).to eq '[at: 4]'
43
- expect(c.strfregexp('%e')).to eq '5'
44
- end
45
-
46
- specify('#strfregexp length') do
47
- root = RP.parse(/a[b]c/)
48
-
49
- expect(root.strfregexp('%S')).to eq '5'
50
-
51
- a = root.first
52
- expect(a.strfregexp('%S')).to eq '1'
53
-
54
- set = root[1]
55
- expect(set.strfregexp('%S')).to eq '3'
56
- end
57
-
58
- specify('#strfregexp coded offset') do
59
- root = RP.parse(/a[b]c/)
60
-
61
- expect(root.strfregexp('%o')).to eq '@0+5'
62
-
63
- a = root.first
64
- expect(a.strfregexp('%o')).to eq '@0+1'
65
-
66
- set = root[1]
67
- expect(set.strfregexp('%o')).to eq '@1+3'
68
- end
69
-
70
- specify('#strfregexp type token') do
71
- root = RP.parse(/a[b](c)/)
72
-
73
- expect(root.strfregexp('%y')).to eq 'expression'
74
- expect(root.strfregexp('%k')).to eq 'root'
75
- expect(root.strfregexp('%i')).to eq 'expression:root'
76
- expect(root.strfregexp('%c')).to eq 'Regexp::Expression::Root'
77
-
78
- a = root.first
79
- expect(a.strfregexp('%y')).to eq 'literal'
80
- expect(a.strfregexp('%k')).to eq 'literal'
81
- expect(a.strfregexp('%i')).to eq 'literal:literal'
82
- expect(a.strfregexp('%c')).to eq 'Regexp::Expression::Literal'
83
-
84
- set = root[1]
85
- expect(set.strfregexp('%y')).to eq 'set'
86
- expect(set.strfregexp('%k')).to eq 'character'
87
- expect(set.strfregexp('%i')).to eq 'set:character'
88
- expect(set.strfregexp('%c')).to eq 'Regexp::Expression::CharacterSet'
89
-
90
- group = root.last
91
- expect(group.strfregexp('%y')).to eq 'group'
92
- expect(group.strfregexp('%k')).to eq 'capture'
93
- expect(group.strfregexp('%i')).to eq 'group:capture'
94
- expect(group.strfregexp('%c')).to eq 'Regexp::Expression::Group::Capture'
95
- end
96
-
97
- specify('#strfregexp quantifier') do
98
- root = RP.parse(/a+[b](c)?d{3,4}/)
99
-
100
- expect(root.strfregexp('%q')).to eq '{1}'
101
- expect(root.strfregexp('%Q')).to eq ''
102
- expect(root.strfregexp('%z, %Z')).to eq '1, 1'
103
-
104
- a = root.first
105
- expect(a.strfregexp('%q')).to eq '{1, or-more}'
106
- expect(a.strfregexp('%Q')).to eq '+'
107
- expect(a.strfregexp('%z, %Z')).to eq '1, -1'
108
-
109
- set = root[1]
110
- expect(set.strfregexp('%q')).to eq '{1}'
111
- expect(set.strfregexp('%Q')).to eq ''
112
- expect(set.strfregexp('%z, %Z')).to eq '1, 1'
113
-
114
- group = root[2]
115
- expect(group.strfregexp('%q')).to eq '{0, 1}'
116
- expect(group.strfregexp('%Q')).to eq '?'
117
- expect(group.strfregexp('%z, %Z')).to eq '0, 1'
118
-
119
- d = root.last
120
- expect(d.strfregexp('%q')).to eq '{3, 4}'
121
- expect(d.strfregexp('%Q')).to eq '{3,4}'
122
- expect(d.strfregexp('%z, %Z')).to eq '3, 4'
123
- end
124
-
125
- specify('#strfregexp text') do
126
- root = RP.parse(/a(b(c))|[d-gk-p]+/)
127
-
128
- expect(root.strfregexp('%t')).to eq 'a(b(c))|[d-gk-p]+'
129
- expect(root.strfregexp('%~t')).to eq 'expression:root'
130
-
131
- alt = root.first
132
- expect(alt.strfregexp('%t')).to eq 'a(b(c))|[d-gk-p]+'
133
- expect(alt.strfregexp('%T')).to eq 'a(b(c))|[d-gk-p]+'
134
- expect(alt.strfregexp('%~t')).to eq 'meta:alternation'
135
-
136
- seq_1 = alt.first
137
- expect(seq_1.strfregexp('%t')).to eq 'a(b(c))'
138
- expect(seq_1.strfregexp('%T')).to eq 'a(b(c))'
139
- expect(seq_1.strfregexp('%~t')).to eq 'expression:sequence'
140
-
141
- group = seq_1[1]
142
- expect(group.strfregexp('%t')).to eq '(b(c))'
143
- expect(group.strfregexp('%T')).to eq '(b(c))'
144
- expect(group.strfregexp('%~t')).to eq 'group:capture'
145
-
146
- seq_2 = alt.last
147
- expect(seq_2.strfregexp('%t')).to eq '[d-gk-p]+'
148
- expect(seq_2.strfregexp('%T')).to eq '[d-gk-p]+'
149
-
150
- set = seq_2.first
151
- expect(set.strfregexp('%t')).to eq '[d-gk-p]'
152
- expect(set.strfregexp('%T')).to eq '[d-gk-p]+'
153
- expect(set.strfregexp('%~t')).to eq 'set:character'
154
- end
155
-
156
- specify('#strfregexp combined') do
157
- root = RP.parse(/a{5}|[b-d]+/)
158
-
159
- expect(root.strfregexp('%b')).to eq '@0+11 expression:root'
160
- expect(root.strfregexp('%b')).to eq root.strfregexp('%o %i')
161
-
162
- expect(root.strfregexp('%m')).to eq '@0+11 expression:root {1}'
163
- expect(root.strfregexp('%m')).to eq root.strfregexp('%b %q')
164
-
165
- expect(root.strfregexp('%a')).to eq '@0+11 expression:root {1} a{5}|[b-d]+'
166
- expect(root.strfregexp('%a')).to eq root.strfregexp('%m %t')
167
- end
168
-
169
- specify('#strfregexp conditional') do
170
- root = RP.parse('(?<A>a)(?(<A>)b|c)', 'ruby/2.0')
171
-
172
- expect { root.strfregexp }.not_to(raise_error)
173
- end
174
-
175
- specify('#strfregexp_tree') do
176
- root = RP.parse(/a[b-d]*(e(f+))?/)
177
-
178
- expect(root.strfregexp_tree('%>%o %~t')).to eq(
179
- "@0+15 expression:root\n" +
180
- " @0+1 a\n" +
181
- " @1+6 set:character\n" +
182
- " @2+3 set:range\n" +
183
- " @2+1 b\n" +
184
- " @4+1 d\n" +
185
- " @7+8 group:capture\n" +
186
- " @8+1 e\n" +
187
- " @9+4 group:capture\n" +
188
- " @10+2 f+"
189
- )
190
- end
191
-
192
- specify('#strfregexp_tree separator') do
193
- root = RP.parse(/a[b-d]*(e(f+))?/)
194
-
195
- expect(root.strfregexp_tree('%>%o %~t', true, '-SEP-')).to eq(
196
- "@0+15 expression:root-SEP-" +
197
- " @0+1 a-SEP-" +
198
- " @1+6 set:character-SEP-" +
199
- " @2+3 set:range-SEP-" +
200
- " @2+1 b-SEP-" +
201
- " @4+1 d-SEP-" +
202
- " @7+8 group:capture-SEP-" +
203
- " @8+1 e-SEP-" +
204
- " @9+4 group:capture-SEP-" +
205
- " @10+2 f+"
206
- )
207
- end
208
-
209
- specify('#strfregexp_tree excluding self') do
210
- root = RP.parse(/a[b-d]*(e(f+))?/)
211
-
212
- expect(root.strfregexp_tree('%>%o %~t', false)).to eq(
213
- "@0+1 a\n" +
214
- "@1+6 set:character\n" +
215
- " @2+3 set:range\n" +
216
- " @2+1 b\n" +
217
- " @4+1 d\n" +
218
- "@7+8 group:capture\n" +
219
- " @8+1 e\n" +
220
- " @9+4 group:capture\n" +
221
- " @10+2 f+"
222
- )
223
- end
224
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('ExpressionTests') do
4
- specify('#type?') do
5
- root = RP.parse(/abcd|(ghij)|[klmn]/)
6
-
7
- alt = root.first
8
-
9
- expect(alt.type?(:meta)).to be true
10
- expect(alt.type?(:escape)).to be false
11
- expect(alt.type?(%i[meta escape])).to be true
12
- expect(alt.type?(%i[literal escape])).to be false
13
- expect(alt.type?(:*)).to be true
14
- expect(alt.type?([:*])).to be true
15
- expect(alt.type?(%i[literal escape *])).to be true
16
-
17
- seq_1 = alt[0]
18
- expect(seq_1.type?(:expression)).to be true
19
- expect(seq_1.first.type?(:literal)).to be true
20
-
21
- seq_2 = alt[1]
22
- expect(seq_2.type?(:*)).to be true
23
- expect(seq_2.first.type?(:group)).to be true
24
-
25
- seq_3 = alt[2]
26
- expect(seq_3.first.type?(:set)).to be true
27
- end
28
-
29
- specify('#is?') do
30
- root = RP.parse(/.+|\.?/)
31
-
32
- expect(root.is?(:*)).to be true
33
-
34
- alt = root.first
35
- expect(alt.is?(:*)).to be true
36
- expect(alt.is?(:alternation)).to be true
37
- expect(alt.is?(:alternation, :meta)).to be true
38
-
39
- seq_1 = alt[0]
40
- expect(seq_1.is?(:sequence)).to be true
41
- expect(seq_1.is?(:sequence, :expression)).to be true
42
-
43
- expect(seq_1.first.is?(:dot)).to be true
44
- expect(seq_1.first.is?(:dot, :escape)).to be false
45
- expect(seq_1.first.is?(:dot, :meta)).to be true
46
- expect(seq_1.first.is?(:dot, %i[escape meta])).to be true
47
-
48
- seq_2 = alt[1]
49
- expect(seq_2.first.is?(:dot)).to be true
50
- expect(seq_2.first.is?(:dot, :escape)).to be true
51
- expect(seq_2.first.is?(:dot, :meta)).to be false
52
- expect(seq_2.first.is?(:dot, %i[meta escape])).to be true
53
- end
54
-
55
- specify('#one_of?') do
56
- root = RP.parse(/\Aab(c[\w])d|e.\z/)
57
-
58
- expect(root.one_of?(:*)).to be true
59
- expect(root.one_of?(:* => :*)).to be true
60
- expect(root.one_of?(:* => [:*])).to be true
61
-
62
- alt = root.first
63
- expect(alt.one_of?(:*)).to be true
64
- expect(alt.one_of?(:meta)).to be true
65
- expect(alt.one_of?(:meta, :alternation)).to be true
66
- expect(alt.one_of?(meta: %i[dot bogus])).to be false
67
- expect(alt.one_of?(meta: %i[dot alternation])).to be true
68
-
69
- seq_1 = alt[0]
70
- expect(seq_1.one_of?(:expression)).to be true
71
- expect(seq_1.one_of?(expression: :sequence)).to be true
72
-
73
- expect(seq_1.first.one_of?(:anchor)).to be true
74
- expect(seq_1.first.one_of?(anchor: :bos)).to be true
75
- expect(seq_1.first.one_of?(anchor: :eos)).to be false
76
- expect(seq_1.first.one_of?(anchor: %i[escape meta bos])).to be true
77
- expect(seq_1.first.one_of?(anchor: %i[escape meta eos])).to be false
78
-
79
- seq_2 = alt[1]
80
- expect(seq_2.first.one_of?(:literal)).to be true
81
-
82
- expect(seq_2[1].one_of?(:meta)).to be true
83
- expect(seq_2[1].one_of?(meta: :dot)).to be true
84
- expect(seq_2[1].one_of?(meta: :alternation)).to be false
85
- expect(seq_2[1].one_of?(meta: [:dot])).to be true
86
-
87
- expect(seq_2.last.one_of?(:group)).to be false
88
- expect(seq_2.last.one_of?(group: [:*])).to be false
89
- expect(seq_2.last.one_of?(group: [:*], meta: :*)).to be false
90
-
91
- expect(seq_2.last.one_of?(:meta => [:*], :* => :*)).to be true
92
- expect(seq_2.last.one_of?(meta: [:*], anchor: :*)).to be true
93
- expect(seq_2.last.one_of?(meta: [:*], anchor: :eos)).to be true
94
- expect(seq_2.last.one_of?(meta: [:*], anchor: [:bos])).to be false
95
- expect(seq_2.last.one_of?(meta: [:*], anchor: %i[bos eos])).to be true
96
-
97
- expect { root.one_of?(Object.new) }.to raise_error(ArgumentError)
98
- end
99
- end
@@ -1,161 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Subexpression#traverse') do
4
- specify('Subexpression#traverse') do
5
- root = RP.parse(/a(b(c(d)))|g[h-i]j|klmn/)
6
-
7
- enters = 0
8
- visits = 0
9
- exits = 0
10
-
11
- root.traverse do |event, _exp, _index|
12
- enters = (enters + 1) if event == :enter
13
- visits = (visits + 1) if event == :visit
14
- exits = (exits + 1) if event == :exit
15
- end
16
-
17
- expect(enters).to eq 9
18
- expect(enters).to eq exits
19
-
20
- expect(visits).to eq 9
21
- end
22
-
23
- specify('Subexpression#traverse including self') do
24
- root = RP.parse(/a(b(c(d)))|g[h-i]j|klmn/)
25
-
26
- enters = 0
27
- visits = 0
28
- exits = 0
29
-
30
- root.traverse(true) do |event, _exp, _index|
31
- enters = (enters + 1) if event == :enter
32
- visits = (visits + 1) if event == :visit
33
- exits = (exits + 1) if event == :exit
34
- end
35
-
36
- expect(enters).to eq 10
37
- expect(enters).to eq exits
38
-
39
- expect(visits).to eq 9
40
- end
41
-
42
- specify('Subexpression#traverse without a block') do
43
- root = RP.parse(/abc/)
44
- enum = root.traverse
45
-
46
- expect(enum).to be_a(Enumerator)
47
- event, expr, idx = enum.next
48
- expect(event).to eq(:visit)
49
- expect(expr).to be_a(Regexp::Expression::Literal)
50
- expect(idx).to eq(0)
51
- end
52
-
53
- specify('Subexpression#walk alias') do
54
- root = RP.parse(/abc/)
55
-
56
- expect(root).to respond_to(:walk)
57
- end
58
-
59
- specify('Subexpression#each_expression') do
60
- root = RP.parse(/a(?x:b(c))|g[h-k]/)
61
-
62
- count = 0
63
- root.each_expression { count += 1 }
64
-
65
- expect(count).to eq 13
66
- end
67
-
68
- specify('Subexpression#each_expression including self') do
69
- root = RP.parse(/a(?x:b(c))|g[h-k]/)
70
-
71
- count = 0
72
- root.each_expression(true) { count += 1 }
73
-
74
- expect(count).to eq 14
75
- end
76
-
77
- specify('Subexpression#each_expression indices') do
78
- root = RP.parse(/a(b)c/)
79
-
80
- indices = []
81
- root.each_expression { |_exp, index| (indices << index) }
82
-
83
- expect(indices).to eq [0, 1, 0, 2]
84
- end
85
-
86
- specify('Subexpression#each_expression indices including self') do
87
- root = RP.parse(/a(b)c/)
88
-
89
- indices = []
90
- root.each_expression(true) { |_exp, index| (indices << index) }
91
-
92
- expect(indices).to eq [0, 0, 1, 0, 2]
93
- end
94
-
95
- specify('Subexpression#each_expression without a block') do
96
- root = RP.parse(/abc/)
97
- enum = root.each_expression
98
-
99
- expect(enum).to be_a(Enumerator)
100
- expr, idx = enum.next
101
- expect(expr).to be_a(Regexp::Expression::Literal)
102
- expect(idx).to eq(0)
103
- end
104
-
105
- specify('Subexpression#flat_map without block') do
106
- root = RP.parse(/a(b([c-e]+))?/)
107
-
108
- array = root.flat_map
109
-
110
- expect(array).to be_instance_of(Array)
111
- expect(array.length).to eq 8
112
-
113
- array.each do |item|
114
- expect(item).to be_instance_of(Array)
115
- expect(item.length).to eq 2
116
- expect(item.first).to be_a(Regexp::Expression::Base)
117
- expect(item.last).to be_a(Integer)
118
- end
119
- end
120
-
121
- specify('Subexpression#flat_map without block including self') do
122
- root = RP.parse(/a(b([c-e]+))?/)
123
-
124
- array = root.flat_map(true)
125
-
126
- expect(array).to be_instance_of(Array)
127
- expect(array.length).to eq 9
128
- end
129
-
130
- specify('Subexpression#flat_map indices') do
131
- root = RP.parse(/a(b([c-e]+))?f*g/)
132
-
133
- indices = root.flat_map { |_exp, index| index }
134
-
135
- expect(indices).to eq [0, 1, 0, 1, 0, 0, 0, 1, 2, 3]
136
- end
137
-
138
- specify('Subexpression#flat_map indices including self') do
139
- root = RP.parse(/a(b([c-e]+))?f*g/)
140
-
141
- indices = root.flat_map(true) { |_exp, index| index }
142
-
143
- expect(indices).to eq [0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 3]
144
- end
145
-
146
- specify('Subexpression#flat_map expressions') do
147
- root = RP.parse(/a(b(c(d)))/)
148
-
149
- levels = root.flat_map { |exp, _index| [exp.level, exp.text] if exp.terminal? }.compact
150
-
151
- expect(levels).to eq [[0, 'a'], [1, 'b'], [2, 'c'], [3, 'd']]
152
- end
153
-
154
- specify('Subexpression#flat_map expressions including self') do
155
- root = RP.parse(/a(b(c(d)))/)
156
-
157
- levels = root.flat_map(true) { |exp, _index| [exp.level, exp.to_s] }.compact
158
-
159
- expect(levels).to eq [[nil, 'a(b(c(d)))'], [0, 'a'], [0, '(b(c(d)))'], [1, 'b'], [1, '(c(d))'], [2, 'c'], [2, '(d)'], [3, 'd']]
160
- end
161
- end
@@ -1,128 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Expression#options') do
4
- it 'returns a hash of options/flags that affect the expression' do
5
- exp = RP.parse(/a/ix)[0]
6
- expect(exp).to be_a Literal
7
- expect(exp.options).to eq(i: true, x: true)
8
- end
9
-
10
- it 'includes options that are locally enabled via special groups' do
11
- exp = RP.parse(/(?x)(?m:a)/i)[1][0]
12
- expect(exp).to be_a Literal
13
- expect(exp.options).to eq(i: true, m: true, x: true)
14
- end
15
-
16
- it 'excludes locally disabled options' do
17
- exp = RP.parse(/(?x)(?-im:a)/i)[1][0]
18
- expect(exp).to be_a Literal
19
- expect(exp.options).to eq(x: true)
20
- end
21
-
22
- it 'gives correct precedence to negative options' do
23
- # Negative options have precedence. E.g. /(?i-i)a/ is case-sensitive.
24
- regexp = /(?i-i:a)/
25
- expect(regexp).to match 'a'
26
- expect(regexp).not_to match 'A'
27
-
28
- exp = RP.parse(regexp)[0][0]
29
- expect(exp).to be_a Literal
30
- expect(exp.options).to eq({})
31
- end
32
-
33
- it 'correctly handles multiple negative option parts' do
34
- regexp = /(?--m--mx--) . /mx
35
- expect(regexp).to match ' . '
36
- expect(regexp).not_to match '.'
37
- expect(regexp).not_to match "\n"
38
-
39
- exp = RP.parse(regexp)[2]
40
- expect(exp.options).to eq({})
41
- end
42
-
43
- it 'gives correct precedence when encountering multiple encoding flags' do
44
- # Any encoding flag overrides all previous encoding flags. If there are
45
- # multiple encoding flags in an options string, the last one wins.
46
- # E.g. /(?dau)\w/ matches UTF8 chars but /(?dua)\w/ only ASCII chars.
47
- regexp1 = /(?dau)\w/
48
- regexp2 = /(?dua)\w/
49
- expect(regexp1).to match 'ü'
50
- expect(regexp2).not_to match 'ü'
51
-
52
- exp1 = RP.parse(regexp1)[1]
53
- exp2 = RP.parse(regexp2)[1]
54
- expect(exp1.options).to eq(u: true)
55
- expect(exp2.options).to eq(a: true)
56
- end
57
-
58
- it 'is accessible via shortcuts' do
59
- exp = Root.build
60
-
61
- expect { exp.options[:i] = true }
62
- .to change { exp.i? }.from(false).to(true)
63
- .and change { exp.ignore_case? }.from(false).to(true)
64
- .and change { exp.case_insensitive? }.from(false).to(true)
65
-
66
- expect { exp.options[:m] = true }
67
- .to change { exp.m? }.from(false).to(true)
68
- .and change { exp.multiline? }.from(false).to(true)
69
-
70
- expect { exp.options[:x] = true }
71
- .to change { exp.x? }.from(false).to(true)
72
- .and change { exp.extended? }.from(false).to(true)
73
- .and change { exp.free_spacing? }.from(false).to(true)
74
-
75
- expect { exp.options[:a] = true }
76
- .to change { exp.a? }.from(false).to(true)
77
- .and change { exp.ascii_classes? }.from(false).to(true)
78
-
79
- expect { exp.options[:d] = true }
80
- .to change { exp.d? }.from(false).to(true)
81
- .and change { exp.default_classes? }.from(false).to(true)
82
-
83
- expect { exp.options[:u] = true }
84
- .to change { exp.u? }.from(false).to(true)
85
- .and change { exp.unicode_classes? }.from(false).to(true)
86
- end
87
-
88
- RSpec.shared_examples '#options' do |regexp, path, klass|
89
- it "works for expression class #{klass}" do
90
- exp = RP.parse(/#{regexp.source}/i).dig(*path)
91
- expect(exp).to be_a(klass)
92
- expect(exp).to be_i
93
- expect(exp).not_to be_x
94
- end
95
- end
96
-
97
- include_examples '#options', //, [], Root
98
- include_examples '#options', /a/, [0], Literal
99
- include_examples '#options', /\A/, [0], Anchor::Base
100
- include_examples '#options', /\d/, [0], CharacterType::Base
101
- include_examples '#options', /\n/, [0], EscapeSequence::Base
102
- include_examples '#options', /\K/, [0], Keep::Mark
103
- include_examples '#options', /./, [0], CharacterType::Any
104
- include_examples '#options', /(a)/, [0], Group::Base
105
- include_examples '#options', /(a)/, [0, 0], Literal
106
- include_examples '#options', /(?=a)/, [0], Assertion::Base
107
- include_examples '#options', /(?=a)/, [0, 0], Literal
108
- include_examples '#options', /(a|b)/, [0], Group::Base
109
- include_examples '#options', /(a|b)/, [0, 0], Alternation
110
- include_examples '#options', /(a|b)/, [0, 0, 0], Alternative
111
- include_examples '#options', /(a|b)/, [0, 0, 0, 0], Literal
112
- include_examples '#options', /(a)\1/, [1], Backreference::Base
113
- include_examples '#options', /(a)\k<1>/, [1], Backreference::Number
114
- include_examples '#options', /(a)\g<1>/, [1], Backreference::NumberCall
115
- include_examples '#options', /[a]/, [0], CharacterSet
116
- include_examples '#options', /[a]/, [0, 0], Literal
117
- include_examples '#options', /[a-z]/, [0, 0], CharacterSet::Range
118
- include_examples '#options', /[a-z]/, [0, 0, 0], Literal
119
- include_examples '#options', /[a&&z]/, [0, 0], CharacterSet::Intersection
120
- include_examples '#options', /[a&&z]/, [0, 0, 0], CharacterSet::IntersectedSequence
121
- include_examples '#options', /[a&&z]/, [0, 0, 0, 0], Literal
122
- include_examples '#options', /[[:ascii:]]/, [0, 0], PosixClass
123
- include_examples '#options', /\p{word}/, [0], UnicodeProperty::Base
124
- include_examples '#options', /(a)(?(1)b|c)/, [1], Conditional::Expression
125
- include_examples '#options', /(a)(?(1)b|c)/, [1, 0], Conditional::Condition
126
- include_examples '#options', /(a)(?(1)b|c)/, [1, 1], Conditional::Branch
127
- include_examples '#options', /(a)(?(1)b|c)/, [1, 1, 0], Literal
128
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Expression::Root) do
4
- describe('#initialize') do
5
- it 'supports the old, nonstandard arity for backwards compatibility' do
6
- expect { Root.new }.to output.to_stderr
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Expression::Sequence) do
4
- describe('#initialize') do
5
- it 'supports the old, nonstandard arity for backwards compatibility' do
6
- expect { Sequence.new(0, 0, 0) }.to output.to_stderr
7
- end
8
- end
9
- end
@@ -1,50 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Expression::Subexpression) do
4
- specify('#ts, #te') do
5
- regx = /abcd|ghij|klmn|pqur/
6
- root = RP.parse(regx)
7
-
8
- alt = root.first
9
-
10
- { 0 => [0, 4], 1 => [5, 9], 2 => [10, 14], 3 => [15, 19] }.each do |index, span|
11
- sequence = alt[index]
12
-
13
- expect(sequence.ts).to eq span[0]
14
- expect(sequence.te).to eq span[1]
15
- end
16
- end
17
-
18
- specify('#nesting_level') do
19
- root = RP.parse(/a(b(\d|[ef-g[h]]))/)
20
-
21
- tests = {
22
- 'a' => 1,
23
- 'b' => 2,
24
- '\d|[ef-g[h]]' => 3, # alternation
25
- '\d' => 4, # first alternative
26
- '[ef-g[h]]' => 4, # second alternative
27
- 'e' => 5,
28
- 'f-g' => 5,
29
- 'f' => 6,
30
- 'g' => 6,
31
- 'h' => 6,
32
- }
33
-
34
- root.each_expression do |exp|
35
- next unless expected_nesting_level = tests.delete(exp.to_s)
36
- expect(expected_nesting_level).to eq exp.nesting_level
37
- end
38
-
39
- expect(tests).to be_empty
40
- end
41
-
42
- specify('#dig') do
43
- root = RP.parse(/(((a)))/)
44
-
45
- expect(root.dig(0).to_s).to eq '(((a)))'
46
- expect(root.dig(0, 0, 0, 0).to_s).to eq 'a'
47
- expect(root.dig(0, 0, 0, 0, 0)).to be_nil
48
- expect(root.dig(3, 7)).to be_nil
49
- end
50
- end