regexp_parser 1.7.1 → 2.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +157 -1
- data/Gemfile +6 -1
- data/LICENSE +1 -1
- data/README.md +38 -32
- data/Rakefile +18 -27
- data/lib/regexp_parser/error.rb +4 -0
- 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} +5 -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 +2 -1
- data/lib/regexp_parser/expression/classes/{set.rb → character_set.rb} +0 -0
- data/lib/regexp_parser/expression/classes/conditional.rb +11 -1
- data/lib/regexp_parser/expression/classes/{escape.rb → escape_sequence.rb} +13 -7
- data/lib/regexp_parser/expression/classes/free_space.rb +2 -4
- data/lib/regexp_parser/expression/classes/group.rb +28 -3
- data/lib/regexp_parser/expression/classes/literal.rb +1 -5
- data/lib/regexp_parser/expression/classes/property.rb +1 -3
- data/lib/regexp_parser/expression/classes/root.rb +4 -17
- data/lib/regexp_parser/expression/classes/type.rb +0 -2
- data/lib/regexp_parser/expression/methods/match_length.rb +2 -2
- data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
- data/lib/regexp_parser/expression/methods/traverse.rb +2 -2
- data/lib/regexp_parser/expression/quantifier.rb +11 -2
- data/lib/regexp_parser/expression/sequence.rb +3 -20
- data/lib/regexp_parser/expression/subexpression.rb +1 -2
- data/lib/regexp_parser/expression.rb +7 -139
- data/lib/regexp_parser/lexer.rb +13 -11
- data/lib/regexp_parser/parser.rb +325 -344
- data/lib/regexp_parser/scanner/char_type.rl +11 -11
- data/lib/regexp_parser/scanner/properties/long.csv +604 -0
- data/lib/regexp_parser/scanner/properties/short.csv +242 -0
- data/lib/regexp_parser/scanner/property.rl +2 -2
- data/lib/regexp_parser/scanner/scanner.rl +235 -255
- data/lib/regexp_parser/scanner.rb +1324 -1387
- data/lib/regexp_parser/syntax/any.rb +4 -6
- data/lib/regexp_parser/syntax/base.rb +13 -15
- 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 +696 -0
- data/lib/regexp_parser/syntax/token.rb +45 -0
- data/lib/regexp_parser/syntax/version_lookup.rb +4 -4
- data/lib/regexp_parser/syntax/versions/1.8.6.rb +2 -2
- data/lib/regexp_parser/syntax/versions/1.9.1.rb +1 -1
- data/lib/regexp_parser/syntax/versions/3.1.0.rb +10 -0
- data/lib/regexp_parser/syntax.rb +8 -6
- 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 +34 -165
- 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 -94
- data/spec/expression/clone_spec.rb +0 -120
- 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/root_spec.rb +0 -9
- data/spec/expression/sequence_spec.rb +0 -9
- 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 -100
- 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 -89
- data/spec/lexer/nesting_spec.rb +0 -99
- data/spec/lexer/refcalls_spec.rb +0 -55
- 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/posix_classes_spec.rb +0 -8
- data/spec/parser/properties_spec.rb +0 -115
- data/spec/parser/quantifiers_spec.rb +0 -52
- data/spec/parser/refcalls_spec.rb +0 -112
- 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 -53
- data/spec/scanner/free_space_spec.rb +0 -133
- data/spec/scanner/groups_spec.rb +0 -52
- data/spec/scanner/keep_spec.rb +0 -10
- data/spec/scanner/literals_spec.rb +0 -49
- data/spec/scanner/meta_spec.rb +0 -18
- data/spec/scanner/properties_spec.rb +0 -64
- data/spec/scanner/quantifiers_spec.rb +0 -20
- data/spec/scanner/refcalls_spec.rb +0 -36
- data/spec/scanner/sets_spec.rb +0 -102
- data/spec/scanner/types_spec.rb +0 -14
- data/spec/spec_helper.rb +0 -15
- 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,94 +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
|
-
end
|
@@ -1,120 +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('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
|
@@ -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(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
|
@@ -1,161 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe(Regexp::MatchLength) do
|
4
|
-
ML = described_class
|
5
|
-
|
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
|