regexp_parser 1.3.0 → 1.6.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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -1
  3. data/Gemfile +3 -3
  4. data/README.md +10 -14
  5. data/Rakefile +3 -4
  6. data/lib/regexp_parser/expression.rb +28 -53
  7. data/lib/regexp_parser/expression/classes/backref.rb +18 -10
  8. data/lib/regexp_parser/expression/classes/conditional.rb +7 -2
  9. data/lib/regexp_parser/expression/classes/escape.rb +0 -4
  10. data/lib/regexp_parser/expression/classes/group.rb +4 -2
  11. data/lib/regexp_parser/expression/classes/keep.rb +1 -3
  12. data/lib/regexp_parser/expression/methods/match.rb +13 -0
  13. data/lib/regexp_parser/expression/methods/match_length.rb +172 -0
  14. data/lib/regexp_parser/expression/methods/options.rb +35 -0
  15. data/lib/regexp_parser/expression/methods/strfregexp.rb +0 -1
  16. data/lib/regexp_parser/expression/methods/tests.rb +6 -15
  17. data/lib/regexp_parser/expression/quantifier.rb +2 -2
  18. data/lib/regexp_parser/expression/sequence.rb +3 -6
  19. data/lib/regexp_parser/expression/sequence_operation.rb +2 -6
  20. data/lib/regexp_parser/expression/subexpression.rb +3 -5
  21. data/lib/regexp_parser/lexer.rb +30 -44
  22. data/lib/regexp_parser/parser.rb +47 -24
  23. data/lib/regexp_parser/scanner.rb +1159 -1329
  24. data/lib/regexp_parser/scanner/char_type.rl +0 -3
  25. data/lib/regexp_parser/scanner/properties/long.yml +34 -1
  26. data/lib/regexp_parser/scanner/properties/short.yml +12 -0
  27. data/lib/regexp_parser/scanner/scanner.rl +82 -190
  28. data/lib/regexp_parser/syntax/tokens.rb +2 -10
  29. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +72 -21
  30. data/lib/regexp_parser/syntax/versions/2.6.0.rb +10 -0
  31. data/lib/regexp_parser/syntax/versions/2.6.2.rb +10 -0
  32. data/lib/regexp_parser/syntax/versions/2.6.3.rb +10 -0
  33. data/lib/regexp_parser/version.rb +1 -1
  34. data/regexp_parser.gemspec +3 -3
  35. data/spec/expression/base_spec.rb +94 -0
  36. data/spec/expression/clone_spec.rb +120 -0
  37. data/spec/expression/conditional_spec.rb +89 -0
  38. data/spec/expression/free_space_spec.rb +27 -0
  39. data/spec/expression/methods/match_length_spec.rb +154 -0
  40. data/spec/expression/methods/match_spec.rb +25 -0
  41. data/spec/expression/methods/strfregexp_spec.rb +224 -0
  42. data/spec/expression/methods/tests_spec.rb +99 -0
  43. data/spec/expression/methods/traverse_spec.rb +140 -0
  44. data/spec/expression/options_spec.rb +128 -0
  45. data/spec/expression/root_spec.rb +9 -0
  46. data/spec/expression/sequence_spec.rb +9 -0
  47. data/spec/expression/subexpression_spec.rb +50 -0
  48. data/spec/expression/to_h_spec.rb +26 -0
  49. data/spec/expression/to_s_spec.rb +100 -0
  50. data/spec/lexer/all_spec.rb +22 -0
  51. data/spec/lexer/conditionals_spec.rb +53 -0
  52. data/spec/lexer/escapes_spec.rb +14 -0
  53. data/spec/lexer/keep_spec.rb +10 -0
  54. data/spec/lexer/literals_spec.rb +89 -0
  55. data/spec/lexer/nesting_spec.rb +99 -0
  56. data/spec/lexer/refcalls_spec.rb +55 -0
  57. data/spec/parser/all_spec.rb +43 -0
  58. data/spec/parser/alternation_spec.rb +88 -0
  59. data/spec/parser/anchors_spec.rb +17 -0
  60. data/spec/parser/conditionals_spec.rb +179 -0
  61. data/spec/parser/errors_spec.rb +30 -0
  62. data/spec/parser/escapes_spec.rb +121 -0
  63. data/spec/parser/free_space_spec.rb +130 -0
  64. data/spec/parser/groups_spec.rb +108 -0
  65. data/spec/parser/keep_spec.rb +6 -0
  66. data/spec/parser/posix_classes_spec.rb +8 -0
  67. data/spec/parser/properties_spec.rb +115 -0
  68. data/spec/parser/quantifiers_spec.rb +51 -0
  69. data/spec/parser/refcalls_spec.rb +112 -0
  70. data/spec/parser/set/intersections_spec.rb +127 -0
  71. data/spec/parser/set/ranges_spec.rb +111 -0
  72. data/spec/parser/sets_spec.rb +178 -0
  73. data/spec/parser/types_spec.rb +18 -0
  74. data/spec/scanner/all_spec.rb +18 -0
  75. data/spec/scanner/anchors_spec.rb +21 -0
  76. data/spec/scanner/conditionals_spec.rb +128 -0
  77. data/spec/scanner/errors_spec.rb +68 -0
  78. data/spec/scanner/escapes_spec.rb +53 -0
  79. data/spec/scanner/free_space_spec.rb +133 -0
  80. data/spec/scanner/groups_spec.rb +52 -0
  81. data/spec/scanner/keep_spec.rb +10 -0
  82. data/spec/scanner/literals_spec.rb +49 -0
  83. data/spec/scanner/meta_spec.rb +18 -0
  84. data/spec/scanner/properties_spec.rb +64 -0
  85. data/spec/scanner/quantifiers_spec.rb +20 -0
  86. data/spec/scanner/refcalls_spec.rb +36 -0
  87. data/spec/scanner/sets_spec.rb +102 -0
  88. data/spec/scanner/types_spec.rb +14 -0
  89. data/spec/spec_helper.rb +15 -0
  90. data/{test → spec}/support/runner.rb +9 -8
  91. data/spec/support/shared_examples.rb +77 -0
  92. data/{test → spec}/support/warning_extractor.rb +5 -7
  93. data/spec/syntax/syntax_spec.rb +48 -0
  94. data/spec/syntax/syntax_token_map_spec.rb +23 -0
  95. data/spec/syntax/versions/1.8.6_spec.rb +17 -0
  96. data/spec/syntax/versions/1.9.1_spec.rb +10 -0
  97. data/spec/syntax/versions/1.9.3_spec.rb +9 -0
  98. data/spec/syntax/versions/2.0.0_spec.rb +13 -0
  99. data/spec/syntax/versions/2.2.0_spec.rb +9 -0
  100. data/spec/syntax/versions/aliases_spec.rb +37 -0
  101. data/spec/token/token_spec.rb +85 -0
  102. metadata +144 -143
  103. data/test/expression/test_all.rb +0 -12
  104. data/test/expression/test_base.rb +0 -90
  105. data/test/expression/test_clone.rb +0 -89
  106. data/test/expression/test_conditionals.rb +0 -113
  107. data/test/expression/test_free_space.rb +0 -35
  108. data/test/expression/test_set.rb +0 -84
  109. data/test/expression/test_strfregexp.rb +0 -230
  110. data/test/expression/test_subexpression.rb +0 -58
  111. data/test/expression/test_tests.rb +0 -99
  112. data/test/expression/test_to_h.rb +0 -59
  113. data/test/expression/test_to_s.rb +0 -104
  114. data/test/expression/test_traverse.rb +0 -161
  115. data/test/helpers.rb +0 -10
  116. data/test/lexer/test_all.rb +0 -41
  117. data/test/lexer/test_conditionals.rb +0 -127
  118. data/test/lexer/test_keep.rb +0 -24
  119. data/test/lexer/test_literals.rb +0 -130
  120. data/test/lexer/test_nesting.rb +0 -132
  121. data/test/lexer/test_refcalls.rb +0 -56
  122. data/test/parser/set/test_intersections.rb +0 -127
  123. data/test/parser/set/test_ranges.rb +0 -111
  124. data/test/parser/test_all.rb +0 -64
  125. data/test/parser/test_alternation.rb +0 -92
  126. data/test/parser/test_anchors.rb +0 -34
  127. data/test/parser/test_conditionals.rb +0 -187
  128. data/test/parser/test_errors.rb +0 -63
  129. data/test/parser/test_escapes.rb +0 -134
  130. data/test/parser/test_free_space.rb +0 -139
  131. data/test/parser/test_groups.rb +0 -289
  132. data/test/parser/test_keep.rb +0 -21
  133. data/test/parser/test_posix_classes.rb +0 -27
  134. data/test/parser/test_properties.rb +0 -133
  135. data/test/parser/test_quantifiers.rb +0 -301
  136. data/test/parser/test_refcalls.rb +0 -186
  137. data/test/parser/test_sets.rb +0 -179
  138. data/test/parser/test_types.rb +0 -50
  139. data/test/scanner/test_all.rb +0 -38
  140. data/test/scanner/test_anchors.rb +0 -38
  141. data/test/scanner/test_conditionals.rb +0 -184
  142. data/test/scanner/test_errors.rb +0 -91
  143. data/test/scanner/test_escapes.rb +0 -56
  144. data/test/scanner/test_free_space.rb +0 -200
  145. data/test/scanner/test_groups.rb +0 -79
  146. data/test/scanner/test_keep.rb +0 -35
  147. data/test/scanner/test_literals.rb +0 -89
  148. data/test/scanner/test_meta.rb +0 -40
  149. data/test/scanner/test_properties.rb +0 -312
  150. data/test/scanner/test_quantifiers.rb +0 -37
  151. data/test/scanner/test_refcalls.rb +0 -52
  152. data/test/scanner/test_scripts.rb +0 -53
  153. data/test/scanner/test_sets.rb +0 -119
  154. data/test/scanner/test_types.rb +0 -35
  155. data/test/scanner/test_unicode_blocks.rb +0 -30
  156. data/test/support/disable_autotest.rb +0 -8
  157. data/test/syntax/test_all.rb +0 -6
  158. data/test/syntax/test_syntax.rb +0 -61
  159. data/test/syntax/test_syntax_token_map.rb +0 -25
  160. data/test/syntax/versions/test_1.8.rb +0 -55
  161. data/test/syntax/versions/test_1.9.1.rb +0 -36
  162. data/test/syntax/versions/test_1.9.3.rb +0 -32
  163. data/test/syntax/versions/test_2.0.0.rb +0 -37
  164. data/test/syntax/versions/test_2.2.0.rb +0 -32
  165. data/test/syntax/versions/test_aliases.rb +0 -129
  166. data/test/syntax/versions/test_all.rb +0 -5
  167. data/test/test_all.rb +0 -5
  168. data/test/token/test_all.rb +0 -2
  169. data/test/token/test_token.rb +0 -107
