fear 0.11.0 → 1.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 +5 -5
- data/.gitignore +0 -1
- data/.rubocop.yml +18 -0
- data/.travis.yml +0 -3
- data/CHANGELOG.md +12 -1
- data/Gemfile +1 -0
- data/{gemfiles/dry_equalizer_0.2.1.gemfile.lock → Gemfile.lock} +21 -12
- data/README.md +594 -241
- data/Rakefile +166 -219
- data/benchmarks/README.md +1 -0
- data/benchmarks/dry_do_vs_fear_for.txt +11 -0
- data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +11 -0
- data/benchmarks/factorial.txt +16 -0
- data/benchmarks/fear_gaurd_and1_vs_new.txt +13 -0
- data/benchmarks/fear_gaurd_and2_vs_and.txt +13 -0
- data/benchmarks/fear_gaurd_and3_vs_and_and.txt +13 -0
- data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +11 -0
- data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +13 -0
- data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +14 -0
- data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +11 -0
- data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +11 -0
- data/examples/pattern_extracting.rb +15 -0
- data/examples/pattern_matching_binary_tree_set.rb +96 -0
- data/examples/pattern_matching_number_in_words.rb +54 -0
- data/fear.gemspec +4 -2
- data/lib/fear.rb +21 -4
- data/lib/fear/either.rb +77 -59
- data/lib/fear/either_api.rb +21 -0
- data/lib/fear/empty_partial_function.rb +1 -1
- data/lib/fear/extractor.rb +108 -0
- data/lib/fear/extractor/anonymous_array_splat_matcher.rb +8 -0
- data/lib/fear/extractor/any_matcher.rb +15 -0
- data/lib/fear/extractor/array_head_matcher.rb +34 -0
- data/lib/fear/extractor/array_matcher.rb +38 -0
- data/lib/fear/extractor/array_splat_matcher.rb +14 -0
- data/lib/fear/extractor/empty_list_matcher.rb +18 -0
- data/lib/fear/extractor/extractor_matcher.rb +42 -0
- data/lib/fear/extractor/grammar.rb +201 -0
- data/lib/fear/extractor/grammar.treetop +129 -0
- data/lib/fear/extractor/identifier_matcher.rb +16 -0
- data/lib/fear/extractor/matcher.rb +54 -0
- data/lib/fear/extractor/matcher/and.rb +36 -0
- data/lib/fear/extractor/named_array_splat_matcher.rb +15 -0
- data/lib/fear/extractor/pattern.rb +55 -0
- data/lib/fear/extractor/typed_identifier_matcher.rb +24 -0
- data/lib/fear/extractor/value_matcher.rb +17 -0
- data/lib/fear/extractor_api.rb +33 -0
- data/lib/fear/failure.rb +32 -10
- data/lib/fear/for.rb +14 -69
- data/lib/fear/for_api.rb +66 -0
- data/lib/fear/future.rb +414 -0
- data/lib/fear/future_api.rb +19 -0
- data/lib/fear/left.rb +8 -0
- data/lib/fear/none.rb +17 -8
- data/lib/fear/option.rb +55 -49
- data/lib/fear/option_api.rb +38 -0
- data/lib/fear/partial_function.rb +9 -12
- data/lib/fear/partial_function/empty.rb +1 -1
- data/lib/fear/partial_function/guard.rb +8 -20
- data/lib/fear/partial_function/lifted.rb +1 -0
- data/lib/fear/partial_function_class.rb +10 -0
- data/lib/fear/pattern_match.rb +10 -0
- data/lib/fear/pattern_matching_api.rb +35 -11
- data/lib/fear/promise.rb +87 -0
- data/lib/fear/right.rb +8 -0
- data/lib/fear/some.rb +22 -3
- data/lib/fear/success.rb +22 -1
- data/lib/fear/try.rb +82 -67
- data/lib/fear/try_api.rb +31 -0
- data/lib/fear/unit.rb +28 -0
- data/lib/fear/version.rb +1 -1
- data/spec/fear/done_spec.rb +3 -3
- data/spec/fear/either/mixin_spec.rb +15 -0
- data/spec/fear/either_pattern_match_spec.rb +10 -12
- data/spec/fear/extractor/array_matcher_spec.rb +228 -0
- data/spec/fear/extractor/extractor_matcher_spec.rb +151 -0
- data/spec/fear/extractor/grammar_array_spec.rb +23 -0
- data/spec/fear/extractor/identified_matcher_spec.rb +47 -0
- data/spec/fear/extractor/identifier_matcher_spec.rb +66 -0
- data/spec/fear/extractor/pattern_spec.rb +32 -0
- data/spec/fear/extractor/typed_identifier_matcher_spec.rb +62 -0
- data/spec/fear/extractor/value_matcher_number_spec.rb +77 -0
- data/spec/fear/extractor/value_matcher_string_spec.rb +86 -0
- data/spec/fear/extractor/value_matcher_symbol_spec.rb +69 -0
- data/spec/fear/extractor_api_spec.rb +113 -0
- data/spec/fear/extractor_spec.rb +59 -0
- data/spec/fear/failure_spec.rb +73 -13
- data/spec/fear/for_spec.rb +35 -35
- data/spec/fear/future_spec.rb +466 -0
- data/spec/fear/guard_spec.rb +4 -4
- data/spec/fear/left_spec.rb +40 -14
- data/spec/fear/none_spec.rb +28 -12
- data/spec/fear/option/mixin_spec.rb +37 -0
- data/spec/fear/option_pattern_match_spec.rb +7 -9
- data/spec/fear/partial_function_spec.rb +25 -3
- data/spec/fear/pattern_match_spec.rb +33 -1
- data/spec/fear/promise_spec.rb +94 -0
- data/spec/fear/right_spec.rb +37 -9
- data/spec/fear/some_spec.rb +32 -6
- data/spec/fear/success_spec.rb +32 -4
- data/spec/fear/try/mixin_spec.rb +17 -0
- data/spec/fear/try_pattern_match_spec.rb +8 -10
- data/spec/spec_helper.rb +1 -1
- metadata +115 -20
- data/Appraisals +0 -32
- data/gemfiles/dry_equalizer_0.1.0.gemfile +0 -8
- data/gemfiles/dry_equalizer_0.1.0.gemfile.lock +0 -82
- data/gemfiles/dry_equalizer_0.2.1.gemfile +0 -8
- data/lib/fear/done.rb +0 -22
- data/spec/fear/option_spec.rb +0 -15
@@ -0,0 +1,113 @@
|
|
1
|
+
RSpec.describe Fear::ExtractorApi do
|
2
|
+
def assert(value)
|
3
|
+
expect(value).to eq(true)
|
4
|
+
end
|
5
|
+
|
6
|
+
def assert_not(value)
|
7
|
+
expect(value).not_to eq(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
def assert_invalid_syntax
|
11
|
+
expect do
|
12
|
+
yield
|
13
|
+
end.to raise_error(Fear::PatternSyntaxError)
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_valid_syntax
|
17
|
+
expect { yield }.not_to raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
specify 'Array' do
|
21
|
+
assert(Fear['[]'] === [])
|
22
|
+
assert_not(Fear['[]'] === [1])
|
23
|
+
assert(Fear['[1]'] === [1])
|
24
|
+
assert_not(Fear['[1]'] === [1, 2])
|
25
|
+
assert_not(Fear['[1]'] === [2])
|
26
|
+
assert(Fear['[1, 2]'] === [1, 2])
|
27
|
+
assert_not(Fear['[1, 2]'] === [1, 3])
|
28
|
+
assert_not(Fear['[1, 2]'] === [1, 2, 4])
|
29
|
+
assert_not(Fear['[1, 2]'] === [1])
|
30
|
+
assert(Fear['[*]'] === [])
|
31
|
+
assert(Fear['[*]'] === [1, 2])
|
32
|
+
assert_not(Fear['[1, *]'] === [])
|
33
|
+
assert(Fear['[1, *]'] === [1])
|
34
|
+
assert(Fear['[1, *]'] === [1, 2])
|
35
|
+
assert(Fear['[1, *]'] === [1, 2, 3])
|
36
|
+
assert(Fear['[[1]]'] === [[1]])
|
37
|
+
assert(Fear['[[1],2]'] === [[1], 2])
|
38
|
+
assert(Fear['[[1],*]'] === [[1], 2])
|
39
|
+
assert(Fear['[[*],*]'] === [[1], 2])
|
40
|
+
assert_invalid_syntax { Fear['[*, 2]'] }
|
41
|
+
assert_invalid_syntax { Fear['[*, ]'] }
|
42
|
+
assert_invalid_syntax { Fear['[1, *, ]'] }
|
43
|
+
assert_invalid_syntax { Fear['[1, *, 2]'] }
|
44
|
+
assert_invalid_syntax { Fear['[1, *, *]'] }
|
45
|
+
assert_invalid_syntax { Fear['[*, *]'] }
|
46
|
+
assert(Fear['[a, b]'] === [1, 2])
|
47
|
+
assert_not(Fear['[a, b, c]'] === [1, 2])
|
48
|
+
assert(Fear['[a, b, _]'] === [1, 2, 3])
|
49
|
+
assert(Fear['[a, b, *c]'] === [1, 2])
|
50
|
+
assert_not(Fear['[a, b, c, *d]'] === [1, 2])
|
51
|
+
end
|
52
|
+
|
53
|
+
specify 'String' do
|
54
|
+
assert(Fear['"foo"'] === 'foo')
|
55
|
+
assert(Fear['"f\"oo"'] === 'f"oo')
|
56
|
+
assert_not(Fear['"foo"'] === 'bar')
|
57
|
+
assert(Fear["'foo'"] === 'foo')
|
58
|
+
assert_not(Fear["'foo'"] === 'bar')
|
59
|
+
end
|
60
|
+
|
61
|
+
specify 'Symbol' do
|
62
|
+
assert(Fear[':"foo"'] === :foo)
|
63
|
+
assert(Fear[":'foo'"] === :foo)
|
64
|
+
assert(Fear[':foo'] === :foo)
|
65
|
+
assert_not(Fear[':foo'] === :bar)
|
66
|
+
end
|
67
|
+
|
68
|
+
specify 'Boolean' do
|
69
|
+
assert(Fear['true'] === true)
|
70
|
+
assert(Fear['false'] === false)
|
71
|
+
assert_not(Fear['true'] === false)
|
72
|
+
assert_not(Fear['false'] === true)
|
73
|
+
end
|
74
|
+
|
75
|
+
specify 'Nil' do
|
76
|
+
assert(Fear['nil'] === nil) # rubocop:disable Style/NilComparison
|
77
|
+
assert_not(Fear['nil'] === 42)
|
78
|
+
end
|
79
|
+
|
80
|
+
specify '_' do
|
81
|
+
assert(Fear['_'] === nil) # rubocop:disable Style/NilComparison
|
82
|
+
assert(Fear['_'] === true)
|
83
|
+
assert(Fear['_'] === false)
|
84
|
+
assert(Fear['_'] === 42)
|
85
|
+
assert(Fear['_'] === 'foo')
|
86
|
+
assert(Fear['_'] === [42])
|
87
|
+
end
|
88
|
+
|
89
|
+
specify 'type matching' do
|
90
|
+
class Foo
|
91
|
+
class Bar
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
assert(Fear['Integer'] === 3)
|
96
|
+
assert_not(Fear['Integer'] === '3')
|
97
|
+
assert(Fear['Numeric'] === 3)
|
98
|
+
assert(Fear['Foo::Bar'] === Foo::Bar.new)
|
99
|
+
assert(Fear['var : Integer'] === 3)
|
100
|
+
assert_not(Fear['var : Integer'] === '3')
|
101
|
+
end
|
102
|
+
|
103
|
+
specify 'capture matcher' do
|
104
|
+
assert(Fear['array @ [head : Integer, *tail]'] === [1, 2])
|
105
|
+
assert_not(Fear['array @ [head : Integer, *tail]'] === ['1', 2])
|
106
|
+
end
|
107
|
+
|
108
|
+
specify 'extractor' do
|
109
|
+
assert_valid_syntax { Fear['Foo(a, b : Integer)'] }
|
110
|
+
assert(Fear['Fear::Some(a : Integer)'] === Fear.some(42))
|
111
|
+
assert_not(Fear['Fear::Some(a : Integer)'] === Fear.some('foo'))
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
RSpec.describe Fear::Extractor do
|
2
|
+
describe '.register_extractor' do
|
3
|
+
Foo = Struct.new(:v1, :v2)
|
4
|
+
let(:matcher) do
|
5
|
+
Fear.matcher do |m|
|
6
|
+
m.case(Fear['Foo(43, second : Integer)']) { |second| "43 and #{second}" }
|
7
|
+
m.case(Fear['Foo(42, second : Integer)']) { |second| "42 and #{second}" }
|
8
|
+
m.else { 'no match' }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:extractor) do
|
13
|
+
Fear.case(Foo) { |foo| [foo.v1, foo.v2] }.lift
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'extractor not registered' do
|
17
|
+
it 'raise Fear::Extractor::ExtractorNotFound' do
|
18
|
+
expect do
|
19
|
+
described_class.find_extractor('UnknownExtractor')
|
20
|
+
end.to raise_error(Fear::Extractor::ExtractorNotFound)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'register by name' do
|
25
|
+
let(:extractor) { ->(*) { Fear.some('matched') } }
|
26
|
+
|
27
|
+
before do
|
28
|
+
described_class.register_extractor(
|
29
|
+
'ExtractorRegisteredByName',
|
30
|
+
'ExtractorRegisteredByName2',
|
31
|
+
extractor,
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns extractor' do
|
36
|
+
expect(described_class.find_extractor('ExtractorRegisteredByName')).to eq(extractor)
|
37
|
+
expect(described_class.find_extractor('ExtractorRegisteredByName2')).to eq(extractor)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'register by class' do
|
42
|
+
let(:extractor) { ->(*) { Fear.some('matched') } }
|
43
|
+
ExtractorRegisteredByClass = Class.new
|
44
|
+
|
45
|
+
before do
|
46
|
+
described_class.register_extractor(
|
47
|
+
ExtractorRegisteredByClass,
|
48
|
+
'ExtractorRegisteredByClass2',
|
49
|
+
extractor,
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns extractor' do
|
54
|
+
expect(described_class.find_extractor('ExtractorRegisteredByClass')).to eq(extractor)
|
55
|
+
expect(described_class.find_extractor('ExtractorRegisteredByClass2')).to eq(extractor)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/fear/failure_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
RSpec.describe Fear::Failure do
|
2
2
|
let(:exception) { RuntimeError.new('error') }
|
3
|
-
let(:failure) {
|
3
|
+
let(:failure) { Fear.failure(exception) }
|
4
4
|
|
5
5
|
it_behaves_like Fear::RightBiased::Left do
|
6
6
|
let(:left) { failure }
|
@@ -50,10 +50,10 @@ RSpec.describe Fear::Failure do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
context '#recover_with' do
|
53
|
-
context 'block does not fail' do
|
53
|
+
context 'block matches the error and does not fail' do
|
54
54
|
subject do
|
55
|
-
failure.recover_with do |
|
56
|
-
|
55
|
+
failure.recover_with do |m|
|
56
|
+
m.case(RuntimeError) { |error| Fear.success(error.message) }
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -62,6 +62,18 @@ RSpec.describe Fear::Failure do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
context 'block does not match the error' do
|
66
|
+
subject do
|
67
|
+
failure.recover_with do |m|
|
68
|
+
m.case(ZeroDivisionError) { Fear.success(0) }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'returns the same failure' do
|
73
|
+
is_expected.to eq(failure)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
65
77
|
context 'block fails' do
|
66
78
|
subject(:recover_with) { failure.recover_with { raise 'unexpected error' } }
|
67
79
|
|
@@ -71,16 +83,36 @@ RSpec.describe Fear::Failure do
|
|
71
83
|
end
|
72
84
|
|
73
85
|
context '#recover' do
|
74
|
-
context 'block does not fail' do
|
75
|
-
subject
|
86
|
+
context 'block matches the error and does not fail' do
|
87
|
+
subject do
|
88
|
+
failure.recover do |m|
|
89
|
+
m.case(RuntimeError, &:message)
|
90
|
+
end
|
91
|
+
end
|
76
92
|
|
77
93
|
it 'returns Success of evaluation of the block against the error' do
|
78
|
-
is_expected.to eq(
|
94
|
+
is_expected.to eq(Fear.success('error'))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'block does not match the error' do
|
99
|
+
subject do
|
100
|
+
failure.recover do |m|
|
101
|
+
m.case(ZeroDivisionError, &:message)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns the same failure' do
|
106
|
+
is_expected.to eq(failure)
|
79
107
|
end
|
80
108
|
end
|
81
109
|
|
82
110
|
context 'block fails' do
|
83
|
-
subject(:recover)
|
111
|
+
subject(:recover) do
|
112
|
+
failure.recover do
|
113
|
+
raise 'unexpected error'
|
114
|
+
end
|
115
|
+
end
|
84
116
|
|
85
117
|
it { is_expected.to be_kind_of(described_class) }
|
86
118
|
it { expect { recover.get }.to raise_error(RuntimeError, 'unexpected error') }
|
@@ -89,29 +121,29 @@ RSpec.describe Fear::Failure do
|
|
89
121
|
|
90
122
|
describe '#to_either' do
|
91
123
|
subject { failure.to_either }
|
92
|
-
it { is_expected.to eq(
|
124
|
+
it { is_expected.to eq(Fear.left(exception)) }
|
93
125
|
end
|
94
126
|
|
95
127
|
describe '#===' do
|
96
128
|
subject { match === failure }
|
97
129
|
|
98
130
|
context 'matches erectly' do
|
99
|
-
let(:match) {
|
131
|
+
let(:match) { Fear.failure(exception) }
|
100
132
|
it { is_expected.to eq(true) }
|
101
133
|
end
|
102
134
|
|
103
135
|
context 'value does not match' do
|
104
|
-
let(:match) {
|
136
|
+
let(:match) { Fear.failure(ArgumentError.new) }
|
105
137
|
it { is_expected.to eq(false) }
|
106
138
|
end
|
107
139
|
|
108
140
|
context 'matches by class' do
|
109
|
-
let(:match) {
|
141
|
+
let(:match) { Fear.failure(RuntimeError) }
|
110
142
|
it { is_expected.to eq(true) }
|
111
143
|
end
|
112
144
|
|
113
145
|
context 'does not matches by class' do
|
114
|
-
let(:match) {
|
146
|
+
let(:match) { Fear.failure(ArgumentError) }
|
115
147
|
it { is_expected.to eq(false) }
|
116
148
|
end
|
117
149
|
end
|
@@ -153,4 +185,32 @@ RSpec.describe Fear::Failure do
|
|
153
185
|
it { is_expected.to eq(:default) }
|
154
186
|
end
|
155
187
|
end
|
188
|
+
|
189
|
+
describe '#to_s' do
|
190
|
+
subject { failure.to_s }
|
191
|
+
|
192
|
+
it { is_expected.to eq('#<Fear::Failure exception=#<RuntimeError: error>>') }
|
193
|
+
end
|
194
|
+
|
195
|
+
describe 'pattern matching' do
|
196
|
+
subject { Fear.xcase('Failure(v : ArgumentError)') { 'matched' }.call_or_else(var) { 'nothing' } }
|
197
|
+
|
198
|
+
context 'failure of ArgumentError' do
|
199
|
+
let(:var) { Fear.failure(ArgumentError.new) }
|
200
|
+
|
201
|
+
it { is_expected.to eq('matched') }
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'failure of RuntimeError' do
|
205
|
+
let(:var) { Fear.failure(RuntimeError.new) }
|
206
|
+
|
207
|
+
it { is_expected.to eq('nothing') }
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'not failure' do
|
211
|
+
let(:var) { '42' }
|
212
|
+
|
213
|
+
it { is_expected.to eq('nothing') }
|
214
|
+
end
|
215
|
+
end
|
156
216
|
end
|
data/spec/fear/for_spec.rb
CHANGED
@@ -2,24 +2,24 @@ RSpec.describe Fear::For do
|
|
2
2
|
context 'unary' do
|
3
3
|
context 'Some' do
|
4
4
|
subject do
|
5
|
-
|
5
|
+
Fear.for(Fear.some(2)) { |a| a * 2 }
|
6
6
|
end
|
7
7
|
|
8
|
-
it { is_expected.to eq(
|
8
|
+
it { is_expected.to eq(Fear.some(4)) }
|
9
9
|
end
|
10
10
|
|
11
11
|
context 'None' do
|
12
12
|
subject do
|
13
|
-
|
13
|
+
Fear.for(Fear.none) { |a| a * 2 }
|
14
14
|
end
|
15
15
|
|
16
|
-
it { is_expected.to eq(
|
16
|
+
it { is_expected.to eq(Fear.none) }
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
context 'arrays' do
|
21
21
|
subject do
|
22
|
-
|
22
|
+
Fear.for([1, 2], [2, 3], [3, 4]) do |a, b, c|
|
23
23
|
a * b * c
|
24
24
|
end
|
25
25
|
end
|
@@ -29,83 +29,83 @@ RSpec.describe Fear::For do
|
|
29
29
|
|
30
30
|
context 'ternary' do
|
31
31
|
subject do
|
32
|
-
|
32
|
+
Fear.for(first, second, third) do |a, b, c|
|
33
33
|
a * b * c
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
context 'all Same' do
|
38
|
-
let(:first) {
|
39
|
-
let(:second) {
|
40
|
-
let(:third) {
|
38
|
+
let(:first) { Fear.some(2) }
|
39
|
+
let(:second) { Fear.some(3) }
|
40
|
+
let(:third) { Fear.some(4) }
|
41
41
|
|
42
|
-
it { is_expected.to eq(
|
42
|
+
it { is_expected.to eq(Fear.some(24)) }
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'first is None' do
|
46
|
-
let(:first) {
|
47
|
-
let(:second) {
|
48
|
-
let(:third) {
|
46
|
+
let(:first) { Fear.none }
|
47
|
+
let(:second) { Fear.some(3) }
|
48
|
+
let(:third) { Fear.some(4) }
|
49
49
|
|
50
|
-
it { is_expected.to eq(
|
50
|
+
it { is_expected.to eq(Fear.none) }
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'second is None' do
|
54
|
-
let(:first) {
|
55
|
-
let(:second) {
|
56
|
-
let(:third) {
|
54
|
+
let(:first) { Fear.some(2) }
|
55
|
+
let(:second) { Fear.none }
|
56
|
+
let(:third) { Fear.some(4) }
|
57
57
|
|
58
|
-
it { is_expected.to eq(
|
58
|
+
it { is_expected.to eq(Fear.none) }
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'last is None' do
|
62
|
-
let(:first) {
|
63
|
-
let(:second) {
|
64
|
-
let(:third) {
|
62
|
+
let(:first) { Fear.some(2) }
|
63
|
+
let(:second) { Fear.some(3) }
|
64
|
+
let(:third) { Fear.none }
|
65
65
|
|
66
|
-
it { is_expected.to eq(
|
66
|
+
it { is_expected.to eq(Fear.none) }
|
67
67
|
end
|
68
68
|
|
69
69
|
context 'all Same in lambdas' do
|
70
|
-
let(:first) { proc {
|
71
|
-
let(:second) { proc {
|
72
|
-
let(:third) { proc {
|
70
|
+
let(:first) { proc { Fear.some(2) } }
|
71
|
+
let(:second) { proc { Fear.some(3) } }
|
72
|
+
let(:third) { proc { Fear.some(4) } }
|
73
73
|
|
74
|
-
it { is_expected.to eq(
|
74
|
+
it { is_expected.to eq(Fear.some(24)) }
|
75
75
|
end
|
76
76
|
|
77
77
|
context 'first is None in lambda, second is failure in lambda' do
|
78
|
-
let(:first) { proc {
|
78
|
+
let(:first) { proc { Fear.none } }
|
79
79
|
let(:second) { proc { raise 'kaboom' } }
|
80
80
|
let(:third) { proc {} }
|
81
81
|
|
82
82
|
it 'returns None without evaluating second and third' do
|
83
|
-
is_expected.to eq(
|
83
|
+
is_expected.to eq(Fear.none)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
87
|
context 'second is None in lambda, third is failure in lambda' do
|
88
|
-
let(:first) {
|
89
|
-
let(:second) { proc {
|
88
|
+
let(:first) { Fear.some(2) }
|
89
|
+
let(:second) { proc { Fear.none } }
|
90
90
|
let(:third) { proc { raise 'kaboom' } }
|
91
91
|
|
92
92
|
it 'returns None without evaluating third' do
|
93
|
-
is_expected.to eq(
|
93
|
+
is_expected.to eq(Fear.none)
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
98
|
context 'refer to previous variable from lambda' do
|
99
99
|
subject do
|
100
|
-
|
100
|
+
Fear.for(first, second, third) do |_, b, c|
|
101
101
|
b * c
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
let(:first) {
|
105
|
+
let(:first) { Fear.some(Fear.some(2)) }
|
106
106
|
let(:second) { ->(a) { a.map { |x| x * 2 } } }
|
107
|
-
let(:third) { proc {
|
107
|
+
let(:third) { proc { Fear.some(3) } }
|
108
108
|
|
109
|
-
it { is_expected.to eq(
|
109
|
+
it { is_expected.to eq(Fear.some(12)) }
|
110
110
|
end
|
111
111
|
end
|