trailblazer-macro 2.1.0.rc14 → 2.1.4
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/.travis.yml +9 -8
- data/CHANGES.md +23 -0
- data/lib/trailblazer/macro.rb +12 -13
- data/lib/trailblazer/macro/model.rb +9 -3
- data/lib/trailblazer/macro/rescue.rb +1 -1
- data/lib/trailblazer/macro/version.rb +1 -1
- data/lib/trailblazer/macro/wrap.rb +3 -1
- data/test/docs/guard_test.rb +0 -24
- data/test/docs/model_test.rb +20 -0
- data/test/docs/nested_test.rb +30 -0
- data/test/docs/rescue_test.rb +26 -1
- data/test/docs/wrap_test.rb +216 -80
- data/test/operation/model_test.rb +2 -5
- data/test/test_helper.rb +4 -3
- data/trailblazer-macro.gemspec +4 -2
- metadata +51 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4da758ccf1b9e9ff6fa413c687fe09c6df11449b84a775c65280a73d1b80f72
|
4
|
+
data.tar.gz: 23bd67cc32f045487ca761e15227fe562e87b7cde3616e7335a8ee3126c51217
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4671b91a21144afc728dba8397282a49f6517d183349179a357da87e57a223cb4f5cb81f3d29f0bda0e3013db7581367e02a6de28a19bfbc7b83dd286a3f0d9a
|
7
|
+
data.tar.gz: 339a312f0c7f7bee0afe5f74b06d3694ff826daff2e5bbfe4190a3238252cd92feb36ab14cf2429814eaf5b18e50abdac18bee594b7229c37fc64df8856e18b8
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
# 2.1.4
|
2
|
+
|
3
|
+
* Upgrade DSL version to fix step's circuit interface eating passed arguments
|
4
|
+
* Upgrade OP version to remove OP::Container reference in tests
|
5
|
+
|
6
|
+
# 2.1.3
|
7
|
+
|
8
|
+
* Rename Model()'s `not_found_end` kwarg to `not_found_terminus` for consistency.
|
9
|
+
|
10
|
+
# 2.1.2
|
11
|
+
|
12
|
+
* Fix to make macros available in all Linear::DSL strategies.
|
13
|
+
* Make `params` optional in `Model`.
|
14
|
+
* Support for adding `End.not_found` end in `Model`.
|
15
|
+
|
16
|
+
# 2.1.1
|
17
|
+
|
18
|
+
* Fix case when Macros generate same id due to small entropy
|
19
|
+
|
20
|
+
# 2.1.0
|
21
|
+
|
22
|
+
* Finally.
|
23
|
+
|
1
24
|
# 2.1.0.rc14
|
2
25
|
|
3
26
|
* Remove the explicit `dsl-linear` dependency.
|
data/lib/trailblazer/macro.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
require "forwardable"
|
1
2
|
require "trailblazer/activity"
|
2
|
-
require "trailblazer/activity/dsl/linear"
|
3
|
+
require "trailblazer/activity/dsl/linear"
|
3
4
|
require "trailblazer/operation" # TODO: remove this dependency
|
4
5
|
|
5
6
|
require "trailblazer/macro/model"
|
@@ -12,18 +13,16 @@ require "trailblazer/macro/wrap"
|
|
12
13
|
|
13
14
|
module Trailblazer
|
14
15
|
module Macro
|
15
|
-
# All macros sit in the {Trailblazer::Macro} namespace, where we forward calls from
|
16
|
-
# operations and activities to.
|
17
|
-
def self.forward_macros(target)
|
18
|
-
target.singleton_class.def_delegators Trailblazer::Macro, :Model, :Wrap, :Rescue, :Nested
|
19
|
-
target.const_set(:Policy, Trailblazer::Macro::Policy)
|
20
|
-
end
|
21
16
|
end
|
22
|
-
end
|
23
17
|
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
18
|
+
# All macros sit in the {Trailblazer::Macro} namespace, where we forward calls from
|
19
|
+
# operations and activities to.
|
20
|
+
module Activity::DSL::Linear::Helper
|
21
|
+
Policy = Trailblazer::Macro::Policy
|
27
22
|
|
28
|
-
|
29
|
-
|
23
|
+
module ClassMethods
|
24
|
+
extend Forwardable
|
25
|
+
def_delegators Trailblazer::Macro, :Model, :Nested, :Wrap, :Rescue
|
26
|
+
end # ClassMethods
|
27
|
+
end # Helper
|
28
|
+
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module Trailblazer::Macro
|
2
|
-
|
2
|
+
|
3
|
+
Linear = Trailblazer::Activity::DSL::Linear
|
4
|
+
|
5
|
+
def self.Model(model_class, action = nil, find_by_key = nil, id: 'model.build', not_found_terminus: false)
|
3
6
|
task = Trailblazer::Activity::TaskBuilder::Binary(Model.new)
|
4
7
|
|
5
8
|
injection = Trailblazer::Activity::TaskWrap::Inject::Defaults::Extension(
|
@@ -8,11 +11,14 @@ module Trailblazer::Macro
|
|
8
11
|
:"model.find_by_key" => find_by_key
|
9
12
|
)
|
10
13
|
|
11
|
-
{task: task, id:
|
14
|
+
options = { task: task, id: id, extensions: [injection] }
|
15
|
+
options = options.merge(Linear::Output(:failure) => Linear::End(:not_found)) if not_found_terminus
|
16
|
+
|
17
|
+
options
|
12
18
|
end
|
13
19
|
|
14
20
|
class Model
|
15
|
-
def call(options, params
|
21
|
+
def call(options, params: nil, **)
|
16
22
|
builder = Model::Builder.new
|
17
23
|
options[:model] = model = builder.call(options, params)
|
18
24
|
options[:"result.model"] = result = Trailblazer::Operation::Result.new(!model.nil?, {})
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Trailblazer
|
2
4
|
module Macro
|
3
|
-
def self.Wrap(user_wrap, id: "Wrap/#{
|
5
|
+
def self.Wrap(user_wrap, id: "Wrap/#{SecureRandom.hex(4)}", &block)
|
4
6
|
activity = Class.new(Activity::FastTrack, &block) # This is currently coupled to {dsl-linear}.
|
5
7
|
|
6
8
|
outputs = activity.to_h[:outputs]
|
data/test/docs/guard_test.rb
CHANGED
@@ -108,30 +108,6 @@ class DocsGuardNamedTest < Minitest::Spec
|
|
108
108
|
}
|
109
109
|
end
|
110
110
|
|
111
|
-
#---
|
112
|
-
# dependency injection
|
113
|
-
class DocsGuardInjectionTest < Minitest::Spec
|
114
|
-
#:di-op
|
115
|
-
class Create < Trailblazer::Operation
|
116
|
-
extend Trailblazer::Operation::Container
|
117
|
-
|
118
|
-
step Policy::Guard( ->(options, current_user:, **) { current_user == Module } )
|
119
|
-
end
|
120
|
-
#:di-op end
|
121
|
-
|
122
|
-
it { Create.(:current_user => Module).inspect("").must_equal %{<Result:true [nil] >} }
|
123
|
-
it {
|
124
|
-
result =
|
125
|
-
#:di-call
|
126
|
-
Create.(
|
127
|
-
{},
|
128
|
-
:current_user => Module,
|
129
|
-
:"policy.default.eval" => Trailblazer::Operation::Policy::Guard.build(->(options, **) { false })
|
130
|
-
)
|
131
|
-
#:di-call end
|
132
|
-
result.inspect("").must_equal %{<Result:false [nil] >} }
|
133
|
-
end
|
134
|
-
|
135
111
|
#---
|
136
112
|
# missing current_user throws exception
|
137
113
|
class DocsGuardMissingKeywordTest < Minitest::Spec
|
data/test/docs/model_test.rb
CHANGED
@@ -45,6 +45,13 @@ class DocsModelTest < Minitest::Spec
|
|
45
45
|
end
|
46
46
|
#:update-with-find-by-key end
|
47
47
|
|
48
|
+
#:update-with-not-found-end
|
49
|
+
class UpdateFailureWithModelNotFound < Trailblazer::Operation
|
50
|
+
step Model( Song, :find_by, not_found_terminus: true )
|
51
|
+
# ..
|
52
|
+
end
|
53
|
+
#:update-with-not-found-end end
|
54
|
+
|
48
55
|
it do
|
49
56
|
#:update-ok
|
50
57
|
result = Update.(params: { id: 1 })
|
@@ -83,6 +90,19 @@ class DocsModelTest < Minitest::Spec
|
|
83
90
|
result.success?.must_equal false
|
84
91
|
end
|
85
92
|
|
93
|
+
it do
|
94
|
+
#:update-with-not-found-end-use
|
95
|
+
result = UpdateFailureWithModelNotFound.(params: {title: nil})
|
96
|
+
result[:model] #=> nil
|
97
|
+
result.success? #=> false
|
98
|
+
result.event #=> #<Trailblazer::Activity::End semantic=:not_found>
|
99
|
+
#:update-with-not-found-end-use end
|
100
|
+
|
101
|
+
result[:model].must_be_nil
|
102
|
+
result.success?.must_equal false
|
103
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:not_found>}
|
104
|
+
end
|
105
|
+
|
86
106
|
#:show
|
87
107
|
class Show < Trailblazer::Operation
|
88
108
|
step Model( Song, :[] )
|
data/test/docs/nested_test.rb
CHANGED
@@ -131,6 +131,36 @@ class NestedInput < Minitest::Spec
|
|
131
131
|
C::Create.(seq: [], params: nil).inspect(:seq).must_equal %{<Result:true [[:create, :validate, :json, :save]] >}
|
132
132
|
end
|
133
133
|
|
134
|
+
it "Nested(:method), with pass_fast returned from nested" do
|
135
|
+
class JustPassFast < Trailblazer::Operation
|
136
|
+
step :just_pass_fast, pass_fast: true
|
137
|
+
include T.def_steps(:just_pass_fast)
|
138
|
+
end
|
139
|
+
|
140
|
+
module D
|
141
|
+
|
142
|
+
create =
|
143
|
+
#:nested-with-pass-fast
|
144
|
+
class Create < Trailblazer::Operation
|
145
|
+
|
146
|
+
def compute_nested(ctx, **)
|
147
|
+
JustPassFast
|
148
|
+
end
|
149
|
+
|
150
|
+
step :create
|
151
|
+
step Nested(:compute_nested)
|
152
|
+
step :save
|
153
|
+
#~meths
|
154
|
+
include T.def_steps(:create, :save)
|
155
|
+
#~meths end
|
156
|
+
end
|
157
|
+
#:nested-with-pass-fast end
|
158
|
+
|
159
|
+
# pass fast
|
160
|
+
create.(seq: []).inspect(:seq).must_equal %{<Result:true [[:create, :just_pass_fast, :save]] >}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
134
164
|
let(:compute_edit) {
|
135
165
|
->(ctx, what:, **) { what }
|
136
166
|
}
|
data/test/docs/rescue_test.rb
CHANGED
@@ -23,7 +23,7 @@ class NestedRescueTest < Minitest::Spec
|
|
23
23
|
fail ->(options, **) { options["outer-err"] = true }, id: "nested/failure"
|
24
24
|
end
|
25
25
|
|
26
|
-
it { Trailblazer::Developer.railway(NestedInsanity).must_match /\[>Rescue\(\
|
26
|
+
it { Trailblazer::Developer.railway(NestedInsanity).must_match /\[>Rescue\(.{8}\),>nested/ } # FIXME: better introspect tests for all id-generating macros.
|
27
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
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
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] >} }
|
@@ -126,4 +126,29 @@ Rescue( handler: :instance_method )
|
|
126
126
|
it { Memo::Create.( { seq: [], } ).inspect(:seq, :exception_class).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify], nil] >} }
|
127
127
|
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq, :exception_class).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error], RuntimeError] >} }
|
128
128
|
end
|
129
|
+
|
130
|
+
=begin
|
131
|
+
Rescue(), fast_track: true {}
|
132
|
+
=end
|
133
|
+
class RescueWithFastTrack < Minitest::Spec
|
134
|
+
Memo = Class.new
|
135
|
+
|
136
|
+
#:rescue-fasttrack
|
137
|
+
class Memo::Create < Trailblazer::Operation
|
138
|
+
rescue_block = ->(*) {
|
139
|
+
step :update, Output(:failure) => End(:fail_fast)
|
140
|
+
step :rehash
|
141
|
+
}
|
142
|
+
|
143
|
+
step :find_model
|
144
|
+
step Rescue(&rescue_block), fail_fast: true
|
145
|
+
step :notify
|
146
|
+
fail :log_error
|
147
|
+
#~methods
|
148
|
+
include T.def_steps(:find_model, :update, :notify, :log_error, :rehash)
|
149
|
+
end
|
150
|
+
|
151
|
+
it { Memo::Create.( { seq: [], } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
152
|
+
it { Memo::Create.( { seq: [], update: false } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update]] >} }
|
153
|
+
end
|
129
154
|
end
|
data/test/docs/wrap_test.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class DocsWrapTest < Minitest::Spec
|
4
|
-
module Memo
|
5
|
-
end
|
6
|
-
|
7
4
|
=begin
|
8
5
|
When success: return the block's returns
|
9
6
|
When raise: return {Railway.fail!}
|
@@ -11,11 +8,10 @@ When raise: return {Railway.fail!}
|
|
11
8
|
#:wrap-handler
|
12
9
|
class HandleUnsafeProcess
|
13
10
|
def self.call((ctx, flow_options), *, &block)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
11
|
+
yield # calls the wrapped steps
|
12
|
+
rescue
|
13
|
+
ctx[:exception] = $!.message
|
14
|
+
[ Trailblazer::Operation::Railway.fail!, [ctx, flow_options] ]
|
19
15
|
end
|
20
16
|
end
|
21
17
|
#:wrap-handler end
|
@@ -64,6 +60,11 @@ result.wtf? #=>
|
|
64
60
|
=end
|
65
61
|
end
|
66
62
|
|
63
|
+
=begin
|
64
|
+
Writing into ctx in a Wrap()
|
65
|
+
=end
|
66
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } )[:exception].must_equal("nope!") }
|
67
|
+
|
67
68
|
=begin
|
68
69
|
When success: return the block's returns
|
69
70
|
When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
@@ -74,13 +75,9 @@ When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
|
74
75
|
class Memo::Create < Trailblazer::Operation
|
75
76
|
class HandleUnsafeProcess
|
76
77
|
def self.call((ctx), *, &block)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
puts $!
|
81
|
-
ctx[:exception] = $!.message
|
82
|
-
[ Trailblazer::Operation::Railway.fail!, [ctx, {}] ]
|
83
|
-
end
|
78
|
+
yield # calls the wrapped steps
|
79
|
+
rescue
|
80
|
+
[ Trailblazer::Operation::Railway.fail!, [ctx, {}] ]
|
84
81
|
end
|
85
82
|
end
|
86
83
|
|
@@ -112,11 +109,9 @@ When raise: return {Railway.fail_fast!} and configure Wrap() to {fast_track: t
|
|
112
109
|
#:fail-fast-handler
|
113
110
|
class HandleUnsafeProcess
|
114
111
|
def self.call((ctx), *, &block)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
[ Trailblazer::Operation::Railway.fail_fast!, [ctx, {}] ]
|
119
|
-
end
|
112
|
+
yield # calls the wrapped steps
|
113
|
+
rescue
|
114
|
+
[ Trailblazer::Operation::Railway.fail_fast!, [ctx, {}] ]
|
120
115
|
end
|
121
116
|
end
|
122
117
|
#:fail-fast-handler end
|
@@ -145,122 +140,176 @@ When raise: return {Railway.fail_fast!} and configure Wrap() to {fast_track: t
|
|
145
140
|
When success: return the block's returns
|
146
141
|
When raise: return {Railway.fail!} or {Railway.pass!}
|
147
142
|
=end
|
148
|
-
class
|
149
|
-
Memo
|
143
|
+
class WrapWithCustomEndsTest < Minitest::Spec
|
144
|
+
Memo = Module.new
|
150
145
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
146
|
+
#:custom-handler
|
147
|
+
class MyTransaction
|
148
|
+
MyFailSignal = Class.new(Trailblazer::Activity::Signal)
|
149
|
+
|
150
|
+
def self.call((ctx, flow_options), *, &block)
|
151
|
+
yield # calls the wrapped steps
|
152
|
+
rescue
|
153
|
+
MyFailSignal
|
159
154
|
end
|
160
155
|
end
|
156
|
+
#:custom-handler end
|
161
157
|
|
162
|
-
#:
|
163
|
-
class
|
164
|
-
|
165
|
-
|
158
|
+
#:custom
|
159
|
+
class Memo::Create < Trailblazer::Operation
|
160
|
+
step :find_model
|
161
|
+
step Wrap( MyTransaction ) {
|
162
|
+
step :update
|
163
|
+
step :rehash
|
164
|
+
},
|
165
|
+
Output(:success) => End(:transaction_worked),
|
166
|
+
Output(MyTransaction::MyFailSignal, :failure) => End(:transaction_failed)
|
167
|
+
step :notify
|
168
|
+
fail :log_error
|
169
|
+
#~methods
|
170
|
+
include T.def_steps(:find_model, :update, :notify, :log_error)
|
171
|
+
include Rehash
|
172
|
+
#~methods end
|
173
|
+
end
|
174
|
+
#:custom end
|
166
175
|
|
167
|
-
|
176
|
+
it do
|
177
|
+
result = Memo::Create.( { seq: [] } )
|
178
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
179
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_worked>}
|
180
|
+
end
|
168
181
|
|
169
|
-
|
170
|
-
|
182
|
+
it do
|
183
|
+
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
184
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
185
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_failed>}
|
171
186
|
end
|
172
|
-
|
187
|
+
end
|
188
|
+
|
189
|
+
=begin
|
190
|
+
When success: return the block's returns
|
191
|
+
When raise: return {Railway.pass!} and go "successful"
|
192
|
+
=end
|
193
|
+
class WrapGoesIntoPassFromRescueTest < Minitest::Spec
|
194
|
+
Memo = Module.new
|
173
195
|
|
174
|
-
#:transaction
|
175
196
|
class Memo::Create < Trailblazer::Operation
|
197
|
+
class HandleUnsafeProcess
|
198
|
+
def self.call((ctx), *, &block)
|
199
|
+
yield # calls the wrapped steps
|
200
|
+
rescue
|
201
|
+
[ Trailblazer::Operation::Railway.pass!, [ctx, {}] ]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
176
205
|
step :find_model
|
177
|
-
|
178
|
-
step Wrap( MyTransaction ) {
|
206
|
+
step Wrap( HandleUnsafeProcess ) {
|
179
207
|
step :update
|
180
208
|
step :rehash
|
181
209
|
}
|
182
|
-
#:wrap-only end
|
183
210
|
step :notify
|
184
211
|
fail :log_error
|
212
|
+
|
185
213
|
#~methods
|
186
214
|
include T.def_steps(:find_model, :update, :notify, :log_error)
|
187
215
|
include Rehash
|
188
216
|
#~methods end
|
189
217
|
end
|
190
|
-
#:transaction end
|
191
218
|
|
192
219
|
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
193
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:
|
220
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
194
221
|
end
|
195
222
|
|
196
223
|
=begin
|
197
224
|
When success: return the block's returns
|
198
|
-
When raise: return {
|
225
|
+
When raise: return {true} and go "successful"
|
226
|
+
You can return boolean true in wrap.
|
199
227
|
=end
|
200
|
-
class
|
201
|
-
Memo
|
202
|
-
Sequel = WrapWithTransactionTest::Sequel
|
228
|
+
class WrapGoesIntoBooleanTrueFromRescueTest < Minitest::Spec
|
229
|
+
Memo = Module.new
|
203
230
|
|
204
|
-
|
205
|
-
|
206
|
-
|
231
|
+
class Memo::Create < Trailblazer::Operation
|
232
|
+
class HandleUnsafeProcess
|
233
|
+
def self.call((ctx), *, &block)
|
234
|
+
yield # calls the wrapped steps
|
235
|
+
rescue
|
236
|
+
true
|
237
|
+
end
|
238
|
+
end
|
207
239
|
|
208
|
-
|
209
|
-
|
240
|
+
step :find_model
|
241
|
+
step Wrap( HandleUnsafeProcess ) {
|
242
|
+
step :update
|
243
|
+
step :rehash
|
244
|
+
}
|
245
|
+
step :notify
|
246
|
+
fail :log_error
|
210
247
|
|
211
|
-
|
248
|
+
#~methods
|
249
|
+
include T.def_steps(:find_model, :update, :notify, :log_error)
|
250
|
+
include Rehash
|
251
|
+
#~methods end
|
252
|
+
end
|
212
253
|
|
213
|
-
|
214
|
-
|
254
|
+
it "translates true returned form a wrap to a signal with a `success` semantic" do
|
255
|
+
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
256
|
+
result.inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >}
|
257
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
215
258
|
end
|
216
|
-
|
259
|
+
end
|
260
|
+
|
261
|
+
=begin
|
262
|
+
When success: return the block's returns
|
263
|
+
When raise: return {false} and go "failed"
|
264
|
+
You can return boolean false in wrap.
|
265
|
+
=end
|
266
|
+
class WrapGoesIntoBooleanFalseFromRescueTest < Minitest::Spec
|
267
|
+
Memo = Module.new
|
217
268
|
|
218
|
-
#:custom
|
219
269
|
class Memo::Create < Trailblazer::Operation
|
270
|
+
class HandleUnsafeProcess
|
271
|
+
def self.call((ctx), *, &block)
|
272
|
+
yield # calls the wrapped steps
|
273
|
+
rescue
|
274
|
+
false
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
220
278
|
step :find_model
|
221
|
-
step Wrap(
|
279
|
+
step Wrap( HandleUnsafeProcess ) {
|
222
280
|
step :update
|
223
281
|
step :rehash
|
224
|
-
}
|
225
|
-
Output(:success) => End(:transaction_worked),
|
226
|
-
Output(MyTransaction::MyFailSignal, :failure) => End(:transaction_failed)
|
282
|
+
}
|
227
283
|
step :notify
|
228
284
|
fail :log_error
|
285
|
+
|
229
286
|
#~methods
|
230
287
|
include T.def_steps(:find_model, :update, :notify, :log_error)
|
231
288
|
include Rehash
|
232
289
|
#~methods end
|
233
290
|
end
|
234
|
-
#:custom end
|
235
|
-
|
236
|
-
it do
|
237
|
-
result = Memo::Create.( { seq: [] } )
|
238
|
-
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
239
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_worked>}
|
240
|
-
end
|
241
291
|
|
242
|
-
it do
|
292
|
+
it "translates false returned form a wrap to a signal with a `failure` semantic" do
|
243
293
|
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
244
|
-
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash]] >}
|
245
|
-
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:
|
294
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >}
|
295
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
246
296
|
end
|
247
297
|
end
|
248
298
|
|
249
299
|
=begin
|
250
300
|
When success: return the block's returns
|
251
|
-
When raise: return {
|
301
|
+
When raise: return {nil} and go "failed"
|
302
|
+
You can return nil in wrap.
|
252
303
|
=end
|
253
|
-
class
|
304
|
+
class WrapGoesIntoNilFromRescueTest < Minitest::Spec
|
254
305
|
Memo = Module.new
|
255
306
|
|
256
307
|
class Memo::Create < Trailblazer::Operation
|
257
308
|
class HandleUnsafeProcess
|
258
309
|
def self.call((ctx), *, &block)
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
[ Trailblazer::Operation::Railway.pass!, [ctx, {}] ]
|
263
|
-
end
|
310
|
+
yield # calls the wrapped steps
|
311
|
+
rescue
|
312
|
+
nil
|
264
313
|
end
|
265
314
|
end
|
266
315
|
|
@@ -278,7 +327,94 @@ When raise: return {Railway.pass!} and go "successful"
|
|
278
327
|
#~methods end
|
279
328
|
end
|
280
329
|
|
330
|
+
it "translates nil returned form a wrap to a signal with a `failure` semantic" do
|
331
|
+
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
332
|
+
result.inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >}
|
333
|
+
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
=begin
|
338
|
+
When success: return the block's returns
|
339
|
+
When raise: return {Railway.fail!}
|
340
|
+
This one is mostly to show how one could wrap steps in a transaction
|
341
|
+
=end
|
342
|
+
class WrapWithTransactionTest < Minitest::Spec
|
343
|
+
Memo = Module.new
|
344
|
+
|
345
|
+
module Sequel
|
346
|
+
def self.transaction
|
347
|
+
end_event, (ctx, flow_options) = yield
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
#:transaction-handler
|
352
|
+
class MyTransaction
|
353
|
+
def self.call((ctx, flow_options), *, &block)
|
354
|
+
Sequel.transaction { yield } # calls the wrapped steps
|
355
|
+
rescue
|
356
|
+
[ Trailblazer::Operation::Railway.fail!, [ctx, flow_options] ]
|
357
|
+
end
|
358
|
+
end
|
359
|
+
#:transaction-handler end
|
360
|
+
|
361
|
+
#:transaction
|
362
|
+
class Memo::Create < Trailblazer::Operation
|
363
|
+
step :find_model
|
364
|
+
step Wrap( MyTransaction ) {
|
365
|
+
step :update
|
366
|
+
step :rehash
|
367
|
+
}
|
368
|
+
step :notify
|
369
|
+
fail :log_error
|
370
|
+
#~methods
|
371
|
+
include T.def_steps(:find_model, :update, :notify, :log_error)
|
372
|
+
include Rehash
|
373
|
+
#~methods end
|
374
|
+
end
|
375
|
+
#:transaction end
|
376
|
+
|
281
377
|
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
282
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:
|
378
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >} }
|
379
|
+
end
|
380
|
+
|
381
|
+
=begin
|
382
|
+
When success: return {Railway.pass_fast!}
|
383
|
+
When failure: return {Railway.fail!}
|
384
|
+
This one is mostly to show how one could evaluate Wrap()'s return value based on Wrap() block's return
|
385
|
+
=end
|
386
|
+
class WrapWithBlockReturnSignatureCheckTest < Minitest::Spec
|
387
|
+
Memo = Module.new
|
388
|
+
|
389
|
+
#:handler-with-signature-evaluator
|
390
|
+
class HandleUnsafeProcess
|
391
|
+
def self.call((_ctx, _flow_options), *, &block)
|
392
|
+
signal, (ctx, flow_options) = yield
|
393
|
+
evaluated_signal = if signal.to_h[:semantic] == :success
|
394
|
+
Trailblazer::Operation::Railway.pass_fast!
|
395
|
+
else
|
396
|
+
Trailblazer::Operation::Railway.fail!
|
397
|
+
end
|
398
|
+
[ evaluated_signal, [ctx, flow_options] ]
|
399
|
+
end
|
400
|
+
end
|
401
|
+
#:handler-with-signature-evaluator end
|
402
|
+
|
403
|
+
#:transaction
|
404
|
+
class Memo::Create < Trailblazer::Operation
|
405
|
+
step :find_model
|
406
|
+
step Wrap( HandleUnsafeProcess ) {
|
407
|
+
step :update
|
408
|
+
}, fast_track: true # because Wrap can return pass_fast! now
|
409
|
+
step :notify
|
410
|
+
fail :log_error
|
411
|
+
#~methods
|
412
|
+
include T.def_steps(:find_model, :update, :notify, :log_error)
|
413
|
+
#~methods end
|
414
|
+
end
|
415
|
+
#:transaction end
|
416
|
+
|
417
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update]] >} }
|
418
|
+
it { Memo::Create.( { seq: [], update: false } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :log_error]] >} }
|
283
419
|
end
|
284
420
|
end
|
@@ -19,11 +19,8 @@ class ModelTest < Minitest::Spec
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# :new new.
|
22
|
-
it
|
23
|
-
|
24
|
-
|
25
|
-
result = Create.(params: {})
|
26
|
-
|
22
|
+
it "initializes new model's instance" do
|
23
|
+
result = Create.()
|
27
24
|
result[:model].inspect.must_equal %{#<struct ModelTest::Song id=nil, title=nil>}
|
28
25
|
end
|
29
26
|
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require "trailblazer/macro"
|
3
|
+
|
1
4
|
require "delegate" # Ruby 2.2
|
2
5
|
require "minitest/autorun"
|
3
6
|
|
4
7
|
require "trailblazer/developer"
|
5
|
-
require "trailblazer/macro"
|
6
|
-
|
7
8
|
|
8
9
|
module Mock
|
9
10
|
class Result
|
@@ -39,7 +40,7 @@ T = Trailblazer::Activity::Testing
|
|
39
40
|
module Rehash
|
40
41
|
def rehash(ctx, seq:, rehash_raise: false, **)
|
41
42
|
seq << :rehash
|
42
|
-
raise if rehash_raise
|
43
|
+
raise "nope!" if rehash_raise
|
43
44
|
true
|
44
45
|
end
|
45
46
|
end
|
data/trailblazer-macro.gemspec
CHANGED
@@ -25,7 +25,9 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "roar"
|
26
26
|
spec.add_development_dependency "trailblazer-developer"
|
27
27
|
|
28
|
-
spec.add_dependency "trailblazer-
|
28
|
+
spec.add_dependency "trailblazer-activity", ">= 0.11.2", "< 1.0.0"
|
29
|
+
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.3.3", "< 1.0.0"
|
30
|
+
spec.add_dependency "trailblazer-operation", ">= 0.6.5" # TODO: this dependency will be removed.
|
29
31
|
|
30
|
-
spec.required_ruby_version = ">= 2.
|
32
|
+
spec.required_ruby_version = ">= 2.2.0"
|
31
33
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-macro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
- Marc Tich
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-12-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -95,20 +95,60 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: trailblazer-activity
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.11.2
|
105
|
+
- - "<"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: 1.0.0
|
108
|
+
type: :runtime
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 0.11.2
|
115
|
+
- - "<"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.0.0
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: trailblazer-activity-dsl-linear
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.3.3
|
125
|
+
- - "<"
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: 1.0.0
|
128
|
+
type: :runtime
|
129
|
+
prerelease: false
|
130
|
+
version_requirements: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 0.3.3
|
135
|
+
- - "<"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 1.0.0
|
98
138
|
- !ruby/object:Gem::Dependency
|
99
139
|
name: trailblazer-operation
|
100
140
|
requirement: !ruby/object:Gem::Requirement
|
101
141
|
requirements:
|
102
142
|
- - ">="
|
103
143
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.5
|
144
|
+
version: 0.6.5
|
105
145
|
type: :runtime
|
106
146
|
prerelease: false
|
107
147
|
version_requirements: !ruby/object:Gem::Requirement
|
108
148
|
requirements:
|
109
149
|
- - ">="
|
110
150
|
- !ruby/object:Gem::Version
|
111
|
-
version: 0.5
|
151
|
+
version: 0.6.5
|
112
152
|
description: Macros for Trailblazer's operation
|
113
153
|
email:
|
114
154
|
- apotonick@gmail.com
|
@@ -152,7 +192,7 @@ homepage: http://trailblazer.to
|
|
152
192
|
licenses:
|
153
193
|
- LGPL-3.0
|
154
194
|
metadata: {}
|
155
|
-
post_install_message:
|
195
|
+
post_install_message:
|
156
196
|
rdoc_options: []
|
157
197
|
require_paths:
|
158
198
|
- lib
|
@@ -160,16 +200,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
200
|
requirements:
|
161
201
|
- - ">="
|
162
202
|
- !ruby/object:Gem::Version
|
163
|
-
version: 2.
|
203
|
+
version: 2.2.0
|
164
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
205
|
requirements:
|
166
|
-
- - "
|
206
|
+
- - ">="
|
167
207
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
208
|
+
version: '0'
|
169
209
|
requirements: []
|
170
|
-
|
171
|
-
|
172
|
-
signing_key:
|
210
|
+
rubygems_version: 3.0.8
|
211
|
+
signing_key:
|
173
212
|
specification_version: 4
|
174
213
|
summary: 'Macros for Trailblazer''s operation: Policy, Wrap, Rescue and more.'
|
175
214
|
test_files:
|