dry-transaction 0.10.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +20 -14
  4. data/lib/dry/transaction/builder.rb +2 -4
  5. data/lib/dry/transaction/callable.rb +38 -0
  6. data/lib/dry/transaction/errors.rb +27 -0
  7. data/lib/dry/transaction/instance_methods.rb +22 -5
  8. data/lib/dry/transaction/operation.rb +4 -4
  9. data/lib/dry/transaction/operation_resolver.rb +5 -1
  10. data/lib/dry/transaction/result_matcher.rb +3 -3
  11. data/lib/dry/transaction/stack.rb +24 -0
  12. data/lib/dry/transaction/step.rb +37 -21
  13. data/lib/dry/transaction/step_adapter.rb +49 -0
  14. data/lib/dry/transaction/step_adapters/around.rb +25 -0
  15. data/lib/dry/transaction/step_adapters/check.rb +18 -0
  16. data/lib/dry/transaction/step_adapters/map.rb +3 -3
  17. data/lib/dry/transaction/step_adapters/raw.rb +6 -12
  18. data/lib/dry/transaction/step_adapters/tee.rb +4 -4
  19. data/lib/dry/transaction/step_adapters/try.rb +11 -8
  20. data/lib/dry/transaction/step_adapters.rb +2 -0
  21. data/lib/dry/transaction/version.rb +1 -1
  22. data/lib/dry/transaction.rb +14 -11
  23. data/spec/examples.txt +81 -65
  24. data/spec/integration/around_spec.rb +81 -0
  25. data/spec/integration/custom_step_adapters_spec.rb +6 -4
  26. data/spec/integration/operation_spec.rb +3 -3
  27. data/spec/integration/passing_step_arguments_spec.rb +1 -1
  28. data/spec/integration/publishing_step_events_spec.rb +36 -17
  29. data/spec/integration/transaction_spec.rb +165 -37
  30. data/spec/integration/transaction_without_steps_spec.rb +101 -0
  31. data/spec/spec_helper.rb +14 -5
  32. data/spec/support/container.rb +10 -0
  33. data/spec/support/database.rb +12 -0
  34. data/spec/support/db_transactions.rb +45 -0
  35. data/spec/support/result_mixin.rb +3 -0
  36. data/spec/unit/step_adapters/around_spec.rb +46 -0
  37. data/spec/unit/step_adapters/check_spec.rb +43 -0
  38. data/spec/unit/step_adapters/map_spec.rb +5 -12
  39. data/spec/unit/step_adapters/raw_spec.rb +16 -32
  40. data/spec/unit/step_adapters/tee_spec.rb +4 -10
  41. data/spec/unit/step_adapters/try_spec.rb +24 -33
  42. data/spec/unit/step_spec.rb +41 -10
  43. metadata +39 -21
  44. data/spec/support/either_mixin.rb +0 -3
@@ -1,51 +1,35 @@
1
- RSpec.describe Dry::Transaction::StepAdapters::Raw do
1
+ RSpec.describe Dry::Transaction::StepAdapters::Raw, adapter: true do
2
2
 
3
3
  subject { described_class.new }
4
4
 
5
- let(:operation) {
6
- -> (input) { input.upcase }
7
- }
8
-
9
- let(:step) {
10
- Dry::Transaction::Step.new(subject, :step, :step, operation, {})
11
- }
5
+ let(:options) { { step_name: "unit" } }
12
6
 
13
7
  describe "#call" do
14
8
 
15
- context "when the result of the operation is NOT a Dry::Monads::Either" do
9
+ context "when the result of the operation is NOT a Dry::Monads::Result" do
16
10
 
17
- it "raises an ArgumentError" do
18
- expect do
19
- subject.call(step, 'input')
20
- end.to raise_error(ArgumentError)
21
- end
22
- end
23
-
24
- context "when the result of the operation is a Left Monad" do
25
11
  let(:operation) {
26
- -> (input) { Left(input.upcase) }
12
+ -> (input) { input.upcase }
27
13
  }
28
14
 
29
- it "return a Left Monad" do
30
- expect(subject.call(step, 'input')).to be_a Dry::Monads::Either::Left
31
- end
32
-
33
- it "return the result of the operation as output" do
34
- expect(subject.call(step, 'input').value).to eql 'INPUT'
15
+ it "raises an InvalidResultError" do
16
+ expect {
17
+ subject.(operation, options, "input")
18
+ }.to raise_error(
19
+ Dry::Transaction::InvalidResultError,
20
+ "step +unit+ must return a Result object"
21
+ )
35
22
  end
36
23
  end
37
24
 
38
- context "when the result of the operation is a Right Monad" do
25
+ context "when the result of the operation is a Success value" do
26
+
39
27
  let(:operation) {
40
- -> (input) { Right(input.upcase) }
28
+ -> (input) { Success(input.upcase) }
41
29
  }
