dry-transaction 0.13.0 → 0.13.1
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/CHANGELOG.md +308 -0
- data/LICENSE +20 -0
- data/README.md +15 -41
- data/dry-transaction.gemspec +35 -0
- data/lib/dry-transaction.rb +2 -0
- data/lib/dry/transaction.rb +2 -0
- data/lib/dry/transaction/builder.rb +6 -4
- data/lib/dry/transaction/callable.rb +5 -0
- data/lib/dry/transaction/dsl.rb +2 -0
- data/lib/dry/transaction/errors.rb +2 -0
- data/lib/dry/transaction/instance_methods.rb +6 -4
- data/lib/dry/transaction/operation.rb +5 -3
- data/lib/dry/transaction/operation_resolver.rb +2 -0
- data/lib/dry/transaction/result_matcher.rb +3 -1
- data/lib/dry/transaction/stack.rb +2 -0
- data/lib/dry/transaction/step.rb +6 -4
- data/lib/dry/transaction/step_adapter.rb +6 -4
- data/lib/dry/transaction/step_adapters.rb +9 -7
- data/lib/dry/transaction/step_adapters/around.rb +4 -2
- data/lib/dry/transaction/step_adapters/check.rb +2 -0
- data/lib/dry/transaction/step_adapters/map.rb +2 -0
- data/lib/dry/transaction/step_adapters/raw.rb +5 -3
- data/lib/dry/transaction/step_adapters/tee.rb +2 -0
- data/lib/dry/transaction/step_adapters/try.rb +3 -1
- data/lib/dry/transaction/step_failure.rb +2 -0
- data/lib/dry/transaction/version.rb +3 -1
- metadata +14 -110
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -97
- data/LICENSE.md +0 -9
- data/Rakefile +0 -6
- data/spec/examples.txt +0 -88
- data/spec/integration/around_spec.rb +0 -120
- data/spec/integration/auto_injection_spec.rb +0 -32
- data/spec/integration/custom_step_adapters_spec.rb +0 -41
- data/spec/integration/operation_spec.rb +0 -30
- data/spec/integration/passing_step_arguments_spec.rb +0 -51
- data/spec/integration/publishing_step_events_spec.rb +0 -119
- data/spec/integration/transaction_spec.rb +0 -573
- data/spec/integration/transaction_without_steps_spec.rb +0 -101
- data/spec/spec_helper.rb +0 -116
- data/spec/support/container.rb +0 -10
- data/spec/support/database.rb +0 -12
- data/spec/support/db_transactions.rb +0 -45
- data/spec/support/result_mixin.rb +0 -3
- data/spec/support/test_module_constants.rb +0 -11
- data/spec/unit/step_adapters/around_spec.rb +0 -46
- data/spec/unit/step_adapters/check_spec.rb +0 -43
- data/spec/unit/step_adapters/map_spec.rb +0 -16
- data/spec/unit/step_adapters/raw_spec.rb +0 -36
- data/spec/unit/step_adapters/tee_spec.rb +0 -17
- data/spec/unit/step_adapters/try_spec.rb +0 -89
- data/spec/unit/step_spec.rb +0 -139
@@ -1,17 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Transaction::StepAdapters::Tee, :adapter do
|
2
|
-
|
3
|
-
subject { described_class.new }
|
4
|
-
|
5
|
-
let(:operation) {
|
6
|
-
-> (input) { input.upcase }
|
7
|
-
}
|
8
|
-
|
9
|
-
let(:options) { { step_name: "unit" } }
|
10
|
-
|
11
|
-
describe "#call" do
|
12
|
-
|
13
|
-
it "return a Success value" do
|
14
|
-
expect(subject.(operation, options, ["input"])).to eql(Success("input"))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Transaction::StepAdapters::Try do
|
2
|
-
|
3
|
-
subject { described_class.new }
|
4
|
-
|
5
|
-
let(:operation) {
|
6
|
-
-> (input) {
|
7
|
-
raise(Test::NotValidError, 'not a string') unless input.is_a? String
|
8
|
-
input.upcase
|
9
|
-
}
|
10
|
-
}
|
11
|
-
|
12
|
-
let(:options) { { catch: Test::NotValidError, step_name: "unit" } }
|
13
|
-
|
14
|
-
before do
|
15
|
-
Test::NotValidError = Class.new(StandardError)
|
16
|
-
Test::BetterNamingError = Class.new(StandardError)
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#call" do
|
20
|
-
|
21
|
-
context "without the :catch option" do
|
22
|
-
let(:options) { { step_name: "unit" } }
|
23
|
-
|
24
|
-
it "raises an ArgumentError" do
|
25
|
-
expect {
|
26
|
-
subject.(operation, options, ["something"])
|
27
|
-
}.to raise_error(
|
28
|
-
Dry::Transaction::MissingCatchListError,
|
29
|
-
"step +unit+ requires one or more exception classes provided via +catch:+"
|
30
|
-
)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "with the :catch option" do
|
35
|
-
|
36
|
-
context "when the error was raised" do
|
37
|
-
|
38
|
-
it "returns a Failure value" do
|
39
|
-
expect(subject.(operation, options, [1234])).to be_a_failure
|
40
|
-
end
|
41
|
-
|
42
|
-
it "returns the raised error as output" do
|
43
|
-
result = subject.(operation, options, [1234])
|
44
|
-
expect(result.failure).to be_a Test::NotValidError
|
45
|
-
expect(result.failure.message).to eql("not a string")
|
46
|
-
end
|
47
|
-
|
48
|
-
context "when using the :raise option" do
|
49
|
-
let(:options) {
|
50
|
-
{
|
51
|
-
catch: Test::NotValidError,
|
52
|
-
raise: Test::BetterNamingError
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
it "returns a Failure value" do
|
57
|
-
expect(subject.(operation, options, [1234])).to be_a_failure
|
58
|
-
end
|
59
|
-
|
60
|
-
it "returns the error specified by :raise as output" do
|
61
|
-
result = subject.(operation, options, [1234])
|
62
|
-
expect(result.failure).to be_a Test::BetterNamingError
|
63
|
-
expect(result.failure.message).to eql("not a string")
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context "when the error was NOT raised" do
|
69
|
-
|
70
|
-
it "returns a Success value" do
|
71
|
-
expect(subject.(operation, options, ["input"])).to eql(Success("INPUT"))
|
72
|
-
end
|
73
|
-
|
74
|
-
context "when using the :raise option" do
|
75
|
-
let(:options) {
|
76
|
-
{
|
77
|
-
catch: Test::NotValidError,
|
78
|
-
raise: Test::BetterNamingError
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
it "returns a Success value" do
|
83
|
-
expect(subject.(operation, options, ["input"])).to eql(Success("INPUT"))
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
data/spec/unit/step_spec.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Transaction::Step do
|
2
|
-
let(:step_adapter) { ->(step, input, *args) { step.operation.call(input, *args) } }
|
3
|
-
let(:step_name) { :test }
|
4
|
-
let(:operation_name) { step_name }
|
5
|
-
|
6
|
-
subject(:step) {
|
7
|
-
described_class.new(
|
8
|
-
adapter: step_adapter,
|
9
|
-
name: step_name,
|
10
|
-
operation_name: operation_name,
|
11
|
-
operation: operation,
|
12
|
-
options: {}
|
13
|
-
)
|
14
|
-
}
|
15
|
-
|
16
|
-
describe "#call" do
|
17
|
-
let(:listener) do
|
18
|
-
Class.new do
|
19
|
-
attr_reader :started, :success, :failed
|
20
|
-
|
21
|
-
def initialize
|
22
|
-
@started = []
|
23
|
-
@success = []
|
24
|
-
@failed = []
|
25
|
-
end
|
26
|
-
|
27
|
-
def on_step(event)
|
28
|
-
started << event[:step_name]
|
29
|
-
end
|
30
|
-
def on_step_succeeded(event)
|
31
|
-
success << "succeded_#{event[:step_name]}"
|
32
|
-
end
|
33
|
-
def on_step_failed(event)
|
34
|
-
failed << "failed_#{event[:step_name]}"
|
35
|
-
end
|
36
|
-
end.new
|
37
|
-
end
|
38
|
-
|
39
|
-
let(:input) { "input" }
|
40
|
-
subject { step.call(input) }
|
41
|
-
|
42
|
-
context "when operation succeeds" do
|
43
|
-
let(:operation) { proc { |input| Dry::Monads.Success(input) } }
|
44
|
-
|
45
|
-
it { is_expected.to be_success }
|
46
|
-
|
47
|
-
it "publishes step_succeeded" do
|
48
|
-
expect(listener).to receive(:on_step_succeeded).and_call_original
|
49
|
-
step.subscribe(listener)
|
50
|
-
subject
|
51
|
-
|
52
|
-
expect(listener.success).to eq ['succeded_test']
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when operation starts" do
|
57
|
-
let(:operation) { proc { |input| Dry::Monads.Success(input) } }
|
58
|
-
|
59
|
-
it "publishes step" do
|
60
|
-
expect(listener).to receive(:on_step).and_call_original
|
61
|
-
step.subscribe(listener)
|
62
|
-
subject
|
63
|
-
|
64
|
-
expect(listener.started).to eq [:test]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context "when operation fails" do
|
69
|
-
let(:operation) { proc { |input| Dry::Monads.Failure("error") } }
|
70
|
-
|
71
|
-
it { is_expected.to be_failure }
|
72
|
-
|
73
|
-
it "wraps value in StepFailure" do
|
74
|
-
aggregate_failures do
|
75
|
-
expect(subject.failure).to be_a Dry::Transaction::StepFailure
|
76
|
-
expect(subject.failure.value).to eq "error"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
it "publishes step_failed" do
|
81
|
-
expect(listener).to receive(:on_step_failed).and_call_original
|
82
|
-
step.subscribe(listener)
|
83
|
-
subject
|
84
|
-
|
85
|
-
expect(listener.failed).to eq ['failed_test']
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#with" do
|
91
|
-
let(:operation) { proc { |a, b| a + b } }
|
92
|
-
context "without arguments" do
|
93
|
-
it "returns itself" do
|
94
|
-
expect(step.with).to eq step
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context "with operation argument" do
|
99
|
-
it "returns new instance with only operation changed" do
|
100
|
-
new_operation = proc { |a,b| a * b }
|
101
|
-
new_step = step.with(operation: new_operation)
|
102
|
-
expect(new_step).to_not eq step
|
103
|
-
expect(new_step.operation_name).to eq step.operation_name
|
104
|
-
expect(new_step.operation).to_not eq step.operation
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context "with call_args argument" do
|
109
|
-
let(:call_args) { [12] }
|
110
|
-
it "returns new instance with only call_args changed" do
|
111
|
-
new_step = step.with(call_args: call_args)
|
112
|
-
expect(new_step).to_not eq step
|
113
|
-
expect(new_step.operation_name).to eq step.operation_name
|
114
|
-
expect(new_step.call_args).to_not eq step.call_args
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe "#arity" do
|
120
|
-
subject { step.arity }
|
121
|
-
|
122
|
-
context "when operation is a proc" do
|
123
|
-
let(:operation) { proc { |a, b| a + b } }
|
124
|
-
it { is_expected.to eq 2 }
|
125
|
-
end
|
126
|
-
|
127
|
-
context "when operation is an object with call method" do
|
128
|
-
let(:operation) do
|
129
|
-
Class.new do
|
130
|
-
def call(a, b, c)
|
131
|
-
a + b + c
|
132
|
-
end
|
133
|
-
end.new
|
134
|
-
end
|
135
|
-
|
136
|
-
it { is_expected.to eq 3 }
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|