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
data/spec/fear/guard_spec.rb
CHANGED
@@ -15,13 +15,13 @@ RSpec.describe Fear::PartialFunction::Guard do
|
|
15
15
|
|
16
16
|
context 'Symbol' do
|
17
17
|
context 'match' do
|
18
|
-
subject { Fear::PartialFunction::Guard.new(:even?) ===
|
18
|
+
subject { Fear::PartialFunction::Guard.new(:even?) === :even? }
|
19
19
|
|
20
20
|
it { is_expected.to eq(true) }
|
21
21
|
end
|
22
22
|
|
23
23
|
context 'not match' do
|
24
|
-
subject { Fear::PartialFunction::Guard.new(:even?) ===
|
24
|
+
subject { Fear::PartialFunction::Guard.new(:even?) === 4 }
|
25
25
|
|
26
26
|
it { is_expected.to eq(false) }
|
27
27
|
end
|
@@ -44,14 +44,14 @@ RSpec.describe Fear::PartialFunction::Guard do
|
|
44
44
|
describe '.and' do
|
45
45
|
context 'match' do
|
46
46
|
subject { guard === 4 }
|
47
|
-
let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even
|
47
|
+
let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even?.to_proc, ->(x) { x.even? }]) }
|
48
48
|
|
49
49
|
it { is_expected.to eq(true) }
|
50
50
|
end
|
51
51
|
|
52
52
|
context 'not match' do
|
53
53
|
subject { guard === 3 }
|
54
|
-
let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even
|
54
|
+
let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even?.to_proc, ->(x) { x.even? }]) }
|
55
55
|
|
56
56
|
it { is_expected.to eq(false) }
|
57
57
|
end
|
data/spec/fear/left_spec.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
RSpec.describe Fear::Left do
|
2
|
-
include Fear::Either::Mixin
|
3
|
-
|
4
2
|
it_behaves_like Fear::RightBiased::Left do
|
5
|
-
let(:left) {
|
3
|
+
let(:left) { Fear.left('value') }
|
6
4
|
end
|
7
5
|
|
8
|
-
let(:left) {
|
6
|
+
let(:left) { Fear.left('value') }
|
9
7
|
|
10
8
|
describe '#right?' do
|
11
9
|
subject { left }
|
@@ -41,7 +39,7 @@ RSpec.describe Fear::Left do
|
|
41
39
|
|
42
40
|
describe '#or_else' do
|
43
41
|
subject { left.or_else { alternative } }
|
44
|
-
let(:alternative) {
|
42
|
+
let(:alternative) { Fear.left(42) }
|
45
43
|
|
46
44
|
it 'returns alternative' do
|
47
45
|
is_expected.to eq(alternative)
|
@@ -70,7 +68,7 @@ RSpec.describe Fear::Left do
|
|
70
68
|
|
71
69
|
describe '#swap' do
|
72
70
|
subject { left.swap }
|
73
|
-
it { is_expected.to eq(
|
71
|
+
it { is_expected.to eq(Fear.right('value')) }
|
74
72
|
end
|
75
73
|
|
76
74
|
describe '#reduce' do
|
@@ -88,12 +86,12 @@ RSpec.describe Fear::Left do
|
|
88
86
|
subject(:join_right) { either.join_right }
|
89
87
|
|
90
88
|
context 'value is Either' do
|
91
|
-
let(:either) { described_class.new(
|
89
|
+
let(:either) { described_class.new(Fear.left('error')) }
|
92
90
|
it { is_expected.to eq(either) }
|
93
91
|
end
|
94
92
|
|
95
93
|
context 'value s not Either' do
|
96
|
-
let(:either) {
|
94
|
+
let(:either) { Fear.left('error') }
|
97
95
|
it { is_expected.to eq(either) }
|
98
96
|
end
|
99
97
|
end
|
@@ -102,10 +100,10 @@ RSpec.describe Fear::Left do
|
|
102
100
|
context 'value is Either' do
|
103
101
|
subject { either.join_left }
|
104
102
|
let(:either) { described_class.new(value) }
|
105
|
-
let(:value) {
|
103
|
+
let(:value) { Fear.left('error') }
|
106
104
|
|
107
105
|
it 'returns value' do
|
108
|
-
is_expected.to eq(
|
106
|
+
is_expected.to eq(Fear.left('error'))
|
109
107
|
end
|
110
108
|
end
|
111
109
|
|
@@ -122,22 +120,22 @@ RSpec.describe Fear::Left do
|
|
122
120
|
subject { match === left }
|
123
121
|
|
124
122
|
context 'matches erectly' do
|
125
|
-
let(:match) {
|
123
|
+
let(:match) { Fear.left('value') }
|
126
124
|
it { is_expected.to eq(true) }
|
127
125
|
end
|
128
126
|
|
129
127
|
context 'value does not match' do
|
130
|
-
let(:match) {
|
128
|
+
let(:match) { Fear.left('error') }
|
131
129
|
it { is_expected.to eq(false) }
|
132
130
|
end
|
133
131
|
|
134
132
|
context 'matches by class' do
|
135
|
-
let(:match) {
|
133
|
+
let(:match) { Fear.left(String) }
|
136
134
|
it { is_expected.to eq(true) }
|
137
135
|
end
|
138
136
|
|
139
137
|
context 'does not matches by class' do
|
140
|
-
let(:match) {
|
138
|
+
let(:match) { Fear.left(Integer) }
|
141
139
|
it { is_expected.to eq(false) }
|
142
140
|
end
|
143
141
|
end
|
@@ -179,4 +177,32 @@ RSpec.describe Fear::Left do
|
|
179
177
|
it { is_expected.to eq(:default) }
|
180
178
|
end
|
181
179
|
end
|
180
|
+
|
181
|
+
describe '#to_s' do
|
182
|
+
subject { left.to_s }
|
183
|
+
|
184
|
+
it { is_expected.to eq('#<Fear::Left value="value">') }
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'pattern matching' do
|
188
|
+
subject { Fear.xcase('Left(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
|
189
|
+
|
190
|
+
context 'left of int' do
|
191
|
+
let(:var) { Fear.left(42) }
|
192
|
+
|
193
|
+
it { is_expected.to eq('matched 42') }
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'left of string' do
|
197
|
+
let(:var) { Fear.left('42') }
|
198
|
+
|
199
|
+
it { is_expected.to eq('nothing') }
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'not left' do
|
203
|
+
let(:var) { '42' }
|
204
|
+
|
205
|
+
it { is_expected.to eq('nothing') }
|
206
|
+
end
|
207
|
+
end
|
182
208
|
end
|
data/spec/fear/none_spec.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
RSpec.describe Fear::None do
|
2
|
-
include Fear::Option::Mixin
|
3
|
-
|
4
2
|
it_behaves_like Fear::RightBiased::Left do
|
5
|
-
let(:left) {
|
3
|
+
let(:left) { Fear.none }
|
6
4
|
end
|
7
5
|
|
8
|
-
subject(:none) {
|
6
|
+
subject(:none) { Fear.none }
|
9
7
|
|
10
8
|
describe '#get' do
|
11
9
|
subject { proc { none.get } }
|
@@ -19,7 +17,7 @@ RSpec.describe Fear::None do
|
|
19
17
|
|
20
18
|
describe '#or_else' do
|
21
19
|
subject { none.or_else { alternative } }
|
22
|
-
let(:alternative) {
|
20
|
+
let(:alternative) { Fear.some(42) }
|
23
21
|
|
24
22
|
it 'returns alternative' do
|
25
23
|
is_expected.to eq(alternative)
|
@@ -35,7 +33,7 @@ RSpec.describe Fear::None do
|
|
35
33
|
subject { none.select { |value| value > 42 } }
|
36
34
|
|
37
35
|
it 'always return None' do
|
38
|
-
is_expected.to eq(
|
36
|
+
is_expected.to eq(Fear.none)
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
@@ -43,7 +41,7 @@ RSpec.describe Fear::None do
|
|
43
41
|
subject { none.reject { |value| value > 42 } }
|
44
42
|
|
45
43
|
it 'always return None' do
|
46
|
-
is_expected.to eq(
|
44
|
+
is_expected.to eq(Fear.none)
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -54,21 +52,23 @@ RSpec.describe Fear::None do
|
|
54
52
|
end
|
55
53
|
|
56
54
|
describe '.inherited' do
|
57
|
-
subject { -> { Class.new(Fear
|
55
|
+
subject { -> { Class.new(Fear.none.class) } }
|
58
56
|
|
59
|
-
it
|
57
|
+
it 'raises error' do
|
58
|
+
is_expected.to raise_error(RuntimeError, 'you are not allowed to inherit from NoneClass, use Fear::None instead')
|
59
|
+
end
|
60
60
|
end
|
61
61
|
|
62
62
|
describe '#to_s' do
|
63
63
|
subject { none.to_s }
|
64
64
|
|
65
|
-
it { is_expected.to eq('Fear::
|
65
|
+
it { is_expected.to eq('#<Fear::NoneClass>') }
|
66
66
|
end
|
67
67
|
|
68
68
|
describe '#inspect' do
|
69
69
|
subject { none.inspect }
|
70
70
|
|
71
|
-
it { is_expected.to eq('Fear::
|
71
|
+
it { is_expected.to eq('#<Fear::NoneClass>') }
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#===' do
|
@@ -79,7 +79,7 @@ RSpec.describe Fear::None do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
context 'Fear::Some' do
|
82
|
-
subject { Fear::None ===
|
82
|
+
subject { Fear::None === Fear.some(4) }
|
83
83
|
|
84
84
|
it { is_expected.to eq(false) }
|
85
85
|
end
|
@@ -126,4 +126,20 @@ RSpec.describe Fear::None do
|
|
126
126
|
it { is_expected.to eq(:default) }
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
describe 'pattern matching' do
|
131
|
+
subject { Fear.xcase('None()') { 'matched' }.call_or_else(var) { 'nothing' } }
|
132
|
+
|
133
|
+
context 'none' do
|
134
|
+
let(:var) { Fear.none }
|
135
|
+
|
136
|
+
it { is_expected.to eq('matched') }
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'not none' do
|
140
|
+
let(:var) { '42' }
|
141
|
+
|
142
|
+
it { is_expected.to eq('nothing') }
|
143
|
+
end
|
144
|
+
end
|
129
145
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
RSpec.describe Fear::Option::Mixin do
|
2
|
+
include Fear::Option::Mixin
|
3
|
+
|
4
|
+
describe 'Option()' do
|
5
|
+
context 'value is nil' do
|
6
|
+
subject { Option(nil) }
|
7
|
+
|
8
|
+
it { is_expected.to eq(Fear.none) }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'value is not nil' do
|
12
|
+
subject { Option(42) }
|
13
|
+
|
14
|
+
it { is_expected.to eq(Fear.some(42)) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Some()' do
|
19
|
+
context 'value is nil' do
|
20
|
+
subject { Some(nil) }
|
21
|
+
|
22
|
+
it { is_expected.to eq(Fear::Some.new(nil)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'value is not nil' do
|
26
|
+
subject { Option(42) }
|
27
|
+
|
28
|
+
it { is_expected.to eq(Fear::Some.new(42)) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'None()' do
|
33
|
+
subject { None() }
|
34
|
+
|
35
|
+
it { is_expected.to eq(Fear::None) }
|
36
|
+
end
|
37
|
+
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
RSpec.describe Fear::OptionPatternMatch do
|
2
|
-
include Fear::Option::Mixin
|
3
|
-
|
4
2
|
context 'Some' do
|
5
3
|
let(:matcher) do
|
6
4
|
described_class.new do |m|
|
7
|
-
m.some(:even
|
8
|
-
m.some(:odd
|
5
|
+
m.some(:even?.to_proc) { |x| "#{x} is even" }
|
6
|
+
m.some(:odd?.to_proc) { |x| "#{x} is odd" }
|
9
7
|
end
|
10
8
|
end
|
11
9
|
|
12
10
|
it do
|
13
|
-
expect(matcher.call(
|
14
|
-
expect(matcher.call(
|
11
|
+
expect(matcher.call(Fear.some(4))).to eq('4 is even')
|
12
|
+
expect(matcher.call(Fear.some(3))).to eq('3 is odd')
|
15
13
|
expect do
|
16
|
-
matcher.call(
|
14
|
+
matcher.call(Fear.none)
|
17
15
|
end.to raise_error(Fear::MatchError)
|
18
16
|
end
|
19
17
|
end
|
@@ -26,9 +24,9 @@ RSpec.describe Fear::OptionPatternMatch do
|
|
26
24
|
end
|
27
25
|
|
28
26
|
it do
|
29
|
-
expect(matcher.call(
|
27
|
+
expect(matcher.call(Fear.none)).to eq('nil')
|
30
28
|
expect do
|
31
|
-
matcher.call(
|
29
|
+
matcher.call(Fear.some(3))
|
32
30
|
end.to raise_error(Fear::MatchError)
|
33
31
|
end
|
34
32
|
end
|
@@ -1,10 +1,22 @@
|
|
1
1
|
RSpec.describe Fear::PartialFunction do
|
2
2
|
describe 'Fear.case()' do
|
3
|
+
context 'condition is extractor' do
|
4
|
+
subject do
|
5
|
+
Fear.xcase('[1, [2, second_of_second, *], 3, *rest]') do |second_of_second:, rest:|
|
6
|
+
[second_of_second, rest]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it { is_expected.to be_defined_at([1, [2, 2, 3, 4], 3, 6, 7]) }
|
11
|
+
it { is_expected.not_to be_defined_at([1, [1, 3, 3, 4], 3, 6, 7]) }
|
12
|
+
it { is_expected.not_to be_defined_at([1, [1, 2, 3, 4], 4, 6, 7]) }
|
13
|
+
end
|
14
|
+
|
3
15
|
context 'condition as symbol' do
|
4
16
|
subject { Fear.case(:even?) { |x| x } }
|
5
17
|
|
6
|
-
it '
|
7
|
-
is_expected.to be_defined_at(
|
18
|
+
it 'matches against the same symbol' do
|
19
|
+
is_expected.to be_defined_at(:even?)
|
8
20
|
is_expected.not_to be_defined_at(3)
|
9
21
|
end
|
10
22
|
end
|
@@ -28,7 +40,7 @@ RSpec.describe Fear::PartialFunction do
|
|
28
40
|
end
|
29
41
|
|
30
42
|
context 'multiple condition' do
|
31
|
-
subject { Fear.case(Integer, :even
|
43
|
+
subject { Fear.case(Integer, :even?.to_proc, ->(x) { x % 3 == 0 }) { |x| x } }
|
32
44
|
|
33
45
|
it do
|
34
46
|
is_expected.to be_defined_at(12)
|
@@ -93,6 +105,16 @@ RSpec.describe Fear::PartialFunction do
|
|
93
105
|
|
94
106
|
it { is_expected.to raise_error(Fear::MatchError, 'partial function not defined at: 0') }
|
95
107
|
end
|
108
|
+
|
109
|
+
context 'defined and condition is extractor' do
|
110
|
+
subject { partial_function.call([1, 2, 3, 4, 5]) }
|
111
|
+
|
112
|
+
let(:partial_function) do
|
113
|
+
Fear.xcase('[1, second, 3, *rest]') { |second:, rest:| [second, rest] }
|
114
|
+
end
|
115
|
+
|
116
|
+
it { is_expected.to eq([2, [4, 5]]) }
|
117
|
+
end
|
96
118
|
end
|
97
119
|
|
98
120
|
describe '#to_proc', '#call' do
|
@@ -1,5 +1,37 @@
|
|
1
1
|
RSpec.describe Fear::PatternMatch do
|
2
|
-
|
2
|
+
context 'extracting' do
|
3
|
+
let(:matcher) do
|
4
|
+
described_class.new do |m|
|
5
|
+
m.xcase('Date(year, 2, 29)', ->(year:) { year < 2000 }) do |year:|
|
6
|
+
"#{year} is a leap year before Millennium"
|
7
|
+
end
|
8
|
+
m.xcase('Date(year, 2, 29)') do |year:|
|
9
|
+
"#{year} is a leap year after Millennium"
|
10
|
+
end
|
11
|
+
m.case(Date) do |date|
|
12
|
+
"#{date.year} is not a leap year"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'before Millennium' do
|
18
|
+
subject { matcher.call(Date.parse('1996-02-29')) }
|
19
|
+
|
20
|
+
it { is_expected.to eq('1996 is a leap year before Millennium') }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'after Millennium' do
|
24
|
+
subject { matcher.call(Date.parse('2004-02-29')) }
|
25
|
+
|
26
|
+
it { is_expected.to eq('2004 is a leap year after Millennium') }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'not leap' do
|
30
|
+
subject { matcher.call(Date.parse('2003-01-24')) }
|
31
|
+
|
32
|
+
it { is_expected.to eq('2003 is not a leap year') }
|
33
|
+
end
|
34
|
+
end
|
3
35
|
|
4
36
|
context 'else at the end' do
|
5
37
|
let(:matcher) do
|
@@ -0,0 +1,94 @@
|
|
1
|
+
RSpec.describe Fear::Promise do
|
2
|
+
let(:value) { 42 }
|
3
|
+
let(:error) { StandardError.new('something went wrong') }
|
4
|
+
|
5
|
+
def not_completed_promise
|
6
|
+
Fear::Promise.new(executor: Concurrent::ImmediateExecutor.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'not completed' do
|
10
|
+
it '#success! returns self' do
|
11
|
+
completed_promise = not_completed_promise.success!(value)
|
12
|
+
|
13
|
+
expect(completed_promise).to eq completed_promise
|
14
|
+
end
|
15
|
+
|
16
|
+
it '#success returns true' do
|
17
|
+
completed = not_completed_promise.success(value)
|
18
|
+
|
19
|
+
expect(completed).to be true
|
20
|
+
end
|
21
|
+
|
22
|
+
it '#failure! returns self' do
|
23
|
+
completed_promise = not_completed_promise.failure!(error)
|
24
|
+
|
25
|
+
expect(completed_promise).to eq completed_promise
|
26
|
+
end
|
27
|
+
|
28
|
+
it '#failure returns true' do
|
29
|
+
completed = not_completed_promise.failure(error)
|
30
|
+
|
31
|
+
expect(completed).to be true
|
32
|
+
end
|
33
|
+
|
34
|
+
it '#completed? returns true' do
|
35
|
+
expect(not_completed_promise).not_to be_completed
|
36
|
+
end
|
37
|
+
|
38
|
+
it '#future returns not completed future' do
|
39
|
+
future = not_completed_promise.to_future
|
40
|
+
|
41
|
+
expect(future).not_to be_completed
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'completed' do
|
46
|
+
def completed_promise
|
47
|
+
not_completed_promise.success!(value)
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#success! fails with exception' do
|
51
|
+
expect do
|
52
|
+
completed_promise.success!(value)
|
53
|
+
end.to raise_exception(Fear::IllegalStateException)
|
54
|
+
end
|
55
|
+
|
56
|
+
it '#success returns false' do
|
57
|
+
completed = completed_promise.success(value)
|
58
|
+
|
59
|
+
expect(completed).to be false
|
60
|
+
end
|
61
|
+
|
62
|
+
it '#failure! fails with exception' do
|
63
|
+
expect do
|
64
|
+
completed_promise.failure!(error)
|
65
|
+
end.to raise_exception(Fear::IllegalStateException)
|
66
|
+
end
|
67
|
+
|
68
|
+
it '#failure returns false' do
|
69
|
+
completed = completed_promise.success(error)
|
70
|
+
|
71
|
+
expect(completed).to be false
|
72
|
+
end
|
73
|
+
|
74
|
+
it '#completed? returns true' do
|
75
|
+
expect(completed_promise).to be_completed
|
76
|
+
end
|
77
|
+
|
78
|
+
context '#future' do
|
79
|
+
subject(:future) do
|
80
|
+
completed_promise.to_future
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'is completed' do
|
84
|
+
expect(future).to be_completed
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'completed with value' do
|
88
|
+
future_value = future.value
|
89
|
+
|
90
|
+
expect(future_value).to eq Fear.some(Fear.success(value))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|