trailblazer-macro 2.1.0.rc14 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 257d35af044c9e6d7f243f1435d2f6caaf0a2c6fbc4099b6417c8c0f7c44bf39
4
- data.tar.gz: 07e52e6cc9a2b94b686ddf12462deb2076df5b3e189ff5207fe4f2a0dbdafb48
3
+ metadata.gz: d4da758ccf1b9e9ff6fa413c687fe09c6df11449b84a775c65280a73d1b80f72
4
+ data.tar.gz: 23bd67cc32f045487ca761e15227fe562e87b7cde3616e7335a8ee3126c51217
5
5
  SHA512:
6
- metadata.gz: be1d7c595f022b2d8df45e630b2d72082a3625fa0b685462ae86c5ada6adf428927373c82cc05b39bcbb24c2c098e48506cf071ea06483b21fb5625343e81f0d
7
- data.tar.gz: 30ed38e17b3a5edfcecbfc831a668bf348c0ab1edff3684ae48d499e457ed73790f1205bf0e18a24f217d7e2fe92560beef20c0c332bae4d3253b5b949d9878d
6
+ metadata.gz: 4671b91a21144afc728dba8397282a49f6517d183349179a357da87e57a223cb4f5cb81f3d29f0bda0e3013db7581367e02a6de28a19bfbc7b83dd286a3f0d9a
7
+ data.tar.gz: 339a312f0c7f7bee0afe5f74b06d3694ff826daff2e5bbfe4190a3238252cd92feb36ab14cf2429814eaf5b18e50abdac18bee594b7229c37fc64df8856e18b8
@@ -1,11 +1,12 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
- - 2.6.2
5
- - 2.5.5
6
- - 2.4.4
7
- - 2.3.7
8
- - 2.2
9
- - 2.1
10
-
3
+ - ruby-head
4
+ - 2.7
5
+ - 2.6
6
+ - 2.5
7
+ - 2.4
11
8
  cache: bundler
9
+ jobs:
10
+ allow_failures:
11
+ - rvm: ruby-head
12
+ - rvm: 2.7
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.
@@ -1,5 +1,6 @@
1
+ require "forwardable"
1
2
  require "trailblazer/activity"
2
- require "trailblazer/activity/dsl/linear" # TODO: remove this dependency
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
- # TODO: Forwardable.def_delegators(Operation, Macro, :Model, :Wrap) would be amazing. It really sucks to extend a foreign class.
25
- # Trailblazer::Operation.singleton_class.extend Forwardable
26
- # Trailblazer::Macro.forward_macros(Trailblazer::Operation)
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
- Trailblazer::Activity::FastTrack.singleton_class.extend Forwardable
29
- Trailblazer::Macro.forward_macros(Trailblazer::Activity::FastTrack) # monkey-patching sucks.
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
- def self.Model(model_class, action = nil, find_by_key = nil)
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: "model.build", extensions: [injection]}
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?, {})
@@ -20,7 +20,7 @@ module Trailblazer
20
20
  end
21
21
  end
22
22
 
23
- Wrap(rescue_block, id: "Rescue(#{rand(100)})", &block)
23
+ Wrap(rescue_block, id: "Rescue(#{SecureRandom.hex(4)})", &block)
24
24
  # FIXME: name
25
25
  # [ step, name: "Rescue:#{block.source_location.last}" ]
26
26
  end
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Macro
4
- VERSION = "2.1.0.rc14".freeze
4
+ VERSION = "2.1.4"
5
5
  end
6
6
  end
7
7
  end
@@ -1,6 +1,8 @@
1
+ require 'securerandom'
2
+
1
3
  module Trailblazer
2
4
  module Macro
3
- def self.Wrap(user_wrap, id: "Wrap/#{rand(100)}", &block)
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]
@@ -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
@@ -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, :[] )
@@ -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
  }
@@ -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\(\d+\),>nested/ } # FIXME: better introspect tests for all id-generating macros.
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
@@ -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
- begin
15
- yield # calls the wrapped steps
16
- rescue
17
- [ Trailblazer::Operation::Railway.fail!, [ctx, flow_options] ]
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
- begin
78
- yield # calls the wrapped steps
79
- rescue
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
- begin
116
- yield # calls the wrapped steps
117
- rescue
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 WrapWithTransactionTest < Minitest::Spec
149
- Memo = Module.new
143
+ class WrapWithCustomEndsTest < Minitest::Spec
144
+ Memo = Module.new
150
145
 
151
- module Sequel
152
- def self.transaction
153
- begin
154
- end_event, (ctx, flow_options) = yield
155
- true
156
- rescue
157
- false
158
- end
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
- #:transaction-handler
163
- class MyTransaction
164
- def self.call((ctx, flow_options), *, &block)
165
- result = Sequel.transaction { yield }
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
- signal = result ? Trailblazer::Operation::Railway.pass! : Trailblazer::Operation::Railway.fail!
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
- [ signal, [ctx, flow_options] ]
170
- end
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
- #:transaction-handler end
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
- #:wrap-only
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:false [[:find_model, :update, :rehash, :log_error]] >} }
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 {Railway.fail!} or {Railway.pass!}
225
+ When raise: return {true} and go "successful"
226
+ You can return boolean true in wrap.
199
227
  =end
200
- class WrapWithCustomEndsTest < Minitest::Spec
201
- Memo = Module.new
202
- Sequel = WrapWithTransactionTest::Sequel
228
+ class WrapGoesIntoBooleanTrueFromRescueTest < Minitest::Spec
229
+ Memo = Module.new
203
230
 
204
- #:custom-handler
205
- class MyTransaction
206
- MyFailSignal = Class.new(Trailblazer::Activity::Signal)
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
- def self.call((ctx, flow_options), *, &block)
209
- result = Sequel.transaction { yield }
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
- signal = result ? Trailblazer::Operation::Railway.pass! : MyFailSignal
248
+ #~methods
249
+ include T.def_steps(:find_model, :update, :notify, :log_error)
250
+ include Rehash
251
+ #~methods end
252
+ end
212
253
 
213
- [ signal, [ctx, flow_options] ]
214
- end
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
- #:custom-handler end
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( MyTransaction ) {
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=:transaction_failed>}
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 {Railway.pass!} and go "successful"
301
+ When raise: return {nil} and go "failed"
302
+ You can return nil in wrap.
252
303
  =end
253
- class WrapGoesIntoPassFromRescueTest < Minitest::Spec
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
- begin
260
- yield # calls the wrapped steps
261
- rescue
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:true [[:find_model, :update, :rehash, :notify]] >} }
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 { Create.(params: {})[:model].inspect.must_equal %{#<struct ModelTest::Song id=nil, title=nil>} }
23
- it do
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
 
@@ -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
@@ -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-operation", ">= 0.5.2" # TODO: this dependency will be removed.
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.0.0"
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.0.rc14
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: 2019-09-18 00:00:00.000000000 Z
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.2
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.2
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.0.0
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: 1.3.1
208
+ version: '0'
169
209
  requirements: []
170
- rubyforge_project:
171
- rubygems_version: 2.7.6
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: