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.
- checksums.yaml +5 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +20 -14
- data/lib/dry/transaction/builder.rb +2 -4
- data/lib/dry/transaction/callable.rb +38 -0
- data/lib/dry/transaction/errors.rb +27 -0
- data/lib/dry/transaction/instance_methods.rb +22 -5
- data/lib/dry/transaction/operation.rb +4 -4
- data/lib/dry/transaction/operation_resolver.rb +5 -1
- data/lib/dry/transaction/result_matcher.rb +3 -3
- data/lib/dry/transaction/stack.rb +24 -0
- data/lib/dry/transaction/step.rb +37 -21
- data/lib/dry/transaction/step_adapter.rb +49 -0
- data/lib/dry/transaction/step_adapters/around.rb +25 -0
- data/lib/dry/transaction/step_adapters/check.rb +18 -0
- data/lib/dry/transaction/step_adapters/map.rb +3 -3
- data/lib/dry/transaction/step_adapters/raw.rb +6 -12
- data/lib/dry/transaction/step_adapters/tee.rb +4 -4
- data/lib/dry/transaction/step_adapters/try.rb +11 -8
- data/lib/dry/transaction/step_adapters.rb +2 -0
- data/lib/dry/transaction/version.rb +1 -1
- data/lib/dry/transaction.rb +14 -11
- data/spec/examples.txt +81 -65
- data/spec/integration/around_spec.rb +81 -0
- data/spec/integration/custom_step_adapters_spec.rb +6 -4
- data/spec/integration/operation_spec.rb +3 -3
- data/spec/integration/passing_step_arguments_spec.rb +1 -1
- data/spec/integration/publishing_step_events_spec.rb +36 -17
- data/spec/integration/transaction_spec.rb +165 -37
- data/spec/integration/transaction_without_steps_spec.rb +101 -0
- data/spec/spec_helper.rb +14 -5
- data/spec/support/container.rb +10 -0
- data/spec/support/database.rb +12 -0
- data/spec/support/db_transactions.rb +45 -0
- data/spec/support/result_mixin.rb +3 -0
- data/spec/unit/step_adapters/around_spec.rb +46 -0
- data/spec/unit/step_adapters/check_spec.rb +43 -0
- data/spec/unit/step_adapters/map_spec.rb +5 -12
- data/spec/unit/step_adapters/raw_spec.rb +16 -32
- data/spec/unit/step_adapters/tee_spec.rb +4 -10
- data/spec/unit/step_adapters/try_spec.rb +24 -33
- data/spec/unit/step_spec.rb +41 -10
- metadata +39 -21
- data/spec/support/either_mixin.rb +0 -3
data/lib/dry/transaction.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
require "dry/monads/
|
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.
|
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) `
|
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
|
-
# `
|
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 `
|
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
|
-
# * `
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# * `
|
41
|
-
#
|
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
|
-
#
|
57
|
+
# Success(result)
|
55
58
|
# end
|
56
59
|
# end
|
57
60
|
#
|
data/spec/examples.txt
CHANGED
@@ -1,65 +1,81 @@
|
|
1
|
-
example_id
|
2
|
-
|
3
|
-
./spec/integration/
|
4
|
-
./spec/integration/
|
5
|
-
./spec/integration/
|
6
|
-
./spec/integration/
|
7
|
-
./spec/integration/
|
8
|
-
./spec/integration/
|
9
|
-
./spec/integration/
|
10
|
-
./spec/integration/
|
11
|
-
./spec/integration/
|
12
|
-
./spec/integration/
|
13
|
-
./spec/integration/publishing_step_events_spec.rb[1:
|
14
|
-
./spec/integration/publishing_step_events_spec.rb[1:
|
15
|
-
./spec/integration/
|
16
|
-
./spec/integration/
|
17
|
-
./spec/integration/
|
18
|
-
./spec/integration/
|
19
|
-
./spec/integration/transaction_spec.rb[1:1:
|
20
|
-
./spec/integration/transaction_spec.rb[1:2
|
21
|
-
./spec/integration/transaction_spec.rb[1:3
|
22
|
-
./spec/integration/transaction_spec.rb[1:4
|
23
|
-
./spec/integration/transaction_spec.rb[1:5
|
24
|
-
./spec/integration/transaction_spec.rb[1:
|
25
|
-
./spec/integration/transaction_spec.rb[1:
|
26
|
-
./spec/integration/transaction_spec.rb[1:
|
27
|
-
./spec/integration/transaction_spec.rb[1:
|
28
|
-
./spec/integration/transaction_spec.rb[1:
|
29
|
-
./spec/integration/transaction_spec.rb[1:
|
30
|
-
./spec/integration/transaction_spec.rb[1:8:
|
31
|
-
./spec/integration/transaction_spec.rb[1:
|
32
|
-
./spec/integration/transaction_spec.rb[1:9:
|
33
|
-
./spec/integration/transaction_spec.rb[1:9:
|
34
|
-
./spec/integration/transaction_spec.rb[1:9:
|
35
|
-
./spec/integration/transaction_spec.rb[1:9:
|
36
|
-
./spec/integration/transaction_spec.rb[1:9:
|
37
|
-
./spec/integration/transaction_spec.rb[1:10:1]
|
38
|
-
./spec/
|
39
|
-
./spec/
|
40
|
-
./spec/
|
41
|
-
./spec/
|
42
|
-
./spec/
|
43
|
-
./spec/
|
44
|
-
./spec/
|
45
|
-
./spec/
|
46
|
-
./spec/
|
47
|
-
./spec/
|
48
|
-
./spec/
|
49
|
-
./spec/
|
50
|
-
./spec/
|
51
|
-
./spec/
|
52
|
-
./spec/
|
53
|
-
./spec/unit/step_adapters/
|
54
|
-
./spec/unit/step_adapters/
|
55
|
-
./spec/unit/step_adapters/
|
56
|
-
./spec/unit/
|
57
|
-
./spec/unit/
|
58
|
-
./spec/unit/
|
59
|
-
./spec/unit/
|
60
|
-
./spec/unit/
|
61
|
-
./spec/unit/
|
62
|
-
./spec/unit/
|
63
|
-
./spec/unit/
|
64
|
-
./spec/unit/
|
65
|
-
./spec/unit/
|
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::
|
26
|
+
extend Dry::Monads::Result::Mixin
|
25
27
|
|
26
|
-
register :enqueue, ->
|
27
|
-
Test::QUEUE <<
|
28
|
-
|
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
|
-
|
9
|
+
Success(input)
|
10
10
|
end
|
11
11
|
end.new
|
12
12
|
}
|
13
13
|
|
14
|
-
it "mixes in the
|
15
|
-
expect(operation.("hello")).to
|
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::
|
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.
|
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)
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
46
|
-
expect(subscriber).to
|
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
|
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
|
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.
|
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
|
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
|
116
|
+
expect(subscriber.failed).to eq [ { step_name: :verify, args: [ { name: "" }, "Jade"], value: "wrong name"} ]
|
98
117
|
end
|
99
118
|
end
|
100
119
|
end
|