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,13 +1,14 @@
1
- require "dry/monads/either"
1
+ require "dry/monads/result"
2
2
  require "dry/transaction/version"
3
3
  require "dry/transaction/step_adapters"
4
4
  require "dry/transaction/builder"
5
+ require "dry/transaction/errors"
5
6
 
6
7
  module Dry
7
8
  # Business transaction DSL
8
9
  module Transaction
9
10
  def self.included(klass)
10
- klass.send :include, Dry::Transaction()
11
+ klass.include(Dry::Transaction())
11
12
  end
12
13
  end
13
14
 
@@ -24,21 +25,23 @@ module Dry
24
25
  # transaction, with its output passed as the input to the next operation.
25
26
  # Operations will only be called if the previous step was a success.
26
27
  #
27
- # A step is successful when it returns a [dry-monads](dry-monads) `Right`
28
+ # A step is successful when it returns a [dry-monads](dry-monads) `Success`
28
29
  # object wrapping its output value. A step is a failure when it returns a
29
- # `Left` object. If your operations already return a `Right` or `Left`, they
30
+ # `Failure` object. If your operations already return a `Success` or `Failure`, they
30
31
  # can be added to your operation as plain `step` steps.
31
32
  #
32
33
  # Add operation to your transaction with the `step` method.
33
34
  #
34
- # If your operations don't already return `Right` or `Left`, then they can be
35
+ # If your operations don't already return `Success` or `Failure`, then they can be
35
36
  # added to the transaction with the following steps:
36
37
  #
37
- # * `map` --- wrap the output of the operation in a `Right`
38
- # * `try` --- wrap the output of the operation in a `Right`, unless a certain
39
- # exception is raised, which will be caught and returned as a `Left`.
40
- # * `tee` --- ignore the output of the operation and pass through its original
41
- # input as a `Right`.
38
+ # * `check` --- wrap original input in `Success` or `Failure` according to operation
39
+ # return value, and pass it as output.
40
+ # * `map` --- wrap the output of the operation in a `Success`
41
+ # * `try` --- wrap the output of the operation in a `Success`, unless a certain
42
+ # exception is raised, which will be caught and returned as a `Failure`.
43
+ # * `tee` --- ignore the output of the operation and pass through its original
44
+ # input as a `Success`
42
45
  #
43
46
  # [dry-monads]: https://rubygems.org/gems/dry-monads
44
47
  #
@@ -51,7 +54,7 @@ module Dry
51
54
  #
52
55
  # def second_step(input)
53
56
  # result = do_something_with(input)
54
- # Right(result)
57
+ # Success(result)
55
58
  # end
56
59
  # end
57
60
  #
