regexp_parser 2.1.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +31 -27
- data/Rakefile +6 -70
- data/lib/regexp_parser/expression/base.rb +123 -0
- data/lib/regexp_parser/expression/classes/anchor.rb +0 -2
- data/lib/regexp_parser/expression/classes/{backref.rb → backreference.rb} +0 -0
- data/lib/regexp_parser/expression/classes/{set → character_set}/intersection.rb +0 -0
- data/lib/regexp_parser/expression/classes/{set → character_set}/range.rb +0 -0
- data/lib/regexp_parser/expression/classes/{set.rb → character_set.rb} +0 -0
- data/lib/regexp_parser/expression/classes/{escape.rb → escape_sequence.rb} +13 -7
- data/lib/regexp_parser/expression/classes/free_space.rb +0 -2
- data/lib/regexp_parser/expression/classes/literal.rb +1 -5
- data/lib/regexp_parser/expression/classes/property.rb +0 -2
- data/lib/regexp_parser/expression/classes/root.rb +0 -1
- data/lib/regexp_parser/expression/classes/type.rb +0 -2
- data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
- data/lib/regexp_parser/expression/quantifier.rb +1 -1
- data/lib/regexp_parser/expression/sequence.rb +0 -1
- data/lib/regexp_parser/expression/subexpression.rb +0 -1
- data/lib/regexp_parser/expression.rb +6 -130
- data/lib/regexp_parser/lexer.rb +8 -6
- data/lib/regexp_parser/scanner/properties/long.csv +622 -0
- data/lib/regexp_parser/scanner/properties/short.csv +246 -0
- data/lib/regexp_parser/scanner/scanner.rl +6 -4
- data/lib/regexp_parser/scanner.rb +126 -124
- data/lib/regexp_parser/syntax/any.rb +2 -7
- data/lib/regexp_parser/syntax/base.rb +91 -66
- data/lib/regexp_parser/syntax/token/anchor.rb +15 -0
- data/lib/regexp_parser/syntax/{tokens → token}/assertion.rb +2 -2
- data/lib/regexp_parser/syntax/token/backreference.rb +30 -0
- data/lib/regexp_parser/syntax/{tokens → token}/character_set.rb +2 -2
- data/lib/regexp_parser/syntax/{tokens → token}/character_type.rb +3 -3
- data/lib/regexp_parser/syntax/{tokens → token}/conditional.rb +3 -3
- data/lib/regexp_parser/syntax/token/escape.rb +31 -0
- data/lib/regexp_parser/syntax/{tokens → token}/group.rb +7 -7
- data/lib/regexp_parser/syntax/{tokens → token}/keep.rb +1 -1
- data/lib/regexp_parser/syntax/{tokens → token}/meta.rb +2 -2
- data/lib/regexp_parser/syntax/{tokens → token}/posix_class.rb +3 -3
- data/lib/regexp_parser/syntax/token/quantifier.rb +35 -0
- data/lib/regexp_parser/syntax/token/unicode_property.rb +722 -0
- data/lib/regexp_parser/syntax/token.rb +45 -0
- data/lib/regexp_parser/syntax/version_lookup.rb +20 -29
- data/lib/regexp_parser/syntax/versions/1.8.6.rb +13 -20
- data/lib/regexp_parser/syntax/versions/1.9.1.rb +10 -17
- data/lib/regexp_parser/syntax/versions/1.9.3.rb +3 -10
- data/lib/regexp_parser/syntax/versions/2.0.0.rb +8 -15
- data/lib/regexp_parser/syntax/versions/2.2.0.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.3.0.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.4.0.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.4.1.rb +2 -8
- data/lib/regexp_parser/syntax/versions/2.5.0.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.6.0.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.6.2.rb +3 -9
- data/lib/regexp_parser/syntax/versions/2.6.3.rb +3 -9
- data/lib/regexp_parser/syntax/versions/3.1.0.rb +4 -0
- data/lib/regexp_parser/syntax/versions/3.2.0.rb +4 -0
- data/lib/regexp_parser/syntax/versions.rb +1 -1
- data/lib/regexp_parser/syntax.rb +1 -1
- data/lib/regexp_parser/token.rb +9 -20
- data/lib/regexp_parser/version.rb +1 -1
- data/lib/regexp_parser.rb +0 -2
- data/regexp_parser.gemspec +20 -22
- metadata +36 -167
- data/lib/regexp_parser/scanner/properties/long.yml +0 -594
- data/lib/regexp_parser/scanner/properties/short.yml +0 -237
- data/lib/regexp_parser/syntax/tokens/anchor.rb +0 -15
- data/lib/regexp_parser/syntax/tokens/backref.rb +0 -24
- data/lib/regexp_parser/syntax/tokens/escape.rb +0 -30
- data/lib/regexp_parser/syntax/tokens/quantifier.rb +0 -35
- data/lib/regexp_parser/syntax/tokens/unicode_property.rb +0 -675
- data/lib/regexp_parser/syntax/tokens.rb +0 -45
- data/spec/expression/base_spec.rb +0 -104
- data/spec/expression/clone_spec.rb +0 -152
- data/spec/expression/conditional_spec.rb +0 -89
- data/spec/expression/free_space_spec.rb +0 -27
- data/spec/expression/methods/match_length_spec.rb +0 -161
- data/spec/expression/methods/match_spec.rb +0 -25
- data/spec/expression/methods/strfregexp_spec.rb +0 -224
- data/spec/expression/methods/tests_spec.rb +0 -99
- data/spec/expression/methods/traverse_spec.rb +0 -161
- data/spec/expression/options_spec.rb +0 -128
- data/spec/expression/subexpression_spec.rb +0 -50
- data/spec/expression/to_h_spec.rb +0 -26
- data/spec/expression/to_s_spec.rb +0 -108
- data/spec/lexer/all_spec.rb +0 -22
- data/spec/lexer/conditionals_spec.rb +0 -53
- data/spec/lexer/delimiters_spec.rb +0 -68
- data/spec/lexer/escapes_spec.rb +0 -14
- data/spec/lexer/keep_spec.rb +0 -10
- data/spec/lexer/literals_spec.rb +0 -64
- data/spec/lexer/nesting_spec.rb +0 -99
- data/spec/lexer/refcalls_spec.rb +0 -60
- data/spec/parser/all_spec.rb +0 -43
- data/spec/parser/alternation_spec.rb +0 -88
- data/spec/parser/anchors_spec.rb +0 -17
- data/spec/parser/conditionals_spec.rb +0 -179
- data/spec/parser/errors_spec.rb +0 -30
- data/spec/parser/escapes_spec.rb +0 -121
- data/spec/parser/free_space_spec.rb +0 -130
- data/spec/parser/groups_spec.rb +0 -108
- data/spec/parser/keep_spec.rb +0 -6
- data/spec/parser/options_spec.rb +0 -28
- data/spec/parser/posix_classes_spec.rb +0 -8
- data/spec/parser/properties_spec.rb +0 -115
- data/spec/parser/quantifiers_spec.rb +0 -68
- data/spec/parser/refcalls_spec.rb +0 -117
- data/spec/parser/set/intersections_spec.rb +0 -127
- data/spec/parser/set/ranges_spec.rb +0 -111
- data/spec/parser/sets_spec.rb +0 -178
- data/spec/parser/types_spec.rb +0 -18
- data/spec/scanner/all_spec.rb +0 -18
- data/spec/scanner/anchors_spec.rb +0 -21
- data/spec/scanner/conditionals_spec.rb +0 -128
- data/spec/scanner/delimiters_spec.rb +0 -52
- data/spec/scanner/errors_spec.rb +0 -67
- data/spec/scanner/escapes_spec.rb +0 -64
- data/spec/scanner/free_space_spec.rb +0 -165
- data/spec/scanner/groups_spec.rb +0 -61
- data/spec/scanner/keep_spec.rb +0 -10
- data/spec/scanner/literals_spec.rb +0 -39
- data/spec/scanner/meta_spec.rb +0 -18
- data/spec/scanner/options_spec.rb +0 -36
- data/spec/scanner/properties_spec.rb +0 -64
- data/spec/scanner/quantifiers_spec.rb +0 -25
- data/spec/scanner/refcalls_spec.rb +0 -55
- data/spec/scanner/sets_spec.rb +0 -151
- data/spec/scanner/types_spec.rb +0 -14
- data/spec/spec_helper.rb +0 -16
- data/spec/support/runner.rb +0 -42
- data/spec/support/shared_examples.rb +0 -77
- data/spec/support/warning_extractor.rb +0 -60
- data/spec/syntax/syntax_spec.rb +0 -48
- data/spec/syntax/syntax_token_map_spec.rb +0 -23
- data/spec/syntax/versions/1.8.6_spec.rb +0 -17
- data/spec/syntax/versions/1.9.1_spec.rb +0 -10
- data/spec/syntax/versions/1.9.3_spec.rb +0 -9
- data/spec/syntax/versions/2.0.0_spec.rb +0 -13
- data/spec/syntax/versions/2.2.0_spec.rb +0 -9
- data/spec/syntax/versions/aliases_spec.rb +0 -37
- data/spec/token/token_spec.rb +0 -85
@@ -1,104 +0,0 @@
|
|
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
|
-
|
95
|
-
specify('#base_length') do
|
96
|
-
expect(RP.parse(/(aa)/)[0].base_length).to eq 4
|
97
|
-
expect(RP.parse(/(aa){42}/)[0].base_length).to eq 4
|
98
|
-
end
|
99
|
-
|
100
|
-
specify('#full_length') do
|
101
|
-
expect(RP.parse(/(aa)/)[0].full_length).to eq 4
|
102
|
-
expect(RP.parse(/(aa){42}/)[0].full_length).to eq 8
|
103
|
-
end
|
104
|
-
end
|
@@ -1,152 +0,0 @@
|
|
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('Group::Options#clone') do
|
76
|
-
root = RP.parse('foo(?i)bar')
|
77
|
-
copy = root.clone
|
78
|
-
|
79
|
-
expect(copy.to_s).to eq root.to_s
|
80
|
-
|
81
|
-
root_1 = root[1]
|
82
|
-
copy_1 = copy[1]
|
83
|
-
|
84
|
-
expect(root_1.option_changes).to eq copy_1.option_changes
|
85
|
-
expect(root_1.option_changes.object_id).not_to eq copy_1.option_changes.object_id
|
86
|
-
|
87
|
-
# regression test
|
88
|
-
expect { root_1.clone }.not_to(change { root_1.option_changes.object_id })
|
89
|
-
end
|
90
|
-
|
91
|
-
specify('Backreference::Base#clone') do
|
92
|
-
root = RP.parse('(foo)\1')
|
93
|
-
copy = root.clone
|
94
|
-
|
95
|
-
expect(copy.to_s).to eq root.to_s
|
96
|
-
|
97
|
-
root_1 = root[1]
|
98
|
-
copy_1 = copy[1]
|
99
|
-
|
100
|
-
expect(root_1.referenced_expression.to_s).to eq copy_1.referenced_expression.to_s
|
101
|
-
expect(root_1.referenced_expression.object_id).not_to eq copy_1.referenced_expression.object_id
|
102
|
-
|
103
|
-
# regression test
|
104
|
-
expect { root_1.clone }.not_to(change { root_1.referenced_expression.object_id })
|
105
|
-
end
|
106
|
-
|
107
|
-
specify('Sequence#clone') do
|
108
|
-
root = RP.parse(/(a|b)/)
|
109
|
-
copy = root.clone
|
110
|
-
|
111
|
-
# regression test
|
112
|
-
expect(copy.to_s).to eq root.to_s
|
113
|
-
|
114
|
-
root_seq_op = root[0][0]
|
115
|
-
copy_seq_op = copy[0][0]
|
116
|
-
root_seq_1 = root[0][0][0]
|
117
|
-
copy_seq_1 = copy[0][0][0]
|
118
|
-
|
119
|
-
expect(root_seq_op.object_id).not_to eq copy_seq_op.object_id
|
120
|
-
expect(root_seq_1.object_id).not_to eq copy_seq_1.object_id
|
121
|
-
copy_seq_1.expressions.each_with_index do |exp, index|
|
122
|
-
expect(root_seq_1[index].object_id).not_to eq exp.object_id
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe('Base#unquantified_clone') do
|
127
|
-
it 'produces a clone' do
|
128
|
-
root = RP.parse(/^a(b([cde])f)g$/)
|
129
|
-
copy = root.unquantified_clone
|
130
|
-
|
131
|
-
expect(copy.to_s).to eq root.to_s
|
132
|
-
|
133
|
-
expect(copy.object_id).not_to eq root.object_id
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'does not carry over the callee quantifier' do
|
137
|
-
expect(RP.parse(/a{3}/)[0]).to be_quantified
|
138
|
-
expect(RP.parse(/a{3}/)[0].unquantified_clone).not_to be_quantified
|
139
|
-
|
140
|
-
expect(RP.parse(/[a]{3}/)[0]).to be_quantified
|
141
|
-
expect(RP.parse(/[a]{3}/)[0].unquantified_clone).not_to be_quantified
|
142
|
-
|
143
|
-
expect(RP.parse(/(a|b){3}/)[0]).to be_quantified
|
144
|
-
expect(RP.parse(/(a|b){3}/)[0].unquantified_clone).not_to be_quantified
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'keeps quantifiers of callee children' do
|
148
|
-
expect(RP.parse(/(a{3}){3}/)[0][0]).to be_quantified
|
149
|
-
expect(RP.parse(/(a{3}){3}/)[0].unquantified_clone[0]).to be_quantified
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
@@ -1,89 +0,0 @@
|
|
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
|
@@ -1,27 +0,0 @@
|
|
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(Regexp::Parser::Error)
|
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(Regexp::Parser::Error)
|
26
|
-
end
|
27
|
-
end
|
@@ -1,161 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
ML = Regexp::MatchLength
|
4
|
-
|
5
|
-
RSpec.describe(Regexp::MatchLength) do
|
6
|
-
specify('literal') { expect(ML.of(/a/).minmax).to eq [1, 1] }
|
7
|
-
specify('literal sequence') { expect(ML.of(/abc/).minmax).to eq [3, 3] }
|
8
|
-
specify('dot') { expect(ML.of(/./).minmax).to eq [1, 1] }
|
9
|
-
specify('set') { expect(ML.of(/[abc]/).minmax).to eq [1, 1] }
|
10
|
-
specify('type') { expect(ML.of(/\d/).minmax).to eq [1, 1] }
|
11
|
-
specify('escape') { expect(ML.of(/\n/).minmax).to eq [1, 1] }
|
12
|
-
specify('property') { expect(ML.of(/\p{ascii}/).minmax).to eq [1, 1] }
|
13
|
-
specify('codepoint list') { expect(ML.of(/\u{61 62 63}/).minmax).to eq [3, 3] }
|
14
|
-
specify('multi-char literal') { expect(ML.of(/abc/).minmax).to eq [3, 3] }
|
15
|
-
specify('fixed quantified') { expect(ML.of(/a{5}/).minmax).to eq [5, 5] }
|
16
|
-
specify('range quantified') { expect(ML.of(/a{5,9}/).minmax).to eq [5, 9] }
|
17
|
-
specify('nested quantified') { expect(ML.of(/(a{2}){3,4}/).minmax).to eq [6, 8] }
|
18
|
-
specify('open-end quantified') { expect(ML.of(/a*/).minmax).to eq [0, Float::INFINITY] }
|
19
|
-
specify('empty subexpression') { expect(ML.of(//).minmax).to eq [0, 0] }
|
20
|
-
specify('anchor') { expect(ML.of(/^$/).minmax).to eq [0, 0] }
|
21
|
-
specify('lookaround') { expect(ML.of(/(?=abc)/).minmax).to eq [0, 0] }
|
22
|
-
specify('free space') { expect(ML.of(/ /x).minmax).to eq [0, 0] }
|
23
|
-
specify('comment') { expect(ML.of(/(?#comment)/x).minmax).to eq [0, 0] }
|
24
|
-
specify('backreference') { expect(ML.of(/(abc){2}\1/).minmax).to eq [9, 9] }
|
25
|
-
specify('subexp call') { expect(ML.of(/(abc){2}\g<-1>/).minmax).to eq [9, 9] }
|
26
|
-
specify('alternation') { expect(ML.of(/a|bcde/).minmax).to eq [1, 4] }
|
27
|
-
specify('nested alternation') { expect(ML.of(/a|bc(d|efg)/).minmax).to eq [1, 5] }
|
28
|
-
specify('quantified alternation') { expect(ML.of(/a|bcde?/).minmax).to eq [1, 4] }
|
29
|
-
if ruby_version_at_least('2.4.1')
|
30
|
-
specify('absence group') { expect(ML.of('(?~abc)').minmax).to eq [0, Float::INFINITY] }
|
31
|
-
end
|
32
|
-
|
33
|
-
specify('raises for missing references') do
|
34
|
-
exp = RP.parse(/(a)\1/).last
|
35
|
-
exp.referenced_expression = nil
|
36
|
-
expect { exp.match_length }.to raise_error(ArgumentError)
|
37
|
-
end
|
38
|
-
|
39
|
-
describe('::of') do
|
40
|
-
it('works with Regexps') { expect(ML.of(/foo/).minmax).to eq [3, 3] }
|
41
|
-
it('works with Strings') { expect(ML.of('foo').minmax).to eq [3, 3] }
|
42
|
-
it('works with Expressions') { expect(ML.of(RP.parse(/foo/)).minmax).to eq [3, 3] }
|
43
|
-
end
|
44
|
-
|
45
|
-
describe('Expression#match_length') do
|
46
|
-
it('returns the MatchLength') { expect(RP.parse(/abc/).match_length.minmax).to eq [3, 3] }
|
47
|
-
end
|
48
|
-
|
49
|
-
describe('Expression#inner_match_length') do
|
50
|
-
it 'returns the MatchLength of an expression that does not count towards parent match_length' do
|
51
|
-
exp = RP.parse(/(?=ab|cdef)/)[0]
|
52
|
-
expect(exp).to be_a Regexp::Expression::Assertion::Base
|
53
|
-
expect(exp.match_length.minmax).to eq [0, 0]
|
54
|
-
expect(exp.inner_match_length.minmax).to eq [2, 4]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe('#include?') do
|
59
|
-
specify('unquantified') do
|
60
|
-
expect(ML.of(/a/)).to include 1
|
61
|
-
expect(ML.of(/a/)).not_to include 0
|
62
|
-
expect(ML.of(/a/)).not_to include 2
|
63
|
-
end
|
64
|
-
|
65
|
-
specify('fixed quantified') do
|
66
|
-
expect(ML.of(/a{5}/)).to include 5
|
67
|
-
expect(ML.of(/a{5}/)).not_to include 0
|
68
|
-
expect(ML.of(/a{5}/)).not_to include 4
|
69
|
-
expect(ML.of(/a{5}/)).not_to include 6
|
70
|
-
end
|
71
|
-
|
72
|
-
specify('variably quantified') do
|
73
|
-
expect(ML.of(/a?/)).to include 0
|
74
|
-
expect(ML.of(/a?/)).to include 1
|
75
|
-
expect(ML.of(/a?/)).not_to include 2
|
76
|
-
end
|
77
|
-
|
78
|
-
specify('nested quantified') do
|
79
|
-
expect(ML.of(/(a{2}){3,4}/)).to include 6
|
80
|
-
expect(ML.of(/(a{2}){3,4}/)).to include 8
|
81
|
-
expect(ML.of(/(a{2}){3,4}/)).not_to include 0
|
82
|
-
expect(ML.of(/(a{2}){3,4}/)).not_to include 5
|
83
|
-
expect(ML.of(/(a{2}){3,4}/)).not_to include 7
|
84
|
-
expect(ML.of(/(a{2}){3,4}/)).not_to include 9
|
85
|
-
end
|
86
|
-
|
87
|
-
specify('branches') do
|
88
|
-
expect(ML.of(/ab|cdef/)).to include 2
|
89
|
-
expect(ML.of(/ab|cdef/)).to include 4
|
90
|
-
expect(ML.of(/ab|cdef/)).not_to include 0
|
91
|
-
expect(ML.of(/ab|cdef/)).not_to include 3
|
92
|
-
expect(ML.of(/ab|cdef/)).not_to include 5
|
93
|
-
end
|
94
|
-
|
95
|
-
specify('called on leaf node') do
|
96
|
-
expect(ML.of(RP.parse(/a{2}/)[0])).to include 2
|
97
|
-
expect(ML.of(RP.parse(/a{2}/)[0])).not_to include 0
|
98
|
-
expect(ML.of(RP.parse(/a{2}/)[0])).not_to include 1
|
99
|
-
expect(ML.of(RP.parse(/a{2}/)[0])).not_to include 3
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe('#fixed?') do
|
104
|
-
specify('unquantified') { expect(ML.of(/a/)).to be_fixed }
|
105
|
-
specify('fixed quantified') { expect(ML.of(/a{5}/)).to be_fixed }
|
106
|
-
specify('variably quantified') { expect(ML.of(/a?/)).not_to be_fixed }
|
107
|
-
specify('equal branches') { expect(ML.of(/ab|cd/)).to be_fixed }
|
108
|
-
specify('unequal branches') { expect(ML.of(/ab|cdef/)).not_to be_fixed }
|
109
|
-
specify('equal quantified branches') { expect(ML.of(/a{2}|cd/)).to be_fixed }
|
110
|
-
specify('unequal quantified branches') { expect(ML.of(/a{3}|cd/)).not_to be_fixed }
|
111
|
-
specify('empty') { expect(ML.of(//)).to be_fixed }
|
112
|
-
end
|
113
|
-
|
114
|
-
describe('#each') do
|
115
|
-
it 'returns an Enumerator if called without a block' do
|
116
|
-
result = ML.of(/a?/).each
|
117
|
-
expect(result).to be_a(Enumerator)
|
118
|
-
expect(result.next).to eq 0
|
119
|
-
expect(result.next).to eq 1
|
120
|
-
expect { result.next }.to raise_error(StopIteration)
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'is aware of limit option even if called without a block' do
|
124
|
-
result = ML.of(/a?/).each(limit: 1)
|
125
|
-
expect(result).to be_a(Enumerator)
|
126
|
-
expect(result.next).to eq 0
|
127
|
-
expect { result.next }.to raise_error(StopIteration)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'is limited to 1000 iterations in case there are infinite match lengths' do
|
131
|
-
expect(ML.of(/a*/).first(3000).size).to eq 1000
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'scaffolds the Enumerable interface' do
|
135
|
-
expect(ML.of(/abc|defg/).count).to eq 2
|
136
|
-
expect(ML.of(/(ab)*/).first(5)).to eq [0, 2, 4, 6, 8]
|
137
|
-
expect(ML.of(/a{,10}/).any? { |len| len > 20 }).to be false
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe('#endless_each') do
|
142
|
-
it 'returns an Enumerator if called without a block' do
|
143
|
-
result = ML.of(/a?/).endless_each
|
144
|
-
expect(result).to be_a(Enumerator)
|
145
|
-
expect(result.next).to eq 0
|
146
|
-
expect(result.next).to eq 1
|
147
|
-
expect { result.next }.to raise_error(StopIteration)
|
148
|
-
end
|
149
|
-
|
150
|
-
it 'never stops iterating for infinite match lengths' do
|
151
|
-
expect(ML.of(/a*/).endless_each.first(3000).size).to eq 3000
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
describe('#inspect') do
|
156
|
-
it 'is nice' do
|
157
|
-
result = RP.parse(/a{2,4}/)[0].match_length
|
158
|
-
expect(result.inspect).to eq '#<Regexp::MatchLength<Literal> min=2 max=4>'
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe('Expression#match') do
|
4
|
-
it 'returns the #match result of the respective Regexp' do
|
5
|
-
expect(RP.parse(/a/).match('a')[0]).to eq 'a'
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'can be given an offset, just like Regexp#match' do
|
9
|
-
expect(RP.parse(/./).match('ab', 1)[0]).to eq 'b'
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'works with the #=~ alias' do
|
13
|
-
expect(RP.parse(/a/) =~ 'a').to be_a MatchData
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
RSpec.describe('Expression#match?') do
|
18
|
-
it 'returns true if the Respective Regexp matches' do
|
19
|
-
expect(RP.parse(/a/).match?('a')).to be true
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns false if the Respective Regexp does not match' do
|
23
|
-
expect(RP.parse(/a/).match?('b')).to be false
|
24
|
-
end
|
25
|
-
end
|