regexp_parser 1.4.0 → 1.7.1

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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/Gemfile +3 -3
  4. data/README.md +11 -18
  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/methods/traverse.rb +3 -1
  18. data/lib/regexp_parser/expression/quantifier.rb +2 -2
  19. data/lib/regexp_parser/expression/sequence.rb +3 -6
  20. data/lib/regexp_parser/expression/sequence_operation.rb +2 -6
  21. data/lib/regexp_parser/expression/subexpression.rb +3 -5
  22. data/lib/regexp_parser/lexer.rb +30 -44
  23. data/lib/regexp_parser/parser.rb +47 -24
  24. data/lib/regexp_parser/scanner.rb +1228 -1367
  25. data/lib/regexp_parser/scanner/char_type.rl +0 -3
  26. data/lib/regexp_parser/scanner/properties/long.yml +15 -1
  27. data/lib/regexp_parser/scanner/properties/short.yml +5 -0
  28. data/lib/regexp_parser/scanner/scanner.rl +101 -194
  29. data/lib/regexp_parser/syntax/tokens.rb +2 -10
  30. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +30 -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 +2 -2
  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 +161 -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 +161 -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/delimiters_spec.rb +68 -0
  53. data/spec/lexer/escapes_spec.rb +14 -0
  54. data/spec/lexer/keep_spec.rb +10 -0
  55. data/spec/lexer/literals_spec.rb +89 -0
  56. data/spec/lexer/nesting_spec.rb +99 -0
  57. data/spec/lexer/refcalls_spec.rb +55 -0
  58. data/spec/parser/all_spec.rb +43 -0
  59. data/spec/parser/alternation_spec.rb +88 -0
  60. data/spec/parser/anchors_spec.rb +17 -0
  61. data/spec/parser/conditionals_spec.rb +179 -0
  62. data/spec/parser/errors_spec.rb +30 -0
  63. data/spec/parser/escapes_spec.rb +121 -0
  64. data/spec/parser/free_space_spec.rb +130 -0
  65. data/spec/parser/groups_spec.rb +108 -0
  66. data/spec/parser/keep_spec.rb +6 -0
  67. data/spec/parser/posix_classes_spec.rb +8 -0
  68. data/spec/parser/properties_spec.rb +115 -0
  69. data/spec/parser/quantifiers_spec.rb +52 -0
  70. data/spec/parser/refcalls_spec.rb +112 -0
  71. data/spec/parser/set/intersections_spec.rb +127 -0
  72. data/spec/parser/set/ranges_spec.rb +111 -0
  73. data/spec/parser/sets_spec.rb +178 -0
  74. data/spec/parser/types_spec.rb +18 -0
  75. data/spec/scanner/all_spec.rb +18 -0
  76. data/spec/scanner/anchors_spec.rb +21 -0
  77. data/spec/scanner/conditionals_spec.rb +128 -0
  78. data/spec/scanner/delimiters_spec.rb +52 -0
  79. data/spec/scanner/errors_spec.rb +67 -0
  80. data/spec/scanner/escapes_spec.rb +53 -0
  81. data/spec/scanner/free_space_spec.rb +133 -0
  82. data/spec/scanner/groups_spec.rb +52 -0
  83. data/spec/scanner/keep_spec.rb +10 -0
  84. data/spec/scanner/literals_spec.rb +49 -0
  85. data/spec/scanner/meta_spec.rb +18 -0
  86. data/spec/scanner/properties_spec.rb +64 -0
  87. data/spec/scanner/quantifiers_spec.rb +20 -0
  88. data/spec/scanner/refcalls_spec.rb +36 -0
  89. data/spec/scanner/sets_spec.rb +102 -0
  90. data/spec/scanner/types_spec.rb +14 -0
  91. data/spec/spec_helper.rb +15 -0
  92. data/{test → spec}/support/runner.rb +9 -8
  93. data/spec/support/shared_examples.rb +77 -0
  94. data/{test → spec}/support/warning_extractor.rb +5 -7
  95. data/spec/syntax/syntax_spec.rb +48 -0
  96. data/spec/syntax/syntax_token_map_spec.rb +23 -0
  97. data/spec/syntax/versions/1.8.6_spec.rb +17 -0
  98. data/spec/syntax/versions/1.9.1_spec.rb +10 -0
  99. data/spec/syntax/versions/1.9.3_spec.rb +9 -0
  100. data/spec/syntax/versions/2.0.0_spec.rb +13 -0
  101. data/spec/syntax/versions/2.2.0_spec.rb +9 -0
  102. data/spec/syntax/versions/aliases_spec.rb +37 -0
  103. data/spec/token/token_spec.rb +85 -0
  104. metadata +149 -144
  105. data/test/expression/test_all.rb +0 -12
  106. data/test/expression/test_base.rb +0 -90
  107. data/test/expression/test_clone.rb +0 -89
  108. data/test/expression/test_conditionals.rb +0 -113
  109. data/test/expression/test_free_space.rb +0 -35
  110. data/test/expression/test_set.rb +0 -84
  111. data/test/expression/test_strfregexp.rb +0 -230
  112. data/test/expression/test_subexpression.rb +0 -58
  113. data/test/expression/test_tests.rb +0 -99
  114. data/test/expression/test_to_h.rb +0 -59
  115. data/test/expression/test_to_s.rb +0 -104
  116. data/test/expression/test_traverse.rb +0 -161
  117. data/test/helpers.rb +0 -10
  118. data/test/lexer/test_all.rb +0 -41
  119. data/test/lexer/test_conditionals.rb +0 -127
  120. data/test/lexer/test_keep.rb +0 -24
  121. data/test/lexer/test_literals.rb +0 -130
  122. data/test/lexer/test_nesting.rb +0 -132
  123. data/test/lexer/test_refcalls.rb +0 -56
  124. data/test/parser/set/test_intersections.rb +0 -127
  125. data/test/parser/set/test_ranges.rb +0 -111
  126. data/test/parser/test_all.rb +0 -64
  127. data/test/parser/test_alternation.rb +0 -92
  128. data/test/parser/test_anchors.rb +0 -34
  129. data/test/parser/test_conditionals.rb +0 -187
  130. data/test/parser/test_errors.rb +0 -63
  131. data/test/parser/test_escapes.rb +0 -134
  132. data/test/parser/test_free_space.rb +0 -139
  133. data/test/parser/test_groups.rb +0 -289
  134. data/test/parser/test_keep.rb +0 -21
  135. data/test/parser/test_posix_classes.rb +0 -27
  136. data/test/parser/test_properties.rb +0 -134
  137. data/test/parser/test_quantifiers.rb +0 -301
  138. data/test/parser/test_refcalls.rb +0 -186
  139. data/test/parser/test_sets.rb +0 -179
  140. data/test/parser/test_types.rb +0 -50
  141. data/test/scanner/test_all.rb +0 -38
  142. data/test/scanner/test_anchors.rb +0 -38
  143. data/test/scanner/test_conditionals.rb +0 -184
  144. data/test/scanner/test_errors.rb +0 -91
  145. data/test/scanner/test_escapes.rb +0 -56
  146. data/test/scanner/test_free_space.rb +0 -200
  147. data/test/scanner/test_groups.rb +0 -79
  148. data/test/scanner/test_keep.rb +0 -35
  149. data/test/scanner/test_literals.rb +0 -89
  150. data/test/scanner/test_meta.rb +0 -40
  151. data/test/scanner/test_properties.rb +0 -312
  152. data/test/scanner/test_quantifiers.rb +0 -37
  153. data/test/scanner/test_refcalls.rb +0 -52
  154. data/test/scanner/test_scripts.rb +0 -53
  155. data/test/scanner/test_sets.rb +0 -119
  156. data/test/scanner/test_types.rb +0 -35
  157. data/test/scanner/test_unicode_blocks.rb +0 -30
  158. data/test/support/disable_autotest.rb +0 -8
  159. data/test/syntax/test_all.rb +0 -6
  160. data/test/syntax/test_syntax.rb +0 -61
  161. data/test/syntax/test_syntax_token_map.rb +0 -25
  162. data/test/syntax/versions/test_1.8.rb +0 -55
  163. data/test/syntax/versions/test_1.9.1.rb +0 -36
  164. data/test/syntax/versions/test_1.9.3.rb +0 -32
  165. data/test/syntax/versions/test_2.0.0.rb +0 -37
  166. data/test/syntax/versions/test_2.2.0.rb +0 -32
  167. data/test/syntax/versions/test_aliases.rb +0 -129
  168. data/test/syntax/versions/test_all.rb +0 -5
  169. data/test/test_all.rb +0 -5
  170. data/test/token/test_all.rb +0 -2
  171. data/test/token/test_token.rb +0 -107