data/spec/examples.txt CHANGED
@@ -1,65 +1,81 @@
1
- example_id | status | run_time |
2
- -------------------------------------------------------- | ------ | --------------- |
3
- ./spec/integration/custom_step_adapters_spec.rb[1:1] | passed | 0.00042 seconds |
4
- ./spec/integration/operation_spec.rb[1:1] | passed | 0.00017 seconds |
5
- ./spec/integration/operation_spec.rb[1:2] | passed | 0.00014 seconds |
6
- ./spec/integration/passing_step_arguments_spec.rb[1:1:1] | passed | 0.00142 seconds |
7
- ./spec/integration/passing_step_arguments_spec.rb[1:2:1] | passed | 0.00248 seconds |
8
- ./spec/integration/passing_step_arguments_spec.rb[1:3:1] | passed | 0.0003 seconds |
9
- ./spec/integration/publishing_step_events_spec.rb[1:1:1] | passed | 0.00072 seconds |
10
- ./spec/integration/publishing_step_events_spec.rb[1:1:2] | passed | 0.00067 seconds |
11
- ./spec/integration/publishing_step_events_spec.rb[1:2:1] | passed | 0.00061 seconds |
12
- ./spec/integration/publishing_step_events_spec.rb[1:2:2] | passed | 0.00057 seconds |
13
- ./spec/integration/publishing_step_events_spec.rb[1:3:1] | passed | 0.00084 seconds |
14
- ./spec/integration/publishing_step_events_spec.rb[1:3:2] | passed | 0.00207 seconds |
15
- ./spec/integration/transaction_spec.rb[1:1:1] | passed | 0.00115 seconds |
16
- ./spec/integration/transaction_spec.rb[1:1:2] | passed | 0.00095 seconds |
17
- ./spec/integration/transaction_spec.rb[1:1:3] | passed | 0.00098 seconds |
18
- ./spec/integration/transaction_spec.rb[1:1:4] | passed | 0.00133 seconds |
19
- ./spec/integration/transaction_spec.rb[1:1:5] | passed | 0.00104 seconds |
20
- ./spec/integration/transaction_spec.rb[1:2:1] | passed | 0.00212 seconds |
21
- ./spec/integration/transaction_spec.rb[1:3:1] | passed | 0.00048 seconds |
22
- ./spec/integration/transaction_spec.rb[1:4:1] | passed | 0.00061 seconds |
23
- ./spec/integration/transaction_spec.rb[1:5:1] | passed | 0.00062 seconds |
24
- ./spec/integration/transaction_spec.rb[1:6:1] | passed | 0.00283 seconds |
25
- ./spec/integration/transaction_spec.rb[1:7:1] | passed | 0.00051 seconds |
26
- ./spec/integration/transaction_spec.rb[1:8:1] | passed | 0.00307 seconds |
27
- ./spec/integration/transaction_spec.rb[1:8:2] | passed | 0.0007 seconds |
28
- ./spec/integration/transaction_spec.rb[1:8:3] | passed | 0.00173 seconds |
29
- ./spec/integration/transaction_spec.rb[1:8:4] | passed | 0.00162 seconds |
30
- ./spec/integration/transaction_spec.rb[1:8:5] | passed | 0.0006 seconds |
31
- ./spec/integration/transaction_spec.rb[1:8:6] | passed | 0.00052 seconds |
32
- ./spec/integration/transaction_spec.rb[1:9:1] | passed | 0.0006 seconds |
33
- ./spec/integration/transaction_spec.rb[1:9:2] | passed | 0.00073 seconds |
34
- ./spec/integration/transaction_spec.rb[1:9:3] | passed | 0.00156 seconds |
35
- ./spec/integration/transaction_spec.rb[1:9:4] | passed | 0.00097 seconds |
36
- ./spec/integration/transaction_spec.rb[1:9:5] | passed | 0.00068 seconds |
37
- ./spec/integration/transaction_spec.rb[1:10:1] | passed | 0.00062 seconds |
38
- ./spec/unit/step_adapters/map_spec.rb[1:1:1] | passed | 0.00056 seconds |
39
- ./spec/unit/step_adapters/map_spec.rb[1:1:2] | passed | 0.001 seconds |
40
- ./spec/unit/step_adapters/raw_spec.rb[1:1:1:1] | passed | 0.00013 seconds |
41
- ./spec/unit/step_adapters/raw_spec.rb[1:1:2:1] | passed | 0.0001 seconds |
42
- ./spec/unit/step_adapters/raw_spec.rb[1:1:2:2] | passed | 0.00012 seconds |
43
- ./spec/unit/step_adapters/raw_spec.rb[1:1:3:1] | passed | 0.0001 seconds |
44
- ./spec/unit/step_adapters/raw_spec.rb[1:1:3:2] | passed | 0.00011 seconds |
45
- ./spec/unit/step_adapters/tee_spec.rb[1:1:1] | passed | 0.00011 seconds |
46
- ./spec/unit/step_adapters/tee_spec.rb[1:1:2] | passed | 0.00009 seconds |
47
- ./spec/unit/step_adapters/try_spec.rb[1:1:1:1] | passed | 0.00015 seconds |
48
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:1] | passed | 0.00012 seconds |
49
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:2] | passed | 0.00016 seconds |
50
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:3:1] | passed | 0.00013 seconds |
51
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:3:2] | passed | 0.00012 seconds |
52
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:1] | passed | 0.00011 seconds |
53
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:2] | passed | 0.00012 seconds |
54
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:3:1] | passed | 0.00011 seconds |
55
- ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:3:2] | passed | 0.00012 seconds |
56
- ./spec/unit/step_spec.rb[1:1:1:1] | passed | 0.00024 seconds |
57
- ./spec/unit/step_spec.rb[1:1:1:2] | passed | 0.01629 seconds |
58
- ./spec/unit/step_spec.rb[1:1:2:1] | passed | 0.00016 seconds |
59
- ./spec/unit/step_spec.rb[1:1:2:2] | passed | 0.00161 seconds |
60
- ./spec/unit/step_spec.rb[1:1:2:3] | passed | 0.00038 seconds |
61
- ./spec/unit/step_spec.rb[1:2:1:1] | passed | 0.00018 seconds |
62
- ./spec/unit/step_spec.rb[1:2:2:1] | passed | 0.00011 seconds |
63
- ./spec/unit/step_spec.rb[1:2:3:1] | passed | 0.00013 seconds |
64
- ./spec/unit/step_spec.rb[1:3:1:1] | passed | 0.00012 seconds |
65
- ./spec/unit/step_spec.rb[1:3:2:1] | passed | 0.00013 seconds |
1
+ example_id | status | run_time |
2
+ ----------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/integration/around_spec.rb[1:1] | passed | 0.00176 seconds |
4
+ ./spec/integration/around_spec.rb[1:2] | passed | 0.00362 seconds |
5
+ ./spec/integration/around_spec.rb[1:3] | passed | 0.00089 seconds |
6
+ ./spec/integration/around_spec.rb[1:4] | passed | 0.00249 seconds |
7
+ ./spec/integration/custom_step_adapters_spec.rb[1:1] | passed | 0.00198 seconds |
8
+ ./spec/integration/operation_spec.rb[1:1] | passed | 0.00012 seconds |
9
+ ./spec/integration/operation_spec.rb[1:2] | passed | 0.00094 seconds |
10
+ ./spec/integration/passing_step_arguments_spec.rb[1:1:1] | passed | 0.00085 seconds |
11
+ ./spec/integration/passing_step_arguments_spec.rb[1:2:1] | passed | 0.00061 seconds |
12
+ ./spec/integration/passing_step_arguments_spec.rb[1:3:1] | passed | 0.00039 seconds |
13
+ ./spec/integration/publishing_step_events_spec.rb[1:1:1] | passed | 0.00243 seconds |
14
+ ./spec/integration/publishing_step_events_spec.rb[1:1:2] | passed | 0.00068 seconds |
15
+ ./spec/integration/publishing_step_events_spec.rb[1:2:1] | passed | 0.00058 seconds |
16
+ ./spec/integration/publishing_step_events_spec.rb[1:2:2] | passed | 0.00056 seconds |
17
+ ./spec/integration/publishing_step_events_spec.rb[1:3:1] | passed | 0.0007 seconds |
18
+ ./spec/integration/publishing_step_events_spec.rb[1:3:2] | passed | 0.00077 seconds |
19
+ ./spec/integration/transaction_spec.rb[1:1:1] | passed | 0.0006 seconds |
20
+ ./spec/integration/transaction_spec.rb[1:1:2] | passed | 0.00058 seconds |
21
+ ./spec/integration/transaction_spec.rb[1:1:3] | passed | 0.00083 seconds |
22
+ ./spec/integration/transaction_spec.rb[1:1:4] | passed | 0.00062 seconds |
23
+ ./spec/integration/transaction_spec.rb[1:1:5] | passed | 0.00056 seconds |
24
+ ./spec/integration/transaction_spec.rb[1:2:1] | passed | 0.00059 seconds |
25
+ ./spec/integration/transaction_spec.rb[1:3:1] | passed | 0.00098 seconds |
26
+ ./spec/integration/transaction_spec.rb[1:4:1] | passed | 0.00084 seconds |
27
+ ./spec/integration/transaction_spec.rb[1:5:1] | passed | 0.00057 seconds |
28
+ ./spec/integration/transaction_spec.rb[1:6:1] | passed | 0.00054 seconds |
29
+ ./spec/integration/transaction_spec.rb[1:7:1] | passed | 0.00086 seconds |
30
+ ./spec/integration/transaction_spec.rb[1:8:1] | passed | 0.00084 seconds |
31
+ ./spec/integration/transaction_spec.rb[1:9:1] | passed | 0.00075 seconds |
32
+ ./spec/integration/transaction_spec.rb[1:9:2] | passed | 0.00064 seconds |
33
+ ./spec/integration/transaction_spec.rb[1:9:3] | passed | 0.00079 seconds |
34
+ ./spec/integration/transaction_spec.rb[1:9:4] | passed | 0.00101 seconds |
35
+ ./spec/integration/transaction_spec.rb[1:9:5] | passed | 0.00089 seconds |
36
+ ./spec/integration/transaction_spec.rb[1:9:6] | passed | 0.00094 seconds |
37
+ ./spec/integration/transaction_spec.rb[1:10:1] | passed | 0.00061 seconds |
38
+ ./spec/integration/transaction_spec.rb[1:10:2] | passed | 0.00056 seconds |
39
+ ./spec/integration/transaction_spec.rb[1:10:3] | passed | 0.0006 seconds |
40
+ ./spec/integration/transaction_spec.rb[1:10:4] | passed | 0.00055 seconds |
41
+ ./spec/integration/transaction_spec.rb[1:10:5] | passed | 0.00061 seconds |
42
+ ./spec/integration/transaction_spec.rb[1:11:1] | passed | 0.00085 seconds |
43
+ ./spec/integration/transaction_spec.rb[1:12:1] | passed | 0.00046 seconds |
44
+ ./spec/integration/transaction_spec.rb[1:13:1:1:1] | passed | 0.00066 seconds |
45
+ ./spec/integration/transaction_spec.rb[1:13:2:1:1] | passed | 0.00064 seconds |
46
+ ./spec/integration/transaction_spec.rb[1:13:2:2:1] | passed | 0.00048 seconds |
47
+ ./spec/integration/transaction_without_steps_spec.rb[1:1:1] | passed | 0.00268 seconds |
48
+ ./spec/integration/transaction_without_steps_spec.rb[1:1:2] | passed | 0.00095 seconds |
49
+ ./spec/integration/transaction_without_steps_spec.rb[1:1:3] | passed | 0.00087 seconds |
50
+ ./spec/integration/transaction_without_steps_spec.rb[1:1:4] | passed | 0.0008 seconds |
51
+ ./spec/integration/transaction_without_steps_spec.rb[1:2:1] | passed | 0.00082 seconds |
52
+ ./spec/integration/transaction_without_steps_spec.rb[1:3:1] | passed | 0.00103 seconds |
53
+ ./spec/unit/step_adapters/around_spec.rb[1:1:1:1] | passed | 0.00024 seconds |
54
+ ./spec/unit/step_adapters/around_spec.rb[1:1:2:1] | passed | 0.00019 seconds |
55
+ ./spec/unit/step_adapters/around_spec.rb[1:1:3:1] | passed | 0.0001 seconds |
56
+ ./spec/unit/step_adapters/check_spec.rb[1:1:1] | passed | 0.00009 seconds |
57
+ ./spec/unit/step_adapters/check_spec.rb[1:1:2:1] | passed | 0.0001 seconds |
58
+ ./spec/unit/step_adapters/check_spec.rb[1:1:3:1] | passed | 0.0001 seconds |
59
+ ./spec/unit/step_adapters/check_spec.rb[1:1:4:1] | passed | 0.0001 seconds |
60
+ ./spec/unit/step_adapters/map_spec.rb[1:1:1] | passed | 0.0001 seconds |
61
+ ./spec/unit/step_adapters/raw_spec.rb[1:1:1:1] | passed | 0.00012 seconds |
62
+ ./spec/unit/step_adapters/raw_spec.rb[1:1:2:1] | passed | 0.0001 seconds |
63
+ ./spec/unit/step_adapters/tee_spec.rb[1:1:1] | passed | 0.0001 seconds |
64
+ ./spec/unit/step_adapters/try_spec.rb[1:1:1:1] | passed | 0.0002 seconds |
65
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:1] | passed | 0.00013 seconds |
66
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:2] | passed | 0.00016 seconds |
67
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:3:1] | passed | 0.00012 seconds |
68
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:1:3:2] | passed | 0.00015 seconds |
69
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:1] | passed | 0.00018 seconds |
70
+ ./spec/unit/step_adapters/try_spec.rb[1:1:2:2:2:1] | passed | 0.00011 seconds |
71
+ ./spec/unit/step_spec.rb[1:1:1:1] | passed | 0.0002 seconds |
72
+ ./spec/unit/step_spec.rb[1:1:1:2] | passed | 0.00054 seconds |
73
+ ./spec/unit/step_spec.rb[1:1:2:1] | passed | 0.00033 seconds |
74
+ ./spec/unit/step_spec.rb[1:1:3:1] | passed | 0.00018 seconds |
75
+ ./spec/unit/step_spec.rb[1:1:3:2] | passed | 0.00251 seconds |
76
+ ./spec/unit/step_spec.rb[1:1:3:3] | passed | 0.0125 seconds |
77
+ ./spec/unit/step_spec.rb[1:2:1:1] | passed | 0.00011 seconds |
78
+ ./spec/unit/step_spec.rb[1:2:2:1] | passed | 0.00011 seconds |
79
+ ./spec/unit/step_spec.rb[1:2:3:1] | passed | 0.00014 seconds |
80
+ ./spec/unit/step_spec.rb[1:3:1:1] | passed | 0.00011 seconds |
81
+ ./spec/unit/step_spec.rb[1:3:2:1] | passed | 0.00015 seconds |
@@ -0,0 +1,81 @@
1
+ RSpec.describe "around steps" do
2
+ include_context "db transactions"
3
+
4
+ include Dry::Monads::Result::Mixin
5
+
6
+ before do
7
+ container.instance_exec do
8
+ register :validate, -> input { Success(input) }
9
+
10
+ register :persist_user do |user:, **other|
11
+ self[:database] << [:user, user]
12
+ Success(other)
13
+ end
14
+
15
+ register :persist_account do |account: |
16
+ self[:database] << [:account, account]
17
+ Success(true)
18
+ end
19
+ end
20
+ end
21
+
22
+ let(:transaction) do
23
+ Class.new do
24
+ include Dry::Transaction(container: Test::Container)
25
+
26
+ step :validate
27
+ around :transaction
28
+ step :persist_user
29
+ step :persist_account
30
+ step :finalize
31
+ end
32
+ end
33
+
34
+ let(:input) { { user: { name: "Jane" }, account: { balance: 0 } } }
35
+
36
+ it "starts a transaction" do
37
+ called = false
38
+
39
+ finalize = -> x do
40
+ called = true
41
+ expect(database).to(be_in_transaction)
42
+ Success(x)
43
+ end
44
+
45
+ result = transaction.new(finalize: finalize).call(input)
46
+ expect(called).to be true
47
+ expect(result).to eql(Success(true))
48
+ end
49
+
50
+ it "commits transactions" do
51
+ transaction.new(finalize: -> x { Success(x) }).call(input)
52
+
53
+ expect(database).to be_committed
54
+ expect(database).not_to be_rolled_back
55
+ expect(database).not_to be_in_transaction
56
+ expect(database).to eql([[:user, name: "Jane"],
57
+ [:account, balance: 0]])
58
+ end
59
+
60
+ it "rolls back transactions on failure" do
61
+ transaction.new(finalize: -> x { Failure(x) }).call(input)
62
+
63
+ expect(database).to be_rolled_back
64
+ expect(database).not_to be_in_transaction
65
+ expect(database).not_to be_committed
66
+ expect(database).to be_empty
67
+ end
68
+
69
+ it "rolls back transaction on exception" do
70
+ uncaught = Class.new(StandardError)
71
+
72
+ expect {
73
+ transaction.new(finalize: -> x { raise uncaught }).call(input)
74
+ }.to raise_error(uncaught)
75
+
76
+ expect(database).to be_rolled_back
77
+ expect(database).not_to be_in_transaction
78
+ expect(database).not_to be_committed
79
+ expect(database).to be_empty
80
+ end
81
+ end
@@ -3,6 +3,7 @@ RSpec.describe "Custom step adapters" do
3
3
  Class.new do
