trailblazer-macro 2.1.11 → 2.1.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -4
- data/.github/workflows/ci_jruby.yml +19 -0
- data/.github/workflows/ci_legacy.yml +19 -0
- data/.github/workflows/ci_truffleruby.yml +19 -0
- data/CHANGES.md +33 -0
- data/Gemfile +7 -5
- data/lib/trailblazer/macro/each.rb +187 -0
- data/lib/trailblazer/macro/model.rb +4 -5
- data/lib/trailblazer/macro/nested.rb +130 -68
- data/lib/trailblazer/macro/rescue.rb +2 -0
- data/lib/trailblazer/macro/strategy.rb +32 -0
- data/lib/trailblazer/macro/version.rb +1 -1
- data/lib/trailblazer/macro/wrap.rb +72 -65
- data/lib/trailblazer/macro.rb +53 -2
- data/test/docs/autogenerated/operation_each_test.rb +585 -0
- data/test/docs/autogenerated/operation_model_test.rb +263 -0
- data/test/docs/each_test.rb +940 -0
- data/test/docs/macro_test.rb +18 -0
- data/test/docs/model_test.rb +204 -88
- data/test/docs/nested_static_test.rb +730 -0
- data/test/docs/wrap_test.rb +348 -66
- data/test/test_helper.rb +29 -0
- data/trailblazer-macro.gemspec +2 -6
- metadata +21 -58
- data/.rubocop.yml +0 -6
- data/.rubocop_todo.yml +0 -423
- data/test/docs/nested_test.rb +0 -218
- data/test/operation/model_test.rb +0 -89
- data/test/operation/nested_test.rb +0 -98
data/test/docs/wrap_test.rb
CHANGED
@@ -1,5 +1,137 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
+
#@ yield returns a circuit-interface result set, we can return it to the flow
|
4
|
+
#:my_transaction
|
5
|
+
class MyTransaction
|
6
|
+
def self.call((ctx, flow_options), **, &block)
|
7
|
+
signal, (ctx, flow_options) = yield # calls the wrapped steps
|
8
|
+
|
9
|
+
return signal, [ctx, flow_options]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
#:my_transaction end
|
13
|
+
|
14
|
+
class WrapSimpleHandlerTest < Minitest::Spec
|
15
|
+
MyTransaction = ::MyTransaction
|
16
|
+
|
17
|
+
class Song
|
18
|
+
end
|
19
|
+
|
20
|
+
#:upload
|
21
|
+
module Song::Activity
|
22
|
+
class Upload < Trailblazer::Activity::FastTrack
|
23
|
+
step :model
|
24
|
+
step Wrap(MyTransaction) {
|
25
|
+
step :update # this changes the database.
|
26
|
+
step :transfer # this might even break!
|
27
|
+
}
|
28
|
+
step :notify
|
29
|
+
fail :log_error
|
30
|
+
#~meths
|
31
|
+
include T.def_steps(:model, :update, :transfer, :notify, :log_error)
|
32
|
+
#~meths end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
#:upload end
|
36
|
+
|
37
|
+
it do
|
38
|
+
#@ happy days
|
39
|
+
assert_invoke Song::Activity::Upload, seq: "[:model, :update, :transfer, :notify]"
|
40
|
+
#@ transfer returns false
|
41
|
+
assert_invoke Song::Activity::Upload, transfer: false, seq: "[:model, :update, :transfer, :log_error]",
|
42
|
+
terminus: :failure
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class WrapSimpleHandlerRoutesCustomTerminsTest < Minitest::Spec
|
47
|
+
MyTransaction = WrapSimpleHandlerTest::MyTransaction
|
48
|
+
|
49
|
+
class Song
|
50
|
+
end
|
51
|
+
|
52
|
+
module Song::Activity
|
53
|
+
class Upload < Trailblazer::Activity::FastTrack
|
54
|
+
step :model
|
55
|
+
#:out
|
56
|
+
#:out-wrap
|
57
|
+
step Wrap(MyTransaction) {
|
58
|
+
step :update # this changes the database.
|
59
|
+
step :transfer,
|
60
|
+
Output(:failure) => End(:timeout) # creates a third terminus.
|
61
|
+
},
|
62
|
+
#:out-wrap end
|
63
|
+
Output(:timeout) => Track(:fail_fast) # any wiring is possible here.
|
64
|
+
#:out end
|
65
|
+
step :notify
|
66
|
+
fail :log_error
|
67
|
+
#~meths
|
68
|
+
include T.def_steps(:model, :update, :transfer, :notify, :log_error)
|
69
|
+
#~meths end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it do
|
74
|
+
#@ happy days
|
75
|
+
assert_invoke Song::Activity::Upload, seq: "[:model, :update, :transfer, :notify]"
|
76
|
+
#@ transfer returns false
|
77
|
+
assert_invoke Song::Activity::Upload, transfer: false, seq: "[:model, :update, :transfer]",
|
78
|
+
terminus: :fail_fast
|
79
|
+
#@ update returns false
|
80
|
+
assert_invoke Song::Activity::Upload, update: false, seq: "[:model, :update, :log_error]",
|
81
|
+
terminus: :failure
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
#@ handler uses rescue. Pretty sure we got identical tests below.
|
86
|
+
class WrapMyRescueTest < Minitest::Spec
|
87
|
+
#:my_rescue
|
88
|
+
class MyRescue
|
89
|
+
def self.call((ctx, flow_options), **, &block)
|
90
|
+
signal, (ctx, flow_options) = yield # calls the wrapped steps
|
91
|
+
|
92
|
+
return signal, [ctx, flow_options]
|
93
|
+
rescue
|
94
|
+
ctx[:exception] = $!.message
|
95
|
+
return Trailblazer::Activity::Left, [ctx, flow_options]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
#:my_rescue end
|
99
|
+
|
100
|
+
class Song
|
101
|
+
end
|
102
|
+
|
103
|
+
#:upload-rescue
|
104
|
+
module Song::Activity
|
105
|
+
class Upload < Trailblazer::Activity::FastTrack
|
106
|
+
step :model
|
107
|
+
step Wrap(MyRescue) {
|
108
|
+
step :update
|
109
|
+
step :transfer # might raise an exception.
|
110
|
+
}
|
111
|
+
step :notify
|
112
|
+
fail :log_error
|
113
|
+
#~meths
|
114
|
+
include T.def_steps(:model, :update, :transfer, :notify, :log_error)
|
115
|
+
def transfer(ctx, seq:, transfer: true, **)
|
116
|
+
seq << :transfer
|
117
|
+
raise RuntimeError.new("transfer failed") unless transfer
|
118
|
+
transfer
|
119
|
+
end
|
120
|
+
#~meths end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
#:upload-rescue end
|
124
|
+
|
125
|
+
it do
|
126
|
+
#@ happy days
|
127
|
+
assert_invoke Song::Activity::Upload, seq: "[:model, :update, :transfer, :notify]"
|
128
|
+
#@ transfer raises
|
129
|
+
assert_invoke Song::Activity::Upload, transfer: false, seq: "[:model, :update, :transfer, :log_error]",
|
130
|
+
terminus: :failure,
|
131
|
+
expected_ctx_variables: {exception: "transfer failed"}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
3
135
|
class DocsWrapTest < Minitest::Spec
|
4
136
|
=begin
|
5
137
|
When success: return the block's returns
|
@@ -8,7 +140,8 @@ When raise: return {Railway.fail!}
|
|
8
140
|
#:wrap-handler
|
9
141
|
class HandleUnsafeProcess
|
10
142
|
def self.call((ctx, flow_options), *, &block)
|
11
|
-
yield # calls the wrapped steps
|
143
|
+
signal, (ctx, flow_options) = yield # calls the wrapped steps
|
144
|
+
return signal, [ctx, flow_options]
|
12
145
|
rescue
|
13
146
|
ctx[:exception] = $!.message
|
14
147
|
[ Trailblazer::Operation::Railway.fail!, [ctx, flow_options] ]
|
@@ -18,7 +151,7 @@ When raise: return {Railway.fail!}
|
|
18
151
|
|
19
152
|
#:wrap
|
20
153
|
class Memo::Create < Trailblazer::Operation
|
21
|
-
step :
|
154
|
+
step :model
|
22
155
|
step Wrap( HandleUnsafeProcess ) {
|
23
156
|
step :update
|
24
157
|
step :rehash
|
@@ -26,45 +159,21 @@ When raise: return {Railway.fail!}
|
|
26
159
|
step :notify
|
27
160
|
fail :log_error
|
28
161
|
#~methods
|
29
|
-
include T.def_steps(:
|
162
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
30
163
|
include Rehash
|
31
164
|
#~methods end
|
32
165
|
end
|
33
166
|
#:wrap end
|
34
167
|
|
35
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:find_model, :update, :rehash, :notify]] >} }
|
36
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:find_model, :update, :rehash, :log_error]] >} }
|
37
|
-
|
38
|
-
=begin
|
39
|
-
Tracing with Wrap()
|
40
|
-
=end
|
41
168
|
it do
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
#:trace-success
|
49
|
-
result.wtf? #=>
|
50
|
-
|-- #<Trailblazer::Activity::Start semantic=:default>
|
51
|
-
|-- find_model
|
52
|
-
|-- Wrap/85
|
53
|
-
| |-- #<Trailblazer::Activity::Start semantic=:default>
|
54
|
-
| |-- update
|
55
|
-
| |-- rehash
|
56
|
-
| `-- #<Trailblazer::Operation::Railway::End::Success semantic=:success>
|
57
|
-
|-- notify
|
58
|
-
`-- #<Trailblazer::Operation::Railway::End::Success semantic=:success>
|
59
|
-
#:trace-success end
|
60
|
-
=end
|
169
|
+
#@ happy days
|
170
|
+
assert_invoke Memo::Create, seq: "[:model, :update, :rehash, :notify]"
|
171
|
+
#@ rehash raises
|
172
|
+
assert_invoke Memo::Create, rehash_raise: true, seq: "[:model, :update, :rehash, :log_error]",
|
173
|
+
terminus: :failure,
|
174
|
+
expected_ctx_variables: {exception: "nope!"}
|
61
175
|
end
|
62
176
|
|
63
|
-
=begin
|
64
|
-
Writing into ctx in a Wrap()
|
65
|
-
=end
|
66
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } )[:exception].must_equal("nope!") }
|
67
|
-
|
68
177
|
=begin
|
69
178
|
When success: return the block's returns
|
70
179
|
When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
@@ -81,7 +190,7 @@ When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
|
81
190
|
end
|
82
191
|
end
|
83
192
|
|
84
|
-
step :
|
193
|
+
step :model
|
85
194
|
step Wrap( HandleUnsafeProcess ) {
|
86
195
|
step :update
|
87
196
|
step :rehash
|
@@ -90,13 +199,13 @@ When raise: return {Railway.fail!}, but wire Wrap() to {fail_fast: true}
|
|
90
199
|
fail :log_error
|
91
200
|
|
92
201
|
#~methods
|
93
|
-
include T.def_steps(:
|
202
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
94
203
|
include Rehash
|
95
204
|
#~methods end
|
96
205
|
end
|
97
206
|
|
98
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:
|
99
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:
|
207
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >} }
|
208
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash]] >} }
|
100
209
|
end
|
101
210
|
|
102
211
|
=begin
|
@@ -118,7 +227,7 @@ When raise: return {Railway.fail_fast!} and configure Wrap() to {fast_track: t
|
|
118
227
|
|
119
228
|
#:fail-fast
|
120
229
|
class Memo::Create < Trailblazer::Operation
|
121
|
-
step :
|
230
|
+
step :model
|
122
231
|
step Wrap( HandleUnsafeProcess ) {
|
123
232
|
step :update
|
124
233
|
step :rehash
|
@@ -126,14 +235,14 @@ When raise: return {Railway.fail_fast!} and configure Wrap() to {fast_track: t
|
|
126
235
|
step :notify
|
127
236
|
fail :log_error
|
128
237
|
#~methods
|
129
|
-
include T.def_steps(:
|
238
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
130
239
|
include Rehash
|
131
240
|
#~methods end
|
132
241
|
end
|
133
242
|
#:fail-fast end
|
134
243
|
|
135
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:
|
136
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:
|
244
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >} }
|
245
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash]] >} }
|
137
246
|
end
|
138
247
|
|
139
248
|
=begin
|
@@ -157,7 +266,7 @@ When raise: return {Railway.fail!} or {Railway.pass!}
|
|
157
266
|
|
158
267
|
#:custom
|
159
268
|
class Memo::Create < Trailblazer::Operation
|
160
|
-
step :
|
269
|
+
step :model
|
161
270
|
step Wrap( MyTransaction ) {
|
162
271
|
step :update
|
163
272
|
step :rehash
|
@@ -167,7 +276,7 @@ When raise: return {Railway.fail!} or {Railway.pass!}
|
|
167
276
|
step :notify
|
168
277
|
fail :log_error
|
169
278
|
#~methods
|
170
|
-
include T.def_steps(:
|
279
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
171
280
|
include Rehash
|
172
281
|
#~methods end
|
173
282
|
end
|
@@ -175,13 +284,13 @@ When raise: return {Railway.fail!} or {Railway.pass!}
|
|
175
284
|
|
176
285
|
it do
|
177
286
|
result = Memo::Create.( { seq: [] } )
|
178
|
-
result.inspect(:seq).must_equal %{<Result:false [[:
|
287
|
+
result.inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash]] >}
|
179
288
|
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_worked>}
|
180
289
|
end
|
181
290
|
|
182
291
|
it do
|
183
292
|
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
184
|
-
result.inspect(:seq).must_equal %{<Result:false [[:
|
293
|
+
result.inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash]] >}
|
185
294
|
result.event.inspect.must_equal %{#<Trailblazer::Activity::End semantic=:transaction_failed>}
|
186
295
|
end
|
187
296
|
end
|
@@ -202,7 +311,7 @@ When raise: return {Railway.pass!} and go "successful"
|
|
202
311
|
end
|
203
312
|
end
|
204
313
|
|
205
|
-
step :
|
314
|
+
step :model
|
206
315
|
step Wrap( HandleUnsafeProcess ) {
|
207
316
|
step :update
|
208
317
|
step :rehash
|
@@ -211,13 +320,13 @@ When raise: return {Railway.pass!} and go "successful"
|
|
211
320
|
fail :log_error
|
212
321
|
|
213
322
|
#~methods
|
214
|
-
include T.def_steps(:
|
323
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
215
324
|
include Rehash
|
216
325
|
#~methods end
|
217
326
|
end
|
218
327
|
|
219
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:
|
220
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:true [[:
|
328
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >} }
|
329
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >} }
|
221
330
|
end
|
222
331
|
|
223
332
|
=begin
|
@@ -237,7 +346,7 @@ You can return boolean true in wrap.
|
|
237
346
|
end
|
238
347
|
end
|
239
348
|
|
240
|
-
step :
|
349
|
+
step :model
|
241
350
|
step Wrap( HandleUnsafeProcess ) {
|
242
351
|
step :update
|
243
352
|
step :rehash
|
@@ -246,14 +355,14 @@ You can return boolean true in wrap.
|
|
246
355
|
fail :log_error
|
247
356
|
|
248
357
|
#~methods
|
249
|
-
include T.def_steps(:
|
358
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
250
359
|
include Rehash
|
251
360
|
#~methods end
|
252
361
|
end
|
253
362
|
|
254
363
|
it "translates true returned form a wrap to a signal with a `success` semantic" do
|
255
364
|
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
256
|
-
result.inspect(:seq).must_equal %{<Result:true [[:
|
365
|
+
result.inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >}
|
257
366
|
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Success semantic=:success>}
|
258
367
|
end
|
259
368
|
end
|
@@ -275,7 +384,7 @@ You can return boolean false in wrap.
|
|
275
384
|
end
|
276
385
|
end
|
277
386
|
|
278
|
-
step :
|
387
|
+
step :model
|
279
388
|
step Wrap( HandleUnsafeProcess ) {
|
280
389
|
step :update
|
281
390
|
step :rehash
|
@@ -284,14 +393,14 @@ You can return boolean false in wrap.
|
|
284
393
|
fail :log_error
|
285
394
|
|
286
395
|
#~methods
|
287
|
-
include T.def_steps(:
|
396
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
288
397
|
include Rehash
|
289
398
|
#~methods end
|
290
399
|
end
|
291
400
|
|
292
401
|
it "translates false returned form a wrap to a signal with a `failure` semantic" do
|
293
402
|
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
294
|
-
result.inspect(:seq).must_equal %{<Result:false [[:
|
403
|
+
result.inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash, :log_error]] >}
|
295
404
|
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
296
405
|
end
|
297
406
|
end
|
@@ -313,7 +422,7 @@ You can return nil in wrap.
|
|
313
422
|
end
|
314
423
|
end
|
315
424
|
|
316
|
-
step :
|
425
|
+
step :model
|
317
426
|
step Wrap( HandleUnsafeProcess ) {
|
318
427
|
step :update
|
319
428
|
step :rehash
|
@@ -322,14 +431,14 @@ You can return nil in wrap.
|
|
322
431
|
fail :log_error
|
323
432
|
|
324
433
|
#~methods
|
325
|
-
include T.def_steps(:
|
434
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
326
435
|
include Rehash
|
327
436
|
#~methods end
|
328
437
|
end
|
329
438
|
|
330
439
|
it "translates nil returned form a wrap to a signal with a `failure` semantic" do
|
331
440
|
result = Memo::Create.( { seq: [], rehash_raise: true } )
|
332
|
-
result.inspect(:seq).must_equal %{<Result:false [[:
|
441
|
+
result.inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash, :log_error]] >}
|
333
442
|
result.event.inspect.must_equal %{#<Trailblazer::Activity::Railway::End::Failure semantic=:failure>}
|
334
443
|
end
|
335
444
|
end
|
@@ -360,7 +469,7 @@ This one is mostly to show how one could wrap steps in a transaction
|
|
360
469
|
|
361
470
|
#:transaction
|
362
471
|
class Memo::Create < Trailblazer::Operation
|
363
|
-
step :
|
472
|
+
step :model
|
364
473
|
step Wrap( MyTransaction ) {
|
365
474
|
step :update
|
366
475
|
step :rehash
|
@@ -368,14 +477,14 @@ This one is mostly to show how one could wrap steps in a transaction
|
|
368
477
|
step :notify
|
369
478
|
fail :log_error
|
370
479
|
#~methods
|
371
|
-
include T.def_steps(:
|
480
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
372
481
|
include Rehash
|
373
482
|
#~methods end
|
374
483
|
end
|
375
484
|
#:transaction end
|
376
485
|
|
377
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:
|
378
|
-
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:
|
486
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:model, :update, :rehash, :notify]] >} }
|
487
|
+
it { Memo::Create.( { seq: [], rehash_raise: true } ).inspect(:seq).must_equal %{<Result:false [[:model, :update, :rehash, :log_error]] >} }
|
379
488
|
end
|
380
489
|
|
381
490
|
=begin
|
@@ -402,19 +511,192 @@ This one is mostly to show how one could evaluate Wrap()'s return value based on
|
|
402
511
|
|
403
512
|
#:transaction
|
404
513
|
class Memo::Create < Trailblazer::Operation
|
405
|
-
step :
|
514
|
+
step :model
|
406
515
|
step Wrap( HandleUnsafeProcess ) {
|
407
516
|
step :update
|
408
517
|
}, fast_track: true # because Wrap can return pass_fast! now
|
409
518
|
step :notify
|
410
519
|
fail :log_error
|
411
520
|
#~methods
|
412
|
-
include T.def_steps(:
|
521
|
+
include T.def_steps(:model, :update, :notify, :log_error)
|
413
522
|
#~methods end
|
414
523
|
end
|
415
524
|
#:transaction end
|
416
525
|
|
417
|
-
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:
|
418
|
-
it { Memo::Create.( { seq: [], update: false } ).inspect(:seq).must_equal %{<Result:false [[:
|
526
|
+
it { Memo::Create.( { seq: [] } ).inspect(:seq).must_equal %{<Result:true [[:model, :update]] >} }
|
527
|
+
it { Memo::Create.( { seq: [], update: false } ).inspect(:seq).must_equal %{<Result:false [[:model, :update, :log_error]] >} }
|
528
|
+
end
|
529
|
+
|
530
|
+
|
531
|
+
class WrapOperationWithCustomTerminus < Minitest::Spec
|
532
|
+
Song = Module.new
|
533
|
+
|
534
|
+
module Song::Activity
|
535
|
+
class HandleUnsafeProcess
|
536
|
+
def self.call((ctx), *, &block)
|
537
|
+
yield # calls the wrapped steps
|
538
|
+
rescue
|
539
|
+
[ Trailblazer::Operation::Railway.fail_fast!, [ctx, {}] ]
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
class Upload < Trailblazer::Activity::FastTrack
|
544
|
+
step :model
|
545
|
+
step Wrap(HandleUnsafeProcess) {
|
546
|
+
step :send_request,
|
547
|
+
Output(:failure) => End(:timeout__) # adds a terminus {End.timeout}
|
548
|
+
# step :rehash
|
549
|
+
},
|
550
|
+
Output(:timeout__) => Track(:fail_fast)
|
551
|
+
step :upload
|
552
|
+
fail :log_error
|
553
|
+
#~methods
|
554
|
+
include T.def_steps(:model, :send_request, :upload, :log_error)
|
555
|
+
#~methods end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
it do
|
560
|
+
#@ success path
|
561
|
+
assert_invoke Song::Activity::Upload, seq: "[:model, :send_request, :upload]"
|
562
|
+
#@ we travel through {:timeout}
|
563
|
+
assert_invoke Song::Activity::Upload, send_request: false, seq: "[:model, :send_request]", terminus: :fail_fast
|
564
|
+
end
|
565
|
+
|
566
|
+
it "tracing" do
|
567
|
+
assert_equal trace(Song::Activity::Upload, {seq: []})[0], %{TOP
|
568
|
+
|-- Start.default
|
569
|
+
|-- model
|
570
|
+
|-- Wrap/DocsWrapTest::WrapOperationWithCustomTerminus::Song::Activity::HandleUnsafeProcess
|
571
|
+
| |-- Start.default
|
572
|
+
| |-- send_request
|
573
|
+
| `-- End.success
|
574
|
+
|-- upload
|
575
|
+
`-- End.success}
|
576
|
+
|
577
|
+
#@ compile time
|
578
|
+
#@ make sure we can find tasks/compile-time artifacts in Wrap by using their {compile_id}.
|
579
|
+
# assert_equal Trailblazer::Developer::Introspect.find_path(Song::Activity::Upload,
|
580
|
+
# [Wrap])[0].task.inspect,
|
581
|
+
# %{#<Trailblazer::Activity::TaskBuilder::Task user_proc=compute_item>}
|
582
|
+
# puts Trailblazer::Developer::Render::TaskWrap.(activity, ["Each/1", "Each.iterate.block", "invoke_block_activity", :compute_item])
|
583
|
+
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
class WrapUnitTest < Minitest::Spec
|
589
|
+
class HandleUnsafeProcess
|
590
|
+
def self.call((ctx, flow_options), **, &block)
|
591
|
+
yield # calls the wrapped steps
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
it "assigns IDs via {Macro.id_for}" do
|
596
|
+
activity = Class.new(Trailblazer::Activity::Railway) do
|
597
|
+
def self.my_wrap_handler((ctx, flow_options), **, &block)
|
598
|
+
yield # calls the wrapped steps
|
599
|
+
end
|
600
|
+
|
601
|
+
my_wrap_handler = ->((ctx, flow_options), **, &block) do
|
602
|
+
block.call # calls the wrapped steps
|
603
|
+
end
|
604
|
+
|
605
|
+
step Wrap(HandleUnsafeProcess) {}
|
606
|
+
# step Wrap(:my_wrap_handler) {} # FIXME: this doesn't work, yet.
|
607
|
+
step Wrap(method(:my_wrap_handler)) {}
|
608
|
+
step Wrap(my_wrap_handler) {}, id: "proc:my_wrap_handler"
|
609
|
+
end
|
610
|
+
|
611
|
+
[
|
612
|
+
"Wrap/WrapUnitTest::HandleUnsafeProcess",
|
613
|
+
"Wrap/method(:my_wrap_handler)",
|
614
|
+
"proc:my_wrap_handler"
|
615
|
+
].each do |id|
|
616
|
+
assert_equal Trailblazer::Developer::Introspect.find_path(activity, [id])[0].id, id
|
617
|
+
end
|
618
|
+
|
619
|
+
assert_equal trace(activity, {seq: []})[0], %{TOP
|
620
|
+
|-- Start.default
|
621
|
+
|-- Wrap/WrapUnitTest::HandleUnsafeProcess
|
622
|
+
| |-- Start.default
|
623
|
+
| `-- End.success
|
624
|
+
|-- Wrap/method(:my_wrap_handler)
|
625
|
+
| |-- Start.default
|
626
|
+
| `-- End.success
|
627
|
+
|-- proc:my_wrap_handler
|
628
|
+
| |-- Start.default
|
629
|
+
| `-- End.success
|
630
|
+
`-- End.success}
|
631
|
+
end
|
632
|
+
|
633
|
+
it "complies with Introspect API/Patch API" do
|
634
|
+
class MyValidation < Trailblazer::Activity::Railway
|
635
|
+
step :validate
|
636
|
+
include T.def_steps(:validate)
|
637
|
+
end
|
638
|
+
|
639
|
+
activity = Class.new(Trailblazer::Activity::Railway) do
|
640
|
+
step Wrap(HandleUnsafeProcess) {
|
641
|
+
step Subprocess(MyValidation), id: :validation
|
642
|
+
}
|
643
|
+
end
|
644
|
+
|
645
|
+
mock_validation = ->(ctx, seq:, **) { ctx[:seq] = seq + [:mock_validation] }
|
646
|
+
|
647
|
+
#@ Introspect::TaskMap interface
|
648
|
+
assert_equal Trailblazer::Developer::Introspect.find_path(activity,
|
649
|
+
["Wrap/WrapUnitTest::HandleUnsafeProcess", :validation, :validate])[0].task.inspect,
|
650
|
+
%{#<Trailblazer::Activity::TaskBuilder::Task user_proc=validate>}
|
651
|
+
|
652
|
+
#@ Patch interface
|
653
|
+
patched_activity = Trailblazer::Activity::DSL::Linear.Patch(
|
654
|
+
activity,
|
655
|
+
["Wrap/WrapUnitTest::HandleUnsafeProcess"] => -> { step mock_validation, replace: :validation, id: :validation }
|
656
|
+
)
|
657
|
+
|
658
|
+
#@ the original activity with Wrap is unchanged.
|
659
|
+
assert_invoke activity, seq: %{[:validate]}
|
660
|
+
|
661
|
+
#@ the patched version only runs {mock_validation}.
|
662
|
+
assert_invoke patched_activity, seq: %{[:mock_validation]}
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
666
|
+
class WrapStrategyComplianceTest < Minitest::Spec
|
667
|
+
Song = WrapSimpleHandlerTest::Song
|
668
|
+
|
669
|
+
it do
|
670
|
+
#:patch
|
671
|
+
upload_with_upsert = Trailblazer::Activity::DSL::Linear.Patch(
|
672
|
+
Song::Activity::Upload,
|
673
|
+
["Wrap/MyTransaction"] => -> { step :upsert, replace: :update }
|
674
|
+
)
|
675
|
+
#:patch end
|
676
|
+
upload_with_upsert.include(T.def_steps(:upsert))
|
677
|
+
|
678
|
+
#@ Original class isn't changed.
|
679
|
+
assert_invoke Song::Activity::Upload, seq: "[:model, :update, :transfer, :notify]"
|
680
|
+
#@ Patched class runs
|
681
|
+
assert_invoke upload_with_upsert, seq: "[:model, :upsert, :transfer, :notify]"
|
682
|
+
end
|
683
|
+
|
684
|
+
it "find_path" do
|
685
|
+
assert_equal Trailblazer::Developer::Introspect.find_path(Song::Activity::Upload,
|
686
|
+
["Wrap/MyTransaction", :transfer])[0].task.inspect,
|
687
|
+
%{#<Trailblazer::Activity::TaskBuilder::Task user_proc=transfer>}
|
688
|
+
|
689
|
+
=begin
|
690
|
+
#:find_path
|
691
|
+
node, _ = Trailblazer::Developer::Introspect.find_path(
|
692
|
+
Song::Activity::Upload,
|
693
|
+
["Wrap/MyTransaction", :transfer])
|
694
|
+
#=> #<Node ...>
|
695
|
+
#:find_path end
|
696
|
+
=end
|
697
|
+
end
|
698
|
+
|
699
|
+
it "tracing" do
|
700
|
+
# Trailblazer::Developer.wtf?(Song::Activity::Upload, {seq: []})
|
419
701
|
end
|
420
702
|
end
|
data/test/test_helper.rb
CHANGED
@@ -44,3 +44,32 @@ module Rehash
|
|
44
44
|
true
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
Minitest::Spec.include Trailblazer::Activity::Testing::Assertions
|
49
|
+
|
50
|
+
Minitest::Spec.class_eval do
|
51
|
+
def trace(activity, ctx)
|
52
|
+
stack, signal, (ctx, _) = Trailblazer::Developer::Trace.invoke(activity, [ctx, {}])
|
53
|
+
return Trailblazer::Developer::Trace::Present.(stack, node_options: {stack.to_a[0]=>{label: "TOP"}}).gsub(/:\d+/, ""), signal, ctx
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
# signal, (ctx, _) = Trailblazer::Activity.(Song::Activity::Create,
|
60
|
+
# params: {title: "Olympia"}, # some random variable.
|
61
|
+
# "model.class": Hit,
|
62
|
+
# "model.action": :find_by,
|
63
|
+
# "model.find_by_key": :title, seq: []
|
64
|
+
# )
|
65
|
+
|
66
|
+
# #:update-ok
|
67
|
+
# signal, (ctx, _) = Trailblazer::Activity.(Song::Activity::Update, params: {id: 1}, seq: [])
|
68
|
+
# ctx[:model] #=> #<Song id=1, ...>
|
69
|
+
# puts signal #=> #<Trailblazer::Activity::End semantic=:success>
|
70
|
+
# #:update-ok end
|
71
|
+
|
72
|
+
|
73
|
+
# require "trailblazer/core"
|
74
|
+
# Trailblazer::Core.convert_operation_test("test/docs/model_test.rb")
|
75
|
+
# Trailblazer::Core.convert_operation_test("test/docs/each_test.rb")
|
data/trailblazer-macro.gemspec
CHANGED
@@ -17,16 +17,12 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_development_dependency "bundler"
|
21
20
|
spec.add_development_dependency "minitest"
|
22
21
|
spec.add_development_dependency "rake"
|
23
|
-
|
24
|
-
spec.add_development_dependency "multi_json"
|
25
|
-
spec.add_development_dependency "roar"
|
26
22
|
spec.add_development_dependency "trailblazer-developer"
|
27
23
|
|
28
|
-
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 1.
|
29
|
-
spec.add_dependency "trailblazer-operation", ">= 0.
|
24
|
+
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 1.1.0", "< 1.2.0"
|
25
|
+
spec.add_dependency "trailblazer-operation", ">= 0.9.0" # TODO: this dependency will be removed. currently needed for tests?! and for Guard::Result
|
30
26
|
|
31
27
|
spec.required_ruby_version = ">= 2.2.0"
|
32
28
|
end
|