@@ -39,15 +39,7 @@ require 'regexp_parser/syntax/tokens/unicode_property'
39
39
  # into the All and Types constants.
40
40
  module Regexp::Syntax
41
41
  module Token
42
- if RUBY_VERSION >= '1.9'
43
- All = Map.map {|k,v| v}.flatten.uniq.sort
44
- else
45
- All = Map.map {|k,v| v}.flatten.uniq
46
- end
47
-
48
- Types = Map.keys
49
-
50
- All.freeze
51
- Types.freeze
42
+ All = Map.values.flatten.uniq.sort.freeze
43
+ Types = Map.keys.freeze
52
44
  end
53
45
  end
@@ -53,6 +53,10 @@ module Regexp::Syntax
53
53
 
54
54
  Age_V2_6_0 = [:'age=11.0']
55
55
 
56
+ Age_V2_6_2 = [:'age=12.0']
57
+
58
+ Age_V2_6_3 = [:'age=12.1']
59
+
56
60
  Age = all[:Age_V]
57
61
 
58
62
  Derived_V1_9_0 = [
@@ -297,6 +301,18 @@ module Regexp::Syntax
297
301
  :sogdian,
298
302
  ]
299
303
 
304
+ Script_V2_6_2 = [
305
+ :egyptian_hieroglyph_format_controls,
306
+ :elymaic,
307
+ :nandinagari,
308
+ :nyiakeng_puachue_hmong,
309
+ :ottoman_siyaq_numbers,
310
+ :small_kana_extension,
311
+ :symbols_and_pictographs_extended_a,
312
+ :tamil_supplement,
313
+ :wancho,
314
+ ]
315
+
300
316
  Script = all[:Script_V]