4
4
  include Dry::Transaction(container: Test::Container, step_adapters: Test::CustomStepAdapters)
5
5
 
6
+ check :jane?, with: :jane?
6
7
  map :process, with: :process
7
8
  tee :persist, with: :persist
8
9
  enqueue :deliver, with: :deliver
@@ -15,17 +16,18 @@ RSpec.describe "Custom step adapters" do
15
16
 
16
17
  module Test
17
18
  Container = {
19
+ jane?: -> input { input["name"] == "Jane" },
18
20
  process: -> input { {name: input["name"], email: input["email"]} },
19
21
  persist: -> input { Test::DB << input and true },
20
22
  deliver: -> input { "Delivered email to #{input[:email]}" },
21
23
  }
22
24
 
23
25
  class CustomStepAdapters < Dry::Transaction::StepAdapters
24
- extend Dry::Monads::Either::Mixin
26
+ extend Dry::Monads::Result::Mixin
25
27
 
26
- register :enqueue, -> step, input, *args {
27
- Test::QUEUE << step.operation.call(input, *args)
28
- Right(input)
28
+ register :enqueue, -> operation, _options, args {
29
+ Test::QUEUE << operation.(*args)
30
+ Success(args[0])
29
31
  }
30
32
  end
31
33
  end
@@ -6,13 +6,13 @@ RSpec.describe Dry::Transaction::Operation do
6
6
  include Dry::Transaction::Operation
7
7
 
8
8
  def call(input)
9
- Right(input)
9
+ Success(input)
10
10
  end
11
11
  end.new
12
12
  }
