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
@@ -1,39 +1,7 @@
|
|
1
|
-
|
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
|
1
|
+
# frozen_string_literal: true
|
22
2
|
|
23
|
-
|
24
|
-
|
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
|
35
|
-
|
36
|
-
context 'else at the end' do
|
3
|
+
RSpec.describe Fear::PatternMatch do
|
4
|
+
context "else at the end" do
|
37
5
|
let(:matcher) do
|
38
6
|
described_class.new do |m|
|
39
7
|
m.case(Integer) { |x| "#{x} is int" }
|
@@ -42,27 +10,27 @@ RSpec.describe Fear::PatternMatch do
|
|
42
10
|
end
|
43
11
|
end
|
44
12
|
|
45
|
-
context
|
46
|
-
subject { matcher.
|
13
|
+
context "Integer" do
|
14
|
+
subject { matcher.(4) }
|
47
15
|
|
48
|
-
it { is_expected.to eq(
|
16
|
+
it { is_expected.to eq("4 is int") }
|
49
17
|
end
|
50
18
|
|
51
|
-
context
|
52
|
-
subject { matcher.
|
19
|
+
context "String" do
|
20
|
+
subject { matcher.("4") }
|
53
21
|
|
54
|
-
it { is_expected.to eq(
|
22
|
+
it { is_expected.to eq("4 is str") }
|
55
23
|
end
|
56
24
|
|
57
|
-
context
|
58
|
-
subject { matcher.
|
25
|
+
context "Symbol" do
|
26
|
+
subject { matcher.(:a) }
|
59
27
|
|
60
|
-
it { is_expected.to eq(
|
28
|
+
it { is_expected.to eq("a is something else") }
|
61
29
|
end
|
62
30
|
end
|
63
31
|
|
64
|
-
context
|
65
|
-
subject { matcher.
|
32
|
+
context "else before other branches" do
|
33
|
+
subject { matcher.(4) }
|
66
34
|
|
67
35
|
let(:matcher) do
|
68
36
|
described_class.new do |m|
|
@@ -71,11 +39,11 @@ RSpec.describe Fear::PatternMatch do
|
|
71
39
|
end
|
72
40
|
end
|
73
41
|
|
74
|
-
it { is_expected.to eq(
|
42
|
+
it { is_expected.to eq("4 is something else") }
|
75
43
|
end
|
76
44
|
|
77
|
-
context
|
78
|
-
subject { matcher.
|
45
|
+
context "several else branches" do
|
46
|
+
subject { matcher.(4) }
|
79
47
|
|
80
48
|
let(:matcher) do
|
81
49
|
described_class.new do |m|
|
@@ -84,8 +52,8 @@ RSpec.describe Fear::PatternMatch do
|
|
84
52
|
end
|
85
53
|
end
|
86
54
|
|
87
|
-
it
|
88
|
-
is_expected.to eq(
|
55
|
+
it "first one wins" do
|
56
|
+
is_expected.to eq("4 else 1")
|
89
57
|
end
|
90
58
|
end
|
91
59
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::PatternMatchingApi do
|
4
|
+
describe "Fear.match" do
|
5
|
+
subject do
|
6
|
+
Fear.match(value) do |m|
|
7
|
+
m.case(Integer, :even?.to_proc) { |x| "#{x} is even" }
|
8
|
+
m.case(Integer, :odd?.to_proc) { |x| "#{x} is odd" }
|
9
|
+
m.else { |x| "#{x} is not a number" }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when one branch matches" do
|
14
|
+
let(:value) { 42 }
|
15
|
+
|
16
|
+
it { is_expected.to eq("42 is even") }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when another branch matches" do
|
20
|
+
let(:value) { 21 }
|
21
|
+
|
22
|
+
it { is_expected.to eq("21 is odd") }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when else matches" do
|
26
|
+
let(:value) { "foo" }
|
27
|
+
|
28
|
+
it { is_expected.to eq("foo is not a number") }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/fear/promise_spec.rb
CHANGED
@@ -1,93 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe Fear::Promise do
|
2
4
|
let(:value) { 42 }
|
3
|
-
let(:error) { StandardError.new(
|
5
|
+
let(:error) { StandardError.new("something went wrong") }
|
4
6
|
|
5
7
|
def not_completed_promise
|
6
8
|
Fear::Promise.new(executor: Concurrent::ImmediateExecutor.new)
|
7
9
|
end
|
8
10
|
|
9
|
-
context
|
10
|
-
it
|
11
|
+
context "not completed" do
|
12
|
+
it "#success! returns self" do
|
11
13
|
completed_promise = not_completed_promise.success!(value)
|
12
14
|
|
13
15
|
expect(completed_promise).to eq completed_promise
|
14
16
|
end
|
15
17
|
|
16
|
-
it
|
18
|
+
it "#success returns true" do
|
17
19
|
completed = not_completed_promise.success(value)
|
18
20
|
|
19
21
|
expect(completed).to be true
|
20
22
|
end
|
21
23
|
|
22
|
-
it
|
24
|
+
it "#failure! returns self" do
|
23
25
|
completed_promise = not_completed_promise.failure!(error)
|
24
26
|
|
25
27
|
expect(completed_promise).to eq completed_promise
|
26
28
|
end
|
27
29
|
|
28
|
-
it
|
30
|
+
it "#failure returns true" do
|
29
31
|
completed = not_completed_promise.failure(error)
|
30
32
|
|
31
33
|
expect(completed).to be true
|
32
34
|
end
|
33
35
|
|
34
|
-
it
|
36
|
+
it "#completed? returns true" do
|
35
37
|
expect(not_completed_promise).not_to be_completed
|
36
38
|
end
|
37
39
|
|
38
|
-
it
|
40
|
+
it "#future returns not completed future" do
|
39
41
|
future = not_completed_promise.to_future
|
40
42
|
|
41
43
|
expect(future).not_to be_completed
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
context
|
47
|
+
context "completed" do
|
46
48
|
def completed_promise
|
47
49
|
not_completed_promise.success!(value)
|
48
50
|
end
|
49
51
|
|
50
|
-
it
|
52
|
+
it "#success! fails with exception" do
|
51
53
|
expect do
|
52
54
|
completed_promise.success!(value)
|
53
55
|
end.to raise_exception(Fear::IllegalStateException)
|
54
56
|
end
|
55
57
|
|
56
|
-
it
|
58
|
+
it "#success returns false" do
|
57
59
|
completed = completed_promise.success(value)
|
58
60
|
|
59
61
|
expect(completed).to be false
|
60
62
|
end
|
61
63
|
|
62
|
-
it
|
64
|
+
it "#failure! fails with exception" do
|
63
65
|
expect do
|
64
66
|
completed_promise.failure!(error)
|
65
67
|
end.to raise_exception(Fear::IllegalStateException)
|
66
68
|
end
|
67
69
|
|
68
|
-
it
|
70
|
+
it "#failure returns false" do
|
69
71
|
completed = completed_promise.success(error)
|
70
72
|
|
71
73
|
expect(completed).to be false
|
72
74
|
end
|
73
75
|
|
74
|
-
it
|
76
|
+
it "#completed? returns true" do
|
75
77
|
expect(completed_promise).to be_completed
|
76
78
|
end
|
77
79
|
|
78
|
-
context
|
79
|
-
subject(:future)
|
80
|
-
completed_promise.to_future
|
81
|
-
end
|
80
|
+
context "#future" do
|
81
|
+
subject(:future) { Fear::Await.ready(promise.to_future, 0.01) }
|
82
82
|
|
83
|
-
|
83
|
+
let(:promise) { Fear::Promise.new.success!(value) }
|
84
|
+
|
85
|
+
it "is completed" do
|
84
86
|
expect(future).to be_completed
|
85
87
|
end
|
86
88
|
|
87
|
-
it
|
88
|
-
|
89
|
-
|
90
|
-
expect(future_value).to eq Fear.some(Fear.success(value))
|
89
|
+
it "completed with value" do
|
90
|
+
expect(future.value).to be_some_of(Fear.success(value))
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -1,85 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.shared_examples Fear::RightBiased::Left do
|
2
|
-
describe
|
4
|
+
describe "#include?" do
|
3
5
|
subject { left }
|
4
|
-
it { is_expected.not_to include(
|
6
|
+
it { is_expected.not_to include("value") }
|
5
7
|
end
|
6
8
|
|
7
|
-
describe
|
8
|
-
context
|
9
|
-
subject { left.get_or_else {
|
9
|
+
describe "#get_or_else" do
|
10
|
+
context "with block" do
|
11
|
+
subject { left.get_or_else { "default" } }
|
10
12
|
|
11
|
-
it
|
12
|
-
is_expected.to eq(
|
13
|
+
it "returns default value" do
|
14
|
+
is_expected.to eq("default")
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
context
|
17
|
-
subject { left.get_or_else(
|
18
|
+
context "with default argument" do
|
19
|
+
subject { left.get_or_else("default") }
|
18
20
|
|
19
|
-
it
|
20
|
-
is_expected.to eq(
|
21
|
+
it "returns default value" do
|
22
|
+
is_expected.to eq("default")
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
|
-
context
|
26
|
+
context "with false argument" do
|
25
27
|
subject { left.get_or_else(false) }
|
26
28
|
|
27
|
-
it
|
29
|
+
it "returns default value" do
|
28
30
|
is_expected.to eq(false)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
context
|
34
|
+
context "with nil argument" do
|
33
35
|
subject { left.get_or_else(nil) }
|
34
36
|
|
35
|
-
it
|
37
|
+
it "returns default value" do
|
36
38
|
is_expected.to eq(nil)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
|
-
describe
|
43
|
+
describe "#each" do
|
42
44
|
subject do
|
43
45
|
proc do |block|
|
44
46
|
expect(left.each(&block)).to eq(left)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
it
|
50
|
+
it "does not call the block" do
|
49
51
|
is_expected.not_to yield_control
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
describe
|
55
|
+
describe "#map" do
|
54
56
|
subject { left.map(&:length) }
|
55
57
|
|
56
|
-
it
|
58
|
+
it "returns self" do
|
57
59
|
is_expected.to eq(left)
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
describe
|
63
|
+
describe "#flat_map" do
|
62
64
|
subject { left.flat_map(&:length) }
|
63
65
|
|
64
|
-
it
|
66
|
+
it "returns self" do
|
65
67
|
is_expected.to eq(left)
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
69
|
-
describe
|
71
|
+
describe "#to_option" do
|
70
72
|
subject { left.to_option }
|
71
73
|
it { is_expected.to eq(Fear::None) }
|
72
74
|
end
|
73
75
|
|
74
|
-
describe
|
75
|
-
subject { left.any? { |v| v ==
|
76
|
+
describe "#any?" do
|
77
|
+
subject { left.any? { |v| v == "value" } }
|
76
78
|
it { is_expected.to eq(false) }
|
77
79
|
end
|
78
80
|
|
79
|
-
describe
|
81
|
+
describe "#===" do
|
80
82
|
subject { match === left }
|
81
83
|
|
82
|
-
context
|
84
|
+
context "the same object" do
|
83
85
|
let(:match) { left }
|
84
86
|
it { is_expected.to eq(true) }
|
85
87
|
end
|
@@ -1,141 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.shared_examples Fear::RightBiased::Right do
|
2
|
-
describe
|
3
|
-
context
|
4
|
-
subject { right.include?(
|
4
|
+
describe "#include?" do
|
5
|
+
context "contains value" do
|
6
|
+
subject { right.include?("value") }
|
5
7
|
it { is_expected.to eq(true) }
|
6
8
|
end
|
7
9
|
|
8
|
-
context
|
9
|
-
subject { right.include?(
|
10
|
+
context "does not contain value" do
|
11
|
+
subject { right.include?("another value") }
|
10
12
|
it { is_expected.to eq(false) }
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
describe
|
15
|
-
context
|
16
|
-
subject { right.get_or_else {
|
16
|
+
describe "#get_or_else" do
|
17
|
+
context "with block" do
|
18
|
+
subject { right.get_or_else { "default" } }
|
17
19
|
|
18
|
-
it
|
19
|
-
is_expected.to eq(
|
20
|
+
it "returns value" do
|
21
|
+
is_expected.to eq("value")
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
context
|
24
|
-
subject { right.get_or_else(
|
25
|
+
context "with default argument" do
|
26
|
+
subject { right.get_or_else("default") }
|
25
27
|
|
26
|
-
it
|
27
|
-
is_expected.to eq(
|
28
|
+
it "returns value" do
|
29
|
+
is_expected.to eq("value")
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
context
|
33
|
+
context "with false argument" do
|
32
34
|
subject { right.get_or_else(false) }
|
33
35
|
|
34
|
-
it
|
35
|
-
is_expected.to eq(
|
36
|
+
it "returns value" do
|
37
|
+
is_expected.to eq("value")
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
context
|
41
|
+
context "with nil argument" do
|
40
42
|
subject { right.get_or_else(nil) }
|
41
43
|
|
42
|
-
it
|
43
|
-
is_expected.to eq(
|
44
|
+
it "returns value" do
|
45
|
+
is_expected.to eq("value")
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
describe
|
50
|
+
describe "#each" do
|
49
51
|
subject do
|
50
52
|
proc do |block|
|
51
53
|
expect(right.each(&block)).to eq(right)
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
it
|
56
|
-
is_expected.to yield_with_args(
|
57
|
+
it "calls the block with value" do
|
58
|
+
is_expected.to yield_with_args("value")
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
describe
|
61
|
-
it
|
62
|
+
describe "#or_else" do
|
63
|
+
it "does not call block" do
|
62
64
|
expect { |probe| right.or_else(&probe) }.not_to yield_control
|
63
65
|
end
|
64
66
|
|
65
|
-
it
|
67
|
+
it "returns the same object" do
|
66
68
|
expect(right.or_else { 42 }).to eql(right)
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
|
-
describe
|
72
|
+
describe "#map" do
|
71
73
|
subject { right.map(&:length) }
|
72
74
|
|
73
|
-
it
|
75
|
+
it "perform transformation" do
|
74
76
|
is_expected.to eq(described_class.new(5))
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
78
|
-
describe
|
79
|
-
context
|
80
|
+
describe "#flat_map" do
|
81
|
+
context "block returns neither left, nor right" do
|
80
82
|
subject { proc { right.flat_map { 42 } } }
|
81
83
|
|
82
|
-
it
|
84
|
+
it "fails with TypeError" do
|
83
85
|
is_expected.to raise_error(TypeError)
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
87
|
-
context
|
89
|
+
context "block returns RightBiased" do
|
88
90
|
subject { right.flat_map { |e| described_class.new("Result: #{e}") } }
|
89
91
|
|
90
|
-
it
|
91
|
-
is_expected.to eq(described_class.new(
|
92
|
+
it "maps to block result" do
|
93
|
+
is_expected.to eq(described_class.new("Result: value"))
|
92
94
|
end
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
96
|
-
describe
|
98
|
+
describe "#to_option" do
|
97
99
|
subject { right.to_option }
|
98
|
-
it { is_expected.to eq(Fear::Some.new(
|
100
|
+
it { is_expected.to eq(Fear::Some.new("value")) }
|
99
101
|
end
|
100
102
|
|
101
|
-
describe
|
103
|
+
describe "#any?" do
|
102
104
|
subject { right.any?(&predicate) }
|
103
105
|
|
104
|
-
context
|
105
|
-
let(:predicate) { ->(v) { v ==
|
106
|
+
context "matches predicate" do
|
107
|
+
let(:predicate) { ->(v) { v == "value" } }
|
106
108
|
it { is_expected.to eq(true) }
|
107
109
|
end
|
108
110
|
|
109
|
-
context
|
110
|
-
let(:predicate) { ->(v) { v !=
|
111
|
+
context "does not match predicate" do
|
112
|
+
let(:predicate) { ->(v) { v != "value" } }
|
111
113
|
it { is_expected.to eq(false) }
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
115
|
-
describe
|
117
|
+
describe "#===" do
|
116
118
|
subject { match === right }
|
117
119
|
|
118
|
-
context
|
119
|
-
let(:match) { described_class.new(
|
120
|
+
context "matches erectly" do
|
121
|
+
let(:match) { described_class.new("value") }
|
120
122
|
it { is_expected.to eq(true) }
|
121
123
|
end
|
122
124
|
|
123
|
-
context
|
125
|
+
context "the same object" do
|
124
126
|
let(:match) { right }
|
125
127
|
it { is_expected.to eq(true) }
|
126
128
|
end
|
127
129
|
|
128
|
-
context
|
129
|
-
let(:match) { described_class.new(
|
130
|
+
context "value does not match" do
|
131
|
+
let(:match) { described_class.new("error") }
|
130
132
|
it { is_expected.to eq(false) }
|
131
133
|
end
|
132
134
|
|
133
|
-
context
|
135
|
+
context "matches by class" do
|
134
136
|
let(:match) { described_class.new(String) }
|
135
137
|
it { is_expected.to eq(true) }
|
136
138
|
end
|
137
139
|
|
138
|
-
context
|
140
|
+
context "does not matches by class" do
|
139
141
|
let(:match) { described_class.new(Integer) }
|
140
142
|
it { is_expected.to eq(false) }
|
141
143
|
end
|