301
317
 
302
318
  UnicodeBlock_V1_9_0 = [
@@ -612,6 +628,18 @@ module Regexp::Syntax
612
628
  :in_sogdian,
613
629
  ]
614
630
 
631
+ UnicodeBlock_V2_6_2 = [
632
+ :in_egyptian_hieroglyph_format_controls,
633
+ :in_elymaic,
634
+ :in_nandinagari,
635
+ :in_nyiakeng_puachue_hmong,
636
+ :in_ottoman_siyaq_numbers,
637
+ :in_small_kana_extension,
638
+ :in_symbols_and_pictographs_extended_a,
639
+ :in_tamil_supplement,
640
+ :in_wancho,
641
+ ]
642
+
615
643
  UnicodeBlock = all[:UnicodeBlock_V]
616
644
 
617
645
  Emoji_V2_5_0 = [
@@ -632,6 +660,8 @@ module Regexp::Syntax
632
660
  V2_4_0 = all[:V2_4_0]
633
661
  V2_5_0 = all[:V2_5_0]
634
662
  V2_6_0 = all[:V2_6_0]
663
+ V2_6_2 = all[:V2_6_2]
664
+ V2_6_3 = all[:V2_6_3]
635
665
 
636
666
  All = all[/^V\d+_\d+_\d+$/]
637
667
 
@@ -0,0 +1,10 @@
1
+ module Regexp::Syntax
2
+ class V2_6_2 < Regexp::Syntax::V2_6_0
3
+ def initialize
4
+ super
5
+
6
+ implements :property, UnicodeProperty::V2_6_2
7
+ implements :nonproperty, UnicodeProperty::V2_6_2
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Regexp::Syntax
2
+ class V2_6_3 < Regexp::Syntax::V2_6_2
3
+ def initialize
4
+ super
5
+
6
+ implements :property, UnicodeProperty::V2_6_3
7
+ implements :nonproperty, UnicodeProperty::V2_6_3
8
+ end
9
+ end
10
+ end
@@ -1,5 +1,5 @@
1
1
  class Regexp
2
2
  class Parser
3
- VERSION = '1.4.0'
3
+ VERSION = '1.7.1'
4
4
  end
5
5
  end
@@ -21,12 +21,12 @@ Gem::Specification.new do |gem|
21
21
 
22
22
  gem.require_paths = ['lib']
23
23
 
24
- gem.files = Dir.glob('{lib,test}/**/*.rb') +
24
+ gem.files = Dir.glob('{lib,spec}/**/*.rb') +
25
25
  Dir.glob('lib/**/*.rl') +
26
26
  Dir.glob('lib/**/*.yml') +
27
27
  %w(Gemfile Rakefile LICENSE README.md CHANGELOG.md regexp_parser.gemspec)
28
28
 
29
- gem.test_files = Dir.glob('test/**/*.rb')
29
+ gem.test_files = Dir.glob('spec/**/*.rb')
30
30
 
31
31
  gem.rdoc_options = ["--inline-source", "--charset=UTF-8"]
32
32
 
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe(Regexp::Expression::Base) do
4
+ specify('#to_re') do
5
+ re_text = '^a*(b([cde]+))+f?$'
6
+
7
+ re = RP.parse(re_text).to_re
8
+
9
+ expect(re).to be_a(::Regexp)
10
+ expect(re_text).to eq re.source
11
+ end
12
+
13
+ specify('#level') do
14
+ regexp = /^a(b(c(d)))e$/
15
+ root = RP.parse(regexp)
16
+
17
+ ['^', 'a', '(b(c(d)))', 'e', '$'].each_with_index do |t, i|
18
+ expect(root[i].to_s).to eq t
19
+ expect(root[i].level).to eq 0
20
+ end
21
+
22
+ expect(root[2][0].to_s).to eq 'b'
23
+ expect(root[2][0].level).to eq 1
24
+
25
+ expect(root[2][1][0].to_s).to eq 'c'
26
+ expect(root[2][1][0].level).to eq 2
27
+
28
+ expect(root[2][1][1][0].to_s).to eq 'd'
29
+ expect(root[2][1][1][0].level).to eq 3
30
+ end
31
+
32
+ specify('#terminal?') do
33
+ root = RP.parse('^a([b]+)c$')
34
+
35
+ expect(root).not_to be_terminal
36
+
37
+ expect(root[0]).to be_terminal
38
+ expect(root[1]).to be_terminal
39
+ expect(root[2]).not_to be_terminal
40
+ expect(root[2][0]).not_to be_terminal
41
+ expect(root[2][0][0]).to be_terminal
42
+ expect(root[3]).to be_terminal
43
+ expect(root[4]).to be_terminal
44
+ end
45
+
46
+ specify('alt #terminal?') do
47
+ root = RP.parse('^(ab|cd)$')
48
+
49
+ expect(root).not_to be_terminal
50
+
51
+ expect(root[0]).to be_terminal
52
+ expect(root[1]).not_to be_terminal
53
+ expect(root[1][0]).not_to be_terminal
54
+ expect(root[1][0][0]).not_to be_terminal
55
+ expect(root[1][0][0][0]).to be_terminal
56
+ expect(root[1][0][1]).not_to be_terminal
57
+ expect(root[1][0][1][0]).to be_terminal
58
+ end
59
+
60
+ specify('#coded_offset') do
61
+ root = RP.parse('^a*(b+(c?))$')
62
+
63
+ expect(root.coded_offset).to eq '@0+12'
64
+
65
+ [
66
+ ['@0+1', '^'],
67
+ ['@1+2', 'a*'],
68
+ ['@3+8', '(b+(c?))'],
69
+ ['@11+1', '$'],
70
+ ].each_with_index do |check, i|
71
+ against = [root[i].coded_offset, root[i].to_s]
72
+
73
+ expect(against).to eq check
74
+ end
75
+
76
+ expect([root[2][0].coded_offset, root[2][0].to_s]).to eq ['@4+2', 'b+']
77
+ expect([root[2][1].coded_offset, root[2][1].to_s]).to eq ['@6+4', '(c?)']
78
+ expect([root[2][1][0].coded_offset, root[2][1][0].to_s]).to eq ['@7+2', 'c?']
79
+ end
80
+
81
+ specify('#quantity') do
82
+ expect(RP.parse(/aa/)[0].quantity).to eq [nil, nil]
83
+ expect(RP.parse(/a?/)[0].quantity).to eq [0, 1]
84
+ expect(RP.parse(/a*/)[0].quantity).to eq [0, -1]
85
+ expect(RP.parse(/a+/)[0].quantity).to eq [1, -1]
86
+ end
87
+
88
+ specify('#repetitions') do
89
+ expect(RP.parse(/aa/)[0].repetitions).to eq 1..1
90
+ expect(RP.parse(/a?/)[0].repetitions).to eq 0..1
91
+ expect(RP.parse(/a*/)[0].repetitions).to eq 0..(Float::INFINITY)
92
+ expect(RP.parse(/a+/)[0].repetitions).to eq 1..(Float::INFINITY)
93
+ end
94
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('Expression#clone') do
4
+ specify('Base#clone') do
5
+ root = RP.parse(/^(?i:a)b+$/i)
6
+ copy = root.clone
7
+
8
+ expect(copy.to_s).to eq root.to_s
9
+
10
+ expect(root.object_id).not_to eq copy.object_id
11
+ expect(root.text).to eq copy.text
12
+ expect(root.text.object_id).not_to eq copy.text.object_id
13
+
14
+ root_1 = root[1]
15
+ copy_1 = copy[1]
16
+
17
+ expect(root_1.options).to eq copy_1.options
18
+ expect(root_1.options.object_id).not_to eq copy_1.options.object_id
19
+
20
+ root_2 = root[2]
21
+ copy_2 = copy[2]
22
+
23
+ expect(root_2).to be_quantified
24
+ expect(copy_2).to be_quantified
25
+ expect(root_2.quantifier.text).to eq copy_2.quantifier.text
26
+ expect(root_2.quantifier.text.object_id).not_to eq copy_2.quantifier.text.object_id
27
+ expect(root_2.quantifier.object_id).not_to eq copy_2.quantifier.object_id
28
+
29
+ # regression test
30
+ expect { root_2.clone }.not_to change { root_2.quantifier.object_id }
31
+ expect { root_2.clone }.not_to change { root_2.quantifier.text.object_id }
32
+ end
33
+
34
+ specify('Subexpression#clone') do
35
+ root = RP.parse(/^a(b([cde])f)g$/)
36
+ copy = root.clone
37
+
38
+ expect(copy.to_s).to eq root.to_s
39
+
40
+ expect(root).to respond_to(:expressions)
41
+ expect(copy).to respond_to(:expressions)
42
+ expect(root.expressions.object_id).not_to eq copy.expressions.object_id
43
+ copy.expressions.each_with_index do |exp, index|
44
+ expect(root[index].object_id).not_to eq exp.object_id
45
+ end
46
+ copy[2].each_with_index do |exp, index|
47
+ expect(root[2][index].object_id).not_to eq exp.object_id
48
+ end
49
+
50
+ # regression test
51
+ expect { root.clone }.not_to change { root.expressions.object_id }
52
+ end
53
+
54
+ specify('Group::Named#clone') do
55
+ root = RP.parse('^(?<somename>a)+bc$')
56
+ copy = root.clone
57
+
58
+ expect(copy.to_s).to eq root.to_s
59
+
60
+ root_1 = root[1]
61
+ copy_1 = copy[1]
62
+
63
+ expect(root_1.name).to eq copy_1.name
64
+ expect(root_1.name.object_id).not_to eq copy_1.name.object_id
65
+ expect(root_1.text).to eq copy_1.text
66
+ expect(root_1.expressions.object_id).not_to eq copy_1.expressions.object_id
67
+ copy_1.expressions.each_with_index do |exp, index|
68
+ expect(root_1[index].object_id).not_to eq exp.object_id
69
+ end
70
+
71
+ # regression test
72
+ expect { root_1.clone }.not_to change { root_1.name.object_id }
73
+ end
74
+
75
+ specify('Sequence#clone') do
76
+ root = RP.parse(/(a|b)/)
77
+ copy = root.clone
78
+
79
+ # regression test
80
+ expect(copy.to_s).to eq root.to_s
81
+
82
+ root_seq_op = root[0][0]
83
+ copy_seq_op = copy[0][0]
84
+ root_seq_1 = root[0][0][0]
85
+ copy_seq_1 = copy[0][0][0]
86
+
87
+ expect(root_seq_op.object_id).not_to eq copy_seq_op.object_id
88
+ expect(root_seq_1.object_id).not_to eq copy_seq_1.object_id
89
+ copy_seq_1.expressions.each_with_index do |exp, index|
90
+ expect(root_seq_1[index].object_id).not_to eq exp.object_id
91
+ end
92
+ end
93
+
94
+ describe('Base#unquantified_clone') do
95
+ it 'produces a clone' do
96
+ root = RP.parse(/^a(b([cde])f)g$/)
97
+ copy = root.unquantified_clone
98
+
99
+ expect(copy.to_s).to eq root.to_s
100
+
101
+ expect(copy.object_id).not_to eq root.object_id
102
+ end
103
+
104
+ it 'does not carry over the callee quantifier' do
105
+ expect(RP.parse(/a{3}/)[0]).to be_quantified
106
+ expect(RP.parse(/a{3}/)[0].unquantified_clone).not_to be_quantified
107
+
108
+ expect(RP.parse(/[a]{3}/)[0]).to be_quantified
109
+ expect(RP.parse(/[a]{3}/)[0].unquantified_clone).not_to be_quantified
110
+
111
+ expect(RP.parse(/(a|b){3}/)[0]).to be_quantified
112
+ expect(RP.parse(/(a|b){3}/)[0].unquantified_clone).not_to be_quantified
113
+ end
114
+
115
+ it 'keeps quantifiers of callee children' do
116
+ expect(RP.parse(/(a{3}){3}/)[0][0]).to be_quantified
117
+ expect(RP.parse(/(a{3}){3}/)[0].unquantified_clone[0]).to be_quantified
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe(Regexp::Expression::Conditional) do
4
+ let(:root) { RP.parse('^(a(b))(b(?(1)c|(?(2)d|(?(3)e|f)))g)$') }
5
+ let(:cond_1) { root[2][1] }
6
+ let(:cond_2) { root[2][1][2][0] }
7
+ let(:cond_3) { root[2][1][2][0][2][0] }
8
+
9
+ specify('root level') do
10
+ [
11
+ '^',
12
+ '(a(b))',
13
+ '(b(?(1)c|(?(2)d|(?(3)e|f)))g)',
14
+ '$'
15
+ ].each_with_index do |t, i|
16
+ expect(root[i].conditional_level).to eq 0
17
+ expect(root[i].to_s).to eq t
18
+ end
19
+
20
+ expect(root[2][0].to_s).to eq 'b'
21
+ expect(root[2][0].conditional_level).to eq 0
22
+ end
23
+
24
+ specify('level one') do
25
+ condition = cond_1.condition
26
+ branch_1 = cond_1.branches.first
27
+
28
+ expect(condition).to be_a Conditional::Condition
29
+ expect(condition.to_s).to eq '(1)'
30
+ expect(condition.conditional_level).to eq 1
31
+
32
+ expect(branch_1).to be_a Conditional::Branch
33
+ expect(branch_1.to_s).to eq 'c'
34
+ expect(branch_1.conditional_level).to eq 1
35
+
36
+ expect(branch_1.first.to_s).to eq 'c'
37
+ expect(branch_1.first.conditional_level).to eq 1
38
+ end
39
+
40
+ specify('level two') do
41
+ condition = cond_2.condition
42
+ branch_1 = cond_2.branches.first
43
+ branch_2 = cond_2.branches.last
44
+
45
+ expect(cond_2.to_s).to start_with '(?'
46
+ expect(cond_2.conditional_level).to eq 1
47
+
48
+ expect(condition).to be_a Conditional::Condition
49
+ expect(condition.to_s).to eq '(2)'
50
+ expect(condition.conditional_level).to eq 2
51
+
52
+ expect(branch_1).to be_a Conditional::Branch
53
+ expect(branch_1.to_s).to eq 'd'
54
+ expect(branch_1.conditional_level).to eq 2
55
+
56
+ expect(branch_1.first.to_s).to eq 'd'
57
+ expect(branch_1.first.conditional_level).to eq 2
58
+
59
+ expect(branch_2.first.to_s).to start_with '(?'
60
+ expect(branch_2.first.conditional_level).to eq 2
61
+ end
62
+
63
+ specify('level three') do
64
+ condition = cond_3.condition
65
+ branch_1 = cond_3.branches.first
66
+ branch_2 = cond_3.branches.last
67
+
68
+ expect(condition).to be_a Conditional::Condition
69
+ expect(condition.to_s).to eq '(3)'
70
+ expect(condition.conditional_level).to eq 3
71
+
72
+ expect(cond_3.to_s).to eq '(?(3)e|f)'
73
+ expect(cond_3.conditional_level).to eq 2
74
+
75
+ expect(branch_1).to be_a Conditional::Branch
76
+ expect(branch_1.to_s).to eq 'e'
77
+ expect(branch_1.conditional_level).to eq 3
78
+
79
+ expect(branch_1.first.to_s).to eq 'e'
80
+ expect(branch_1.first.conditional_level).to eq 3
81
+
82
+ expect(branch_2).to be_a Conditional::Branch
83
+ expect(branch_2.to_s).to eq 'f'
84
+ expect(branch_2.conditional_level).to eq 3
85
+
86
+ expect(branch_2.first.to_s).to eq 'f'
87
+ expect(branch_2.first.conditional_level).to eq 3
88
+ end
89
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe(Regexp::Expression::FreeSpace) do
4
+ specify('white space quantify raises error') do
5
+ regexp = /
6
+ a # Comment
7
+ /x
8
+
9
+ root = RP.parse(regexp)
10
+ space = root[0]
11
+
12
+ expect(space).to be_instance_of(FreeSpace::WhiteSpace)
13
+ expect { space.quantify(:dummy, '#') }.to raise_error(RuntimeError)
14
+ end
15
+
16
+ specify('comment quantify raises error') do
17
+ regexp = /
18
+ a # Comment
19
+ /x
20
+
21
+ root = RP.parse(regexp)
22
+ comment = root[3]
23
+
24
+ expect(comment).to be_instance_of(FreeSpace::Comment)
25
+ expect { comment.quantify(:dummy, '#') }.to raise_error(RuntimeError)
26
+ end
27
+ end