13
13
 
14
- it "mixes in the Either monad constructors" do
15
- expect(operation.("hello")).to be_right
14
+ it "mixes in the Result monad constructors" do
15
+ expect(operation.("hello")).to be_success
16
16
  end
17
17
 
18
18
  it "supports pattern matching when called with a block" do
@@ -29,7 +29,7 @@ RSpec.describe "Passing additional arguments to step operations" do
29
29
  let(:step_options) { {validate: ["doe.com"]} }
30
30
 
31
31
  it "passes the arguments and calls the operations successfully" do
32
- expect(call_transaction).to be_a Dry::Monads::Either::Right
32
+ expect(call_transaction).to be_a Dry::Monads::Result::Success
33
33
  end
34
34
  end
35
35
 
@@ -4,7 +4,7 @@ RSpec.describe "publishing step events" do
4
4
  extend Dry::Container::Mixin
5
5
 
6
6
  register :process, -> input { {name: input["name"]} }
7
- register :verify, -> input { input[:name].to_s != "" ? Dry::Monads.Right(input) : Dry::Monads.Left("no name") }
7
+ register :verify, -> input { input[:name].to_s != "" ? Dry::Monads.Success(input) : Dry::Monads.Failure("no name") }
8
8
  register :persist, -> input { Test::DB << input and true }