42
30
 
43
- it "return a Right Monad" do
44
- expect(subject.call(step, 'input')).to be_a Dry::Monads::Either::Right
45
- end
46
-
47
- it "return the result of the operation as output" do
48
- expect(subject.call(step, 'input').value).to eql 'INPUT'
31
+ it "return a Success value" do
32
+ expect(subject.(operation, options, "input")).to eql(Success("INPUT"))
49
33
  end
50
34
  end
51
35
  end
@@ -1,4 +1,4 @@
1
- RSpec.describe Dry::Transaction::StepAdapters::Tee do
1
+ RSpec.describe Dry::Transaction::StepAdapters::Tee, :adapter do
2
2
 
3
3
  subject { described_class.new }
4
4
 
@@ -6,18 +6,12 @@ RSpec.describe Dry::Transaction::StepAdapters::Tee do
6
6
  -> (input) { input.upcase }
7
7
  }
8
8
 
9
- let(:step) {
10
- Dry::Transaction::Step.new(subject, :step, :step, operation, {})
11
- }
9
+ let(:options) { { step_name: "unit" } }
12
10
 
13
11
  describe "#call" do
14
12
 
15
- it "return a Right Monad" do
16
- expect(subject.call(step, 'input')).to be_a Dry::Monads::Either::Right
17
- end
18
-
19
- it "return the original input as output" do
20
- expect(subject.call(step, 'input').value).to eql 'input'
13
+ it "return a Success value" do
14
+ expect(subject.(operation, options, ["input"])).to eql(Success("input"))
21
15
  end
22
16
  end
23
17
  end
@@ -9,11 +9,7 @@ RSpec.describe Dry::Transaction::StepAdapters::Try do
9
9
  }
10
10
  }
11
11
 
12
- let(:step) {
13
- Dry::Transaction::Step.new(subject, :step, :step, operation, options)
14
- }
15
-
16
- let(:options) { { catch: Test::NotValidError } }
12
+ let(:options) { { catch: Test::NotValidError, step_name: "unit" } }
17
13
 
18
14
  before do
19
15
  Test::NotValidError = Class.new(StandardError)
@@ -23,12 +19,15 @@ RSpec.describe Dry::Transaction::StepAdapters::Try do
23
19
  describe "#call" do
24
20
 
25
21
  context "without the :catch option" do
26
- let(:options) { { } }
22
+ let(:options) { { step_name: "unit" } }
27
23
 
28
24
  it "raises an ArgumentError" do
29
- expect do
30
- subject.call(step, {})
31
- end.to raise_error(ArgumentError)
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
+ )
32
31
  end
33
32
  end
34
33
 
@@ -36,14 +35,14 @@ RSpec.describe Dry::Transaction::StepAdapters::Try do
36
35
 
37
36
  context "when the error was raised" do
38
37
 
39
- it "return a Left Monad" do
40
- expect(subject.call(step, 1234)).to be_a Dry::Monads::Either::Left
38
+ it "returns a Failure value" do
39
+ expect(subject.(operation, options, [1234])).to be_a_failure
41
40
  end
42
41
 
43
- it "return the raised error as output" do
44
- result = subject.call(step, 1234)
45
- expect(result.value).to be_a Test::NotValidError
46
- expect(result.value.message).to eql 'not a string'
42
+ it "returns the raised error as output" do
43
+ result = subject.(operation, options, [1234])
44
+ expect(result.left).to be_a Test::NotValidError
45
+ expect(result.left.message).to eql("not a string")
47
46
  end
48
47
 
49
48
  context "when using the :raise option" do
@@ -54,26 +53,22 @@ RSpec.describe Dry::Transaction::StepAdapters::Try do
54
53
  }
55
54
  }
56
55
 
57
- it "return a Left Monad" do
58
- expect(subject.call(step, 1234)).to be_a Dry::Monads::Either::Left
56
+ it "returns a Failure value" do
57
+ expect(subject.(operation, options, [1234])).to be_a_failure
59
58
  end
60
59
 
61
- it "return the error specified by :raise as output" do
62
- result = subject.call(step, 1234)
63
- expect(result.value).to be_a Test::BetterNamingError
64
- expect(result.value.message).to eql 'not a string'
60
+ it "returns the error specified by :raise as output" do
61
+ result = subject.(operation, options, [1234])
62
+ expect(result.left).to be_a Test::BetterNamingError
63
+ expect(result.left.message).to eql("not a string")
65
64
  end
66
65
  end
67
66
  end
68
67
 
69
68
  context "when the error was NOT raised" do
70
69
 
