fear 1.0.0 → 2.0.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +27 -0
- data/.github/workflows/rubocop.yml +39 -0
- data/.github/workflows/spec.yml +42 -0
- data/.rubocop.yml +4 -60
- data/.simplecov +17 -0
- data/CHANGELOG.md +29 -1
- data/Gemfile +5 -5
- data/Gemfile.lock +86 -50
- data/README.md +240 -209
- data/Rakefile +72 -65
- data/examples/pattern_extracting.rb +10 -8
- data/examples/pattern_matching_binary_tree_set.rb +7 -2
- data/examples/pattern_matching_number_in_words.rb +48 -42
- data/fear.gemspec +33 -34
- data/lib/dry/types/fear/option.rb +125 -0
- data/lib/dry/types/fear.rb +8 -0
- data/lib/fear/await.rb +33 -0
- data/lib/fear/awaitable.rb +28 -0
- data/lib/fear/either.rb +15 -4
- data/lib/fear/either_api.rb +4 -0
- data/lib/fear/either_pattern_match.rb +9 -5
- data/lib/fear/empty_partial_function.rb +3 -1
- data/lib/fear/failure.rb +7 -7
- data/lib/fear/failure_pattern_match.rb +4 -0
- data/lib/fear/for.rb +4 -2
- data/lib/fear/for_api.rb +5 -1
- data/lib/fear/future.rb +157 -82
- data/lib/fear/future_api.rb +17 -4
- data/lib/fear/left.rb +3 -9
- data/lib/fear/left_pattern_match.rb +2 -0
- data/lib/fear/none.rb +28 -10
- data/lib/fear/none_pattern_match.rb +2 -0
- data/lib/fear/option.rb +30 -2
- data/lib/fear/option_api.rb +4 -0
- data/lib/fear/option_pattern_match.rb +8 -3
- data/lib/fear/partial_function/and_then.rb +4 -2
- data/lib/fear/partial_function/any.rb +2 -0
- data/lib/fear/partial_function/combined.rb +3 -1
- data/lib/fear/partial_function/empty.rb +6 -0
- data/lib/fear/partial_function/guard/and.rb +2 -0
- data/lib/fear/partial_function/guard/and3.rb +2 -0
- data/lib/fear/partial_function/guard/or.rb +2 -0
- data/lib/fear/partial_function/guard.rb +8 -6
- data/lib/fear/partial_function/lifted.rb +2 -0
- data/lib/fear/partial_function/or_else.rb +5 -1
- data/lib/fear/partial_function.rb +18 -9
- data/lib/fear/partial_function_class.rb +3 -1
- data/lib/fear/pattern_match.rb +3 -11
- data/lib/fear/pattern_matching_api.rb +6 -28
- data/lib/fear/promise.rb +7 -5
- data/lib/fear/right.rb +3 -9
- data/lib/fear/right_biased.rb +5 -3
- data/lib/fear/right_pattern_match.rb +4 -0
- data/lib/fear/some.rb +35 -8
- data/lib/fear/some_pattern_match.rb +2 -0
- data/lib/fear/struct.rb +237 -0
- data/lib/fear/success.rb +7 -8
- data/lib/fear/success_pattern_match.rb +4 -0
- data/lib/fear/try.rb +8 -2
- data/lib/fear/try_api.rb +4 -0
- data/lib/fear/try_pattern_match.rb +9 -5
- data/lib/fear/unit.rb +6 -2
- data/lib/fear/utils.rb +14 -2
- data/lib/fear/version.rb +4 -1
- data/lib/fear.rb +26 -44
- data/spec/dry/types/fear/option/constrained_spec.rb +22 -0
- data/spec/dry/types/fear/option/core_spec.rb +77 -0
- data/spec/dry/types/fear/option/default_spec.rb +21 -0
- data/spec/dry/types/fear/option/hash_spec.rb +58 -0
- data/spec/dry/types/fear/option/option_spec.rb +97 -0
- data/spec/fear/awaitable_spec.rb +19 -0
- data/spec/fear/done_spec.rb +7 -5
- data/spec/fear/either/mixin_spec.rb +4 -2
- data/spec/fear/either_pattern_match_spec.rb +10 -8
- data/spec/fear/either_pattern_matching_spec.rb +28 -0
- data/spec/fear/either_spec.rb +26 -0
- data/spec/fear/failure_spec.rb +57 -70
- data/spec/fear/for/mixin_spec.rb +15 -0
- data/spec/fear/for_spec.rb +19 -17
- data/spec/fear/future_spec.rb +477 -237
- data/spec/fear/guard_spec.rb +136 -24
- data/spec/fear/left_spec.rb +57 -70
- data/spec/fear/none_spec.rb +39 -43
- data/spec/fear/option/mixin_spec.rb +9 -7
- data/spec/fear/option_pattern_match_spec.rb +10 -8
- data/spec/fear/option_pattern_matching_spec.rb +34 -0
- data/spec/fear/option_spec.rb +142 -0
- data/spec/fear/partial_function/any_spec.rb +25 -0
- data/spec/fear/partial_function/empty_spec.rb +12 -10
- data/spec/fear/partial_function_and_then_spec.rb +39 -37
- data/spec/fear/partial_function_composition_spec.rb +46 -44
- data/spec/fear/partial_function_or_else_spec.rb +92 -90
- data/spec/fear/partial_function_spec.rb +91 -61
- data/spec/fear/pattern_match_spec.rb +19 -51
- data/spec/fear/pattern_matching_api_spec.rb +31 -0
- data/spec/fear/promise_spec.rb +23 -23
- data/spec/fear/right_biased/left.rb +28 -26
- data/spec/fear/right_biased/right.rb +51 -49
- data/spec/fear/right_spec.rb +48 -68
- data/spec/fear/some_spec.rb +30 -40
- data/spec/fear/success_spec.rb +40 -60
- data/spec/fear/try/mixin_spec.rb +19 -3
- data/spec/fear/try_api_spec.rb +23 -0
- data/spec/fear/try_pattern_match_spec.rb +10 -8
- data/spec/fear/try_pattern_matching_spec.rb +34 -0
- data/spec/fear/utils_spec.rb +16 -14
- data/spec/spec_helper.rb +13 -7
- data/spec/struct_pattern_matching_spec.rb +36 -0
- data/spec/struct_spec.rb +194 -0
- data/spec/support/dry_types.rb +6 -0
- metadata +128 -87
- data/.travis.yml +0 -13
- data/lib/fear/extractor/anonymous_array_splat_matcher.rb +0 -8
- data/lib/fear/extractor/any_matcher.rb +0 -15
- data/lib/fear/extractor/array_head_matcher.rb +0 -34
- data/lib/fear/extractor/array_matcher.rb +0 -38
- data/lib/fear/extractor/array_splat_matcher.rb +0 -14
- data/lib/fear/extractor/empty_list_matcher.rb +0 -18
- data/lib/fear/extractor/extractor_matcher.rb +0 -42
- data/lib/fear/extractor/grammar.rb +0 -201
- data/lib/fear/extractor/grammar.treetop +0 -129
- data/lib/fear/extractor/identifier_matcher.rb +0 -16
- data/lib/fear/extractor/matcher/and.rb +0 -36
- data/lib/fear/extractor/matcher.rb +0 -54
- data/lib/fear/extractor/named_array_splat_matcher.rb +0 -15
- data/lib/fear/extractor/pattern.rb +0 -55
- data/lib/fear/extractor/typed_identifier_matcher.rb +0 -24
- data/lib/fear/extractor/value_matcher.rb +0 -17
- data/lib/fear/extractor.rb +0 -108
- data/lib/fear/extractor_api.rb +0 -33
- data/spec/fear/extractor/array_matcher_spec.rb +0 -228
- data/spec/fear/extractor/extractor_matcher_spec.rb +0 -151
- data/spec/fear/extractor/grammar_array_spec.rb +0 -23
- data/spec/fear/extractor/identified_matcher_spec.rb +0 -47
- data/spec/fear/extractor/identifier_matcher_spec.rb +0 -66
- data/spec/fear/extractor/pattern_spec.rb +0 -32
- data/spec/fear/extractor/typed_identifier_matcher_spec.rb +0 -62
- data/spec/fear/extractor/value_matcher_number_spec.rb +0 -77
- data/spec/fear/extractor/value_matcher_string_spec.rb +0 -86
- data/spec/fear/extractor/value_matcher_symbol_spec.rb +0 -69
- data/spec/fear/extractor_api_spec.rb +0 -113
- data/spec/fear/extractor_spec.rb +0 -59
@@ -1,228 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::ArrayMatcher do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
context 'empty array' do
|
9
|
-
let(:pattern) { '[]' }
|
10
|
-
|
11
|
-
it { is_expected.to be_defined_at([]) }
|
12
|
-
it { is_expected.not_to be_defined_at([1]) }
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'empty array with splat' do
|
16
|
-
let(:pattern) { '[*]' }
|
17
|
-
|
18
|
-
it { is_expected.to be_defined_at([]) }
|
19
|
-
it { is_expected.to be_defined_at([1]) }
|
20
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'empty array with named splat' do
|
24
|
-
let(:pattern) { '[*var]' }
|
25
|
-
|
26
|
-
it { is_expected.to be_defined_at([]) }
|
27
|
-
it { is_expected.to be_defined_at([1]) }
|
28
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'one element array' do
|
32
|
-
let(:pattern) { '[1]' }
|
33
|
-
|
34
|
-
it { is_expected.not_to be_defined_at([]) }
|
35
|
-
it { is_expected.to be_defined_at([1]) }
|
36
|
-
it { is_expected.not_to be_defined_at([1, 2]) }
|
37
|
-
it { is_expected.not_to be_defined_at([2, 1]) }
|
38
|
-
|
39
|
-
context 'identifier' do
|
40
|
-
let(:pattern) { '[var]' }
|
41
|
-
|
42
|
-
it { is_expected.not_to be_defined_at([]) }
|
43
|
-
it { is_expected.to be_defined_at([1]) }
|
44
|
-
it { is_expected.to be_defined_at([[1]]) }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'two elements array with nested matcher' do
|
49
|
-
let(:pattern) { '[[1, *], 1]' }
|
50
|
-
|
51
|
-
it { is_expected.not_to be_defined_at([]) }
|
52
|
-
it { is_expected.to be_defined_at([[1], 1]) }
|
53
|
-
it { is_expected.to be_defined_at([[1, 2], 1]) }
|
54
|
-
it { is_expected.not_to be_defined_at([[1, 2], 2]) }
|
55
|
-
it { is_expected.not_to be_defined_at([2, 1]) }
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'one element array with splat' do
|
59
|
-
let(:pattern) { '[1, *]' }
|
60
|
-
|
61
|
-
it { is_expected.not_to be_defined_at([]) }
|
62
|
-
it { is_expected.to be_defined_at([1]) }
|
63
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
64
|
-
it { is_expected.to be_defined_at([1, 2, 3]) }
|
65
|
-
it { is_expected.not_to be_defined_at([2, 1]) }
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'one element array with named splat' do
|
69
|
-
let(:pattern) { '[1, *var]' }
|
70
|
-
|
71
|
-
it { is_expected.not_to be_defined_at([]) }
|
72
|
-
it { is_expected.to be_defined_at([1]) }
|
73
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
74
|
-
it { is_expected.to be_defined_at([1, 2, 3]) }
|
75
|
-
it { is_expected.not_to be_defined_at([2, 1]) }
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'three elements array' do
|
79
|
-
context 'with identifier in the middle' do
|
80
|
-
let(:pattern) { '[1, var, 2]' }
|
81
|
-
|
82
|
-
it { is_expected.not_to be_defined_at([]) }
|
83
|
-
it { is_expected.to be_defined_at([1, 3, 2]) }
|
84
|
-
it { is_expected.not_to be_defined_at([1, 2, 3]) }
|
85
|
-
it { is_expected.not_to be_defined_at([1, 2, 3, 4]) }
|
86
|
-
it { is_expected.not_to be_defined_at([1]) }
|
87
|
-
it { is_expected.not_to be_defined_at([2]) }
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'head and tail' do
|
91
|
-
let(:pattern) { '[head, *tail]' }
|
92
|
-
|
93
|
-
it { is_expected.not_to be_defined_at([]) }
|
94
|
-
it { is_expected.to be_defined_at([1, 3, 2]) }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'two element array' do
|
99
|
-
let(:pattern) { '[ 1, 2 ]' }
|
100
|
-
|
101
|
-
it { is_expected.not_to be_defined_at([]) }
|
102
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
103
|
-
it { is_expected.not_to be_defined_at([1]) }
|
104
|
-
it { is_expected.not_to be_defined_at([2]) }
|
105
|
-
it { is_expected.not_to be_defined_at([1, 3]) }
|
106
|
-
it { is_expected.not_to be_defined_at([2, 2]) }
|
107
|
-
it { is_expected.not_to be_defined_at([1, 2, 3]) }
|
108
|
-
|
109
|
-
context 'with identifier at the beginning' do
|
110
|
-
let(:pattern) { '[var, 2]' }
|
111
|
-
|
112
|
-
it { is_expected.not_to be_defined_at([]) }
|
113
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
114
|
-
it { is_expected.not_to be_defined_at([1, 3]) }
|
115
|
-
it { is_expected.not_to be_defined_at([1]) }
|
116
|
-
it { is_expected.not_to be_defined_at([2]) }
|
117
|
-
it { is_expected.not_to be_defined_at([1, 2, 3]) }
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
describe '#call' do
|
123
|
-
subject { matcher.call(other) }
|
124
|
-
|
125
|
-
context 'on the same array' do
|
126
|
-
let(:other) { [1] }
|
127
|
-
let(:pattern) { '[1]' }
|
128
|
-
|
129
|
-
it { is_expected.to eq({}) }
|
130
|
-
end
|
131
|
-
|
132
|
-
context 'with splat on another array' do
|
133
|
-
let(:other) { [2, 1] }
|
134
|
-
let(:pattern) { '[2, *]' }
|
135
|
-
|
136
|
-
it { is_expected.to eq({}) }
|
137
|
-
end
|
138
|
-
|
139
|
-
context 'with identifier at the middle of an array' do
|
140
|
-
let(:other) { [2, 1, 3] }
|
141
|
-
let(:pattern) { '[2, var, 3]' }
|
142
|
-
|
143
|
-
it { is_expected.to eq(var: 1) }
|
144
|
-
end
|
145
|
-
|
146
|
-
context 'with identifier at the end of an array' do
|
147
|
-
let(:other) { [2, 1, 3] }
|
148
|
-
let(:pattern) { '[2, 1, var]' }
|
149
|
-
|
150
|
-
it { is_expected.to eq(var: 3) }
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'with named splat matching all the array' do
|
154
|
-
let(:other) { [2, 1, 3, 4] }
|
155
|
-
let(:pattern) { '[*var]' }
|
156
|
-
|
157
|
-
it { is_expected.to eq(var: [2, 1, 3, 4]) }
|
158
|
-
end
|
159
|
-
|
160
|
-
context 'with named splat matching tail of an array' do
|
161
|
-
let(:other) { [2, 1, 3, 4] }
|
162
|
-
let(:pattern) { '[2, 1, *var]' }
|
163
|
-
|
164
|
-
it { is_expected.to eq(var: [3, 4]) }
|
165
|
-
end
|
166
|
-
|
167
|
-
context 'with named splat at the end of an array' do
|
168
|
-
let(:other) { [2, 1] }
|
169
|
-
let(:pattern) { '[2, 1, *var]' }
|
170
|
-
|
171
|
-
it { is_expected.to eq(var: []) }
|
172
|
-
end
|
173
|
-
|
174
|
-
context 'with several identifiers in an array' do
|
175
|
-
let(:other) { [2, 1, 3] }
|
176
|
-
let(:pattern) { '[a, 1, b]' }
|
177
|
-
|
178
|
-
it { is_expected.to eq(a: 2, b: 3) }
|
179
|
-
end
|
180
|
-
|
181
|
-
context 'head and tail' do
|
182
|
-
let(:other) { [2, 1, 3] }
|
183
|
-
let(:pattern) { '[head, *tail]' }
|
184
|
-
|
185
|
-
it { is_expected.to eq(head: 2, tail: [1, 3]) }
|
186
|
-
end
|
187
|
-
|
188
|
-
context 'ignore head, capture tail' do
|
189
|
-
let(:other) { [2, 1, 3] }
|
190
|
-
let(:pattern) { '[_, *tail]' }
|
191
|
-
|
192
|
-
it { is_expected.to eq(tail: [1, 3]) }
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
describe '#failure_reason' do
|
197
|
-
subject { matcher.failure_reason(other) }
|
198
|
-
|
199
|
-
context 'on the same array' do
|
200
|
-
let(:other) { [1] }
|
201
|
-
let(:pattern) { '[1]' }
|
202
|
-
|
203
|
-
it { is_expected.to eq(Fear.none) }
|
204
|
-
end
|
205
|
-
|
206
|
-
context 'on another array' do
|
207
|
-
let(:other) { [2, 1] }
|
208
|
-
let(:pattern) { '[2, 2]' }
|
209
|
-
|
210
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
211
|
-
Expected `1` to match:
|
212
|
-
[2, 2]
|
213
|
-
~~~~^
|
214
|
-
ERROR
|
215
|
-
end
|
216
|
-
|
217
|
-
context 'element type mismatch' do
|
218
|
-
let(:other) { [2, 1] }
|
219
|
-
let(:pattern) { '[[2], 1]' }
|
220
|
-
|
221
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
222
|
-
Expected `2` to match:
|
223
|
-
[[2], 1]
|
224
|
-
~~^
|
225
|
-
ERROR
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
@@ -1,151 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::ExtractorMatcher do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
context 'boolean extractor' do
|
9
|
-
let(:pattern) { 'IsEven()' }
|
10
|
-
|
11
|
-
it { is_expected.to be_defined_at(42) }
|
12
|
-
it { is_expected.not_to be_defined_at(43) }
|
13
|
-
it { is_expected.not_to be_defined_at('foo') }
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'single argument extractor' do
|
17
|
-
let(:pattern) { 'Fear::Some(a : Integer)' }
|
18
|
-
|
19
|
-
it { is_expected.to be_defined_at(Fear.some(42)) }
|
20
|
-
it { is_expected.not_to be_defined_at('foo') }
|
21
|
-
it { is_expected.not_to be_defined_at(Fear.some('foo')) }
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'single argument extractor with array as an argument' do
|
25
|
-
let(:pattern) { 'Fear::Some([1, 2])' }
|
26
|
-
|
27
|
-
it { is_expected.to be_defined_at(Fear.some([1, 2])) }
|
28
|
-
it { is_expected.not_to be_defined_at(Fear.some([1, 1])) }
|
29
|
-
it { is_expected.not_to be_defined_at(Fear.some('foo')) }
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'multiple arguments extractor' do
|
33
|
-
let(:pattern) { 'Date(2017, month, _)' }
|
34
|
-
|
35
|
-
it { is_expected.to be_defined_at(Date.parse('2017-02-15')) }
|
36
|
-
it { is_expected.not_to be_defined_at(Date.parse('2018-02-15')) }
|
37
|
-
it { is_expected.not_to be_defined_at('foo') }
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'Struct' do
|
41
|
-
StructDate = Struct.new(:year, :month, :day)
|
42
|
-
|
43
|
-
let(:pattern) { 'StructDate(2017, month, _)' }
|
44
|
-
|
45
|
-
it { is_expected.to be_defined_at(StructDate.new(2017, 2, 15)) }
|
46
|
-
it { is_expected.not_to be_defined_at(StructDate.new(2018, 2, 15)) }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe '#call' do
|
51
|
-
subject { matcher.call(other) }
|
52
|
-
|
53
|
-
context 'single argument extractor' do
|
54
|
-
let(:pattern) { 'Fear::Some(a : Integer)' }
|
55
|
-
let(:other) { Fear.some(42) }
|
56
|
-
|
57
|
-
it { is_expected.to eq(a: 42) }
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'multiple arguments extractor' do
|
61
|
-
let(:pattern) { 'Date(2017, month, day)' }
|
62
|
-
let(:other) { Date.parse('2017-02-15') }
|
63
|
-
|
64
|
-
it { is_expected.to eq(month: 2, day: 15) }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '#failure_reason' do
|
69
|
-
subject { matcher.failure_reason(other) }
|
70
|
-
|
71
|
-
context 'no argument extractor' do
|
72
|
-
let(:pattern) { 'IsEven()' }
|
73
|
-
|
74
|
-
context 'defined' do
|
75
|
-
let(:other) { 42 }
|
76
|
-
|
77
|
-
it { is_expected.to eq(Fear.none) }
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'not defined' do
|
81
|
-
let(:other) { 43 }
|
82
|
-
|
83
|
-
it { is_expected.to eq(Fear.some(<<-MSG.strip)) }
|
84
|
-
Expected `43` to match:
|
85
|
-
IsEven()
|
86
|
-
^
|
87
|
-
MSG
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context 'single argument extractor' do
|
92
|
-
let(:pattern) { 'Fear::Some(a : Integer)' }
|
93
|
-
|
94
|
-
context 'defined' do
|
95
|
-
let(:other) { Fear.some(42) }
|
96
|
-
|
97
|
-
it { is_expected.to eq(Fear.none) }
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'not defined' do
|
101
|
-
let(:other) { Fear.some('42') }
|
102
|
-
|
103
|
-
it { is_expected.to eq(Fear.some(<<-MSG.strip)) }
|
104
|
-
Expected `"42"` to match:
|
105
|
-
Fear::Some(a : Integer)
|
106
|
-
~~~~~~~~~~~~~~~^
|
107
|
-
MSG
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'single argument extractor, array argument' do
|
112
|
-
let(:pattern) { 'Fear::Some([1, 2])' }
|
113
|
-
|
114
|
-
context 'defined' do
|
115
|
-
let(:other) { Fear.some([1, 2]) }
|
116
|
-
|
117
|
-
it { is_expected.to eq(Fear.none) }
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'not defined' do
|
121
|
-
let(:other) { Fear.some([1, 1]) }
|
122
|
-
|
123
|
-
it { is_expected.to eq(Fear.some(<<-MSG.strip)) }
|
124
|
-
Expected `1` to match:
|
125
|
-
Fear::Some([1, 2])
|
126
|
-
~~~~~~~~~~~~~~~^
|
127
|
-
MSG
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context 'multiple arguments extractor' do
|
132
|
-
let(:pattern) { 'Date(year, 02, day)' }
|
133
|
-
|
134
|
-
context 'defined' do
|
135
|
-
let(:other) { Date.parse('2017-02-15') }
|
136
|
-
|
137
|
-
it { is_expected.to eq(Fear.none) }
|
138
|
-
end
|
139
|
-
|
140
|
-
context 'not defined' do
|
141
|
-
let(:other) { Date.parse('2017-04-15') }
|
142
|
-
|
143
|
-
it { is_expected.to eq(Fear.some(<<-MSG.strip)) }
|
144
|
-
Expected `4` to match:
|
145
|
-
Date(year, 02, day)
|
146
|
-
~~~~~~~~~~~^
|
147
|
-
MSG
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::Grammar, 'Array' do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
context 'non empty array' do
|
6
|
-
let(:pattern) { '[1, 2, 3, 4]' }
|
7
|
-
|
8
|
-
it do
|
9
|
-
first = matcher.head
|
10
|
-
rest_after_first = matcher.tail
|
11
|
-
|
12
|
-
expect(first).to be_kind_of(Fear::Extractor::ArrayHeadMatcher)
|
13
|
-
expect(first.matcher.value).to eq(1)
|
14
|
-
expect(rest_after_first).to be_kind_of(Fear::Extractor::ArrayMatcher)
|
15
|
-
|
16
|
-
second = rest_after_first.head
|
17
|
-
rest_after_second = rest_after_first.tail
|
18
|
-
expect(second).to be_kind_of(Fear::Extractor::ArrayHeadMatcher)
|
19
|
-
expect(second.matcher.value).to eq(2)
|
20
|
-
expect(rest_after_second).to be_kind_of(Fear::Extractor::ArrayMatcher)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
RSpec.describe 'Fear::Extractor::IdentifiedMatcher' do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
let(:pattern) { 'array @ [1, *tail]' }
|
9
|
-
|
10
|
-
it { is_expected.to be_defined_at([1, 2]) }
|
11
|
-
it { is_expected.not_to be_defined_at('foo') }
|
12
|
-
it { is_expected.not_to be_defined_at([2, 1]) }
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '#call' do
|
16
|
-
subject { matcher.call(other) }
|
17
|
-
|
18
|
-
context 'defined' do
|
19
|
-
let(:other) { [1, 2] }
|
20
|
-
let(:pattern) { 'array @ [1, *tail]' }
|
21
|
-
|
22
|
-
it { is_expected.to eq(array: [1, 2], tail: [2]) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#failure_reason' do
|
27
|
-
subject { matcher.failure_reason(other) }
|
28
|
-
|
29
|
-
let(:pattern) { 'array @ [1, *tail]' }
|
30
|
-
|
31
|
-
context 'match integer' do
|
32
|
-
let(:other) { [1, 2] }
|
33
|
-
|
34
|
-
it { is_expected.to eq(Fear.none) }
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'does not match float' do
|
38
|
-
let(:other) { [2, 2] }
|
39
|
-
|
40
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
41
|
-
Expected `2` to match:
|
42
|
-
array @ [1, *tail]
|
43
|
-
~~~~~~~~~^
|
44
|
-
ERROR
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::IdentifierMatcher do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
let(:pattern) { 'number' }
|
9
|
-
|
10
|
-
it { is_expected.to be_defined_at(1) }
|
11
|
-
it { is_expected.to be_defined_at('foo') }
|
12
|
-
it { is_expected.to be_defined_at(1.2) }
|
13
|
-
it { is_expected.to be_defined_at([1, '2']) }
|
14
|
-
|
15
|
-
context 'within array' do
|
16
|
-
let(:pattern) { '[1, n, 2]' }
|
17
|
-
|
18
|
-
it { is_expected.to be_defined_at([1, 2, 2]) }
|
19
|
-
it { is_expected.to be_defined_at([1, 'foo', 2]) }
|
20
|
-
it { is_expected.not_to be_defined_at([1, 'foo']) }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#call' do
|
25
|
-
subject { matcher.call(other) }
|
26
|
-
|
27
|
-
let(:pattern) { '1.0' }
|
28
|
-
|
29
|
-
context 'defined' do
|
30
|
-
let(:other) { 1 }
|
31
|
-
|
32
|
-
it { is_expected.to eq({}) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#failure_reason' do
|
37
|
-
subject { matcher.failure_reason(other) }
|
38
|
-
|
39
|
-
let(:pattern) { '1.0' }
|
40
|
-
|
41
|
-
context 'match integer' do
|
42
|
-
let(:other) { 1 }
|
43
|
-
let(:pattern) { '1' }
|
44
|
-
|
45
|
-
it { is_expected.to eq(Fear.none) }
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'match float' do
|
49
|
-
let(:other) { 1.0 }
|
50
|
-
let(:pattern) { '1' }
|
51
|
-
|
52
|
-
it { is_expected.to eq(Fear.none) }
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'does not match another integer' do
|
56
|
-
let(:other) { 2 }
|
57
|
-
let(:pattern) { '1' }
|
58
|
-
|
59
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
60
|
-
Expected `2` to match:
|
61
|
-
1
|
62
|
-
^
|
63
|
-
ERROR
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::Pattern do
|
2
|
-
describe '.new' do
|
3
|
-
context 'invalid syntax' do
|
4
|
-
subject { -> { described_class.new('[1, 2, 3') } }
|
5
|
-
|
6
|
-
it 'shows where the error happens' do
|
7
|
-
is_expected.to raise_error(Fear::PatternSyntaxError) { |error|
|
8
|
-
lines = error.message.split("\n")
|
9
|
-
expect(lines[0]).to start_with('Expected one of')
|
10
|
-
.and(end_with('at line 1, column 9 (byte 9):'))
|
11
|
-
|
12
|
-
expect(lines[1]).to eq('[1, 2, 3')
|
13
|
-
expect(lines[2]).to eq('~~~~~~~~^')
|
14
|
-
}
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '#failure_reason' do
|
20
|
-
let(:pattern) { described_class.new('Some([:err, 444])') }
|
21
|
-
|
22
|
-
context 'not defined' do
|
23
|
-
subject { pattern.failure_reason(Fear.some([:err, 445])) }
|
24
|
-
|
25
|
-
it { is_expected.to eq(<<-MSG.strip) }
|
26
|
-
Expected `445` to match:
|
27
|
-
Some([:err, 444])
|
28
|
-
~~~~~~~~~~~~^
|
29
|
-
MSG
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::TypedIdentifierMatcher do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
let(:pattern) { 'var : Integer' }
|
9
|
-
|
10
|
-
it { is_expected.to be_defined_at(1) }
|
11
|
-
it { is_expected.not_to be_defined_at('foo') }
|
12
|
-
it { is_expected.not_to be_defined_at(1.2) }
|
13
|
-
|
14
|
-
context 'within array' do
|
15
|
-
let(:pattern) { '[1, n : String, 2]' }
|
16
|
-
|
17
|
-
it { is_expected.to be_defined_at([1, 'foo', 2]) }
|
18
|
-
it { is_expected.not_to be_defined_at([1, 2, 2]) }
|
19
|
-
it { is_expected.not_to be_defined_at([1, 'foo']) }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe '#call' do
|
24
|
-
subject { matcher.call(other) }
|
25
|
-
|
26
|
-
context 'defined' do
|
27
|
-
let(:other) { 1 }
|
28
|
-
let(:pattern) { 'var : Integer' }
|
29
|
-
|
30
|
-
it { is_expected.to eq(var: 1) }
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'defined within array' do
|
34
|
-
let(:other) { [4, 2, 1, 6] }
|
35
|
-
let(:pattern) { '[head : Integer, *tail]' }
|
36
|
-
|
37
|
-
it { is_expected.to eq(head: 4, tail: [2, 1, 6]) }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe '#' do
|
42
|
-
subject { matcher.failure_reason(other) }
|
43
|
-
|
44
|
-
let(:pattern) { 'var : Integer' }
|
45
|
-
|
46
|
-
context 'match integer' do
|
47
|
-
let(:other) { 1 }
|
48
|
-
|
49
|
-
it { is_expected.to eq(Fear.none) }
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'does not match float' do
|
53
|
-
let(:other) { 1.0 }
|
54
|
-
|
55
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
56
|
-
Expected `1.0` to match:
|
57
|
-
var : Integer
|
58
|
-
~~~~~~^
|
59
|
-
ERROR
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
RSpec.describe Fear::Extractor::ValueMatcher, 'Number' do
|
2
|
-
let(:parser) { Fear::Extractor::GrammarParser.new }
|
3
|
-
let(:matcher) { parser.parse(pattern).to_matcher }
|
4
|
-
|
5
|
-
describe '#defined_at?' do
|
6
|
-
subject { matcher }
|
7
|
-
|
8
|
-
context 'Integer' do
|
9
|
-
let(:pattern) { '1' }
|
10
|
-
|
11
|
-
it { is_expected.to be_defined_at(1) }
|
12
|
-
it { is_expected.to be_defined_at(1.0) }
|
13
|
-
it { is_expected.not_to be_defined_at(2) }
|
14
|
-
it { is_expected.not_to be_defined_at('1') }
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'Float' do
|
18
|
-
context 'against float' do
|
19
|
-
let(:pattern) { '1.2' }
|
20
|
-
|
21
|
-
it { is_expected.to be_defined_at(1.2) }
|
22
|
-
it { is_expected.not_to be_defined_at(1.3) }
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'against integer' do
|
26
|
-
let(:pattern) { '1.0' }
|
27
|
-
|
28
|
-
it { is_expected.to be_defined_at(1) }
|
29
|
-
it { is_expected.not_to be_defined_at(2) }
|
30
|
-
it { is_expected.not_to be_defined_at('1') }
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe '#call' do
|
36
|
-
subject { matcher.call(other) }
|
37
|
-
|
38
|
-
let(:pattern) { '1.0' }
|
39
|
-
|
40
|
-
context 'defined' do
|
41
|
-
let(:other) { 1 }
|
42
|
-
|
43
|
-
it { is_expected.to eq({}) }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe '#failure_reason' do
|
48
|
-
subject { matcher.failure_reason(other) }
|
49
|
-
|
50
|
-
let(:pattern) { '1.0' }
|
51
|
-
|
52
|
-
context 'match integer' do
|
53
|
-
let(:other) { 1 }
|
54
|
-
let(:pattern) { '1' }
|
55
|
-
|
56
|
-
it { is_expected.to eq(Fear.none) }
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'match float' do
|
60
|
-
let(:other) { 1.0 }
|
61
|
-
let(:pattern) { '1' }
|
62
|
-
|
63
|
-
it { is_expected.to eq(Fear.none) }
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'does not match another integer' do
|
67
|
-
let(:other) { 2 }
|
68
|
-
let(:pattern) { '1' }
|
69
|
-
|
70
|
-
it { is_expected.to eq(Fear.some(<<-ERROR.strip)) }
|
71
|
-
Expected `2` to match:
|
72
|
-
1
|
73
|
-
^
|
74
|
-
ERROR
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|