9
9
  end
10
10
  }
@@ -19,7 +19,27 @@ RSpec.describe "publishing step events" do
19
19
  end.new
20
20
  }
21
21
 
22
- let(:subscriber) { spy(:subscriber) }
22
+ let(:subscriber) do
23
+ Class.new do
24
+ attr_reader :started, :success, :failed
25
+
26
+ def initialize
27
+ @started = []
28
+ @success = []
29
+ @failed = []
30
+ end
31
+
32
+ def on_step(event)
33
+ started << event[:step_name]
34
+ end
35
+ def on_step_succeeded(event)
36
+ success << {step_name: event[:step_name], args: event[:args]}
37
+ end
38
+ def on_step_failed(event)
39
+ failed << {step_name: event[:step_name], args: event[:args], value: event[:value]}
40
+ end
41
+ end.new
42
+ end
23
43
 
24
44
  before do
25
45
  Test::DB = []
@@ -34,17 +54,20 @@ RSpec.describe "publishing step events" do
34
54
  specify "subscriber receives success events" do
35
55
  transaction.call("name" => "Jane")
36
56
 
37
- expect(subscriber).to have_received(:process_success).with(name: "Jane")
38
- expect(subscriber).to have_received(:verify_success).with(name: "Jane")
39
- expect(subscriber).to have_received(:persist_success).with(name: "Jane")
57
+ expected_result = [
58
+ { step_name: :process, args: [ {"name" => "Jane"} ] },
59
+ { step_name: :verify, args: [ { name: "Jane" } ] },
60
+ { step_name: :persist, args: [ { name: "Jane" } ] }
61
+ ]
62
+
63
+ expect(subscriber.success).to eq expected_result
40
64
  end