71
- it "return a Right Monad" do
72
- expect(subject.call(step, 'input')).to be_a Dry::Monads::Either::Right
73
- end
74
-
75
- it "return the result of the operation as output" do
76
- expect(subject.call(step, 'input').value).to eql 'INPUT'
70
+ it "returns a Success value" do
71
+ expect(subject.(operation, options, ["input"])).to eql(Success("INPUT"))
77
72
  end
78
73
 
79
74
  context "when using the :raise option" do
@@ -84,12 +79,8 @@ RSpec.describe Dry::Transaction::StepAdapters::Try do
84
79
  }
85
80
  }
86
81
 
87
- it "return a Right Monad" do
88
- expect(subject.call(step, 'input')).to be_a Dry::Monads::Either::Right
89
- end
90
-
91
- it "return the result of the operation as output" do
92
- expect(subject.call(step, 'input').value).to eql 'INPUT'
82
+ it "returns a Success value" do
83
+ expect(subject.(operation, options, ["input"])).to eql(Success("INPUT"))
93
84
  end
94
85
  end
95
86
  end
@@ -8,8 +8,23 @@ RSpec.describe Dry::Transaction::Step do
8
8
  describe "#call" do
9
9
  let(:listener) do
10
10
  Class.new do
11
- def test_success(*args); end
12
- alias_method :test_failure, :test_success
11
+ attr_reader :started, :success, :failed
12
+
13
+ def initialize
14
+ @started = []
15
+ @success = []
16
+ @failed = []
17
+ end
18
+
19
+ def on_step(event)
20
+ started << event[:step_name]
21
+ end
22
+ def on_step_succeeded(event)
23
+ success << "succeded_#{event[:step_name]}"
24
+ end
25
+ def on_step_failed(event)
26
+ failed << "failed_#{event[:step_name]}"
27
+ end
13
28
  end.new
14
29
  end
15
30
 
@@ -17,33 +32,49 @@ RSpec.describe Dry::Transaction::Step do
17
32
  subject { step.call(input) }
18
33
 
19
34
  context "when operation succeeds" do
20
- let(:operation) { proc { |input| Dry::Monads::Either::Right.new(input) } }
35
+ let(:operation) { proc { |input| Dry::Monads::Result::Success.new(input) } }
21
36
 
22
37
  it { is_expected.to be_right }
23
38
 
24
- it "publishes success" do
25
- expect(listener).to receive(:test_success).with(input)
39
+ it "publishes step_succeeded" do
40
+ expect(listener).to receive(:on_step_succeeded).and_call_original
26
41
  step.subscribe(listener)
27
42
  subject
43
+
44
+ expect(listener.success).to eq ['succeded_test']
45
+ end
46
+ end
47
+
48
+ context "when operation starts" do
49
+ let(:operation) { proc { |input| Dry::Monads::Result::Right.new(input) } }
50
+
51
+ it "publishes step" do
52
+ expect(listener).to receive(:on_step).and_call_original
53
+ step.subscribe(listener)
54
+ subject
55
+
56
+ expect(listener.started).to eq [:test]
28
57
  end
29
58
  end
30
59
 
31
60
  context "when operation fails" do
32
- let(:operation) { proc { |input| Dry::Monads::Either::Left.new("error") } }
61
+ let(:operation) { proc { |input| Dry::Monads::Result::Failure.new("error") } }
33
62
 
34
63
  it { is_expected.to be_left }
35
64
 
36
65
  it "wraps value in StepFailure" do
37
66
  aggregate_failures do
38
- expect(subject.value).to be_a Dry::Transaction::StepFailure
39
- expect(subject.value.value).to eq "error"
67
+ expect(subject.left).to be_a Dry::Transaction::StepFailure
68
+ expect(subject.left.value).to eq "error"
40
69
  end
41
70
  end
42
71
 
43
- it "publishes failure" do
44
- expect(listener).to receive(:test_failure).with(input, "error")
72
+ it "publishes step_failed" do
73
+ expect(listener).to receive(:on_step_failed).and_call_original
45
74
  step.subscribe(listener)
46
75
  subject
76
+
77
+ expect(listener.failed).to eq ['failed_test']
47
78
  end
48
79
  end
49
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-transaction
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Riley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-10 00:00:00.000000000 Z
11
+ date: 2018-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-container
@@ -25,47 +25,47 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.2.8
27
27
  - !ruby/object:Gem::Dependency
28
- name: dry-matcher
28
+ name: dry-events
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.0
33
+ version: 0.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.5.0
40
+ version: 0.1.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: dry-monads
42
+ name: dry-matcher
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.0.1
47
+ version: 0.7.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.0.1
54
+ version: 0.7.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: wisper
56
+ name: dry-monads
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.6.0
61
+ version: 0.4.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.6.0
68
+ version: 0.4.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +85,9 @@ dependencies:
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '11.2'
90
+ - - ">="
88
91
  - !ruby/object:Gem::Version
