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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +27 -0
  3. data/.github/workflows/rubocop.yml +39 -0
  4. data/.github/workflows/spec.yml +42 -0
  5. data/.rubocop.yml +4 -60
  6. data/.simplecov +17 -0
  7. data/CHANGELOG.md +29 -1
  8. data/Gemfile +5 -5
  9. data/Gemfile.lock +86 -50
  10. data/README.md +240 -209
  11. data/Rakefile +72 -65
  12. data/examples/pattern_extracting.rb +10 -8
  13. data/examples/pattern_matching_binary_tree_set.rb +7 -2
  14. data/examples/pattern_matching_number_in_words.rb +48 -42
  15. data/fear.gemspec +33 -34
  16. data/lib/dry/types/fear/option.rb +125 -0
  17. data/lib/dry/types/fear.rb +8 -0
  18. data/lib/fear/await.rb +33 -0
  19. data/lib/fear/awaitable.rb +28 -0
  20. data/lib/fear/either.rb +15 -4
  21. data/lib/fear/either_api.rb +4 -0
  22. data/lib/fear/either_pattern_match.rb +9 -5
  23. data/lib/fear/empty_partial_function.rb +3 -1
  24. data/lib/fear/failure.rb +7 -7
  25. data/lib/fear/failure_pattern_match.rb +4 -0
  26. data/lib/fear/for.rb +4 -2
  27. data/lib/fear/for_api.rb +5 -1
  28. data/lib/fear/future.rb +157 -82
  29. data/lib/fear/future_api.rb +17 -4
  30. data/lib/fear/left.rb +3 -9
  31. data/lib/fear/left_pattern_match.rb +2 -0
  32. data/lib/fear/none.rb +28 -10
  33. data/lib/fear/none_pattern_match.rb +2 -0
  34. data/lib/fear/option.rb +30 -2
  35. data/lib/fear/option_api.rb +4 -0
  36. data/lib/fear/option_pattern_match.rb +8 -3
  37. data/lib/fear/partial_function/and_then.rb +4 -2
  38. data/lib/fear/partial_function/any.rb +2 -0
  39. data/lib/fear/partial_function/combined.rb +3 -1
  40. data/lib/fear/partial_function/empty.rb +6 -0
  41. data/lib/fear/partial_function/guard/and.rb +2 -0
  42. data/lib/fear/partial_function/guard/and3.rb +2 -0
  43. data/lib/fear/partial_function/guard/or.rb +2 -0
  44. data/lib/fear/partial_function/guard.rb +8 -6
  45. data/lib/fear/partial_function/lifted.rb +2 -0
  46. data/lib/fear/partial_function/or_else.rb +5 -1
  47. data/lib/fear/partial_function.rb +18 -9
  48. data/lib/fear/partial_function_class.rb +3 -1
  49. data/lib/fear/pattern_match.rb +3 -11
  50. data/lib/fear/pattern_matching_api.rb +6 -28
  51. data/lib/fear/promise.rb +7 -5
  52. data/lib/fear/right.rb +3 -9
  53. data/lib/fear/right_biased.rb +5 -3
  54. data/lib/fear/right_pattern_match.rb +4 -0
  55. data/lib/fear/some.rb +35 -8
  56. data/lib/fear/some_pattern_match.rb +2 -0
  57. data/lib/fear/struct.rb +237 -0
  58. data/lib/fear/success.rb +7 -8
  59. data/lib/fear/success_pattern_match.rb +4 -0
  60. data/lib/fear/try.rb +8 -2
  61. data/lib/fear/try_api.rb +4 -0
  62. data/lib/fear/try_pattern_match.rb +9 -5
  63. data/lib/fear/unit.rb +6 -2
  64. data/lib/fear/utils.rb +14 -2
  65. data/lib/fear/version.rb +4 -1
  66. data/lib/fear.rb +26 -44
  67. data/spec/dry/types/fear/option/constrained_spec.rb +22 -0
  68. data/spec/dry/types/fear/option/core_spec.rb +77 -0
  69. data/spec/dry/types/fear/option/default_spec.rb +21 -0
  70. data/spec/dry/types/fear/option/hash_spec.rb +58 -0
  71. data/spec/dry/types/fear/option/option_spec.rb +97 -0
  72. data/spec/fear/awaitable_spec.rb +19 -0
  73. data/spec/fear/done_spec.rb +7 -5
  74. data/spec/fear/either/mixin_spec.rb +4 -2
  75. data/spec/fear/either_pattern_match_spec.rb +10 -8
  76. data/spec/fear/either_pattern_matching_spec.rb +28 -0
  77. data/spec/fear/either_spec.rb +26 -0
  78. data/spec/fear/failure_spec.rb +57 -70
  79. data/spec/fear/for/mixin_spec.rb +15 -0
  80. data/spec/fear/for_spec.rb +19 -17
  81. data/spec/fear/future_spec.rb +477 -237
  82. data/spec/fear/guard_spec.rb +136 -24
  83. data/spec/fear/left_spec.rb +57 -70
  84. data/spec/fear/none_spec.rb +39 -43
  85. data/spec/fear/option/mixin_spec.rb +9 -7
  86. data/spec/fear/option_pattern_match_spec.rb +10 -8
  87. data/spec/fear/option_pattern_matching_spec.rb +34 -0
  88. data/spec/fear/option_spec.rb +142 -0
  89. data/spec/fear/partial_function/any_spec.rb +25 -0
  90. data/spec/fear/partial_function/empty_spec.rb +12 -10
  91. data/spec/fear/partial_function_and_then_spec.rb +39 -37
  92. data/spec/fear/partial_function_composition_spec.rb +46 -44
  93. data/spec/fear/partial_function_or_else_spec.rb +92 -90
  94. data/spec/fear/partial_function_spec.rb +91 -61
  95. data/spec/fear/pattern_match_spec.rb +19 -51
  96. data/spec/fear/pattern_matching_api_spec.rb +31 -0
  97. data/spec/fear/promise_spec.rb +23 -23
  98. data/spec/fear/right_biased/left.rb +28 -26
  99. data/spec/fear/right_biased/right.rb +51 -49
  100. data/spec/fear/right_spec.rb +48 -68
  101. data/spec/fear/some_spec.rb +30 -40
  102. data/spec/fear/success_spec.rb +40 -60
  103. data/spec/fear/try/mixin_spec.rb +19 -3
  104. data/spec/fear/try_api_spec.rb +23 -0
  105. data/spec/fear/try_pattern_match_spec.rb +10 -8
  106. data/spec/fear/try_pattern_matching_spec.rb +34 -0
  107. data/spec/fear/utils_spec.rb +16 -14
  108. data/spec/spec_helper.rb +13 -7
  109. data/spec/struct_pattern_matching_spec.rb +36 -0
  110. data/spec/struct_spec.rb +194 -0
  111. data/spec/support/dry_types.rb +6 -0
  112. metadata +128 -87
  113. data/.travis.yml +0 -13
  114. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +0 -8
  115. data/lib/fear/extractor/any_matcher.rb +0 -15
  116. data/lib/fear/extractor/array_head_matcher.rb +0 -34
  117. data/lib/fear/extractor/array_matcher.rb +0 -38
  118. data/lib/fear/extractor/array_splat_matcher.rb +0 -14
  119. data/lib/fear/extractor/empty_list_matcher.rb +0 -18
  120. data/lib/fear/extractor/extractor_matcher.rb +0 -42
  121. data/lib/fear/extractor/grammar.rb +0 -201
  122. data/lib/fear/extractor/grammar.treetop +0 -129
  123. data/lib/fear/extractor/identifier_matcher.rb +0 -16
  124. data/lib/fear/extractor/matcher/and.rb +0 -36
  125. data/lib/fear/extractor/matcher.rb +0 -54
  126. data/lib/fear/extractor/named_array_splat_matcher.rb +0 -15
  127. data/lib/fear/extractor/pattern.rb +0 -55
  128. data/lib/fear/extractor/typed_identifier_matcher.rb +0 -24
  129. data/lib/fear/extractor/value_matcher.rb +0 -17
  130. data/lib/fear/extractor.rb +0 -108
  131. data/lib/fear/extractor_api.rb +0 -33
  132. data/spec/fear/extractor/array_matcher_spec.rb +0 -228
  133. data/spec/fear/extractor/extractor_matcher_spec.rb +0 -151
  134. data/spec/fear/extractor/grammar_array_spec.rb +0 -23
  135. data/spec/fear/extractor/identified_matcher_spec.rb +0 -47
  136. data/spec/fear/extractor/identifier_matcher_spec.rb +0 -66
  137. data/spec/fear/extractor/pattern_spec.rb +0 -32
  138. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +0 -62
  139. data/spec/fear/extractor/value_matcher_number_spec.rb +0 -77
  140. data/spec/fear/extractor/value_matcher_string_spec.rb +0 -86
  141. data/spec/fear/extractor/value_matcher_symbol_spec.rb +0 -69
  142. data/spec/fear/extractor_api_spec.rb +0 -113
  143. 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