trailblazer-macro 2.1.11 → 2.1.13
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/.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
|