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
data/spec/fear/right_spec.rb
CHANGED
@@ -1,76 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Right do
|
2
4
|
it_behaves_like Fear::RightBiased::Right do
|
3
|
-
let(:right) { Fear.right(
|
5
|
+
let(:right) { Fear.right("value") }
|
4
6
|
end
|
5
7
|
|
6
|
-
let(:right) { Fear.right(
|
8
|
+
let(:right) { Fear.right("value") }
|
7
9
|
|
8
|
-
describe
|
10
|
+
describe "#right?" do
|
9
11
|
subject { right }
|
10
12
|
it { is_expected.to be_right }
|
11
13
|
end
|
12
14
|
|
13
|
-
describe
|
15
|
+
describe "#left?" do
|
14
16
|
subject { right }
|
15
17
|
it { is_expected.not_to be_left }
|
16
18
|
end
|
17
19
|
|
18
|
-
describe
|
20
|
+
describe "#select_or_else" do
|
19
21
|
subject { right.select_or_else(default, &predicate) }
|
20
22
|
|
21
|
-
context
|
22
|
-
let(:predicate) { ->(v) { v ==
|
23
|
+
context "predicate evaluates to true" do
|
24
|
+
let(:predicate) { ->(v) { v == "value" } }
|
23
25
|
let(:default) { -1 }
|
24
26
|
it { is_expected.to eq(right) }
|
25
27
|
end
|
26
28
|
|
27
|
-
context
|
28
|
-
let(:predicate) { ->(v) { v !=
|
29
|
+
context "predicate evaluates to false and default is a proc" do
|
30
|
+
let(:predicate) { ->(v) { v != "value" } }
|
29
31
|
let(:default) { -> { -1 } }
|
30
32
|
it { is_expected.to eq(Fear.left(-1)) }
|
31
33
|
end
|
32
34
|
|
33
|
-
context
|
34
|
-
let(:predicate) { ->(v) { v !=
|
35
|
+
context "predicate evaluates to false and default is not a proc" do
|
36
|
+
let(:predicate) { ->(v) { v != "value" } }
|
35
37
|
let(:default) { -1 }
|
36
38
|
it { is_expected.to eq(Fear.left(-1)) }
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
|
-
describe
|
42
|
+
describe "#select" do
|
41
43
|
subject { right.select(&predicate) }
|
42
44
|
|
43
|
-
context
|
44
|
-
let(:predicate) { ->(v) { v ==
|
45
|
+
context "predicate evaluates to true" do
|
46
|
+
let(:predicate) { ->(v) { v == "value" } }
|
45
47
|
it { is_expected.to eq(right) }
|
46
48
|
end
|
47
49
|
|
48
|
-
context
|
49
|
-
let(:predicate) { ->(v) { v !=
|
50
|
-
it { is_expected.to eq(Fear.left(
|
50
|
+
context "predicate evaluates to false" do
|
51
|
+
let(:predicate) { ->(v) { v != "value" } }
|
52
|
+
it { is_expected.to eq(Fear.left("value")) }
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
|
-
describe
|
56
|
+
describe "#reject" do
|
55
57
|
subject { right.reject(&predicate) }
|
56
58
|
|
57
|
-
context
|
58
|
-
let(:predicate) { ->(v) { v ==
|
59
|
-
it { is_expected.to eq(Fear.left(
|
59
|
+
context "predicate evaluates to true" do
|
60
|
+
let(:predicate) { ->(v) { v == "value" } }
|
61
|
+
it { is_expected.to eq(Fear.left("value")) }
|
60
62
|
end
|
61
63
|
|
62
|
-
context
|
63
|
-
let(:predicate) { ->(v) { v !=
|
64
|
+
context "predicate evaluates to false" do
|
65
|
+
let(:predicate) { ->(v) { v != "value" } }
|
64
66
|
it { is_expected.to eq(right) }
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
describe
|
70
|
+
describe "#swap" do
|
69
71
|
subject { right.swap }
|
70
|
-
it { is_expected.to eq(Fear.left(
|
72
|
+
it { is_expected.to eq(Fear.left("value")) }
|
71
73
|
end
|
72
74
|
|
73
|
-
describe
|
75
|
+
describe "#reduce" do
|
74
76
|
subject do
|
75
77
|
right.reduce(
|
76
78
|
->(left) { "Left: #{left}" },
|
@@ -78,45 +80,45 @@ RSpec.describe Fear::Right do
|
|
78
80
|
)
|
79
81
|
end
|
80
82
|
|
81
|
-
it { is_expected.to eq(
|
83
|
+
it { is_expected.to eq("Right: value") }
|
82
84
|
end
|
83
85
|
|
84
|
-
describe
|
85
|
-
context
|
86
|
+
describe "#join_right" do
|
87
|
+
context "value is Either" do
|
86
88
|
subject { described_class.new(value).join_right }
|
87
|
-
let(:value) { Fear.left(
|
89
|
+
let(:value) { Fear.left("error") }
|
88
90
|
|
89
|
-
it
|
91
|
+
it "returns value" do
|
90
92
|
is_expected.to eq(value)
|
91
93
|
end
|
92
94
|
end
|
93
95
|
|
94
|
-
context
|
95
|
-
subject { proc { described_class.new(
|
96
|
+
context "value is not Either" do
|
97
|
+
subject { proc { described_class.new("35").join_right } }
|
96
98
|
|
97
|
-
it
|
99
|
+
it "fails with type error" do
|
98
100
|
is_expected.to raise_error(TypeError)
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
|
-
describe
|
104
|
-
context
|
105
|
+
describe "#join_left" do
|
106
|
+
context "value is Either" do
|
105
107
|
subject { either.join_left }
|
106
|
-
let(:either) { described_class.new(Fear.left(
|
108
|
+
let(:either) { described_class.new(Fear.left("error")) }
|
107
109
|
|
108
110
|
it { is_expected.to eq(either) }
|
109
111
|
end
|
110
112
|
|
111
|
-
context
|
113
|
+
context "value is not Either" do
|
112
114
|
subject { either.join_left }
|
113
|
-
let(:either) { described_class.new(
|
115
|
+
let(:either) { described_class.new("result") }
|
114
116
|
it { is_expected.to eq(either) }
|
115
117
|
end
|
116
118
|
end
|
117
119
|
|
118
|
-
describe
|
119
|
-
context
|
120
|
+
describe "#match" do
|
121
|
+
context "matched" do
|
120
122
|
subject do
|
121
123
|
right.match do |m|
|
122
124
|
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
@@ -125,15 +127,15 @@ RSpec.describe Fear::Right do
|
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
128
|
-
it { is_expected.to eq(
|
130
|
+
it { is_expected.to eq("Right: value") }
|
129
131
|
end
|
130
132
|
|
131
|
-
context
|
133
|
+
context "nothing matched and no else given" do
|
132
134
|
subject do
|
133
135
|
proc do
|
134
136
|
right.match do |m|
|
135
137
|
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
136
|
-
m.left { |_|
|
138
|
+
m.left { |_| "noop" }
|
137
139
|
end
|
138
140
|
end
|
139
141
|
end
|
@@ -141,7 +143,7 @@ RSpec.describe Fear::Right do
|
|
141
143
|
it { is_expected.to raise_error(Fear::MatchError) }
|
142
144
|
end
|
143
145
|
|
144
|
-
context
|
146
|
+
context "nothing matched and else given" do
|
145
147
|
subject do
|
146
148
|
right.match do |m|
|
147
149
|
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
@@ -153,31 +155,9 @@ RSpec.describe Fear::Right do
|
|
153
155
|
end
|
154
156
|
end
|
155
157
|
|
156
|
-
describe
|
158
|
+
describe "#to_s" do
|
157
159
|
subject { right.to_s }
|
158
160
|
|
159
161
|
it { is_expected.to eq('#<Fear::Right value="value">') }
|
160
162
|
end
|
161
|
-
|
162
|
-
describe 'pattern matching' do
|
163
|
-
subject { Fear.xcase('Right(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
|
164
|
-
|
165
|
-
context 'right of int' do
|
166
|
-
let(:var) { Fear.right(42) }
|
167
|
-
|
168
|
-
it { is_expected.to eq('matched 42') }
|
169
|
-
end
|
170
|
-
|
171
|
-
context 'right of string' do
|
172
|
-
let(:var) { Fear.right('42') }
|
173
|
-
|
174
|
-
it { is_expected.to eq('nothing') }
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'not right' do
|
178
|
-
let(:var) { '42' }
|
179
|
-
|
180
|
-
it { is_expected.to eq('nothing') }
|
181
|
-
end
|
182
|
-
end
|
183
163
|
end
|
data/spec/fear/some_spec.rb
CHANGED
@@ -1,71 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Some do
|
2
4
|
it_behaves_like Fear::RightBiased::Right do
|
3
|
-
let(:right) { Fear.some(
|
5
|
+
let(:right) { Fear.some("value") }
|
4
6
|
end
|
5
7
|
|
6
8
|
subject(:some) { Fear.some(42) }
|
7
9
|
|
8
|
-
describe
|
10
|
+
describe "#select" do
|
9
11
|
subject { some.select(&predicate) }
|
10
12
|
|
11
|
-
context
|
13
|
+
context "predicate evaluates to true" do
|
12
14
|
let(:predicate) { ->(v) { v > 40 } }
|
13
15
|
it { is_expected.to eq(some) }
|
14
16
|
end
|
15
17
|
|
16
|
-
context
|
18
|
+
context "predicate evaluates to false" do
|
17
19
|
let(:predicate) { ->(v) { v < 40 } }
|
18
20
|
it { is_expected.to eq(Fear.none) }
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
describe
|
24
|
+
describe "#reject" do
|
23
25
|
subject { some.reject(&predicate) }
|
24
26
|
|
25
|
-
context
|
27
|
+
context "predicate evaluates to true" do
|
26
28
|
let(:predicate) { ->(v) { v > 40 } }
|
27
29
|
it { is_expected.to eq(Fear.none) }
|
28
30
|
end
|
29
31
|
|
30
|
-
context
|
32
|
+
context "predicate evaluates to false" do
|
31
33
|
let(:predicate) { ->(v) { v < 40 } }
|
32
34
|
it { is_expected.to eq(some) }
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
|
-
describe
|
38
|
+
describe "#get" do
|
37
39
|
subject { some.get }
|
38
40
|
it { is_expected.to eq(42) }
|
39
41
|
end
|
40
42
|
|
41
|
-
describe
|
43
|
+
describe "#or_nil" do
|
42
44
|
subject { some.or_nil }
|
43
45
|
it { is_expected.to eq(42) }
|
44
46
|
end
|
45
47
|
|
46
|
-
describe
|
48
|
+
describe "#empty?" do
|
47
49
|
subject { some.empty? }
|
48
50
|
it { is_expected.to eq(false) }
|
49
51
|
end
|
50
52
|
|
51
|
-
describe
|
52
|
-
|
53
|
+
describe "#blank?" do
|
54
|
+
subject { some.blank? }
|
55
|
+
it { is_expected.to eq(false) }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#present?" do
|
59
|
+
subject { some.present? }
|
60
|
+
it { is_expected.to be_truthy }
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#match" do
|
64
|
+
context "matched" do
|
53
65
|
subject do
|
54
66
|
some.match do |m|
|
55
67
|
m.some(->(x) { x > 2 }) { |x| x * 2 }
|
56
|
-
m.none {
|
68
|
+
m.none { "noop" }
|
57
69
|
end
|
58
70
|
end
|
59
71
|
|
60
72
|
it { is_expected.to eq(84) }
|
61
73
|
end
|
62
74
|
|
63
|
-
context
|
75
|
+
context "nothing matched and no else given" do
|
64
76
|
subject do
|
65
77
|
proc do
|
66
78
|
some.match do |m|
|
67
79
|
m.some(->(x) { x < 2 }) { |x| x * 2 }
|
68
|
-
m.none {
|
80
|
+
m.none { "noop" }
|
69
81
|
end
|
70
82
|
end
|
71
83
|
end
|
@@ -73,7 +85,7 @@ RSpec.describe Fear::Some do
|
|
73
85
|
it { is_expected.to raise_error(Fear::MatchError) }
|
74
86
|
end
|
75
87
|
|
76
|
-
context
|
88
|
+
context "nothing matched and else given" do
|
77
89
|
subject do
|
78
90
|
some.match do |m|
|
79
91
|
m.none { |x| x * 2 }
|
@@ -85,31 +97,9 @@ RSpec.describe Fear::Some do
|
|
85
97
|
end
|
86
98
|
end
|
87
99
|
|
88
|
-
describe
|
100
|
+
describe "#to_s" do
|
89
101
|
subject { some.to_s }
|
90
102
|
|
91
|
-
it { is_expected.to eq(
|
92
|
-
end
|
93
|
-
|
94
|
-
describe 'pattern matching' do
|
95
|
-
subject { Fear.xcase('Some(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
|
96
|
-
|
97
|
-
context 'some of int' do
|
98
|
-
let(:var) { Fear.some(42) }
|
99
|
-
|
100
|
-
it { is_expected.to eq('matched 42') }
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'some of string' do
|
104
|
-
let(:var) { Fear.some('42') }
|
105
|
-
|
106
|
-
it { is_expected.to eq('nothing') }
|
107
|
-
end
|
108
|
-
|
109
|
-
context 'not some' do
|
110
|
-
let(:var) { '42' }
|
111
|
-
|
112
|
-
it { is_expected.to eq('nothing') }
|
113
|
-
end
|
103
|
+
it { is_expected.to eq("#<Fear::Some get=42>") }
|
114
104
|
end
|
115
105
|
end
|
data/spec/fear/success_spec.rb
CHANGED
@@ -1,114 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Success do
|
2
|
-
let(:success) { Fear.success(
|
4
|
+
let(:success) { Fear.success("value") }
|
3
5
|
|
4
6
|
it_behaves_like Fear::RightBiased::Right do
|
5
7
|
let(:right) { success }
|
6
8
|
|
7
|
-
describe
|
8
|
-
subject(:map) { right.map { raise
|
9
|
+
describe "#map", "block fails" do
|
10
|
+
subject(:map) { right.map { raise "unexpected error" } }
|
9
11
|
|
10
12
|
it { is_expected.to be_kind_of(Fear::Failure) }
|
11
|
-
it { expect { map.get }.to raise_error(RuntimeError,
|
13
|
+
it { expect { map.get }.to raise_error(RuntimeError, "unexpected error") }
|
12
14
|
end
|
13
15
|
|
14
|
-
describe
|
15
|
-
subject(:flat_map) { right.flat_map { raise
|
16
|
+
describe "#flat_map", "block fails" do
|
17
|
+
subject(:flat_map) { right.flat_map { raise "unexpected error" } }
|
16
18
|
|
17
19
|
it { is_expected.to be_kind_of(Fear::Failure) }
|
18
|
-
it { expect { flat_map.get }.to raise_error(RuntimeError,
|
20
|
+
it { expect { flat_map.get }.to raise_error(RuntimeError, "unexpected error") }
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
describe
|
24
|
+
describe "#get" do
|
23
25
|
subject { success.get }
|
24
|
-
it { is_expected.to eq(
|
26
|
+
it { is_expected.to eq("value") }
|
25
27
|
end
|
26
28
|
|
27
|
-
describe
|
29
|
+
describe "#success?" do
|
28
30
|
subject { success }
|
29
31
|
it { is_expected.to be_success }
|
30
32
|
end
|
31
33
|
|
32
|
-
describe
|
34
|
+
describe "#failure?" do
|
33
35
|
subject { success }
|
34
36
|
it { is_expected.not_to be_failure }
|
35
37
|
end
|
36
38
|
|
37
|
-
describe
|
38
|
-
subject { success.or_else { described_class.new(
|
39
|
+
describe "#or_else" do
|
40
|
+
subject { success.or_else { described_class.new("another value") } }
|
39
41
|
it { is_expected.to eq(success) }
|
40
42
|
end
|
41
43
|
|
42
|
-
describe
|
44
|
+
describe "#flatten" do
|
43
45
|
subject { described_class.new(value).flatten }
|
44
46
|
|
45
|
-
context
|
47
|
+
context "value is a Success" do
|
46
48
|
let(:value) { described_class.new(42) }
|
47
49
|
it { is_expected.to eq(described_class.new(42)) }
|
48
50
|
end
|
49
51
|
|
50
|
-
context
|
52
|
+
context "value is a Success of Success" do
|
51
53
|
let(:value) { described_class.new(described_class.new(42)) }
|
52
54
|
it { is_expected.to eq(described_class.new(42)) }
|
53
55
|
end
|
54
56
|
|
55
|
-
context
|
57
|
+
context "value is a Success of Failure" do
|
56
58
|
let(:failure) { Fear::Failure.new(RuntimeError.new) }
|
57
59
|
let(:value) { described_class.new(failure) }
|
58
60
|
it { is_expected.to eq(failure) }
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
describe
|
63
|
-
context
|
64
|
-
subject { success.select { |v| v ==
|
64
|
+
describe "#select" do
|
65
|
+
context "predicate holds for value" do
|
66
|
+
subject { success.select { |v| v == "value" } }
|
65
67
|
it { is_expected.to eq(success) }
|
66
68
|
end
|
67
69
|
|
68
|
-
context
|
69
|
-
subject { proc { success.select { |v| v !=
|
70
|
-
it { is_expected.to raise_error(Fear::NoSuchElementError,
|
70
|
+
context "predicate does not hold for value" do
|
71
|
+
subject { proc { success.select { |v| v != "value" }.get } }
|
72
|
+
it { is_expected.to raise_error(Fear::NoSuchElementError, "Predicate does not hold for `value`") }
|
71
73
|
end
|
72
74
|
|
73
|
-
context
|
74
|
-
subject { proc { success.select { raise
|
75
|
-
it { is_expected.to raise_error(RuntimeError,
|
75
|
+
context "predicate fails with error" do
|
76
|
+
subject { proc { success.select { raise "foo" }.get } }
|
77
|
+
it { is_expected.to raise_error(RuntimeError, "foo") }
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
describe
|
81
|
+
describe "#recover_with" do
|
80
82
|
subject { success.recover_with { |v| Fear.success(v * 2) } }
|
81
83
|
it { is_expected.to eq(success) }
|
82
84
|
end
|
83
85
|
|
84
|
-
describe
|
86
|
+
describe "#recover" do
|
85
87
|
subject { success.recover { |m| m.case { |v| v * 2 } } }
|
86
88
|
it { is_expected.to eq(success) }
|
87
89
|
end
|
88
90
|
|
89
|
-
describe
|
91
|
+
describe "#to_either" do
|
90
92
|
subject { success.to_either }
|
91
|
-
it { is_expected.to eq(Fear.right(
|
93
|
+
it { is_expected.to eq(Fear.right("value")) }
|
92
94
|
end
|
93
95
|
|
94
|
-
describe
|
95
|
-
context
|
96
|
+
describe "#match" do
|
97
|
+
context "matched" do
|
96
98
|
subject do
|
97
99
|
success.match do |m|
|
98
100
|
m.success(->(x) { x.length > 2 }) { |x| x * 2 }
|
99
|
-
m.failure {
|
101
|
+
m.failure { "noop" }
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
|
-
it { is_expected.to eq(
|
105
|
+
it { is_expected.to eq("valuevalue") }
|
104
106
|
end
|
105
107
|
|
106
|
-
context
|
108
|
+
context "nothing matched and no else given" do
|
107
109
|
subject do
|
108
110
|
proc do
|
109
111
|
success.match do |m|
|
110
112
|
m.success(->(x) { x.length < 2 }) { |x| x * 2 }
|
111
|
-
m.failure {
|
113
|
+
m.failure { "noop" }
|
112
114
|
end
|
113
115
|
end
|
114
116
|
end
|
@@ -116,7 +118,7 @@ RSpec.describe Fear::Success do
|
|
116
118
|
it { is_expected.to raise_error(Fear::MatchError) }
|
117
119
|
end
|
118
120
|
|
119
|
-
context
|
121
|
+
context "nothing matched and else given" do
|
120
122
|
subject do
|
121
123
|
success.match do |m|
|
122
124
|
m.failure { |x| x * 2 }
|
@@ -128,31 +130,9 @@ RSpec.describe Fear::Success do
|
|
128
130
|
end
|
129
131
|
end
|
130
132
|
|
131
|
-
describe
|
133
|
+
describe "#to_s" do
|
132
134
|
subject { success.to_s }
|
133
135
|
|
134
136
|
it { is_expected.to eq('#<Fear::Success value="value">') }
|
135
137
|
end
|
136
|
-
|
137
|
-
describe 'pattern matching' do
|
138
|
-
subject { Fear.xcase('Success(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
|
139
|
-
|
140
|
-
context 'success of int' do
|
141
|
-
let(:var) { Fear.success(42) }
|
142
|
-
|
143
|
-
it { is_expected.to eq('matched 42') }
|
144
|
-
end
|
145
|
-
|
146
|
-
context 'success of string' do
|
147
|
-
let(:var) { Fear.success('42') }
|
148
|
-
|
149
|
-
it { is_expected.to eq('nothing') }
|
150
|
-
end
|
151
|
-
|
152
|
-
context 'not success' do
|
153
|
-
let(:var) { '42' }
|
154
|
-
|
155
|
-
it { is_expected.to eq('nothing') }
|
156
|
-
end
|
157
|
-
end
|
158
138
|
end
|
data/spec/fear/try/mixin_spec.rb
CHANGED
@@ -1,17 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Try::Mixin do
|
2
4
|
include Fear::Try::Mixin
|
3
5
|
|
4
|
-
describe
|
5
|
-
context
|
6
|
+
describe "Try()" do
|
7
|
+
context "success" do
|
6
8
|
subject { Try { 4 / 2 } }
|
7
9
|
|
8
10
|
it { is_expected.to eq(Fear::Success.new(2)) }
|
9
11
|
end
|
10
12
|
|
11
|
-
context
|
13
|
+
context "failure" do
|
12
14
|
subject { Try { 4 / 0 } }
|
13
15
|
|
14
16
|
it { is_expected.to be_kind_of(Fear::Failure) }
|
15
17
|
end
|
16
18
|
end
|
19
|
+
|
20
|
+
describe "Success()" do
|
21
|
+
subject { Success(42) }
|
22
|
+
|
23
|
+
it { is_expected.to be_success_of(42) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "Failure()" do
|
27
|
+
subject { Failure(error) }
|
28
|
+
|
29
|
+
let(:error) { StandardError.new }
|
30
|
+
|
31
|
+
it { is_expected.to be_failure_of(error) }
|
32
|
+
end
|
17
33
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::TryApi do
|
4
|
+
describe "Fear.try" do
|
5
|
+
context "when success" do
|
6
|
+
subject { Fear.try { 42 } }
|
7
|
+
|
8
|
+
it { is_expected.to be_success_of(42) }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when failure" do
|
12
|
+
subject { Fear.try { raise RuntimeError } }
|
13
|
+
|
14
|
+
it { is_expected.to be_failure_of(RuntimeError) }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when low level error happened" do
|
18
|
+
subject(:try) { Fear.try { raise Exception } }
|
19
|
+
|
20
|
+
it { expect { try }.to raise_error(Exception) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::TryPatternMatch do
|
2
|
-
context
|
4
|
+
context "Success" do
|
3
5
|
let(:matcher) do
|
4
6
|
described_class.new do |m|
|
5
7
|
m.success(:even?.to_proc) { |x| "#{x} is even" }
|
@@ -8,15 +10,15 @@ RSpec.describe Fear::TryPatternMatch do
|
|
8
10
|
end
|
9
11
|
|
10
12
|
it do
|
11
|
-
expect(matcher.
|
12
|
-
expect(matcher.
|
13
|
+
expect(matcher.(Fear.success(4))).to eq("4 is even")
|
14
|
+
expect(matcher.(Fear.success(3))).to eq("3 is odd")
|
13
15
|
expect do
|
14
|
-
matcher.
|
16
|
+
matcher.(Fear.failure(RuntimeError.new))
|
15
17
|
end.to raise_error(Fear::MatchError)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
context
|
21
|
+
context "Failure" do
|
20
22
|
let(:matcher) do
|
21
23
|
described_class.new do |m|
|
22
24
|
m.failure(RuntimeError) { |x| "#{x} is first" }
|
@@ -25,10 +27,10 @@ RSpec.describe Fear::TryPatternMatch do
|
|
25
27
|
end
|
26
28
|
|
27
29
|
it do
|
28
|
-
expect(matcher.
|
29
|
-
expect(matcher.
|
30
|
+
expect(matcher.(Fear.failure(RuntimeError.new))).to eq("RuntimeError is first")
|
31
|
+
expect(matcher.(Fear.failure(StandardError.new))).to eq("StandardError is second")
|
30
32
|
expect do
|
31
|
-
matcher.
|
33
|
+
matcher.(Fear.success(44))
|
32
34
|
end.to raise_error(Fear::MatchError)
|
33
35
|
end
|
34
36
|
end
|