fear 0.9.0 → 1.2.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/.github/workflows/rubocop.yml +39 -0
- data/.github/workflows/spec.yml +42 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +4 -12
- data/.simplecov +17 -0
- data/CHANGELOG.md +40 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +130 -0
- data/LICENSE.txt +1 -1
- data/README.md +1293 -97
- data/Rakefile +369 -1
- 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 +17 -0
- data/examples/pattern_extracting_ruby2.7.rb +15 -0
- data/examples/pattern_matching_binary_tree_set.rb +101 -0
- data/examples/pattern_matching_number_in_words.rb +60 -0
- data/fear.gemspec +34 -23
- data/lib/dry/types/fear.rb +8 -0
- data/lib/dry/types/fear/option.rb +125 -0
- data/lib/fear.rb +65 -15
- data/lib/fear/await.rb +33 -0
- data/lib/fear/awaitable.rb +28 -0
- data/lib/fear/either.rb +131 -71
- data/lib/fear/either_api.rb +23 -0
- data/lib/fear/either_pattern_match.rb +53 -0
- data/lib/fear/empty_partial_function.rb +38 -0
- data/lib/fear/extractor.rb +112 -0
- data/lib/fear/extractor/anonymous_array_splat_matcher.rb +10 -0
- data/lib/fear/extractor/any_matcher.rb +17 -0
- data/lib/fear/extractor/array_head_matcher.rb +36 -0
- data/lib/fear/extractor/array_matcher.rb +40 -0
- data/lib/fear/extractor/array_splat_matcher.rb +16 -0
- data/lib/fear/extractor/empty_list_matcher.rb +20 -0
- data/lib/fear/extractor/extractor_matcher.rb +44 -0
- data/lib/fear/extractor/grammar.rb +203 -0
- data/lib/fear/extractor/grammar.treetop +129 -0
- data/lib/fear/extractor/identifier_matcher.rb +18 -0
- data/lib/fear/extractor/matcher.rb +53 -0
- data/lib/fear/extractor/matcher/and.rb +38 -0
- data/lib/fear/extractor/named_array_splat_matcher.rb +17 -0
- data/lib/fear/extractor/pattern.rb +58 -0
- data/lib/fear/extractor/typed_identifier_matcher.rb +26 -0
- data/lib/fear/extractor/value_matcher.rb +19 -0
- data/lib/fear/extractor_api.rb +35 -0
- data/lib/fear/failure.rb +46 -14
- data/lib/fear/failure_pattern_match.rb +10 -0
- data/lib/fear/for.rb +37 -95
- data/lib/fear/for_api.rb +68 -0
- data/lib/fear/future.rb +497 -0
- data/lib/fear/future_api.rb +21 -0
- data/lib/fear/left.rb +19 -2
- data/lib/fear/left_pattern_match.rb +11 -0
- data/lib/fear/none.rb +67 -3
- data/lib/fear/none_pattern_match.rb +14 -0
- data/lib/fear/option.rb +120 -56
- data/lib/fear/option_api.rb +40 -0
- data/lib/fear/option_pattern_match.rb +48 -0
- data/lib/fear/partial_function.rb +176 -0
- data/lib/fear/partial_function/and_then.rb +50 -0
- data/lib/fear/partial_function/any.rb +28 -0
- data/lib/fear/partial_function/combined.rb +53 -0
- data/lib/fear/partial_function/empty.rb +10 -0
- data/lib/fear/partial_function/guard.rb +80 -0
- data/lib/fear/partial_function/guard/and.rb +38 -0
- data/lib/fear/partial_function/guard/and3.rb +41 -0
- data/lib/fear/partial_function/guard/or.rb +38 -0
- data/lib/fear/partial_function/lifted.rb +23 -0
- data/lib/fear/partial_function/or_else.rb +64 -0
- data/lib/fear/partial_function_class.rb +38 -0
- data/lib/fear/pattern_match.rb +114 -0
- data/lib/fear/pattern_matching_api.rb +137 -0
- data/lib/fear/promise.rb +95 -0
- data/lib/fear/right.rb +20 -2
- data/lib/fear/right_biased.rb +6 -14
- data/lib/fear/right_pattern_match.rb +11 -0
- data/lib/fear/some.rb +55 -3
- data/lib/fear/some_pattern_match.rb +13 -0
- data/lib/fear/struct.rb +248 -0
- data/lib/fear/success.rb +35 -5
- data/lib/fear/success_pattern_match.rb +12 -0
- data/lib/fear/try.rb +136 -79
- data/lib/fear/try_api.rb +33 -0
- data/lib/fear/try_pattern_match.rb +33 -0
- data/lib/fear/unit.rb +32 -0
- data/lib/fear/utils.rb +39 -14
- data/lib/fear/version.rb +4 -1
- 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 +17 -0
- data/spec/fear/done_spec.rb +8 -6
- data/spec/fear/either/mixin_spec.rb +17 -0
- data/spec/fear/either_pattern_match_spec.rb +37 -0
- data/spec/fear/either_pattern_matching_spec.rb +28 -0
- data/spec/fear/extractor/array_matcher_spec.rb +230 -0
- data/spec/fear/extractor/extractor_matcher_spec.rb +153 -0
- data/spec/fear/extractor/grammar_array_spec.rb +25 -0
- data/spec/fear/extractor/identified_matcher_spec.rb +49 -0
- data/spec/fear/extractor/identifier_matcher_spec.rb +68 -0
- data/spec/fear/extractor/pattern_spec.rb +34 -0
- data/spec/fear/extractor/typed_identifier_matcher_spec.rb +64 -0
- data/spec/fear/extractor/value_matcher_number_spec.rb +79 -0
- data/spec/fear/extractor/value_matcher_string_spec.rb +88 -0
- data/spec/fear/extractor/value_matcher_symbol_spec.rb +71 -0
- data/spec/fear/extractor_api_spec.rb +115 -0
- data/spec/fear/extractor_spec.rb +61 -0
- data/spec/fear/failure_spec.rb +145 -45
- data/spec/fear/for_spec.rb +57 -67
- data/spec/fear/future_spec.rb +691 -0
- data/spec/fear/guard_spec.rb +103 -0
- data/spec/fear/left_spec.rb +112 -46
- data/spec/fear/none_spec.rb +114 -16
- data/spec/fear/option/mixin_spec.rb +39 -0
- data/spec/fear/option_pattern_match_spec.rb +35 -0
- data/spec/fear/option_pattern_matching_spec.rb +34 -0
- data/spec/fear/option_spec.rb +121 -8
- data/spec/fear/partial_function/empty_spec.rb +38 -0
- data/spec/fear/partial_function_and_then_spec.rb +147 -0
- data/spec/fear/partial_function_composition_spec.rb +82 -0
- data/spec/fear/partial_function_or_else_spec.rb +276 -0
- data/spec/fear/partial_function_spec.rb +239 -0
- data/spec/fear/pattern_match_spec.rb +93 -0
- data/spec/fear/pattern_matching_api_spec.rb +31 -0
- data/spec/fear/promise_spec.rb +96 -0
- data/spec/fear/right_biased/left.rb +29 -32
- data/spec/fear/right_biased/right.rb +51 -54
- data/spec/fear/right_spec.rb +109 -41
- data/spec/fear/some_spec.rb +80 -15
- data/spec/fear/success_spec.rb +99 -32
- data/spec/fear/try/mixin_spec.rb +19 -0
- data/spec/fear/try_pattern_match_spec.rb +37 -0
- 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 +226 -0
- data/spec/support/dry_types.rb +6 -0
- metadata +320 -29
- data/.travis.yml +0 -9
- data/lib/fear/done.rb +0 -22
- data/lib/fear/for/evaluation_context.rb +0 -91
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::PatternMatch do
|
4
|
+
context "extracting" do
|
5
|
+
let(:matcher) do
|
6
|
+
described_class.new do |m|
|
7
|
+
m.xcase("Date(year, 2, 29)", ->(year:) { year < 2000 }) do |year:|
|
8
|
+
"#{year} is a leap year before Millennium"
|
9
|
+
end
|
10
|
+
m.xcase("Date(year, 2, 29)") do |year:|
|
11
|
+
"#{year} is a leap year after Millennium"
|
12
|
+
end
|
13
|
+
m.case(Date) do |date|
|
14
|
+
"#{date.year} is not a leap year"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "before Millennium" do
|
20
|
+
subject { matcher.(Date.parse("1996-02-29")) }
|
21
|
+
|
22
|
+
it { is_expected.to eq("1996 is a leap year before Millennium") }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "after Millennium" do
|
26
|
+
subject { matcher.(Date.parse("2004-02-29")) }
|
27
|
+
|
28
|
+
it { is_expected.to eq("2004 is a leap year after Millennium") }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "not leap" do
|
32
|
+
subject { matcher.(Date.parse("2003-01-24")) }
|
33
|
+
|
34
|
+
it { is_expected.to eq("2003 is not a leap year") }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "else at the end" do
|
39
|
+
let(:matcher) do
|
40
|
+
described_class.new do |m|
|
41
|
+
m.case(Integer) { |x| "#{x} is int" }
|
42
|
+
m.case(String) { |x| "#{x} is str" }
|
43
|
+
m.else { |x| "#{x} is something else" }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "Integer" do
|
48
|
+
subject { matcher.(4) }
|
49
|
+
|
50
|
+
it { is_expected.to eq("4 is int") }
|
51
|
+
end
|
52
|
+
|
53
|
+
context "String" do
|
54
|
+
subject { matcher.("4") }
|
55
|
+
|
56
|
+
it { is_expected.to eq("4 is str") }
|
57
|
+
end
|
58
|
+
|
59
|
+
context "Symbol" do
|
60
|
+
subject { matcher.(:a) }
|
61
|
+
|
62
|
+
it { is_expected.to eq("a is something else") }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "else before other branches" do
|
67
|
+
subject { matcher.(4) }
|
68
|
+
|
69
|
+
let(:matcher) do
|
70
|
+
described_class.new do |m|
|
71
|
+
m.else { |x| "#{x} is something else" }
|
72
|
+
m.case(Integer) { |x| "#{x} is int" }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it { is_expected.to eq("4 is something else") }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "several else branches" do
|
80
|
+
subject { matcher.(4) }
|
81
|
+
|
82
|
+
let(:matcher) do
|
83
|
+
described_class.new do |m|
|
84
|
+
m.else { |x| "#{x} else 1" }
|
85
|
+
m.else { |x| "#{x} else 2" }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it "first one wins" do
|
90
|
+
is_expected.to eq("4 else 1")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
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
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Fear::Promise do
|
4
|
+
let(:value) { 42 }
|
5
|
+
let(:error) { StandardError.new("something went wrong") }
|
6
|
+
|
7
|
+
def not_completed_promise
|
8
|
+
Fear::Promise.new(executor: Concurrent::ImmediateExecutor.new)
|
9
|
+
end
|
10
|
+
|
11
|
+
context "not completed" do
|
12
|
+
it "#success! returns self" do
|
13
|
+
completed_promise = not_completed_promise.success!(value)
|
14
|
+
|
15
|
+
expect(completed_promise).to eq completed_promise
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#success returns true" do
|
19
|
+
completed = not_completed_promise.success(value)
|
20
|
+
|
21
|
+
expect(completed).to be true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "#failure! returns self" do
|
25
|
+
completed_promise = not_completed_promise.failure!(error)
|
26
|
+
|
27
|
+
expect(completed_promise).to eq completed_promise
|
28
|
+
end
|
29
|
+
|
30
|
+
it "#failure returns true" do
|
31
|
+
completed = not_completed_promise.failure(error)
|
32
|
+
|
33
|
+
expect(completed).to be true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "#completed? returns true" do
|
37
|
+
expect(not_completed_promise).not_to be_completed
|
38
|
+
end
|
39
|
+
|
40
|
+
it "#future returns not completed future" do
|
41
|
+
future = not_completed_promise.to_future
|
42
|
+
|
43
|
+
expect(future).not_to be_completed
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "completed" do
|
48
|
+
def completed_promise
|
49
|
+
not_completed_promise.success!(value)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#success! fails with exception" do
|
53
|
+
expect do
|
54
|
+
completed_promise.success!(value)
|
55
|
+
end.to raise_exception(Fear::IllegalStateException)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "#success returns false" do
|
59
|
+
completed = completed_promise.success(value)
|
60
|
+
|
61
|
+
expect(completed).to be false
|
62
|
+
end
|
63
|
+
|
64
|
+
it "#failure! fails with exception" do
|
65
|
+
expect do
|
66
|
+
completed_promise.failure!(error)
|
67
|
+
end.to raise_exception(Fear::IllegalStateException)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "#failure returns false" do
|
71
|
+
completed = completed_promise.success(error)
|
72
|
+
|
73
|
+
expect(completed).to be false
|
74
|
+
end
|
75
|
+
|
76
|
+
it "#completed? returns true" do
|
77
|
+
expect(completed_promise).to be_completed
|
78
|
+
end
|
79
|
+
|
80
|
+
context "#future" do
|
81
|
+
subject(:future) do
|
82
|
+
completed_promise.to_future
|
83
|
+
end
|
84
|
+
|
85
|
+
it "is completed" do
|
86
|
+
expect(future).to be_completed
|
87
|
+
end
|
88
|
+
|
89
|
+
it "completed with value" do
|
90
|
+
future_value = future.value
|
91
|
+
|
92
|
+
expect(future_value).to eq Fear.some(Fear.success(value))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,90 +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
|
70
|
-
subject { left.to_a }
|
71
|
-
it { is_expected.to eq([]) }
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#to_option' do
|
71
|
+
describe "#to_option" do
|
75
72
|
subject { left.to_option }
|
76
|
-
it { is_expected.to eq(Fear::None
|
73
|
+
it { is_expected.to eq(Fear::None) }
|
77
74
|
end
|
78
75
|
|
79
|
-
describe
|
80
|
-
subject { left.any? { |v| v ==
|
76
|
+
describe "#any?" do
|
77
|
+
subject { left.any? { |v| v == "value" } }
|
81
78
|
it { is_expected.to eq(false) }
|
82
79
|
end
|
83
80
|
|
84
|
-
describe
|
81
|
+
describe "#===" do
|
85
82
|
subject { match === left }
|
86
83
|
|
87
|
-
context
|
84
|
+
context "the same object" do
|
88
85
|
let(:match) { left }
|
89
86
|
it { is_expected.to eq(true) }
|
90
87
|
end
|
@@ -1,146 +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
|
97
|
-
subject { right.to_a }
|
98
|
-
it { is_expected.to eq(['value']) }
|
99
|
-
end
|
100
|
-
|
101
|
-
describe '#to_option' do
|
98
|
+
describe "#to_option" do
|
102
99
|
subject { right.to_option }
|
103
|
-
it { is_expected.to eq(Fear::Some.new(
|
100
|
+
it { is_expected.to eq(Fear::Some.new("value")) }
|
104
101
|
end
|
105
102
|
|
106
|
-
describe
|
103
|
+
describe "#any?" do
|
107
104
|
subject { right.any?(&predicate) }
|
108
105
|
|
109
|
-
context
|
110
|
-
let(:predicate) { ->(v) { v ==
|
106
|
+
context "matches predicate" do
|
107
|
+
let(:predicate) { ->(v) { v == "value" } }
|
111
108
|
it { is_expected.to eq(true) }
|
112
109
|
end
|
113
110
|
|
114
|
-
context
|
115
|
-
let(:predicate) { ->(v) { v !=
|
111
|
+
context "does not match predicate" do
|
112
|
+
let(:predicate) { ->(v) { v != "value" } }
|
116
113
|
it { is_expected.to eq(false) }
|
117
114
|
end
|
118
115
|
end
|
119
116
|
|
120
|
-
describe
|
117
|
+
describe "#===" do
|
121
118
|
subject { match === right }
|
122
119
|
|
123
|
-
context
|
124
|
-
let(:match) { described_class.new(
|
120
|
+
context "matches erectly" do
|
121
|
+
let(:match) { described_class.new("value") }
|
125
122
|
it { is_expected.to eq(true) }
|
126
123
|
end
|
127
124
|
|
128
|
-
context
|
125
|
+
context "the same object" do
|
129
126
|
let(:match) { right }
|
130
127
|
it { is_expected.to eq(true) }
|
131
128
|
end
|
132
129
|
|
133
|
-
context
|
134
|
-
let(:match) { described_class.new(
|
130
|
+
context "value does not match" do
|
131
|
+
let(:match) { described_class.new("error") }
|
135
132
|
it { is_expected.to eq(false) }
|
136
133
|
end
|
137
134
|
|
138
|
-
context
|
135
|
+
context "matches by class" do
|
139
136
|
let(:match) { described_class.new(String) }
|
140
137
|
it { is_expected.to eq(true) }
|
141
138
|
end
|
142
139
|
|
143
|
-
context
|
140
|
+
context "does not matches by class" do
|
144
141
|
let(:match) { described_class.new(Integer) }
|
145
142
|
it { is_expected.to eq(false) }
|
146
143
|
end
|