89
92
  version: 11.2.2
90
93
  type: :development
@@ -92,6 +95,9 @@ dependencies:
92
95
  version_requirements: !ruby/object:Gem::Requirement
93
96
  requirements:
94
97
  - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '11.2'
100
+ - - ">="
95
101
  - !ruby/object:Gem::Version
96
102
  version: 11.2.2
97
103
  - !ruby/object:Gem::Dependency
@@ -100,28 +106,28 @@ dependencies:
100
106
  requirements:
101
107
  - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: 3.3.0
109
+ version: '3.3'
104
110
  type: :development
105
111
  prerelease: false
106
112
  version_requirements: !ruby/object:Gem::Requirement
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: 3.3.0
116
+ version: '3.3'
111
117
  - !ruby/object:Gem::Dependency
112
118
  name: simplecov
113
119
  requirement: !ruby/object:Gem::Requirement
114
120
  requirements:
115
- - - "~>"
121
+ - - ">="
116
122
  - !ruby/object:Gem::Version
117
- version: 0.10.0
123
+ version: '0'
118
124
  type: :development
119
125
  prerelease: false
120
126
  version_requirements: !ruby/object:Gem::Requirement
121
127
  requirements:
122
- - - "~>"
128
+ - - ">="
123
129
  - !ruby/object:Gem::Version
124
- version: 0.10.0
130
+ version: '0'
125
131
  - !ruby/object:Gem::Dependency
126
132
  name: yard
127
133
  requirement: !ruby/object:Gem::Requirement
@@ -151,13 +157,19 @@ files:
151
157
  - lib/dry-transaction.rb
152
158
  - lib/dry/transaction.rb
153
159
  - lib/dry/transaction/builder.rb
160
+ - lib/dry/transaction/callable.rb
154
161
  - lib/dry/transaction/dsl.rb
162
+ - lib/dry/transaction/errors.rb
155
163
  - lib/dry/transaction/instance_methods.rb
156
164
  - lib/dry/transaction/operation.rb
157
165
  - lib/dry/transaction/operation_resolver.rb
158
166
  - lib/dry/transaction/result_matcher.rb
167
+ - lib/dry/transaction/stack.rb
159
168
  - lib/dry/transaction/step.rb
169
+ - lib/dry/transaction/step_adapter.rb
160
170
  - lib/dry/transaction/step_adapters.rb
171
+ - lib/dry/transaction/step_adapters/around.rb
172
+ - lib/dry/transaction/step_adapters/check.rb
161
173
  - lib/dry/transaction/step_adapters/map.rb
162
174
  - lib/dry/transaction/step_adapters/raw.rb
163
175
  - lib/dry/transaction/step_adapters/tee.rb
@@ -165,14 +177,21 @@ files:
165
177
  - lib/dry/transaction/step_failure.rb
166
178
  - lib/dry/transaction/version.rb
167
179
  - spec/examples.txt
180
+ - spec/integration/around_spec.rb
168
181
  - spec/integration/custom_step_adapters_spec.rb
169
182
  - spec/integration/operation_spec.rb
170
183
  - spec/integration/passing_step_arguments_spec.rb
171
184
  - spec/integration/publishing_step_events_spec.rb
172
185
  - spec/integration/transaction_spec.rb
186
+ - spec/integration/transaction_without_steps_spec.rb
173
187
  - spec/spec_helper.rb
174
- - spec/support/either_mixin.rb
188
+ - spec/support/container.rb
189
+ - spec/support/database.rb
190
+ - spec/support/db_transactions.rb
191
+ - spec/support/result_mixin.rb
175
192
  - spec/support/test_module_constants.rb
193
+ - spec/unit/step_adapters/around_spec.rb
194
+ - spec/unit/step_adapters/check_spec.rb
176
195
  - spec/unit/step_adapters/map_spec.rb
177
196
  - spec/unit/step_adapters/raw_spec.rb
178
197
  - spec/unit/step_adapters/tee_spec.rb
@@ -190,7 +209,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
190
209
  requirements:
191
210
  - - ">="
192
211
  - !ruby/object:Gem::Version
193
- version: 2.1.0
212
+ version: 2.2.0
194
213
  required_rubygems_version: !ruby/object:Gem::Requirement
195
214
  requirements:
196
215
  - - ">="
@@ -198,9 +217,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
217
  version: '0'
199
218
  requirements: []
200
219
  rubyforge_project:
201
- rubygems_version: 2.6.11
220
+ rubygems_version: 2.7.5
202
221
  signing_key:
203
222
  specification_version: 4
204
223
  summary: Business Transaction Flow DSL
205
224
  test_files: []
206
- has_rdoc:
@@ -1,3 +0,0 @@
1
- RSpec.configure do |config|
2
- config.include Dry::Monads::Either::Mixin
3
- end