fear 1.0.0 → 1.1.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/.rubocop.yml +4 -60
- data/.travis.yml +8 -4
- data/CHANGELOG.md +7 -1
- data/Gemfile +5 -3
- data/Gemfile.lock +18 -20
- data/README.md +28 -14
- data/Rakefile +61 -60
- data/examples/pattern_extracting.rb +8 -6
- data/examples/pattern_matching_binary_tree_set.rb +4 -2
- data/examples/pattern_matching_number_in_words.rb +46 -42
- data/fear.gemspec +29 -27
- data/lib/fear.rb +44 -37
- data/lib/fear/await.rb +33 -0
- data/lib/fear/awaitable.rb +28 -0
- data/lib/fear/either.rb +2 -0
- data/lib/fear/either_api.rb +2 -0
- data/lib/fear/either_pattern_match.rb +2 -0
- data/lib/fear/empty_partial_function.rb +3 -1
- data/lib/fear/extractor.rb +30 -28
- data/lib/fear/extractor/anonymous_array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/any_matcher.rb +2 -0
- data/lib/fear/extractor/array_head_matcher.rb +2 -0
- data/lib/fear/extractor/array_matcher.rb +2 -0
- data/lib/fear/extractor/array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/empty_list_matcher.rb +2 -0
- data/lib/fear/extractor/extractor_matcher.rb +5 -3
- data/lib/fear/extractor/grammar.rb +5 -3
- data/lib/fear/extractor/identifier_matcher.rb +2 -0
- data/lib/fear/extractor/matcher.rb +5 -3
- data/lib/fear/extractor/matcher/and.rb +3 -1
- data/lib/fear/extractor/named_array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/pattern.rb +7 -5
- data/lib/fear/extractor/typed_identifier_matcher.rb +2 -0
- data/lib/fear/extractor/value_matcher.rb +2 -0
- data/lib/fear/extractor_api.rb +2 -0
- data/lib/fear/failure.rb +2 -0
- data/lib/fear/failure_pattern_match.rb +2 -0
- data/lib/fear/for.rb +4 -2
- data/lib/fear/for_api.rb +3 -1
- data/lib/fear/future.rb +141 -64
- data/lib/fear/future_api.rb +2 -0
- data/lib/fear/left.rb +3 -1
- data/lib/fear/left_pattern_match.rb +2 -0
- data/lib/fear/none.rb +4 -2
- data/lib/fear/none_pattern_match.rb +2 -0
- data/lib/fear/option.rb +3 -1
- data/lib/fear/option_api.rb +2 -0
- data/lib/fear/option_pattern_match.rb +2 -0
- data/lib/fear/partial_function.rb +10 -8
- 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 +2 -0
- data/lib/fear/partial_function/guard.rb +7 -5
- 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/lifted.rb +2 -0
- data/lib/fear/partial_function/or_else.rb +3 -1
- data/lib/fear/partial_function_class.rb +3 -1
- data/lib/fear/pattern_match.rb +3 -1
- data/lib/fear/pattern_matching_api.rb +3 -1
- data/lib/fear/promise.rb +11 -3
- data/lib/fear/right.rb +3 -1
- data/lib/fear/right_biased.rb +4 -2
- data/lib/fear/right_pattern_match.rb +2 -0
- data/lib/fear/some.rb +2 -0
- data/lib/fear/some_pattern_match.rb +2 -0
- data/lib/fear/struct.rb +235 -0
- data/lib/fear/success.rb +2 -0
- data/lib/fear/success_pattern_match.rb +2 -0
- data/lib/fear/try.rb +2 -0
- data/lib/fear/try_api.rb +2 -0
- data/lib/fear/try_pattern_match.rb +2 -0
- data/lib/fear/unit.rb +6 -2
- data/lib/fear/utils.rb +4 -2
- data/lib/fear/version.rb +4 -1
- 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/extractor/array_matcher_spec.rb +65 -63
- data/spec/fear/extractor/extractor_matcher_spec.rb +64 -62
- data/spec/fear/extractor/grammar_array_spec.rb +5 -3
- data/spec/fear/extractor/identified_matcher_spec.rb +18 -16
- data/spec/fear/extractor/identifier_matcher_spec.rb +26 -24
- data/spec/fear/extractor/pattern_spec.rb +17 -15
- data/spec/fear/extractor/typed_identifier_matcher_spec.rb +23 -21
- data/spec/fear/extractor/value_matcher_number_spec.rb +29 -27
- data/spec/fear/extractor/value_matcher_string_spec.rb +27 -25
- data/spec/fear/extractor/value_matcher_symbol_spec.rb +24 -22
- data/spec/fear/extractor_api_spec.rb +70 -68
- data/spec/fear/extractor_spec.rb +23 -21
- data/spec/fear/failure_spec.rb +59 -57
- data/spec/fear/for_spec.rb +19 -17
- data/spec/fear/future_spec.rb +456 -240
- data/spec/fear/guard_spec.rb +26 -24
- data/spec/fear/left_spec.rb +60 -58
- data/spec/fear/none_spec.rb +36 -34
- data/spec/fear/option/mixin_spec.rb +9 -7
- data/spec/fear/option_pattern_match_spec.rb +10 -8
- 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 +46 -44
- data/spec/fear/pattern_match_spec.rb +31 -29
- data/spec/fear/promise_spec.rb +19 -17
- data/spec/fear/right_biased/left.rb +28 -26
- data/spec/fear/right_biased/right.rb +51 -49
- data/spec/fear/right_spec.rb +58 -56
- data/spec/fear/some_spec.rb +30 -28
- data/spec/fear/success_spec.rb +50 -48
- data/spec/fear/try/mixin_spec.rb +5 -3
- data/spec/fear/try_pattern_match_spec.rb +10 -8
- data/spec/fear/utils_spec.rb +16 -14
- data/spec/spec_helper.rb +7 -5
- data/spec/struct_spec.rb +226 -0
- metadata +18 -13
@@ -1,35 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Option::Mixin do
|
2
4
|
include Fear::Option::Mixin
|
3
5
|
|
4
|
-
describe
|
5
|
-
context
|
6
|
+
describe "Option()" do
|
7
|
+
context "value is nil" do
|
6
8
|
subject { Option(nil) }
|
7
9
|
|
8
10
|
it { is_expected.to eq(Fear.none) }
|
9
11
|
end
|
10
12
|
|
11
|
-
context
|
13
|
+
context "value is not nil" do
|
12
14
|
subject { Option(42) }
|
13
15
|
|
14
16
|
it { is_expected.to eq(Fear.some(42)) }
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
describe
|
19
|
-
context
|
20
|
+
describe "Some()" do
|
21
|
+
context "value is nil" do
|
20
22
|
subject { Some(nil) }
|
21
23
|
|
22
24
|
it { is_expected.to eq(Fear::Some.new(nil)) }
|
23
25
|
end
|
24
26
|
|
25
|
-
context
|
27
|
+
context "value is not nil" do
|
26
28
|
subject { Option(42) }
|
27
29
|
|
28
30
|
it { is_expected.to eq(Fear::Some.new(42)) }
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
describe
|
34
|
+
describe "None()" do
|
33
35
|
subject { None() }
|
34
36
|
|
35
37
|
it { is_expected.to eq(Fear::None) }
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::OptionPatternMatch do
|
2
|
-
context
|
4
|
+
context "Some" do
|
3
5
|
let(:matcher) do
|
4
6
|
described_class.new do |m|
|
5
7
|
m.some(:even?.to_proc) { |x| "#{x} is even" }
|
@@ -8,25 +10,25 @@ RSpec.describe Fear::OptionPatternMatch do
|
|
8
10
|
end
|
9
11
|
|
10
12
|
it do
|
11
|
-
expect(matcher.
|
12
|
-
expect(matcher.
|
13
|
+
expect(matcher.(Fear.some(4))).to eq("4 is even")
|
14
|
+
expect(matcher.(Fear.some(3))).to eq("3 is odd")
|
13
15
|
expect do
|
14
|
-
matcher.
|
16
|
+
matcher.(Fear.none)
|
15
17
|
end.to raise_error(Fear::MatchError)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
context
|
21
|
+
context "None" do
|
20
22
|
let(:matcher) do
|
21
23
|
described_class.new do |m|
|
22
|
-
m.none {
|
24
|
+
m.none { "nil" }
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
it do
|
27
|
-
expect(matcher.
|
29
|
+
expect(matcher.(Fear.none)).to eq("nil")
|
28
30
|
expect do
|
29
|
-
matcher.
|
31
|
+
matcher.(Fear.some(3))
|
30
32
|
end.to raise_error(Fear::MatchError)
|
31
33
|
end
|
32
34
|
end
|
@@ -1,33 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::PartialFunction::EMPTY do
|
2
|
-
describe
|
4
|
+
describe "#defined?" do
|
3
5
|
subject { described_class.defined_at?(42) }
|
4
6
|
|
5
7
|
it { is_expected.to be(false) }
|
6
8
|
end
|
7
9
|
|
8
|
-
describe
|
9
|
-
subject { -> { described_class.
|
10
|
+
describe "#call" do
|
11
|
+
subject { -> { described_class.(42) } }
|
10
12
|
|
11
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
13
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 42") }
|
12
14
|
end
|
13
15
|
|
14
|
-
describe
|
16
|
+
describe "#call_or_else" do
|
15
17
|
subject { described_class.call_or_else(42, &default) }
|
16
18
|
let(:default) { ->(x) { "default: #{x}" } }
|
17
19
|
|
18
|
-
it { is_expected.to eq(
|
20
|
+
it { is_expected.to eq("default: 42") }
|
19
21
|
end
|
20
22
|
|
21
|
-
describe
|
22
|
-
subject { described_class.and_then { |_x|
|
23
|
+
describe "#and_then" do
|
24
|
+
subject { described_class.and_then { |_x| "then" } }
|
23
25
|
|
24
26
|
it { is_expected.to eq(described_class) }
|
25
27
|
end
|
26
28
|
|
27
|
-
describe
|
29
|
+
describe "#or_else" do
|
28
30
|
subject { described_class.or_else(other) }
|
29
31
|
|
30
|
-
let(:other) { Fear.case(proc { true }) {
|
32
|
+
let(:other) { Fear.case(proc { true }) { "other" } }
|
31
33
|
|
32
34
|
it { is_expected.to eq(other) }
|
33
35
|
end
|
@@ -1,60 +1,62 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::PartialFunction, "#and_then" do
|
4
|
+
context "proc" do
|
3
5
|
subject(:pf_and_f) { partial_function.and_then(&function) }
|
4
6
|
|
5
7
|
let(:partial_function) { Fear.case(->(x) { x.even? }) { |x| "pf: #{x}" } }
|
6
8
|
let(:function) { ->(x) { "f: #{x}" } }
|
7
9
|
|
8
|
-
describe
|
9
|
-
context
|
10
|
+
describe "#defined_at?" do
|
11
|
+
context "defined" do
|
10
12
|
subject { pf_and_f.defined_at?(4) }
|
11
13
|
|
12
14
|
it { is_expected.to eq(true) }
|
13
15
|
end
|
14
16
|
|
15
|
-
context
|
17
|
+
context "not defined" do
|
16
18
|
subject { pf_and_f.defined_at?(3) }
|
17
19
|
|
18
20
|
it { is_expected.to eq(false) }
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
describe
|
23
|
-
context
|
24
|
-
subject { pf_and_f.
|
24
|
+
describe "#call" do
|
25
|
+
context "defined" do
|
26
|
+
subject { pf_and_f.(4) }
|
25
27
|
|
26
|
-
it { is_expected.to eq(
|
28
|
+
it { is_expected.to eq("f: pf: 4") }
|
27
29
|
end
|
28
30
|
|
29
|
-
context
|
30
|
-
subject { -> { pf_and_f.
|
31
|
+
context "not defined" do
|
32
|
+
subject { -> { pf_and_f.(3) } }
|
31
33
|
|
32
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
34
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 3") }
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
|
-
describe
|
38
|
+
describe "#call_or_else" do
|
37
39
|
let(:fallback) { ->(x) { "fallback: #{x}" } }
|
38
40
|
|
39
|
-
context
|
41
|
+
context "defined" do
|
40
42
|
subject { pf_and_f.call_or_else(4, &fallback) }
|
41
43
|
|
42
|
-
it { is_expected.to eq(
|
44
|
+
it { is_expected.to eq("f: pf: 4") }
|
43
45
|
end
|
44
46
|
|
45
|
-
context
|
47
|
+
context "not defined" do
|
46
48
|
subject { pf_and_f.call_or_else(3, &fallback) }
|
47
49
|
|
48
|
-
it { is_expected.to eq(
|
50
|
+
it { is_expected.to eq("fallback: 3") }
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
context
|
55
|
+
context "partial function" do
|
54
56
|
subject(:first_and_then_second) { first.and_then(second) }
|
55
57
|
|
56
|
-
describe
|
57
|
-
context
|
58
|
+
describe "#defined_at?" do
|
59
|
+
context "first defined, second defined on result of first" do
|
58
60
|
subject { first_and_then_second.defined_at?(6) }
|
59
61
|
|
60
62
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
@@ -63,7 +65,7 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
|
|
63
65
|
it { is_expected.to eq(true) }
|
64
66
|
end
|
65
67
|
|
66
|
-
context
|
68
|
+
context "first defined, second not defined on result of first" do
|
67
69
|
subject { first_and_then_second.defined_at?(4) }
|
68
70
|
|
69
71
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
@@ -72,7 +74,7 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
|
|
72
74
|
it { is_expected.to eq(false) }
|
73
75
|
end
|
74
76
|
|
75
|
-
context
|
77
|
+
context "first not defined" do
|
76
78
|
subject { first_and_then_second.defined_at?(3) }
|
77
79
|
|
78
80
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
|
@@ -82,9 +84,9 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
|
|
82
84
|
end
|
83
85
|
end
|
84
86
|
|
85
|
-
describe
|
86
|
-
context
|
87
|
-
subject { first_and_then_second.
|
87
|
+
describe "#call" do
|
88
|
+
context "first defined, second defined on result of first" do
|
89
|
+
subject { first_and_then_second.(6) }
|
88
90
|
|
89
91
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
90
92
|
let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
|
@@ -92,29 +94,29 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
|
|
92
94
|
it { is_expected.to eq(1) }
|
93
95
|
end
|
94
96
|
|
95
|
-
context
|
96
|
-
subject { -> { first_and_then_second.
|
97
|
+
context "first defined, second not defined on result of first" do
|
98
|
+
subject { -> { first_and_then_second.(4) } }
|
97
99
|
|
98
100
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
99
101
|
let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
|
100
102
|
|
101
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
103
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 2") }
|
102
104
|
end
|
103
105
|
|
104
|
-
context
|
105
|
-
subject { -> { first_and_then_second.
|
106
|
+
context "first not defined" do
|
107
|
+
subject { -> { first_and_then_second.(3) } }
|
106
108
|
|
107
109
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
|
108
110
|
let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| "second: #{x}" } }
|
109
111
|
|
110
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
112
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 3") }
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
114
|
-
describe
|
116
|
+
describe "#call_or_else" do
|
115
117
|
let(:fallback) { ->(x) { "fallback: #{x}" } }
|
116
118
|
|
117
|
-
context
|
119
|
+
context "first defined, second defined on result of first" do
|
118
120
|
subject { first_and_then_second.call_or_else(6, &fallback) }
|
119
121
|
|
120
122
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
@@ -123,22 +125,22 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
|
|
123
125
|
it { is_expected.to eq(1) }
|
124
126
|
end
|
125
127
|
|
126
|
-
context
|
128
|
+
context "first defined, second not defined on result of first" do
|
127
129
|
subject { first_and_then_second.call_or_else(4, &fallback) }
|
128
130
|
|
129
131
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
|
130
132
|
let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
|
131
133
|
|
132
|
-
it { is_expected.to eq(
|
134
|
+
it { is_expected.to eq("fallback: 4") }
|
133
135
|
end
|
134
136
|
|
135
|
-
context
|
137
|
+
context "first not defined" do
|
136
138
|
subject { first_and_then_second.call_or_else(3, &fallback) }
|
137
139
|
|
138
140
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
|
139
141
|
let(:second) { Fear.case { |x| "second: #{x}" } }
|
140
142
|
|
141
|
-
it { is_expected.to eq(
|
143
|
+
it { is_expected.to eq("fallback: 3") }
|
142
144
|
end
|
143
145
|
end
|
144
146
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file contains tests from
|
2
4
|
# https://github.com/scala/scala/blob/2.13.x/test/junit/scala/PartialFunctionCompositionTest.scala
|
3
5
|
RSpec.describe Fear::PartialFunction do
|
4
|
-
let(:fallback_fun) { ->(_) {
|
6
|
+
let(:fallback_fun) { ->(_) { "fallback" } }
|
5
7
|
let(:pass_all) { Fear.case(proc { true }) { |x| x } }
|
6
8
|
let(:pass_short) { Fear.case(->(x) { x.length < 5 }) { |x| x } }
|
7
|
-
let(:pass_pass) { Fear.case(->(x) { x.include?(
|
9
|
+
let(:pass_pass) { Fear.case(->(x) { x.include?("pass") }) { |x| x } }
|
8
10
|
|
9
11
|
let(:all_and_then_short) { pass_all & pass_short }
|
10
12
|
let(:short_and_then_all) { pass_short & pass_all }
|
@@ -13,68 +15,68 @@ RSpec.describe Fear::PartialFunction do
|
|
13
15
|
let(:pass_and_then_short) { pass_pass & pass_short }
|
14
16
|
let(:short_and_then_pass) { pass_short & pass_pass }
|
15
17
|
|
16
|
-
it
|
17
|
-
expect(all_and_then_short.call_or_else(
|
18
|
-
expect(short_and_then_all.call_or_else(
|
19
|
-
expect(all_and_then_short.defined_at?(
|
20
|
-
expect(short_and_then_all.defined_at?(
|
18
|
+
it "#and_then" do
|
19
|
+
expect(all_and_then_short.call_or_else("pass", &fallback_fun)).to eq("pass")
|
20
|
+
expect(short_and_then_all.call_or_else("pass", &fallback_fun)).to eq("pass")
|
21
|
+
expect(all_and_then_short.defined_at?("pass")).to eq(true)
|
22
|
+
expect(short_and_then_all.defined_at?("pass")).to eq(true)
|
21
23
|
|
22
|
-
expect(all_and_then_pass.call_or_else(
|
23
|
-
expect(pass_and_then_all.call_or_else(
|
24
|
-
expect(all_and_then_pass.defined_at?(
|
25
|
-
expect(pass_and_then_all.defined_at?(
|
24
|
+
expect(all_and_then_pass.call_or_else("pass", &fallback_fun)).to eq("pass")
|
25
|
+
expect(pass_and_then_all.call_or_else("pass", &fallback_fun)).to eq("pass")
|
26
|
+
expect(all_and_then_pass.defined_at?("pass")).to eq(true)
|
27
|
+
expect(pass_and_then_all.defined_at?("pass")).to eq(true)
|
26
28
|
|
27
|
-
expect(all_and_then_pass.call_or_else(
|
28
|
-
expect(pass_and_then_all.call_or_else(
|
29
|
-
expect(all_and_then_pass.defined_at?(
|
30
|
-
expect(pass_and_then_all.defined_at?(
|
29
|
+
expect(all_and_then_pass.call_or_else("longpass", &fallback_fun)).to eq("longpass")
|
30
|
+
expect(pass_and_then_all.call_or_else("longpass", &fallback_fun)).to eq("longpass")
|
31
|
+
expect(all_and_then_pass.defined_at?("longpass")).to eq(true)
|
32
|
+
expect(pass_and_then_all.defined_at?("longpass")).to eq(true)
|
31
33
|
|
32
|
-
expect(all_and_then_short.call_or_else(
|
33
|
-
expect(short_and_then_all.call_or_else(
|
34
|
-
expect(all_and_then_short.defined_at?(
|
35
|
-
expect(short_and_then_all.defined_at?(
|
34
|
+
expect(all_and_then_short.call_or_else("longpass", &fallback_fun)).to eq("fallback")
|
35
|
+
expect(short_and_then_all.call_or_else("longpass", &fallback_fun)).to eq("fallback")
|
36
|
+
expect(all_and_then_short.defined_at?("longpass")).to eq(false)
|
37
|
+
expect(short_and_then_all.defined_at?("longpass")).to eq(false)
|
36
38
|
|
37
|
-
expect(all_and_then_pass.call_or_else(
|
38
|
-
expect(pass_and_then_all.call_or_else(
|
39
|
-
expect(all_and_then_pass.defined_at?(
|
40
|
-
expect(pass_and_then_all.defined_at?(
|
39
|
+
expect(all_and_then_pass.call_or_else("longstr", &fallback_fun)).to eq("fallback")
|
40
|
+
expect(pass_and_then_all.call_or_else("longstr", &fallback_fun)).to eq("fallback")
|
41
|
+
expect(all_and_then_pass.defined_at?("longstr")).to eq(false)
|
42
|
+
expect(pass_and_then_all.defined_at?("longstr")).to eq(false)
|
41
43
|
|
42
|
-
expect(pass_and_then_short.call_or_else(
|
43
|
-
expect(short_and_then_pass.call_or_else(
|
44
|
-
expect(pass_and_then_short.defined_at?(
|
45
|
-
expect(short_and_then_pass.defined_at?(
|
44
|
+
expect(pass_and_then_short.call_or_else("pass", &fallback_fun)).to eq("pass")
|
45
|
+
expect(short_and_then_pass.call_or_else("pass", &fallback_fun)).to eq("pass")
|
46
|
+
expect(pass_and_then_short.defined_at?("pass")).to eq(true)
|
47
|
+
expect(short_and_then_pass.defined_at?("pass")).to eq(true)
|
46
48
|
|
47
|
-
expect(pass_and_then_short.call_or_else(
|
48
|
-
expect(short_and_then_pass.call_or_else(
|
49
|
-
expect(pass_and_then_short.defined_at?(
|
50
|
-
expect(short_and_then_pass.defined_at?(
|
49
|
+
expect(pass_and_then_short.call_or_else("longpass", &fallback_fun)).to eq("fallback")
|
50
|
+
expect(short_and_then_pass.call_or_else("longpass", &fallback_fun)).to eq("fallback")
|
51
|
+
expect(pass_and_then_short.defined_at?("longpass")).to eq(false)
|
52
|
+
expect(short_and_then_pass.defined_at?("longpass")).to eq(false)
|
51
53
|
|
52
|
-
expect(short_and_then_pass.call_or_else(
|
53
|
-
expect(pass_and_then_short.call_or_else(
|
54
|
-
expect(short_and_then_pass.defined_at?(
|
55
|
-
expect(pass_and_then_short.defined_at?(
|
54
|
+
expect(short_and_then_pass.call_or_else("longstr", &fallback_fun)).to eq("fallback")
|
55
|
+
expect(pass_and_then_short.call_or_else("longstr", &fallback_fun)).to eq("fallback")
|
56
|
+
expect(short_and_then_pass.defined_at?("longstr")).to eq(false)
|
57
|
+
expect(pass_and_then_short.defined_at?("longstr")).to eq(false)
|
56
58
|
end
|
57
59
|
|
58
|
-
it
|
59
|
-
first_branch = Fear.case(Integer, &:itself).and_then(Fear.case(1) {
|
60
|
+
it "two branches" do
|
61
|
+
first_branch = Fear.case(Integer, &:itself).and_then(Fear.case(1) { "one" })
|
60
62
|
second_branch = Fear.case(String, &:itself).and_then(
|
61
|
-
(Fear.case(
|
63
|
+
(Fear.case("zero") { 0 }).or_else(Fear.case("one") { 1 }),
|
62
64
|
)
|
63
65
|
|
64
66
|
full = first_branch.or_else(second_branch)
|
65
|
-
expect(full.
|
66
|
-
expect(full.
|
67
|
-
expect(full.
|
67
|
+
expect(full.(1)).to eq("one")
|
68
|
+
expect(full.("zero")).to eq(0)
|
69
|
+
expect(full.("one")).to eq(1)
|
68
70
|
end
|
69
71
|
|
70
|
-
it
|
72
|
+
it "or else anh then" do
|
71
73
|
f1 = Fear.case(->(x) { x < 5 }) { 1 }
|
72
74
|
f2 = Fear.case(->(x) { x > 10 }) { 10 }
|
73
75
|
f3 = Fear.case { |x| x * 2 }
|
74
76
|
|
75
77
|
f5 = f1.and_then(f3).or_else(f2)
|
76
78
|
|
77
|
-
expect(f5.
|
78
|
-
expect(f5.
|
79
|
+
expect(f5.(11)).to eq(10)
|
80
|
+
expect(f5.(3)).to eq(2)
|
79
81
|
end
|
80
82
|
end
|
@@ -1,273 +1,275 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::PartialFunction, "#or_else" do
|
2
4
|
subject(:first_or_else_second) { first.or_else(second) }
|
3
5
|
|
4
6
|
let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
|
5
7
|
let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| "second: #{x}" } }
|
6
8
|
|
7
|
-
describe
|
8
|
-
context
|
9
|
+
describe "#defined_at?" do
|
10
|
+
context "first defined, second not" do
|
9
11
|
subject { first_or_else_second.defined_at?(4) }
|
10
12
|
|
11
13
|
it { is_expected.to eq(true) }
|
12
14
|
end
|
13
15
|
|
14
|
-
context
|
16
|
+
context "first not defined, second defined" do
|
15
17
|
subject { first_or_else_second.defined_at?(9) }
|
16
18
|
|
17
19
|
it { is_expected.to eq(true) }
|
18
20
|
end
|
19
21
|
|
20
|
-
context
|
22
|
+
context "first not defined, second not defined" do
|
21
23
|
subject { first_or_else_second.defined_at?(5) }
|
22
24
|
|
23
25
|
it { is_expected.to eq(false) }
|
24
26
|
end
|
25
27
|
|
26
|
-
context
|
28
|
+
context "first and second defined" do
|
27
29
|
subject { first_or_else_second.defined_at?(6) }
|
28
30
|
|
29
31
|
it { is_expected.to eq(true) }
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
describe
|
34
|
-
context
|
35
|
-
subject { first_or_else_second.
|
35
|
+
describe "#call" do
|
36
|
+
context "first defined, second not" do
|
37
|
+
subject { first_or_else_second.(4) }
|
36
38
|
|
37
|
-
it { is_expected.to eq(
|
39
|
+
it { is_expected.to eq("first: 4") }
|
38
40
|
end
|
39
41
|
|
40
|
-
context
|
41
|
-
subject { first_or_else_second.
|
42
|
+
context "first not defined, second defined" do
|
43
|
+
subject { first_or_else_second.(9) }
|
42
44
|
|
43
|
-
it { is_expected.to eq(
|
45
|
+
it { is_expected.to eq("second: 9") }
|
44
46
|
end
|
45
47
|
|
46
|
-
context
|
47
|
-
subject { -> { first_or_else_second.
|
48
|
+
context "first not defined, second not defined" do
|
49
|
+
subject { -> { first_or_else_second.(5) } }
|
48
50
|
|
49
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
51
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 5") }
|
50
52
|
end
|
51
53
|
|
52
|
-
context
|
53
|
-
subject { first_or_else_second.
|
54
|
+
context "first and second defined" do
|
55
|
+
subject { first_or_else_second.(6) }
|
54
56
|
|
55
|
-
it { is_expected.to eq(
|
57
|
+
it { is_expected.to eq("first: 6") }
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
|
-
describe
|
61
|
+
describe "#call_or_else" do
|
60
62
|
let(:fallback) { ->(x) { "fallback: #{x}" } }
|
61
63
|
|
62
|
-
context
|
64
|
+
context "first defined, second not" do
|
63
65
|
subject { first_or_else_second.call_or_else(4, &fallback) }
|
64
66
|
|
65
|
-
it { is_expected.to eq(
|
67
|
+
it { is_expected.to eq("first: 4") }
|
66
68
|
end
|
67
69
|
|
68
|
-
context
|
70
|
+
context "first not defined, second defined" do
|
69
71
|
subject { first_or_else_second.call_or_else(9, &fallback) }
|
70
72
|
|
71
|
-
it { is_expected.to eq(
|
73
|
+
it { is_expected.to eq("second: 9") }
|
72
74
|
end
|
73
75
|
|
74
|
-
context
|
76
|
+
context "first not defined, second not defined" do
|
75
77
|
subject { first_or_else_second.call_or_else(5, &fallback) }
|
76
78
|
|
77
|
-
it { is_expected.to eq(
|
79
|
+
it { is_expected.to eq("fallback: 5") }
|
78
80
|
end
|
79
81
|
|
80
|
-
context
|
82
|
+
context "first and second defined" do
|
81
83
|
subject { first_or_else_second.call_or_else(6, &fallback) }
|
82
84
|
|
83
|
-
it { is_expected.to eq(
|
85
|
+
it { is_expected.to eq("first: 6") }
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
87
|
-
describe
|
89
|
+
describe "#or_else" do
|
88
90
|
let(:first_or_else_second_or_else_third) { first_or_else_second.or_else(third) }
|
89
91
|
let(:third) { Fear.case(->(x) { x % 7 == 0 }) { |x| "third: #{x}" } }
|
90
92
|
|
91
|
-
describe
|
92
|
-
context
|
93
|
+
describe "#defined_at?" do
|
94
|
+
context "first defined, second not" do
|
93
95
|
subject { first_or_else_second_or_else_third.defined_at?(4) }
|
94
96
|
|
95
97
|
it { is_expected.to eq(true) }
|
96
98
|
end
|
97
99
|
|
98
|
-
context
|
100
|
+
context "first not defined, second defined" do
|
99
101
|
subject { first_or_else_second_or_else_third.defined_at?(9) }
|
100
102
|
|
101
103
|
it { is_expected.to eq(true) }
|
102
104
|
end
|
103
105
|
|
104
|
-
context
|
106
|
+
context "first not defined, second not defined, third defined" do
|
105
107
|
subject { first_or_else_second_or_else_third.defined_at?(7) }
|
106
108
|
|
107
109
|
it { is_expected.to eq(true) }
|
108
110
|
end
|
109
111
|
|
110
|
-
context
|
112
|
+
context "first not defined, second not defined, third not defined" do
|
111
113
|
subject { first_or_else_second_or_else_third.defined_at?(1) }
|
112
114
|
|
113
115
|
it { is_expected.to eq(false) }
|
114
116
|
end
|
115
117
|
|
116
|
-
context
|
118
|
+
context "first, second and third defined" do
|
117
119
|
subject { first_or_else_second.defined_at?(42) }
|
118
120
|
|
119
121
|
it { is_expected.to eq(true) }
|
120
122
|
end
|
121
123
|
end
|
122
124
|
|
123
|
-
describe
|
124
|
-
context
|
125
|
-
subject { first_or_else_second_or_else_third.
|
125
|
+
describe "#call" do
|
126
|
+
context "first defined, second not" do
|
127
|
+
subject { first_or_else_second_or_else_third.(4) }
|
126
128
|
|
127
|
-
it { is_expected.to eq(
|
129
|
+
it { is_expected.to eq("first: 4") }
|
128
130
|
end
|
129
131
|
|
130
|
-
context
|
131
|
-
subject { first_or_else_second_or_else_third.
|
132
|
+
context "first not defined, second defined" do
|
133
|
+
subject { first_or_else_second_or_else_third.(9) }
|
132
134
|
|
133
|
-
it { is_expected.to eq(
|
135
|
+
it { is_expected.to eq("second: 9") }
|
134
136
|
end
|
135
137
|
|
136
|
-
context
|
137
|
-
subject { first_or_else_second_or_else_third.
|
138
|
+
context "first not defined, second not defined, third defined" do
|
139
|
+
subject { first_or_else_second_or_else_third.(7) }
|
138
140
|
|
139
|
-
it { is_expected.to eq(
|
141
|
+
it { is_expected.to eq("third: 7") }
|
140
142
|
end
|
141
143
|
|
142
|
-
context
|
143
|
-
subject { -> { first_or_else_second_or_else_third.
|
144
|
+
context "first not defined, second not defined, third not defined" do
|
145
|
+
subject { -> { first_or_else_second_or_else_third.(1) } }
|
144
146
|
|
145
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
147
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 1") }
|
146
148
|
end
|
147
149
|
|
148
|
-
context
|
149
|
-
subject { first_or_else_second.
|
150
|
+
context "first, second and third defined" do
|
151
|
+
subject { first_or_else_second.(42) }
|
150
152
|
|
151
|
-
it { is_expected.to eq(
|
153
|
+
it { is_expected.to eq("first: 42") }
|
152
154
|
end
|
153
155
|
end
|
154
156
|
|
155
|
-
describe
|
157
|
+
describe "#call_or_else" do
|
156
158
|
let(:fallback) { ->(x) { "fallback: #{x}" } }
|
157
159
|
|
158
|
-
context
|
160
|
+
context "first defined, second not" do
|
159
161
|
subject { first_or_else_second_or_else_third.call_or_else(4, &fallback) }
|
160
162
|
|
161
|
-
it { is_expected.to eq(
|
163
|
+
it { is_expected.to eq("first: 4") }
|
162
164
|
end
|
163
165
|
|
164
|
-
context
|
166
|
+
context "first not defined, second defined" do
|
165
167
|
subject { first_or_else_second_or_else_third.call_or_else(9, &fallback) }
|
166
168
|
|
167
|
-
it { is_expected.to eq(
|
169
|
+
it { is_expected.to eq("second: 9") }
|
168
170
|
end
|
169
171
|
|
170
|
-
context
|
172
|
+
context "first not defined, second not defined, third defined" do
|
171
173
|
subject { first_or_else_second_or_else_third.call_or_else(7, &fallback) }
|
172
174
|
|
173
|
-
it { is_expected.to eq(
|
175
|
+
it { is_expected.to eq("third: 7") }
|
174
176
|
end
|
175
177
|
|
176
|
-
context
|
178
|
+
context "first not defined, second not defined, third not defined" do
|
177
179
|
subject { first_or_else_second_or_else_third.call_or_else(1, &fallback) }
|
178
180
|
|
179
|
-
it { is_expected.to eq(
|
181
|
+
it { is_expected.to eq("fallback: 1") }
|
180
182
|
end
|
181
183
|
|
182
|
-
context
|
184
|
+
context "first, second and third defined" do
|
183
185
|
subject { first_or_else_second_or_else_third.call_or_else(42, &fallback) }
|
184
186
|
|
185
|
-
it { is_expected.to eq(
|
187
|
+
it { is_expected.to eq("first: 42") }
|
186
188
|
end
|
187
189
|
end
|
188
190
|
end
|
189
191
|
|
190
|
-
describe
|
192
|
+
describe "#and_then" do
|
191
193
|
let(:first_or_else_second_and_then_function) { first_or_else_second.and_then(&function) }
|
192
194
|
let(:function) { ->(x) { "f: #{x}" } }
|
193
195
|
|
194
|
-
describe
|
195
|
-
context
|
196
|
+
describe "#defined_at?" do
|
197
|
+
context "first defined, second not" do
|
196
198
|
subject { first_or_else_second_and_then_function.defined_at?(2) }
|
197
199
|
|
198
200
|
it { is_expected.to eq(true) }
|
199
201
|
end
|
200
202
|
|
201
|
-
context
|
203
|
+
context "first not defined, second defined" do
|
202
204
|
subject { first_or_else_second_and_then_function.defined_at?(3) }
|
203
205
|
|
204
206
|
it { is_expected.to eq(true) }
|
205
207
|
end
|
206
208
|
|
207
|
-
context
|
209
|
+
context "first not defined, second not defined" do
|
208
210
|
subject { first_or_else_second_and_then_function.defined_at?(5) }
|
209
211
|
|
210
212
|
it { is_expected.to eq(false) }
|
211
213
|
end
|
212
214
|
|
213
|
-
context
|
215
|
+
context "first defined, second defined" do
|
214
216
|
subject { first_or_else_second_and_then_function.defined_at?(6) }
|
215
217
|
|
216
218
|
it { is_expected.to eq(true) }
|
217
219
|
end
|
218
220
|
end
|
219
221
|
|
220
|
-
describe
|
221
|
-
context
|
222
|
-
subject { first_or_else_second_and_then_function.
|
222
|
+
describe "#call" do
|
223
|
+
context "first defined, second not" do
|
224
|
+
subject { first_or_else_second_and_then_function.(2) }
|
223
225
|
|
224
|
-
it { is_expected.to eq(
|
226
|
+
it { is_expected.to eq("f: first: 2") }
|
225
227
|
end
|
226
228
|
|
227
|
-
context
|
228
|
-
subject { first_or_else_second_and_then_function.
|
229
|
+
context "first not defined, second defined" do
|
230
|
+
subject { first_or_else_second_and_then_function.(3) }
|
229
231
|
|
230
|
-
it { is_expected.to eq(
|
232
|
+
it { is_expected.to eq("f: second: 3") }
|
231
233
|
end
|
232
234
|
|
233
|
-
context
|
234
|
-
subject { -> { first_or_else_second_and_then_function.
|
235
|
+
context "first not defined, second not defined" do
|
236
|
+
subject { -> { first_or_else_second_and_then_function.(5) } }
|
235
237
|
|
236
|
-
it { is_expected.to raise_error(Fear::MatchError,
|
238
|
+
it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 5") }
|
237
239
|
end
|
238
240
|
|
239
|
-
context
|
240
|
-
subject { first_or_else_second_and_then_function.
|
241
|
+
context "first defined, second defined" do
|
242
|
+
subject { first_or_else_second_and_then_function.(6) }
|
241
243
|
|
242
|
-
it { is_expected.to eq(
|
244
|
+
it { is_expected.to eq("f: first: 6") }
|
243
245
|
end
|
244
246
|
end
|
245
247
|
|
246
|
-
describe
|
248
|
+
describe "#call_or_else" do
|
247
249
|
let(:fallback) { ->(x) { "fallback: #{x}" } }
|
248
250
|
|
249
|
-
context
|
251
|
+
context "first defined, second not" do
|
250
252
|
subject { first_or_else_second_and_then_function.call_or_else(2, &fallback) }
|
251
253
|
|
252
|
-
it { is_expected.to eq(
|
254
|
+
it { is_expected.to eq("f: first: 2") }
|
253
255
|
end
|
254
256
|
|
255
|
-
context
|
257
|
+
context "first not defined, second defined" do
|
256
258
|
subject { first_or_else_second_and_then_function.call_or_else(3, &fallback) }
|
257
259
|
|
258
|
-
it { is_expected.to eq(
|
260
|
+
it { is_expected.to eq("f: second: 3") }
|
259
261
|
end
|
260
262
|
|
261
|
-
context
|
263
|
+
context "first not defined, second not defined" do
|
262
264
|
subject { first_or_else_second_and_then_function.call_or_else(5, &fallback) }
|
263
265
|
|
264
|
-
it { is_expected.to eq(
|
266
|
+
it { is_expected.to eq("fallback: 5") }
|
265
267
|
end
|
266
268
|
|
267
|
-
context
|
269
|
+
context "first defined, second defined" do
|
268
270
|
subject { first_or_else_second_and_then_function.call_or_else(6, &fallback) }
|
269
271
|
|
270
|
-
it { is_expected.to eq(
|
272
|
+
it { is_expected.to eq("f: first: 6") }
|
271
273
|
end
|
272
274
|
end
|
273
275
|
end
|