trailblazer-macro 2.1.0.beta1
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/.gitignore +18 -0
- data/.rubocop.yml +16 -0
- data/.rubocop_todo.yml +642 -0
- data/.travis.yml +15 -0
- data/CHANGES.md +3 -0
- data/COMM-LICENSE +91 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +9 -0
- data/README.md +5 -0
- data/Rakefile +13 -0
- data/lib/trailblazer/macro.rb +13 -0
- data/lib/trailblazer/macro/version.rb +5 -0
- data/lib/trailblazer/operation/guard.rb +18 -0
- data/lib/trailblazer/operation/input_output.rb +28 -0
- data/lib/trailblazer/operation/model.rb +52 -0
- data/lib/trailblazer/operation/nested.rb +90 -0
- data/lib/trailblazer/operation/policy.rb +44 -0
- data/lib/trailblazer/operation/pundit.rb +38 -0
- data/lib/trailblazer/operation/rescue.rb +42 -0
- data/lib/trailblazer/operation/wrap.rb +83 -0
- data/test/docs/guard_test.rb +162 -0
- data/test/docs/macro_test.rb +36 -0
- data/test/docs/model_test.rb +75 -0
- data/test/docs/nested_test.rb +113 -0
- data/test/docs/pundit_test.rb +133 -0
- data/test/docs/rescue_test.rb +126 -0
- data/test/docs/wrap_test.rb +274 -0
- data/test/lib/methods.rb +25 -0
- data/test/operation/model_test.rb +54 -0
- data/test/operation/nested_test.rb +293 -0
- data/test/operation/pundit_test.rb +106 -0
- data/test/test_helper.rb +39 -0
- data/trailblazer-macro.gemspec +36 -0
- metadata +243 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
#:policy
|
4
|
+
class MyPolicy
|
5
|
+
def initialize(user, model)
|
6
|
+
@user, @model = user, model
|
7
|
+
end
|
8
|
+
|
9
|
+
def create?
|
10
|
+
@user == Module && @model.id.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def new?
|
14
|
+
@user == Class
|
15
|
+
end
|
16
|
+
end
|
17
|
+
#:policy end
|
18
|
+
|
19
|
+
#--
|
20
|
+
# with policy
|
21
|
+
class DocsPunditProcTest < Minitest::Spec
|
22
|
+
Song = Struct.new(:id)
|
23
|
+
|
24
|
+
#:pundit
|
25
|
+
class Create < Trailblazer::Operation
|
26
|
+
step Model( Song, :new )
|
27
|
+
step Policy::Pundit( MyPolicy, :create? )
|
28
|
+
# ...
|
29
|
+
end
|
30
|
+
#:pundit end
|
31
|
+
|
32
|
+
it { Trailblazer::Operation::Inspect.(Create).must_equal %{[>model.build,>policy.default.eval]} }
|
33
|
+
it { Create.(params: {}, current_user: Module).inspect(:model).must_equal %{<Result:true [#<struct DocsPunditProcTest::Song id=nil>] >} }
|
34
|
+
it { Create.(params: {} ).inspect(:model).must_equal %{<Result:false [#<struct DocsPunditProcTest::Song id=nil>] >} }
|
35
|
+
|
36
|
+
it do
|
37
|
+
#:pundit-result
|
38
|
+
result = Create.(params: {}, current_user: Module)
|
39
|
+
result["result.policy.default"].success? #=> true
|
40
|
+
result["result.policy.default"]["policy"] #=> #<MyPolicy ...>
|
41
|
+
#:pundit-result end
|
42
|
+
result["result.policy.default"].success?.must_equal true
|
43
|
+
result["result.policy.default"]["policy"].is_a?(MyPolicy).must_equal true
|
44
|
+
end
|
45
|
+
|
46
|
+
#---
|
47
|
+
#- override
|
48
|
+
class New < Create
|
49
|
+
step Policy::Pundit( MyPolicy, :new? ), override: true
|
50
|
+
end
|
51
|
+
|
52
|
+
it { Trailblazer::Operation::Inspect.(New).must_equal %{[>model.build,>policy.default.eval]} }
|
53
|
+
it { New.(params: {}, current_user: Class ).inspect(:model).must_equal %{<Result:true [#<struct DocsPunditProcTest::Song id=nil>] >} }
|
54
|
+
it { New.(params: {}, current_user: nil ).inspect(:model).must_equal %{<Result:false [#<struct DocsPunditProcTest::Song id=nil>] >} }
|
55
|
+
|
56
|
+
#---
|
57
|
+
#- override with :name
|
58
|
+
class Edit < Trailblazer::Operation
|
59
|
+
step Policy::Pundit( MyPolicy, :create?, name: "first" )
|
60
|
+
step Policy::Pundit( MyPolicy, :new?, name: "second" )
|
61
|
+
end
|
62
|
+
|
63
|
+
class Update < Edit
|
64
|
+
step Policy::Pundit( MyPolicy, :new?, name: "first" ), override: true
|
65
|
+
end
|
66
|
+
|
67
|
+
it { Trailblazer::Operation::Inspect.(Edit).must_equal %{[>policy.first.eval,>policy.second.eval]} }
|
68
|
+
it { Edit.(params: {}, current_user: Class).inspect(:model).must_equal %{<Result:false [nil] >} }
|
69
|
+
it { Trailblazer::Operation::Inspect.(Update).must_equal %{[>policy.first.eval,>policy.second.eval]} }
|
70
|
+
it { Update.(params: {}, current_user: Class).inspect(:model).must_equal %{<Result:true [nil] >} }
|
71
|
+
|
72
|
+
#---
|
73
|
+
# dependency injection
|
74
|
+
class AnotherPolicy < MyPolicy
|
75
|
+
def create?
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it {
|
81
|
+
result =
|
82
|
+
#:di-call
|
83
|
+
Create.(params: {},
|
84
|
+
current_user: Module,
|
85
|
+
"policy.default.eval" => Trailblazer::Operation::Policy::Pundit.build(AnotherPolicy, :create?)
|
86
|
+
)
|
87
|
+
#:di-call end
|
88
|
+
result.inspect("").must_equal %{<Result:true [nil] >} }
|
89
|
+
end
|
90
|
+
|
91
|
+
#-
|
92
|
+
# with name:
|
93
|
+
class PunditWithNameTest < Minitest::Spec
|
94
|
+
Song = Struct.new(:id)
|
95
|
+
|
96
|
+
#:name
|
97
|
+
class Create < Trailblazer::Operation
|
98
|
+
step Model( Song, :new )
|
99
|
+
step Policy::Pundit( MyPolicy, :create?, name: "after_model" )
|
100
|
+
# ...
|
101
|
+
end
|
102
|
+
#:name end
|
103
|
+
|
104
|
+
it {
|
105
|
+
#:name-call
|
106
|
+
result = Create.(params: {}, current_user: Module)
|
107
|
+
result["result.policy.after_model"].success? #=> true
|
108
|
+
#:name-call end
|
109
|
+
result["result.policy.after_model"].success?.must_equal true }
|
110
|
+
end
|
111
|
+
|
112
|
+
#---
|
113
|
+
# class-level guard
|
114
|
+
# class DocsGuardClassLevelTest < Minitest::Spec
|
115
|
+
# #:class-level
|
116
|
+
# class Create < Trailblazer::Operation
|
117
|
+
# step Policy::Guard[ ->(options) { options["current_user"] == Module } ],
|
118
|
+
# before: "operation.new"
|
119
|
+
# #~pipe--only
|
120
|
+
# step ->(options) { options["x"] = true }
|
121
|
+
# #~pipe--only end
|
122
|
+
# end
|
123
|
+
# #:class-level end
|
124
|
+
|
125
|
+
# it { Create.(); Create["result.policy"].must_be_nil }
|
126
|
+
# it { Create.(params: {}, current_user: Module)["x"].must_equal true }
|
127
|
+
# it { Create.(params: {} )["x"].must_be_nil }
|
128
|
+
# end
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
# TODO:
|
133
|
+
#policy.default
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class NestedRescueTest < Minitest::Spec
|
4
|
+
#---
|
5
|
+
# nested raise (i hope people won't use this but it works)
|
6
|
+
A = Class.new(RuntimeError)
|
7
|
+
Y = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
class NestedInsanity < Trailblazer::Operation
|
10
|
+
step Rescue {
|
11
|
+
step ->(options, **) { options["a"] = true }
|
12
|
+
step Rescue {
|
13
|
+
step ->(options, **) { options["y"] = true }
|
14
|
+
success ->(options, **) { raise Y if options["raise-y"] }
|
15
|
+
step ->(options, **) { options["z"] = true }
|
16
|
+
}
|
17
|
+
step ->(options, **) { options["b"] = true }
|
18
|
+
success ->(options, **) { raise A if options["raise-a"] }
|
19
|
+
step ->(options, **) { options["c"] = true }
|
20
|
+
failure ->(options, **) { options["inner-err"] = true }
|
21
|
+
}
|
22
|
+
step ->(options, **) { options["e"] = true }, id: "nested/e"
|
23
|
+
failure ->(options, **) { options["outer-err"] = true }, id: "nested/failure"
|
24
|
+
end
|
25
|
+
|
26
|
+
it { Trailblazer::Operation::Inspect.(NestedInsanity).must_match /\[>Rescue\(\d+\),>nested/ } # FIXME: better introspect tests for all id-generating macros.
|
27
|
+
it { NestedInsanity.().inspect("a", "y", "z", "b", "c", "e", "inner-err", "outer-err").must_equal %{<Result:true [true, true, true, true, true, true, nil, nil] >} }
|
28
|
+
it { NestedInsanity.( "raise-y" => true).inspect("a", "y", "z", "b", "c", "e", "inner-err", "outer-err").must_equal %{<Result:false [true, true, nil, nil, nil, nil, true, true] >} }
|
29
|
+
it { NestedInsanity.( "raise-a" => true).inspect("a", "y", "z", "b", "c", "e", "inner-err", "outer-err").must_equal %{<Result:false [true, true, true, true, nil, nil, nil, true] >} }
|
30
|
+
|
31
|
+
#-
|
32
|
+
# inheritance
|
33
|
+
class UbernestedInsanity < NestedInsanity
|
34
|
+
end
|
35
|
+
|
36
|
+
it { UbernestedInsanity.().inspect("a", "y", "z", "b", "c", "e", "inner-err", "outer-err").must_equal %{<Result:true [true, true, true, true, true, true, nil, nil] >} }
|
37
|
+
it { UbernestedInsanity.( "raise-a" => true).inspect("a", "y", "z", "b", "c", "e", "inner-err", "outer-err").must_equal %{<Result:false [true, true, true, true, nil, nil, nil, true] >} }
|
38
|
+
end
|
39
|
+
|
40
|
+
class RescueTest < Minitest::Spec
|
41
|
+
|
42
|
+
=begin
|
43
|
+
plain Rescue()
|
44
|
+
=end
|
45
|
+
class RescueWithoutHandlerTest < Minitest::Spec
|
46
|
+
Memo = Class.new
|
47
|
+
|
48
|
+
class Memo::Create < Trailblazer::Operation
|
49
|
+
step :find_model
|
50
|
+
step Rescue() {
|
51
|
+
step :update
|
52
|
+
step :rehash
|
53
|
+
}
|
54
|
+
step :notify
|
55
|
+
fail :log_error
|
56
|
+
#~methods
|
57
|
+
include Test::Methods
|
58
|
+
#~methods end
|
59
|
+
end
|
60
|
+
|
61
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq, :exception_class).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify], nil] >} }
|
62
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >} }
|
63
|
+
end
|
64
|
+
|
65
|
+
=begin
|
66
|
+
Rescue( handler: X )
|
67
|
+
=end
|
68
|
+
class RescueWithHandlerTest < Minitest::Spec
|
69
|
+
Memo = Class.new
|
70
|
+
|
71
|
+
#:rescue-handler
|
72
|
+
class MyHandler
|
73
|
+
def self.call(exception, (ctx), *)
|
74
|
+
ctx[:exception_class] = exception.class
|
75
|
+
end
|
76
|
+
end
|
77
|
+
#:rescue-handler end
|
78
|
+
|
79
|
+
#:rescue
|
80
|
+
class Memo::Create < Trailblazer::Operation
|
81
|
+
step :find_model
|
82
|
+
step Rescue( RuntimeError, handler: MyHandler ) {
|
83
|
+
step :update
|
84
|
+
step :rehash
|
85
|
+
}
|
86
|
+
step :notify
|
87
|
+
fail :log_error
|
88
|
+
#~methods
|
89
|
+
include Test::Methods
|
90
|
+
#~methods end
|
91
|
+
end
|
92
|
+
#:rescue end
|
93
|
+
|
94
|
+
it { Memo::Create.( { seq: [], } ).inspect(:seq, :exception_class).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify], nil] >} }
|
95
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq, :exception_class).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error], RuntimeError] >} }
|
96
|
+
end
|
97
|
+
|
98
|
+
=begin
|
99
|
+
Rescue( handler: :instance_method )
|
100
|
+
=end
|
101
|
+
class RescueWithHandlerTest < Minitest::Spec
|
102
|
+
Memo = Class.new
|
103
|
+
|
104
|
+
#:rescue-method
|
105
|
+
class Memo::Create < Trailblazer::Operation
|
106
|
+
step :find_model
|
107
|
+
step Rescue( RuntimeError, handler: :my_handler ) {
|
108
|
+
step :update
|
109
|
+
step :rehash
|
110
|
+
}
|
111
|
+
step :notify
|
112
|
+
fail :log_error
|
113
|
+
#~methods
|
114
|
+
include Test::Methods
|
115
|
+
#~methods end
|
116
|
+
|
117
|
+
def my_handler(exception, (ctx), *)
|
118
|
+
ctx[:exception_class] = exception.class
|
119
|
+
end
|
120
|
+
end
|
121
|
+
#:rescue-method end
|
122
|
+
|
123
|
+
it { Memo::Create.( { seq: [], } ).inspect(:seq, :exception_class).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify], nil] >} }
|
124
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq, :exception_class).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error], RuntimeError] >} }
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class DocsWrapTest < Minitest::Spec
|
4
|
+
module Memo
|
5
|
+
end
|
6
|
+
|
7
|
+
=begin
|
8
|
+
When success: return the block's returns
|
9
|
+
When raise: return {Railway.fail!}
|
10
|
+
=end
|
11
|
+
#:wrap-handler
|
12
|
+
class HandleUnsafeProcess
|
13
|
+
def self.call((ctx, flow_options), *, &block)
|
14
|
+
begin
|
15
|
+
yield # calls the wrapped steps
|
16
|
+
rescue
|
17
|
+
[ Trailblazer::Operation::Railway.fail!, [ctx, flow_options] ]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
#:wrap-handler end
|
22
|
+
|
23
|
+
#:wrap
|
24
|
+
class Memo::Create < Trailblazer::Operation
|
25
|
+
step :find_model
|
26
|
+
step Wrap( HandleUnsafeProcess ) {
|
27
|
+
step :update
|
28
|
+
step :rehash
|
29
|
+
}
|
30
|
+
step :notify
|
31
|
+
fail :log_error
|
32
|
+
#~methods
|
33
|
+
include Test::Methods
|
34
|
+
#~methods end
|
35
|
+
end
|
36
|
+
#:wrap end
|
37
|
+
|
38
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
39
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >} }
|
40
|
+
|
41
|
+
=begin
|
42
|
+
Tracing with Wrap()
|
43
|
+
=end
|
44
|
+
it do
|
45
|
+
options = { seq: [] }
|
46
|
+
#:trace-call
|
47
|
+
result = Memo::Create.trace( options )
|
48
|
+
#:trace-call end
|
49
|
+
result.wtf.gsub("\n", "").must_match /.*Start.*find_model.*Wrap.*update.*rehash.*success.*notify.*success/
|
50
|
+
=begin
|
51
|
+
#:trace-success
|
52
|
+
result.wtf? #=>
|
53
|
+
|-- #<Trailblazer::Activity::Start semantic=:default>
|
54
|
+
|-- find_model
|
55
|
+
|-- Wrap/85
|
56
|
+
| |-- #<Trailblazer::Activity::Start semantic=:default>
|
57
|
+
| |-- update
|
58
|
+
| |-- rehash
|
59
|
+
| `-- #<Trailblazer::Operation::Railway::End::Success semantic=:success>
|
60
|
+
|-- notify
|
61
|
+
`-- #<Trailblazer::Operation::Railway::End::Success semantic=:success>
|
62
|
+
#:trace-success end
|
63
|
+
=end
|
64
|
+
end
|
65
|
+
|
66
|
+
=begin
|
67
|
+
When success: return the block's returns
|
68
|
+
When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
69
|
+
=end
|
70
|
+
class WrapGoesIntoFailFastTest < Minitest::Spec
|
71
|
+
Memo = Module.new
|
72
|
+
|
73
|
+
class Memo::Create < Trailblazer::Operation
|
74
|
+
class HandleUnsafeProcess
|
75
|
+
def self.call((ctx), *, &block)
|
76
|
+
begin
|
77
|
+
yield # calls the wrapped steps
|
78
|
+
rescue
|
79
|
+
[ Trailblazer::Operation::Railway.fail!, [ctx, {}] ]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
step :find_model
|
85
|
+
step Wrap( HandleUnsafeProcess ) {
|
86
|
+
step :update
|
87
|
+
step :rehash
|
88
|
+
}, fail_fast: true
|
89
|
+
step :notify
|
90
|
+
fail :log_error
|
91
|
+
|
92
|
+
#~methods
|
93
|
+
include Test::Methods
|
94
|
+
#~methods end
|
95
|
+
end
|
96
|
+
|
97
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
98
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >} }
|
99
|
+
end
|
100
|
+
|
101
|
+
=begin
|
102
|
+
When success: return the block's returns
|
103
|
+
When raise: return {Railway.fail_fast!} and configure Wrap() to {fast_track: true}
|
104
|
+
=end
|
105
|
+
class WrapGoesIntoFailFastViaFastTrackTest < Minitest::Spec
|
106
|
+
Memo = Module.new
|
107
|
+
|
108
|
+
#:fail-fast-handler
|
109
|
+
class HandleUnsafeProcess
|
110
|
+
def self.call((ctx), *, &block)
|
111
|
+
begin
|
112
|
+
yield # calls the wrapped steps
|
113
|
+
rescue
|
114
|
+
[ Trailblazer::Operation::Railway.fail_fast!, [ctx, {}] ]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
#:fail-fast-handler end
|
119
|
+
|
120
|
+
#:fail-fast
|
121
|
+
class Memo::Create < Trailblazer::Operation
|
122
|
+
step :find_model
|
123
|
+
step Wrap( HandleUnsafeProcess ) {
|
124
|
+
step :update
|
125
|
+
step :rehash
|
126
|
+
}, fast_track: true
|
127
|
+
step :notify
|
128
|
+
fail :log_error
|
129
|
+
#~methods
|
130
|
+
include Test::Methods
|
131
|
+
#~methods end
|
132
|
+
end
|
133
|
+
#:fail-fast end
|
134
|
+
|
135
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
136
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >} }
|
137
|
+
end
|
138
|
+
|
139
|
+
=begin
|
140
|
+
When success: return the block's returns
|
141
|
+
When raise: return {Railway.fail!} or {Railway.pass!}
|
142
|
+
=end
|
143
|
+
class WrapWithTransactionTest < Minitest::Spec
|
144
|
+
Memo = Module.new
|
145
|
+
|
146
|
+
module Sequel
|
147
|
+
def self.transaction
|
148
|
+
begin
|
149
|
+
end_event, (ctx, flow_options) = yield
|
150
|
+
true
|
151
|
+
rescue
|
152
|
+
false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
#:transaction-handler
|
158
|
+
class MyTransaction
|
159
|
+
def self.call((ctx, flow_options), *, &block)
|
160
|
+
result = Sequel.transaction { yield }
|
161
|
+
|
162
|
+
signal = result ? Trailblazer::Operation::Railway.pass! : Trailblazer::Operation::Railway.fail!
|
163
|
+
|
164
|
+
[ signal, [ctx, flow_options] ]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
#:transaction-handler end
|
168
|
+
|
169
|
+
#:transaction
|
170
|
+
class Memo::Create < Trailblazer::Operation
|
171
|
+
step :find_model
|
172
|
+
step Wrap( MyTransaction ) {
|
173
|
+
step :update
|
174
|
+
step :rehash
|
175
|
+
}
|
176
|
+
step :notify
|
177
|
+
fail :log_error
|
178
|
+
#~methods
|
179
|
+
include Test::Methods
|
180
|
+
#~methods end
|
181
|
+
end
|
182
|
+
#:transaction end
|
183
|
+
|
184
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
185
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >} }
|
186
|
+
end
|
187
|
+
|
188
|
+
=begin
|
189
|
+
When success: return the block's returns
|
190
|
+
When raise: return {Railway.fail!} or {Railway.pass!}
|
191
|
+
=end
|
192
|
+
class WrapWithCustomEndsTest < Minitest::Spec
|
193
|
+
Memo = Module.new
|
194
|
+
Sequel = WrapWithTransactionTest::Sequel
|
195
|
+
|
196
|
+
#:custom-handler
|
197
|
+
class MyTransaction
|
198
|
+
MyFailSignal = Class.new(Trailblazer::Activity::Signal)
|
199
|
+
|
200
|
+
def self.call((ctx, flow_options), *, &block)
|
201
|
+
result = Sequel.transaction { yield }
|
202
|
+
|
203
|
+
signal = result ? Trailblazer::Operation::Railway.pass! : MyFailSignal
|
204
|
+
|
205
|
+
[ signal, [ctx, flow_options] ]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
#:custom-handler end
|
209
|
+
|
210
|
+
#:custom
|
211
|
+
class Memo::Create < Trailblazer::Operation
|
212
|
+
step :find_model
|
213
|
+
step Wrap( MyTransaction ) {
|
214
|
+
step :update
|
215
|
+
step :rehash
|
216
|
+
},
|
217
|
+
Output(:success) => End(:transaction_worked),
|
218
|
+
Output(MyTransaction::MyFailSignal, :failure) => End(:transaction_failed)
|
219
|
+
step :notify
|
220
|
+
fail :log_error
|
221
|
+
#~methods
|
222
|
+
include Test::Methods
|
223
|
+
#~methods end
|
224
|
+
end
|
225
|
+
#:custom end
|
226
|
+
|
227
|
+
it do
|
228
|
+
result = Memo::Create.( { seq: [] } )
|
229
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
230
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_worked>}
|
231
|
+
end
|
232
|
+
|
233
|
+
it do
|
234
|
+
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
235
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
236
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_failed>}
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
=begin
|
241
|
+
When success: return the block's returns
|
242
|
+
When raise: return {Railway.pass!} and go "successful"
|
243
|
+
=end
|
244
|
+
class WrapGoesIntoPassFromRescueTest < Minitest::Spec
|
245
|
+
Memo = Module.new
|
246
|
+
|
247
|
+
class Memo::Create < Trailblazer::Operation
|
248
|
+
class HandleUnsafeProcess
|
249
|
+
def self.call((ctx), *, &block)
|
250
|
+
begin
|
251
|
+
yield # calls the wrapped steps
|
252
|
+
rescue
|
253
|
+
[ Trailblazer::Operation::Railway.pass!, [ctx, {}] ]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
step :find_model
|
259
|
+
step Wrap( HandleUnsafeProcess ) {
|
260
|
+
step :update
|
261
|
+
step :rehash
|
262
|
+
}
|
263
|
+
step :notify
|
264
|
+
fail :log_error
|
265
|
+
|
266
|
+
#~methods
|
267
|
+
include Test::Methods
|
268
|
+
#~methods end
|
269
|
+
end
|
270
|
+
|
271
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
272
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
273
|
+
end
|
274
|
+
end
|