41
65
 
42
66
  specify "subsriber receives success events for passing steps, a failure event for the failing step, and no subsequent events" do
43
67
  transaction.call("name" => "")
44
68
 
45
- expect(subscriber).to have_received(:process_success).with(name: "")
46
- expect(subscriber).to have_received(:verify_failure).with({name: ""}, "no name")
47
- expect(subscriber).not_to have_received(:persist_success)
69
+ expect(subscriber.success).to eq [ { step_name: :process, args:[ { "name" => "" } ] } ]
70
+ expect(subscriber.failed).to eq [ { step_name: :verify, args: [ { name: ""} ], value: "no name" } ]
48
71
  end
49
72
  end
50
73
 
@@ -56,15 +79,13 @@ RSpec.describe "publishing step events" do
56
79
  specify "subscriber receives success event for the specified step" do
57
80
  transaction.call("name" => "Jane")
58
81
 
59
- expect(subscriber).to have_received(:verify_success).with(name: "Jane")
60
- expect(subscriber).not_to have_received(:process_success)
61
- expect(subscriber).not_to have_received(:persist_success)
82
+ expect(subscriber.success).to eq [ { step_name: :verify, args: [ { name: "Jane" } ] } ]
62
83
  end
63
84
 
64
85
  specify "subscriber receives failure event for the specified step" do