@@ -1,289 +0,0 @@
1
- require File.expand_path("../../helpers", __FILE__)
2
-
3
- class TestParserGroups < Test::Unit::TestCase
4
-
5
- def test_parse_root_options_mi
6
- t = RP.parse(/[abc]/mi, 'ruby/1.8')
7
-
8
- assert_equal true, t.m?
9
- assert_equal true, t.i?
10
- assert_equal false, t.x?
11
- end
12
-
13
- def test_parse_option_group
14
- t = RP.parse(/(?m:a)/, 'ruby/1.8')
15
-
16
- assert_equal Group::Options, t.expressions[0].class
17
- assert_equal :options, t.expressions[0].token
18
-
19
- assert_equal true, t.expressions[0].m?
20
- assert_equal false, t.expressions[0].i?
21
- assert_equal false, t.expressions[0].x?
22
-
23
- assert_equal true, t.expressions[0].option_changes[:m]
24
- assert_equal nil, t.expressions[0].option_changes[:i]
25
- end
26
-
27
- def test_parse_self_defeating_option_group
28
- t = RP.parse(/(?m-m:a)/, 'ruby/1.8')
29
-
30
- assert_equal false, t.expressions[0].m?
31
- assert_equal false, t.expressions[0].i?
32
- assert_equal false, t.expressions[0].x?
33
-
34
- assert_equal false, t.expressions[0].option_changes[:m]
35
- assert_equal nil, t.expressions[0].option_changes[:i]
36
- end
37
-
38
- def test_parse_nested_options_activate_one
39
- t = RP.parse(/(?x-mi:a(?m:b))/, 'ruby/1.8')
40
-
41
- assert_equal false, t.expressions[0].m?
42
- assert_equal false, t.expressions[0].i?
43
- assert_equal true, t.expressions[0].x?
44
-
45
- assert_equal true, t.expressions[0].expressions[1].m?
46
- assert_equal false, t.expressions[0].expressions[1].i?
47
- assert_equal true, t.expressions[0].expressions[1].x?
48
-
49
- assert_equal true, t.expressions[0].expressions[1].option_changes[:m]
50
- assert_equal nil, t.expressions[0].expressions[1].option_changes[:i]
51
- assert_equal nil, t.expressions[0].expressions[1].option_changes[:x]
52
- end
53
-
54
- def test_parse_nested_options_deactivate_one
55
- t = RP.parse(/(?ix-m:a(?-i:b))/, 'ruby/1.8')
56
-
57
- assert_equal false, t.expressions[0].m?
58
- assert_equal true, t.expressions[0].i?
59
- assert_equal true, t.expressions[0].x?
60
-
61
- assert_equal false, t.expressions[0].expressions[1].m?
62
- assert_equal false, t.expressions[0].expressions[1].i?
63
- assert_equal true, t.expressions[0].expressions[1].x?
64
-
65
- assert_equal false, t.expressions[0].expressions[1].option_changes[:i]
66
- assert_equal nil, t.expressions[0].expressions[1].option_changes[:m]
67
- assert_equal nil, t.expressions[0].expressions[1].option_changes[:x]
68
- end
69
-
70
- def test_parse_nested_options_invert_all
71
- t = RP.parse('(?xi-m:a(?m-ix:b))', 'ruby/1.8')
72
-
73
- assert_equal false, t.expressions[0].m?
74
- assert_equal true, t.expressions[0].i?
75
- assert_equal true, t.expressions[0].x?
76
-
77
- assert_equal true, t.expressions[0].expressions[1].m?
78
- assert_equal false, t.expressions[0].expressions[1].i?
79
- assert_equal false, t.expressions[0].expressions[1].x?
80
-
81
- assert_equal true, t.expressions[0].expressions[1].option_changes[:m]
82
- assert_equal false, t.expressions[0].expressions[1].option_changes[:i]
83
- assert_equal false, t.expressions[0].expressions[1].option_changes[:x]
84
- end
85
-
86
- def test_parse_nested_options_affect_literal_subexpressions
87
- t = RP.parse(/(?x-mi:a(?m:b))/, 'ruby/1.8')
88
-
89
- # a
90
- assert_equal false, t.expressions[0].expressions[0].m?
91
- assert_equal false, t.expressions[0].expressions[0].i?
92
- assert_equal true, t.expressions[0].expressions[0].x?
93
-
94
- # b
95
- assert_equal true, t.expressions[0].expressions[1].expressions[0].m?
96
- assert_equal false, t.expressions[0].expressions[1].expressions[0].i?
97
- assert_equal true, t.expressions[0].expressions[1].expressions[0].x?
98
- end
99
-
100
- def test_parse_option_switch_group
101
- t = RP.parse(/a(?i-m)b/m, 'ruby/1.8')
102
-
103
- assert_equal Group::Options, t.expressions[1].class
104
- assert_equal :options_switch, t.expressions[1].token
105
-
106
- assert_equal false, t.expressions[1].m?
107
- assert_equal true, t.expressions[1].i?
108
- assert_equal false, t.expressions[1].x?
109
-
110
- assert_equal true, t.expressions[1].option_changes[:i]
111
- assert_equal false, t.expressions[1].option_changes[:m]
112
- assert_equal nil, t.expressions[1].option_changes[:x]
113
- end
114
-
115
- def test_parse_option_switch_affects_following_expressions
116
- t = RP.parse(/a(?i-m)b/m, 'ruby/1.8')
117
-
118
- # a
119
- assert_equal true, t.expressions[0].m?
120
- assert_equal false, t.expressions[0].i?
121
- assert_equal false, t.expressions[0].x?
122
-
123
- # b
124
- assert_equal false, t.expressions[2].m?
125
- assert_equal true, t.expressions[2].i?
126
- assert_equal false, t.expressions[2].x?
127
- end
128
-
129
- def test_parse_option_switch_in_group
130
- t = RP.parse(/(a(?i-m)b)c/m, 'ruby/1.8')
131
-
132
- group1 = t.expressions[0]
133
-
134
- assert_equal true, group1.m?
135
- assert_equal false, group1.i?
136
- assert_equal false, group1.x?
137
-
138
- # a
139
- assert_equal true, group1.expressions[0].m?
140
- assert_equal false, group1.expressions[0].i?
141
- assert_equal false, group1.expressions[0].x?
142
-
143
- # (?i-m)
144
- assert_equal false, group1.expressions[1].m?
145
- assert_equal true, group1.expressions[1].i?
146
- assert_equal false, group1.expressions[1].x?
147
-
148
- # b
149
- assert_equal false, group1.expressions[2].m?
150
- assert_equal true, group1.expressions[2].i?
151
- assert_equal false, group1.expressions[2].x?
152
-
153
- # c
154
- assert_equal true, t.expressions[1].m?
155
- assert_equal false, t.expressions[1].i?
156
- assert_equal false, t.expressions[1].x?
157
- end
158
-
159
- def test_parse_nested_option_switch_in_group
160
- t = RP.parse(/((?i-m)(a(?-i)b))/m, 'ruby/1.8')
161
-
162
- group2 = t.expressions[0].expressions[1]
163
-
164
- assert_equal false, group2.m?
165
- assert_equal true, group2.i?
166
- assert_equal false, group2.x?
167
-
168
- # a
169
- assert_equal false, group2.expressions[0].m?
170
- assert_equal true, group2.expressions[0].i?
171
- assert_equal false, group2.expressions[0].x?
172
-
173
- # (?-i)
174
- assert_equal false, group2.expressions[1].m?
175
- assert_equal false, group2.expressions[1].i?
176
- assert_equal false, group2.expressions[1].x?
177
-
178
- # b
179
- assert_equal false, group2.expressions[2].m?
180
- assert_equal false, group2.expressions[2].i?
181
- assert_equal false, group2.expressions[2].x?
182
- end
183
-
184
- if RUBY_VERSION >= '2.0'
185
- def test_parse_options_dau
186
- t = RP.parse('(?dua:abc)')
187
-
188
- assert_equal false, t.expressions[0].d?
189
- assert_equal true, t.expressions[0].a?
190
- assert_equal false, t.expressions[0].u?
191
- end
192
-
193
- def test_parse_nested_options_dau
194
- t = RP.parse('(?u:a(?d:b))')
195
-
196
- assert_equal true, t.expressions[0].u?
197
- assert_equal false, t.expressions[0].d?
198
- assert_equal false, t.expressions[0].a?
199
-
200
- assert_equal true, t.expressions[0].expressions[1].d?
201
- assert_equal false, t.expressions[0].expressions[1].a?
202
- assert_equal false, t.expressions[0].expressions[1].u?
203
- end
204
-
205
- def test_parse_nested_options_da
206
- t = RP.parse('(?di-xm:a(?da-x:b))')
207
-
208
- assert_equal true, t.expressions[0].d?
209
- assert_equal true, t.expressions[0].i?
210
- assert_equal false, t.expressions[0].m?
211
- assert_equal false, t.expressions[0].x?
212
- assert_equal false, t.expressions[0].a?
213
- assert_equal false, t.expressions[0].u?
214
-
215
- assert_equal false, t.expressions[0].expressions[1].d?
216
- assert_equal true, t.expressions[0].expressions[1].a?
217
- assert_equal false, t.expressions[0].expressions[1].u?
218
- assert_equal false, t.expressions[0].expressions[1].x?
219
- assert_equal false, t.expressions[0].expressions[1].m?
220
- assert_equal true, t.expressions[0].expressions[1].i?
221
- end
222
- end
223
-
224
- def test_parse_lookahead
225
- t = RP.parse('(?=abc)(?!def)', 'ruby/1.8')
226
-
227
- assert t.expressions[0].is_a?(Assertion::Lookahead),
228
- "Expected lookahead, but got #{t.expressions[0].class.name}"
229
-
230
- assert t.expressions[1].is_a?(Assertion::NegativeLookahead),
231
- "Expected negative lookahead, but got #{t.expressions[0].class.name}"
232
- end
233
-
234
- def test_parse_lookbehind
235
- t = RP.parse('(?<=abc)(?<!def)', 'ruby/1.9')
236
-
237
- assert t.expressions[0].is_a?(Assertion::Lookbehind),
238
- "Expected lookbehind, but got #{t.expressions[0].class.name}"
239
-
240
- assert t.expressions[1].is_a?(Assertion::NegativeLookbehind),
241
- "Expected negative lookbehind, but got #{t.expressions[0].class.name}"
242
- end
243
-
244
- def test_parse_comment
245
- t = RP.parse('a(?# is for apple)b(?# for boy)c(?# cat)')
246
-
247
- [1,3,5].each do |i|
248
- assert t.expressions[i].is_a?(Group::Comment),
249
- "Expected comment, but got #{t.expressions[i].class.name}"
250
-
251
- assert_equal :group, t.expressions[i].type
252
- assert_equal :comment, t.expressions[i].token
253
- end
254
- end
255
-
256
- if RUBY_VERSION >= '2.4.1'
257
- def test_parse_absence_group
258
- t = RP.parse('a(?~b)c(?~d)e')
259
-
260
- [1,3].each do |i|
261
- assert t.expressions[i].is_a?(Group::Absence),
262
- "Expected absence group, but got #{t.expressions[i].class.name}"
263
-
264
- assert_equal :group, t.expressions[i].type
265
- assert_equal :absence, t.expressions[i].token
266
- end
267
- end
268
- end
269
-
270
- def test_parse_group_number
271
- t = RP.parse('(a)(?=b)((?:c)(d|(e)))')
272
- assert_equal 1, t[0].number
273
- assert_equal false, t[1].respond_to?(:number)
274
- assert_equal 2, t[2].number
275
- assert_equal false, t[2][0].respond_to?(:number)
276
- assert_equal 3, t[2][1].number
277
- assert_equal 4, t[2][1][0][1][0].number
278
- end
279
-
280
- def test_parse_group_number_at_level
281
- t = RP.parse('(a)(?=b)((?:c)(d|(e)))')
282
- assert_equal 1, t[0].number_at_level
283
- assert_equal false, t[1].respond_to?(:number_at_level)
284
- assert_equal 2, t[2].number_at_level
285
- assert_equal false, t[2][0].respond_to?(:number_at_level)
286
- assert_equal 1, t[2][1].number_at_level
287
- assert_equal 1, t[2][1][0][1][0].number_at_level
288
- end
289
- end
@@ -1,21 +0,0 @@
1
- require File.expand_path("../../helpers", __FILE__)
2
-
3
- class ParserKeep < Test::Unit::TestCase
4
-
5
- def test_parse_keep
6
- regexp = /ab\Kcd/
7
- root = RP.parse(regexp)
8
-
9
- assert_equal Keep::Mark, root[1].class
10
- assert_equal '\\K', root[1].text
11
- end
12
-
13
- def test_parse_keep_nested
14
- regexp = /(a\\\Kb)/
15
- root = RP.parse(regexp)
16
-
17
- assert_equal Keep::Mark, root[0][2].class
18
- assert_equal '\\K', root[0][2].text
19
- end
20
-
21
- end
@@ -1,27 +0,0 @@
1
- require File.expand_path("../../helpers", __FILE__)
2
-
3
- class TestParserPosixClasses < Test::Unit::TestCase
4
- def test_parse_posix_class
5
- root = RP.parse('[[:word:]]')
6
- exp = root[0][0]
7
-
8
- assert_equal PosixClass, exp.class
9
- assert_equal :posixclass, exp.type
10
- assert_equal :word, exp.token
11
- assert_equal 'word', exp.name
12
- assert_equal '[:word:]', exp.text
13
- refute exp.negative?
14
- end
15
-
16
- def test_parse_negative_posix_class
17
- root = RP.parse('[[:^word:]]')
18
- exp = root[0][0]
19
-
20
- assert_equal PosixClass, exp.class
21
- assert_equal :nonposixclass, exp.type
22
- assert_equal :word, exp.token
23
- assert_equal 'word', exp.name
24
- assert_equal '[:^word:]', exp.text
25
- assert exp.negative?
26
- end
27
- end
@@ -1,133 +0,0 @@
1
- require File.expand_path("../../helpers", __FILE__)
2
-
3
- class ParserProperties < Test::Unit::TestCase
4
- modes = ['p', 'P']
5
- example_props = [
6
- 'Alnum',
7
- 'Any',
8
- 'Age=1.1',
9
- 'Dash',
10
- 'di',
11
- 'Default_Ignorable_Code_Point',
12
- 'Math',
13
- 'Noncharacter-Code_Point', # test dash
14
- 'sd',
15
- 'Soft Dotted', # test whitespace
16
- 'sterm',
17
- 'xidc',
18
- 'XID_Continue',
19
- 'Emoji',
20
- ]
21
-
22
- modes.each do |mode|
23
- token_type = mode == 'p' ? :property : :nonproperty
24
-
25
- example_props.each do |property|
26
- define_method "test_parse_#{token_type}_#{property}" do
27
- t = RP.parse "ab\\#{mode}{#{property}}", 'ruby/2.5'
28
-
29
- assert t.expressions.last.is_a?(UnicodeProperty::Base),
30
- "Expected property, but got #{t.expressions.last.class.name}"
31
-
32
- assert_equal token_type, t.expressions.last.type
33
- assert_equal property, t.expressions.last.name
34
- end
35
- end
36
- end
37
-
38
- def test_parse_all_properties_of_current_ruby
39
- unsupported = RegexpPropertyValues.all_for_current_ruby.reject do |prop|
40
- begin RP.parse("\\p{#{prop}}"); rescue SyntaxError, StandardError; nil end
41
- end
42
- assert_empty unsupported
43
- end
44
-
45
- def test_parse_property_negative
46
- t = RP.parse 'ab\p{L}cd', 'ruby/1.9'
47
-
48
- assert_equal false, t.expressions[1].negative?
49
- end
50
-
51
- def test_parse_nonproperty_negative
52
- t = RP.parse 'ab\P{L}cd', 'ruby/1.9'
53
-
54
- assert_equal true, t.expressions[1].negative?
55
- end
56
-
57
- def test_parse_caret_nonproperty_negative
58
- t = RP.parse 'ab\p{^L}cd', 'ruby/1.9'
59
-
60
- assert_equal true, t.expressions[1].negative?
61
- end
62
-
63
- def test_parse_double_negated_property_negative
64
- t = RP.parse 'ab\P{^L}cd', 'ruby/1.9'
65
-
66
- assert_equal false, t.expressions[1].negative?
67
- end
68
-
69
- def test_parse_property_shortcut
70
- assert_equal 'm', RP.parse('\p{mark}').expressions[0].shortcut
71
- assert_equal 'sc', RP.parse('\p{sc}').expressions[0].shortcut
72
- assert_equal nil, RP.parse('\p{in_bengali}').expressions[0].shortcut
73
- end
74
-
75
- def test_parse_property_age
76
- t = RP.parse 'ab\p{age=5.2}cd', 'ruby/1.9'
77
-
78
- assert t.expressions[1].is_a?(UnicodeProperty::Age),
79
- "Expected Age property, but got #{t.expressions[1].class.name}"
80
- end
81
-
82
- def test_parse_property_derived
83
- t = RP.parse 'ab\p{Math}cd', 'ruby/1.9'
84
-
85
- assert t.expressions[1].is_a?(UnicodeProperty::Derived),
86
- "Expected Derived property, but got #{t.expressions[1].class.name}"
87
- end
88
-
89
- def test_parse_property_script
90
- t = RP.parse 'ab\p{Hiragana}cd', 'ruby/1.9'
91
-
92
- assert t.expressions[1].is_a?(UnicodeProperty::Script),
93
- "Expected Script property, but got #{t.expressions[1].class.name}"
94
- end
95
-
96
- def test_parse_property_script_V1_9_3
97
- t = RP.parse 'ab\p{Brahmi}cd', 'ruby/1.9.3'
98
-
99
- assert t.expressions[1].is_a?(UnicodeProperty::Script),
100
- "Expected Script property, but got #{t.expressions[1].class.name}"
101
- end
102
-
103
- def test_parse_property_script_V2_2_0
104
- t = RP.parse 'ab\p{Caucasian_Albanian}cd', 'ruby/2.2'
105
-
106
- assert t.expressions[1].is_a?(UnicodeProperty::Script),
107
- "Expected Script property, but got #{t.expressions[1].class.name}"
108
- end
109
-
110
- def test_parse_property_block
111
- t = RP.parse 'ab\p{InArmenian}cd', 'ruby/1.9'
112
-
113
- assert t.expressions[1].is_a?(UnicodeProperty::Block),
114
- "Expected Block property, but got #{t.expressions[1].class.name}"
115
- end
116
-
117
- def test_parse_property_following_literal
118
- t = RP.parse 'ab\p{Lu}cd', 'ruby/1.9'
119
-
120
- assert t.expressions[2].is_a?(Literal),
121
- "Expected Literal, but got #{t.expressions[2].class.name}"
122
- end
123
-
124
- def test_parse_abandoned_newline_property
125
- t = RP.parse '\p{newline}', 'ruby/1.9'
126
- assert t.expressions.last.is_a?(UnicodeProperty::Base),
127
- "Expected property, but got #{t.expressions.last.class.name}"
128
-
129
- assert_raise(Regexp::Syntax::NotImplementedError) {
130
- RP.parse('\p{newline}', 'ruby/2.0')
131
- }
132
- end
133
- end