switchyard 7.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 +7 -0
- data/.github/workflows/project-build.yml +71 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +101 -0
- data/.solargraph.yml +11 -0
- data/Appraisals +7 -0
- data/CHANGELOG.md +303 -0
- data/CODE_OF_CONDUCT.md +22 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +1663 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/audit/bench.rb +99 -0
- data/audit/verify_findings.rb +172 -0
- data/gemfiles/dry_inflector_0_2_1.gemfile +5 -0
- data/gemfiles/i18n_1_8_11.gemfile +5 -0
- data/lib/switchyard/action.rb +145 -0
- data/lib/switchyard/configuration.rb +36 -0
- data/lib/switchyard/context/key_verifier.rb +124 -0
- data/lib/switchyard/context.rb +208 -0
- data/lib/switchyard/deprecations.rb +26 -0
- data/lib/switchyard/errors.rb +9 -0
- data/lib/switchyard/functional/enum.rb +286 -0
- data/lib/switchyard/functional/maybe.rb +21 -0
- data/lib/switchyard/functional/monad.rb +77 -0
- data/lib/switchyard/functional/null.rb +88 -0
- data/lib/switchyard/functional/option.rb +100 -0
- data/lib/switchyard/functional/result.rb +129 -0
- data/lib/switchyard/functional/sequencer.rb +144 -0
- data/lib/switchyard/i18n/localization_adapter.rb +50 -0
- data/lib/switchyard/localization_adapter.rb +39 -0
- data/lib/switchyard/localization_map.rb +9 -0
- data/lib/switchyard/organizer/execute.rb +16 -0
- data/lib/switchyard/organizer/iterate.rb +30 -0
- data/lib/switchyard/organizer/reduce_case.rb +50 -0
- data/lib/switchyard/organizer/reduce_if.rb +19 -0
- data/lib/switchyard/organizer/reduce_if_else.rb +23 -0
- data/lib/switchyard/organizer/reduce_until.rb +22 -0
- data/lib/switchyard/organizer/reduce_while.rb +31 -0
- data/lib/switchyard/organizer/scoped_reducable.rb +15 -0
- data/lib/switchyard/organizer/with_callback.rb +28 -0
- data/lib/switchyard/organizer/with_reducer.rb +81 -0
- data/lib/switchyard/organizer/with_reducer_factory.rb +20 -0
- data/lib/switchyard/organizer/with_reducer_log_decorator.rb +111 -0
- data/lib/switchyard/organizer.rb +129 -0
- data/lib/switchyard/testing/context_factory.rb +48 -0
- data/lib/switchyard/testing.rb +3 -0
- data/lib/switchyard/version.rb +5 -0
- data/lib/switchyard.rb +36 -0
- data/resources/fail_actions.png +0 -0
- data/resources/light-service.png +0 -0
- data/resources/organizer_and_actions.png +0 -0
- data/resources/skip_actions.png +0 -0
- data/spec/acceptance/add_numbers_spec.rb +11 -0
- data/spec/acceptance/after_actions_spec.rb +87 -0
- data/spec/acceptance/around_each_spec.rb +19 -0
- data/spec/acceptance/before_actions_spec.rb +115 -0
- data/spec/acceptance/custom_log_from_organizer_spec.rb +61 -0
- data/spec/acceptance/deprecation_warnings_spec.rb +82 -0
- data/spec/acceptance/fail_spec.rb +52 -0
- data/spec/acceptance/log_from_organizer_spec.rb +154 -0
- data/spec/acceptance/message_localization_spec.rb +119 -0
- data/spec/acceptance/organizer/add_aliases_spec.rb +28 -0
- data/spec/acceptance/organizer/add_to_context_spec.rb +54 -0
- data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +42 -0
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +90 -0
- data/spec/acceptance/organizer/execute_spec.rb +67 -0
- data/spec/acceptance/organizer/iterate_spec.rb +44 -0
- data/spec/acceptance/organizer/reduce_case_spec.rb +65 -0
- data/spec/acceptance/organizer/reduce_if_else_spec.rb +60 -0
- data/spec/acceptance/organizer/reduce_if_spec.rb +89 -0
- data/spec/acceptance/organizer/reduce_until_spec.rb +49 -0
- data/spec/acceptance/organizer/reduce_while_spec.rb +96 -0
- data/spec/acceptance/organizer/with_callback_spec.rb +113 -0
- data/spec/acceptance/organizer_entry_point_spec.rb +35 -0
- data/spec/acceptance/rollback_spec.rb +183 -0
- data/spec/acceptance/skip_all_remaining_spec.rb +139 -0
- data/spec/acceptance/testing/context_factory_spec.rb +54 -0
- data/spec/action_expected_keys_spec.rb +63 -0
- data/spec/action_expects_and_promises_spec.rb +97 -0
- data/spec/action_optional_expected_keys_spec.rb +107 -0
- data/spec/action_promised_keys_spec.rb +126 -0
- data/spec/action_spec.rb +97 -0
- data/spec/context/inspect_spec.rb +52 -0
- data/spec/context_spec.rb +301 -0
- data/spec/examples/amount_spec.rb +77 -0
- data/spec/examples/controller_spec.rb +63 -0
- data/spec/examples/validate_address_spec.rb +38 -0
- data/spec/i18n_localization_adapter_spec.rb +83 -0
- data/spec/lib/deterministic/class_mixin_spec.rb +24 -0
- data/spec/lib/deterministic/currify_spec.rb +90 -0
- data/spec/lib/deterministic/monad_axioms.rb +46 -0
- data/spec/lib/deterministic/monad_spec.rb +47 -0
- data/spec/lib/deterministic/null_spec.rb +65 -0
- data/spec/lib/deterministic/option_spec.rb +140 -0
- data/spec/lib/deterministic/result/failure_spec.rb +65 -0
- data/spec/lib/deterministic/result/result_map_spec.rb +155 -0
- data/spec/lib/deterministic/result/result_shared.rb +25 -0
- data/spec/lib/deterministic/result/success_spec.rb +41 -0
- data/spec/lib/deterministic/result_spec.rb +63 -0
- data/spec/lib/deterministic/sequencer_spec.rb +506 -0
- data/spec/lib/edge_cases_spec.rb +156 -0
- data/spec/lib/enum_spec.rb +114 -0
- data/spec/lib/native_pattern_matching_spec.rb +74 -0
- data/spec/localization_adapter_spec.rb +66 -0
- data/spec/organizer/with_reducer_spec.rb +56 -0
- data/spec/organizer_key_aliases_spec.rb +29 -0
- data/spec/organizer_spec.rb +115 -0
- data/spec/readme_spec.rb +45 -0
- data/spec/sample/calculates_order_tax_action_spec.rb +16 -0
- data/spec/sample/calculates_tax_spec.rb +30 -0
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +55 -0
- data/spec/sample/provides_free_shipping_action_spec.rb +25 -0
- data/spec/sample/tax/calculates_order_tax_action.rb +10 -0
- data/spec/sample/tax/calculates_tax.rb +11 -0
- data/spec/sample/tax/looks_up_tax_percentage_action.rb +28 -0
- data/spec/sample/tax/provides_free_shipping_action.rb +11 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support.rb +1 -0
- data/spec/test_doubles.rb +656 -0
- data/spec/testing/context_factory/iterate_spec.rb +39 -0
- data/spec/testing/context_factory/reduce_if_spec.rb +40 -0
- data/spec/testing/context_factory/reduce_until_spec.rb +40 -0
- data/spec/testing/context_factory/with_callback_spec.rb +38 -0
- data/spec/testing/context_factory_spec.rb +76 -0
- data/switchyard.gemspec +35 -0
- metadata +351 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require_relative '../monad_axioms'
|
|
3
|
+
require_relative 'result_shared'
|
|
4
|
+
|
|
5
|
+
describe Switchyard::Result::Failure do
|
|
6
|
+
include Switchyard::Prelude::Result
|
|
7
|
+
|
|
8
|
+
it_behaves_like 'a Monad' do
|
|
9
|
+
let(:monad) { described_class }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
subject { described_class.new(1) }
|
|
13
|
+
|
|
14
|
+
specify { expect(subject).to be_an_instance_of described_class }
|
|
15
|
+
specify { expect(subject).to be_failure }
|
|
16
|
+
specify { expect(subject).not_to be_success }
|
|
17
|
+
specify { expect(subject.success?).to be_falsey }
|
|
18
|
+
specify { expect(subject.failure?).to be_truthy }
|
|
19
|
+
|
|
20
|
+
specify { expect(subject).to be_an_instance_of described_class }
|
|
21
|
+
specify { expect(subject).to eq(described_class.new(1)) }
|
|
22
|
+
specify { expect(subject.fmap { |v| v + 1 }).to eq Failure(2) }
|
|
23
|
+
specify { expect(subject.map { |v| Success(v + 1) }).to eq Failure(1) }
|
|
24
|
+
specify { expect(subject.map_err { |v| Success(v + 1) }).to eq Success(2) }
|
|
25
|
+
specify do
|
|
26
|
+
expect(subject.pipe { |v| raise RuntimeError unless v == Failure(1) }).to eq Failure(1)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
specify { expect(subject.or(Success(2))).to eq Success(2) }
|
|
30
|
+
specify { expect(subject.or(Failure(2))).to eq Failure(2) }
|
|
31
|
+
specify { expect(subject.or_else { Success(2) }).to eq Success(2) }
|
|
32
|
+
specify { expect(subject.or_else { Failure(2) }).to eq Failure(2) }
|
|
33
|
+
|
|
34
|
+
specify { expect(subject.and(Success(2))).to eq Failure(1) }
|
|
35
|
+
specify { expect(subject.and_then { Success(2) }).to eq Failure(1) }
|
|
36
|
+
|
|
37
|
+
it_behaves_like 'Result' do
|
|
38
|
+
let(:result) { described_class }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "#or" do
|
|
42
|
+
expect(Success(1).or(Failure(2))).to eq Success(1)
|
|
43
|
+
expect(Failure(1).or(Success(2))).to eq Success(2)
|
|
44
|
+
expect { Failure(1).or(2) }.to raise_error(Switchyard::Monad::NotMonadError)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "#or_else" do
|
|
48
|
+
expect(Success(1).or_else { Failure(2) }).to eq Success(1)
|
|
49
|
+
expect(Failure(1).or_else { |v| Success(v + 1) }).to eq Success(2)
|
|
50
|
+
expect { Failure(1).or_else { 2 } }.to raise_error(Switchyard::Monad::NotMonadError)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "#and" do
|
|
54
|
+
expect(Success(1).and(Success(2))).to eq Success(2)
|
|
55
|
+
expect(Failure(1).and(Success(2))).to eq Failure(1)
|
|
56
|
+
expect { Success(1).and(2) }.to raise_error(Switchyard::Monad::NotMonadError)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "#and_then" do
|
|
60
|
+
expect(Success(1).and_then { Success(2) }).to eq Success(2)
|
|
61
|
+
expect(Failure(1).and_then { Success(2) }).to eq Failure(1)
|
|
62
|
+
expect { Success(1).and_then { 2 } }.to \
|
|
63
|
+
raise_error(Switchyard::Monad::NotMonadError)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Switchyard::Result do
|
|
4
|
+
include Switchyard::Prelude::Result
|
|
5
|
+
|
|
6
|
+
context ">> (map)" do
|
|
7
|
+
specify { expect(Success(0).map { |n| Success(n + 1) }).to eq Success(1) }
|
|
8
|
+
specify { expect(Failure(0).map { |n| Success(n + 1) }).to eq Failure(0) }
|
|
9
|
+
|
|
10
|
+
it "Failure stops execution" do
|
|
11
|
+
class ChainUnderTest
|
|
12
|
+
include Switchyard::Prelude::Result
|
|
13
|
+
|
|
14
|
+
alias :m :method
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
init >>
|
|
18
|
+
m(:validate) >>
|
|
19
|
+
m(:send) >>
|
|
20
|
+
m(:parse)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def init
|
|
24
|
+
Success(:step => 1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def validate(i)
|
|
28
|
+
i[:step] = i[:step] + 1
|
|
29
|
+
Success(i)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def send(i)
|
|
33
|
+
i[:step] = i[:step] + 1
|
|
34
|
+
Failure("Error @ #{i.fetch(:step)}")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def parse(i)
|
|
38
|
+
i[:step] = i[:step] + 1
|
|
39
|
+
Success(i)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test = ChainUnderTest.new
|
|
44
|
+
|
|
45
|
+
expect(test.call).to eq Failure("Error @ 3")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "expects an Result" do
|
|
49
|
+
def returns_non_result(_i)
|
|
50
|
+
2
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
expect { Success(1) >> method(:returns_non_result) }.to \
|
|
54
|
+
raise_error(Switchyard::Monad::NotMonadError)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "works with a block" do
|
|
58
|
+
expect(
|
|
59
|
+
Success(1).map { |i| Success(i + 1) }
|
|
60
|
+
).to eq Success(2)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "works with a lambda" do
|
|
64
|
+
expect(
|
|
65
|
+
Success(1) >> ->(i) { Success(i + 1) }
|
|
66
|
+
).to eq Success(2)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "does not catch exceptions" do
|
|
70
|
+
expect do
|
|
71
|
+
Success(1) >> ->(_i) { raise "error" }
|
|
72
|
+
end.to raise_error(RuntimeError)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "using self as the context for success" do
|
|
77
|
+
class SelfContextUnderTest
|
|
78
|
+
include Switchyard::Prelude::Result
|
|
79
|
+
|
|
80
|
+
def call
|
|
81
|
+
@step = 0
|
|
82
|
+
Success(self)
|
|
83
|
+
.map(&:validate)
|
|
84
|
+
.map(&:build)
|
|
85
|
+
.map(&:send)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def validate
|
|
89
|
+
@step = 1
|
|
90
|
+
Success(self)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def build
|
|
94
|
+
@step = 2
|
|
95
|
+
Success(self)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def send
|
|
99
|
+
@step = 3
|
|
100
|
+
Success(self)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def inspect
|
|
104
|
+
"Step #{@step}"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# # def self.procify(*meths)
|
|
108
|
+
# # meths.each do |m|
|
|
109
|
+
# # new_m = "__#{m}__procified".to_sym
|
|
110
|
+
# # alias new_m m
|
|
111
|
+
# # define_method new_m do |ctx|
|
|
112
|
+
# # method(m)
|
|
113
|
+
# # end
|
|
114
|
+
# # end
|
|
115
|
+
# # end
|
|
116
|
+
|
|
117
|
+
# procify :send
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "works" do
|
|
121
|
+
test = SelfContextUnderTest.new.call
|
|
122
|
+
expect(test).to be_a described_class::Success
|
|
123
|
+
expect(test.inspect).to eq "Success(Step 3)"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "<< (pipe)" do
|
|
128
|
+
it "ignores the output of pipe" do
|
|
129
|
+
acc = "ctx: "
|
|
130
|
+
log = ->(ctx) { acc += ctx.inspect }
|
|
131
|
+
|
|
132
|
+
actual = Success(1).pipe(log).map { Success(2) }
|
|
133
|
+
expect(actual).to eq Success(2)
|
|
134
|
+
expect(acc).to eq "ctx: Success(1)"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "works with <<" do
|
|
138
|
+
log = ->(n) { n.value + 1 }
|
|
139
|
+
foo = ->(n) { Success(n + 1) }
|
|
140
|
+
|
|
141
|
+
Success(1) << log >> foo
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context ">= (try)" do
|
|
146
|
+
it "try (>=) catches errors and wraps them as Failure" do
|
|
147
|
+
def error(ctx)
|
|
148
|
+
raise "error #{ctx}"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
actual = Success(1) >= method(:error)
|
|
152
|
+
expect(actual.inspect).to eq "Failure(#<RuntimeError: error 1>)"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
shared_examples 'Result' do
|
|
2
|
+
let(:result_name) { described_class.name.split("::")[-1] }
|
|
3
|
+
specify { expect(subject.value).to eq 1 }
|
|
4
|
+
specify { expect(result.new(subject)).to eq result.new(1) }
|
|
5
|
+
|
|
6
|
+
it "#fmap" do
|
|
7
|
+
expect(result.new(1).fmap { |e| e + 1 }).to eq result.new(2)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "#bind" do
|
|
11
|
+
expect(result.new(1).bind { |v| result.new(v + 1) }).to eq result.new(2)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "#to_s" do
|
|
15
|
+
expect(result.new(1).to_s).to eq "1"
|
|
16
|
+
# il formato di Hash#to_s/inspect cambia tra Ruby 3.3 e 3.4: costruiamo l'atteso dinamicamente
|
|
17
|
+
expect(result.new(:a => 1).to_s).to eq({ :a => 1 }.to_s)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "#inspect" do
|
|
21
|
+
expect(result.new(1).inspect).to eq "#{result_name}(1)"
|
|
22
|
+
expect(result.new(:a => 1).inspect).to eq "#{result_name}(#{{ :a => 1 }.inspect})"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require_relative '../monad_axioms'
|
|
3
|
+
require_relative 'result_shared'
|
|
4
|
+
|
|
5
|
+
describe Switchyard::Result::Success do
|
|
6
|
+
include Switchyard::Prelude::Result
|
|
7
|
+
|
|
8
|
+
it_behaves_like 'a Monad' do
|
|
9
|
+
let(:monad) { described_class }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
subject { described_class.new(1) }
|
|
13
|
+
|
|
14
|
+
specify { expect(subject).to be_an_instance_of described_class }
|
|
15
|
+
specify { expect(subject).to be_success }
|
|
16
|
+
specify { expect(subject).not_to be_failure }
|
|
17
|
+
specify { expect(subject.success?).to be_truthy }
|
|
18
|
+
specify { expect(subject.failure?).to be_falsey }
|
|
19
|
+
|
|
20
|
+
specify { expect(subject).to be_an_instance_of described_class }
|
|
21
|
+
specify { expect(subject).to eq(described_class.new(1)) }
|
|
22
|
+
specify { expect(subject.fmap { |v| v + 1 }).to eq Success(2) }
|
|
23
|
+
specify { expect(subject.map { |v| Failure(v + 1) }).to eq Failure(2) }
|
|
24
|
+
specify { expect(subject.map_err { |v| Failure(v + 1) }).to eq Success(1) }
|
|
25
|
+
|
|
26
|
+
specify do
|
|
27
|
+
expect(subject.pipe { |r| raise RuntimeError unless r == Success(1) }).to eq Success(1)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
specify { expect(subject.or(Success(2))).to eq Success(1) }
|
|
31
|
+
specify { expect(subject.or_else { Success(2) }).to eq Success(1) }
|
|
32
|
+
|
|
33
|
+
specify { expect(subject.and(Success(2))).to eq Success(2) }
|
|
34
|
+
specify { expect(subject.and(Failure(2))).to eq Failure(2) }
|
|
35
|
+
specify { expect(subject.and_then { Success(2) }).to eq Success(2) }
|
|
36
|
+
specify { expect(subject.and_then { Failure(2) }).to eq Failure(2) }
|
|
37
|
+
|
|
38
|
+
it_behaves_like 'Result' do
|
|
39
|
+
let(:result) { described_class }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Switchyard::Result do
|
|
4
|
+
include Switchyard::Prelude::Result
|
|
5
|
+
|
|
6
|
+
it "can't call Result#new directly" do
|
|
7
|
+
# il formato del messaggio NoMethodError cambia tra le versioni di Ruby
|
|
8
|
+
expect { described_class.new(1) }.to raise_error(NoMethodError, /private method [`']new'/)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "fmap" do
|
|
12
|
+
expect(Success(1).fmap { |n| n + 1 }).to eq Success(2)
|
|
13
|
+
expect(Failure(0).fmap { |n| n + 1 }).to eq Failure(1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "map" do
|
|
17
|
+
expect(Success(1).map { |n| Success(n + 1) }).to eq Success(2)
|
|
18
|
+
expect(Failure(0).map { |n| Success(n + 1) }).to eq Failure(0)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "+" do
|
|
22
|
+
expect(Success([1]) + Failure([2])).to eq Failure([2])
|
|
23
|
+
expect(Success(1) + Success(1)).to eq Success(2)
|
|
24
|
+
expect(Failure(2) + Success(1)).to eq Failure(2)
|
|
25
|
+
expect(Failure([2]) + Failure([3]) + Success(1)).to eq Failure([2, 3])
|
|
26
|
+
expect(Success([1]) + Success([1])).to eq Success([1, 1])
|
|
27
|
+
expect { Success([1]) + Success(1) }.to raise_error TypeError
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
subject { Success(1) }
|
|
31
|
+
# specify { expect(subject).to be_an_instance_of described_class }
|
|
32
|
+
specify { expect(subject).to be_success }
|
|
33
|
+
specify { expect(subject).not_to be_failure }
|
|
34
|
+
specify { expect(subject.success?).to be_truthy }
|
|
35
|
+
specify { expect(subject.failure?).to be_falsey }
|
|
36
|
+
|
|
37
|
+
specify { expect(subject).to be_a described_class }
|
|
38
|
+
# specify { expect(subject).to eq(described_class.new(1)) }
|
|
39
|
+
specify { expect(subject.fmap { |v| v + 1 }).to eq Success(2) }
|
|
40
|
+
specify { expect(subject.map { |v| Failure(v + 1) }).to eq Failure(2) }
|
|
41
|
+
specify { expect(subject.map_err { |v| Failure(v + 1) }).to eq Success(1) }
|
|
42
|
+
|
|
43
|
+
specify do
|
|
44
|
+
expect(subject.pipe do |r|
|
|
45
|
+
raise RuntimeError unless r == Success(1)
|
|
46
|
+
end).to eq Success(1)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
specify { expect(subject.or(Success(2))).to eq Success(1) }
|
|
50
|
+
specify { expect(subject.or_else { Success(2) }).to eq Success(1) }
|
|
51
|
+
|
|
52
|
+
specify { expect(subject.and(Success(2))).to eq Success(2) }
|
|
53
|
+
specify { expect(subject.and(Failure(2))).to eq Failure(2) }
|
|
54
|
+
specify { expect(subject.and_then { Success(2) }).to eq Success(2) }
|
|
55
|
+
specify { expect(subject.and_then { Failure(2) }).to eq Failure(2) }
|
|
56
|
+
|
|
57
|
+
it "try!" do
|
|
58
|
+
expect(described_class.try! { 1 }).to eq Success(1)
|
|
59
|
+
expect(described_class.try! { raise "error" }.inspect).to \
|
|
60
|
+
eq Failure(RuntimeError.new("error")).inspect
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|