65
86
  transaction.call("name" => "")
66
87
 
67
- expect(subscriber).to have_received(:verify_failure).with({name: ""}, "no name")
88
+ expect(subscriber.failed).to eq [ { step_name: :verify, args: [ { name: ""} ], value: "no name" } ]
68
89
  end
69
90
  end
70
91
 
@@ -78,7 +99,7 @@ RSpec.describe "publishing step events" do
78
99
  extend Dry::Container::Mixin
79
100
 
80
101
  register :process, -> input { {name: input["name"]} }
81
- register :verify, -> input, name { input[:name].to_s == name ? Dry::Monads.Right(input) : Dry::Monads.Left("wrong name") }
102
+ register :verify, -> input, name { input[:name].to_s == name ? Dry::Monads.Success(input) : Dry::Monads.Failure("wrong name") }
82
103
  register :persist, -> input { Test::DB << input and true }
83
104
  end
84
105
  }
@@ -86,15 +107,13 @@ RSpec.describe "publishing step events" do
86
107
  specify "subscriber receives success event for the specified step" do
87
108
  transaction.with_step_args(verify: ["Jane"]).call("name" => "Jane")
88
109
 
89
- expect(subscriber).to have_received(:verify_success).with(name: "Jane")
90
- expect(subscriber).not_to have_received(:process_success)
91
- expect(subscriber).not_to have_received(:persist_success)
110
+ expect(subscriber.success).to eq [ { step_name: :verify, args: [ { name: "Jane" }, "Jane"] } ]
92
111
  end
93
112
 
94
113
  specify "subscriber receives failure event for the specified step" do
95
114
  transaction.with_step_args(verify: ["Jade"]).call("name" => "")
96
115
 
97
- expect(subscriber).to have_received(:verify_failure).with({name: ""}, "Jade", "wrong name")
116
+ expect(subscriber.failed).to eq [ { step_name: :verify, args: [ { name: "" }, "Jade"], value: "wrong name"} ]
98
117
  end
99
118
  end
100
119
  end