trailblazer 2.0.7 → 2.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +35 -1
  3. data/Gemfile +6 -12
  4. data/README.md +3 -1
  5. data/Rakefile +6 -17
  6. data/lib/trailblazer.rb +7 -4
  7. data/lib/trailblazer/deprecation/call.rb +46 -0
  8. data/lib/trailblazer/deprecation/context.rb +43 -0
  9. data/lib/trailblazer/operation/contract.rb +40 -9
  10. data/lib/trailblazer/operation/deprecations.rb +21 -0
  11. data/lib/trailblazer/operation/guard.rb +5 -5
  12. data/lib/trailblazer/operation/model.rb +15 -10
  13. data/lib/trailblazer/operation/nested.rb +56 -85
  14. data/lib/trailblazer/operation/persist.rb +4 -2
  15. data/lib/trailblazer/operation/policy.rb +16 -7
  16. data/lib/trailblazer/operation/pundit.rb +3 -3
  17. data/lib/trailblazer/operation/representer.rb +5 -0
  18. data/lib/trailblazer/operation/rescue.rb +12 -9
  19. data/lib/trailblazer/operation/validate.rb +36 -29
  20. data/lib/trailblazer/operation/wrap.rb +49 -11
  21. data/lib/trailblazer/task.rb +20 -0
  22. data/lib/trailblazer/version.rb +1 -1
  23. data/test/benchmark.rb +63 -0
  24. data/test/deprecation/call_test.rb +42 -0
  25. data/test/deprecation/context_test.rb +19 -0
  26. data/test/docs/contract_test.rb +73 -53
  27. data/test/docs/dry_test.rb +2 -2
  28. data/test/docs/fast_test.rb +133 -13
  29. data/test/docs/guard_test.rb +28 -35
  30. data/test/docs/macro_test.rb +1 -1
  31. data/test/docs/model_test.rb +13 -13
  32. data/test/docs/nested_test.rb +54 -122
  33. data/test/docs/operation_test.rb +42 -43
  34. data/test/docs/pundit_test.rb +16 -16
  35. data/test/docs/representer_test.rb +18 -18
  36. data/test/docs/rescue_test.rb +29 -29
  37. data/test/docs/trace_test.rb +82 -0
  38. data/test/docs/wrap_test.rb +59 -26
  39. data/test/module_test.rb +75 -75
  40. data/test/nested_test.rb +293 -0
  41. data/test/operation/contract_test.rb +23 -153
  42. data/test/operation/dsl/contract_test.rb +9 -9
  43. data/test/operation/dsl/representer_test.rb +169 -169
  44. data/test/operation/model_test.rb +15 -21
  45. data/test/operation/persist_test.rb +18 -11
  46. data/test/operation/pundit_test.rb +25 -23
  47. data/test/operation/representer_test.rb +254 -254
  48. data/test/test_helper.rb +5 -2
  49. data/test/variables_test.rb +158 -0
  50. data/trailblazer.gemspec +1 -1
  51. data/untitled +33 -0
  52. metadata +25 -27
  53. data/lib/trailblazer/operation/callback.rb +0 -35
  54. data/lib/trailblazer/operation/procedural/contract.rb +0 -15
  55. data/lib/trailblazer/operation/procedural/validate.rb +0 -22
  56. data/test/operation/callback_test.rb +0 -70
  57. data/test/operation/dsl/callback_test.rb +0 -106
  58. data/test/operation/params_test.rb +0 -36
  59. data/test/operation/pipedream_test.rb +0 -59
  60. data/test/operation/pipetree_test.rb +0 -104
  61. data/test/operation/present_test.rb +0 -24
  62. data/test/operation/resolver_test.rb +0 -47
  63. data/test/operation_test.rb +0 -143
@@ -7,6 +7,7 @@ class DocsContractOverviewTest < Minitest::Spec
7
7
  # app/concepts/song/create.rb
8
8
  class Create < Trailblazer::Operation
9
9
  #~bla
10
+ extend ClassDependencies
10
11
  extend Contract::DSL
11
12
 
12
13
  contract do
@@ -29,16 +30,15 @@ class DocsContractOverviewTest < Minitest::Spec
29
30
  end
30
31
  #:overv-reform end
31
32
 
32
- puts Create["pipetree"].inspect(style: :rows)
33
+ puts Trailblazer::Operation::Inspect.(Create, style: :rows)
33
34
 
34
35
  =begin
35
36
  #:overv-reform-pipe
36
- 0 =======================>>operation.new
37
- 1 ==========================&model.build
38
- 2 =======================>contract.build
39
- 3 ==============&validate.params.extract
40
- 4 ====================&contract.validate
41
- 5 =========================&persist.save
37
+ 0 ==========================&model.build
38
+ 1 =======================>contract.build
39
+ 2 ==============&validate.params.extract
40
+ 3 ====================&contract.validate
41
+ 4 =========================&persist.save
42
42
  #:overv-reform-pipe end
43
43
  =end
44
44
 
@@ -49,7 +49,7 @@ class DocsContractOverviewTest < Minitest::Spec
49
49
  #- result
50
50
  it do
51
51
  #:result
52
- result = Create.({ length: "A" })
52
+ result = Create.(params: { length: "A" })
53
53
 
54
54
  result["result.contract.default"].success? #=> false
55
55
  result["result.contract.default"].errors #=> Errors object
@@ -59,6 +59,19 @@ class DocsContractOverviewTest < Minitest::Spec
59
59
  result["result.contract.default"].success?.must_equal false
60
60
  result["result.contract.default"].errors.messages.must_equal ({:title=>["can't be blank"], :length=>["is not a number"]})
61
61
  end
62
+
63
+ it "shows 2-level tracing" do
64
+ result = Create.trace( params: { length: "A" } )
65
+ result.wtf.gsub(/0x\w+/, "").must_equal %{|-- #<Trailblazer::Activity::Start:>
66
+ |-- model.build
67
+ |-- contract.build
68
+ |-- contract.default.validate
69
+ | |-- #<Trailblazer::Activity::Start:>
70
+ | |-- contract.default.params_extract
71
+ | |-- contract.default.call
72
+ | `-- #<Trailblazer::Activity::End:>
73
+ `-- #<Trailblazer::Operation::Railway::End::Failure:>}
74
+ end
62
75
  end
63
76
 
64
77
  class DocsContractNameTest < Minitest::Spec
@@ -131,6 +144,7 @@ class DocsContractSeparateKeyTest < Minitest::Spec
131
144
  Song = Struct.new(:id, :title)
132
145
  #:key-extr
133
146
  class Create < Trailblazer::Operation
147
+ extend ClassDependencies
134
148
  extend Contract::DSL
135
149
 
136
150
  contract do
@@ -147,14 +161,14 @@ class DocsContractSeparateKeyTest < Minitest::Spec
147
161
  step Contract::Validate( skip_extract: true )
148
162
  step Contract::Persist( method: :sync )
149
163
 
150
- def extract_params!(options)
151
- options["contract.default.params"] = options["params"][type]
164
+ def extract_params!(options, **)
165
+ options["contract.default.params"] = options[:params][type]
152
166
  end
153
167
  end
154
168
  #:key-extr end
155
169
 
156
- it { Create.({ }).inspect("model").must_equal %{<Result:false [#<struct DocsContractSeparateKeyTest::Song id=nil, title=nil>] >} }
157
- it { Create.({"evergreen" => { title: "SVG" }}).inspect("model").must_equal %{<Result:true [#<struct DocsContractSeparateKeyTest::Song id=nil, title="SVG">] >} }
170
+ it { Create.(params: { }).inspect(:model).must_equal %{<Result:false [#<struct DocsContractSeparateKeyTest::Song id=nil, title=nil>] >} }
171
+ it { Create.(params: {"evergreen" => { title: "SVG" }}).inspect(:model).must_equal %{<Result:true [#<struct DocsContractSeparateKeyTest::Song id=nil, title="SVG">] >} }
158
172
  end
159
173
 
160
174
  #---
@@ -188,18 +202,18 @@ class ContractConstantTest < Minitest::Spec
188
202
  end
189
203
  #:constant end
190
204
 
191
- it { Song::Create.({ title: "A" }).inspect("model").must_equal %{<Result:false [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
192
- it { Song::Create.({ title: "Anthony's Song", length: 12 }).inspect("model").must_equal %{<Result:true [#<struct ContractConstantTest::Song title="Anthony's Song", length=12>] >} }
205
+ it { Song::Create.(params: { title: "A" }).inspect(:model).must_equal %{<Result:false [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
206
+ it { Song::Create.(params: { title: "Anthony's Song", length: 12 }).inspect(:model).must_equal %{<Result:true [#<struct ContractConstantTest::Song title="Anthony's Song", length=12>] >} }
193
207
  it do
194
208
  #:constant-result
195
- result = Song::Create.( title: "A" )
209
+ result = Song::Create.(params: { title: "A" })
196
210
  result.success? #=> false
197
211
  result["contract.default"].errors.messages
198
212
  #=> {:title=>["is too short (minimum is 2 characters)"], :length=>["is not a number"]}
199
213
  #:constant-result end
200
214
 
201
215
  #:constant-result-true
202
- result = Song::Create.( title: "Rising Force", length: 13 )
216
+ result = Song::Create.(params: { title: "Rising Force", length: 13 })
203
217
  result.success? #=> true
204
218
  result["model"] #=> #<Song title="Rising Force", length=13>
205
219
  #:constant-result-true end
@@ -214,11 +228,11 @@ class ContractConstantTest < Minitest::Spec
214
228
  end
215
229
  #:constant-new end
216
230
 
217
- it { Song::New.().inspect("model").must_equal %{<Result:true [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
218
- it { Song::New.()["contract.default"].model.inspect.must_equal %{#<struct ContractConstantTest::Song title=nil, length=nil>} }
231
+ it { Song::New.(params: {}).inspect(:model).must_equal %{<Result:true [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
232
+ it { Song::New.(params: {})["contract.default"].model.inspect.must_equal %{#<struct ContractConstantTest::Song title=nil, length=nil>} }
219
233
  it do
220
234
  #:constant-new-result
221
- result = Song::New.()
235
+ result = Song::New.(params: {})
222
236
  result["model"] #=> #<struct Song title=nil, length=nil>
223
237
  result["contract.default"]
224
238
  #=> #<Song::Contract::Create model=#<struct Song title=nil, length=nil>>
@@ -234,22 +248,22 @@ class ContractConstantTest < Minitest::Spec
234
248
  end
235
249
  #:validate-only end
236
250
 
237
- it { Song::ValidateOnly.().inspect("model").must_equal %{<Result:false [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
251
+ it { Song::ValidateOnly.(params: {}).inspect(:model).must_equal %{<Result:false [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
238
252
  it do
239
- result = Song::ValidateOnly.({ title: "Rising Forse", length: 13 })
240
- result.inspect("model").must_equal %{<Result:true [#<struct ContractConstantTest::Song title=nil, length=nil>] >}
253
+ result = Song::ValidateOnly.(params: { title: "Rising Forse", length: 13 })
254
+ result.inspect(:model).must_equal %{<Result:true [#<struct ContractConstantTest::Song title=nil, length=nil>] >}
241
255
  end
242
256
 
243
257
  it do
244
258
  #:validate-only-result-false
245
- result = Song::ValidateOnly.({}) # empty params
259
+ result = Song::ValidateOnly.(params: {}) # empty params
246
260
  result.success? #=> false
247
261
  #:validate-only-result-false end
248
262
  end
249
263
 
250
264
  it do
251
265
  #:validate-only-result
252
- result = Song::ValidateOnly.({ title: "Rising Force", length: 13 })
266
+ result = Song::ValidateOnly.(params: { title: "Rising Force", length: 13 })
253
267
 
254
268
  result.success? #=> true
255
269
  result["model"] #=> #<struct Song title=nil, length=nil>
@@ -276,16 +290,16 @@ class DocsContractKeyTest < Minitest::Spec
276
290
  end
277
291
  #:key end
278
292
 
279
- it { Song::Create.({}).inspect("model", "result.contract.default.extract").must_equal %{<Result:false [#<struct DocsContractKeyTest::Song title=nil, length=nil>, nil] >} }
280
- it { Song::Create.({"song" => { title: "SVG", length: 13 }}).inspect("model").must_equal %{<Result:true [#<struct DocsContractKeyTest::Song title=\"SVG\", length=13>] >} }
293
+ it { Song::Create.(params: {}).inspect(:model, "result.contract.default.extract").must_equal %{<Result:false [#<struct DocsContractKeyTest::Song title=nil, length=nil>, nil] >} }
294
+ it { Song::Create.(params: {"song" => { title: "SVG", length: 13 }}).inspect(:model).must_equal %{<Result:true [#<struct DocsContractKeyTest::Song title=\"SVG\", length=13>] >} }
281
295
  it do
282
296
  #:key-res
283
- result = Song::Create.({ "song" => { title: "Rising Force", length: 13 } })
297
+ result = Song::Create.(params: { "song" => { title: "Rising Force", length: 13 } })
284
298
  result.success? #=> true
285
299
  #:key-res end
286
300
 
287
301
  #:key-res-false
288
- result = Song::Create.({ title: "Rising Force", length: 13 })
302
+ result = Song::Create.(params: { title: "Rising Force", length: 13 })
289
303
  result.success? #=> false
290
304
  #:key-res-false end
291
305
  end
@@ -308,12 +322,12 @@ class ContractNamedConstantTest < Minitest::Spec
308
322
  end
309
323
  #:constant-name end
310
324
 
311
- it { Song::Create.({ title: "A" }).inspect("model").must_equal %{<Result:false [#<struct ContractNamedConstantTest::Song title=nil, length=nil>] >} }
312
- it { Song::Create.({ title: "Anthony's Song", length: 13 }).inspect("model").must_equal %{<Result:true [#<struct ContractNamedConstantTest::Song title="Anthony's Song", length=13>] >} }
325
+ it { Song::Create.(params: { title: "A" }).inspect(:model).must_equal %{<Result:false [#<struct ContractNamedConstantTest::Song title=nil, length=nil>] >} }
326
+ it { Song::Create.(params: { title: "Anthony's Song", length: 13 }).inspect(:model).must_equal %{<Result:true [#<struct ContractNamedConstantTest::Song title="Anthony's Song", length=13>] >} }
313
327
 
314
328
  it do
315
329
  #:name-res
316
- result = Song::Create.({ title: "A" })
330
+ result = Song::Create.(params: { title: "A" })
317
331
  result["contract.form"].errors.messages #=> {:title=>["is too short (minimum is 2 ch...
318
332
  #:name-res end
319
333
  end
@@ -342,13 +356,13 @@ class ContractInjectConstantTest < Minitest::Spec
342
356
  it do
343
357
  #:di-contract-call
344
358
  Create.(
345
- { title: "Anthony's Song" },
359
+ params: { title: "Anthony's Song" },
346
360
  "contract.default.class" => MyContract
347
361
  )
348
362
  #:di-contract-call end
349
363
  end
350
- it { Create.({ title: "A" }, "contract.default.class" => MyContract).inspect("model").must_equal %{<Result:false [#<struct ContractInjectConstantTest::Song id=nil, title=nil>] >} }
351
- it { Create.({ title: "Anthony's Song" }, "contract.default.class" => MyContract).inspect("model").must_equal %{<Result:true [#<struct ContractInjectConstantTest::Song id=nil, title="Anthony's Song">] >} }
364
+ it { Create.(params: { title: "A" }, "contract.default.class" => MyContract).inspect(:model).must_equal %{<Result:false [#<struct ContractInjectConstantTest::Song id=nil, title=nil>] >} }
365
+ it { Create.(params: { title: "Anthony's Song" }, "contract.default.class" => MyContract).inspect(:model).must_equal %{<Result:true [#<struct ContractInjectConstantTest::Song id=nil, title="Anthony's Song">] >} }
352
366
  end
353
367
 
354
368
  class DryValidationContractTest < Minitest::Spec
@@ -360,6 +374,7 @@ class DryValidationContractTest < Minitest::Spec
360
374
  #:dry-schema
361
375
  require "dry/validation"
362
376
  class Create < Trailblazer::Operation
377
+ extend ClassDependencies
363
378
  extend Contract::DSL
364
379
 
365
380
  # contract to verify params formally.
@@ -384,24 +399,25 @@ class DryValidationContractTest < Minitest::Spec
384
399
  end
385
400
  #:dry-schema end
386
401
 
387
- puts "@@@@@ #{Create["pipetree"].inspect(style: :rows)}"
402
+ puts "@@@@@ #{Trailblazer::Operation::Inspect.(Create, style: :rows)}"
388
403
 
389
- it { Create.({}).inspect("model", "result.contract.params").must_equal %{<Result:false [nil, #<Dry::Validation::Result output={} errors={:id=>[\"is missing\"]}>] >} }
390
- it { Create.({ id: 1 }).inspect("model", "result.contract.params").must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>, #<Dry::Validation::Result output={:id=>1} errors={}>] >} }
391
- # it { Create.({ id: 1, title: "" }).inspect("model", "result.contract.form").must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>] >} }
392
- it { Create.({ id: 1, title: "" }).inspect("model").must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>] >} }
393
- it { Create.({ id: 1, title: "Yo" }).inspect("model").must_equal %{<Result:true [#<struct DryValidationContractTest::Song id=nil, title="Yo">] >} }
404
+ it { Create.(params: {}).inspect(:model, "result.contract.params").must_equal %{<Result:false [nil, #<Dry::Validation::Result output={} errors={:id=>[\"is missing\"]}>] >} }
405
+ it { Create.(params: { id: 1 }).inspect(:model, "result.contract.params").must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>, #<Dry::Validation::Result output={:id=>1} errors={}>] >} }
406
+ # it { Create.(params: { id: 1, title: "" }).inspect(:model, "result.contract.form").must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>] >} }
407
+ it { Create.(params: { id: 1, title: "" }).inspect(:model).must_equal %{<Result:false [#<struct DryValidationContractTest::Song id=nil, title=nil>] >} }
408
+ it { Create.(params: { id: 1, title: "Yo" }).inspect(:model).must_equal %{<Result:true [#<struct DryValidationContractTest::Song id=nil, title="Yo">] >} }
394
409
 
395
410
  #:dry-schema-first
396
411
  require "dry/validation"
397
412
  class Delete < Trailblazer::Operation
413
+ extend ClassDependencies
398
414
  extend Contract::DSL
399
415
 
400
416
  contract "params", (Dry::Validation.Schema do
401
417
  required(:id).filled
402
418
  end)
403
419
 
404
- step Contract::Validate( name: "params" ), before: "operation.new"
420
+ step Contract::Validate( name: "params" )#, prepend: true
405
421
  #~more
406
422
  #~more end
407
423
  end
@@ -420,10 +436,11 @@ class DryExplicitSchemaTest < Minitest::Spec
420
436
  #:dry-schema-expl
421
437
  # app/concepts/comment/delete.rb
422
438
  class Delete < Trailblazer::Operation
439
+ extend ClassDependencies
423
440
  extend Contract::DSL
424
441
  contract "params", MySchema
425
442
 
426
- step Contract::Validate( name: "params" ), before: "operation.new"
443
+ step Contract::Validate( name: "params" )#, prepend: true
427
444
  end
428
445
  #:dry-schema-expl end
429
446
  end
@@ -434,6 +451,7 @@ class DocContractBuilderTest < Minitest::Spec
434
451
  #- builder:
435
452
  #:builder-option
436
453
  class Create < Trailblazer::Operation
454
+ extend ClassDependencies
437
455
  extend Contract::DSL
438
456
 
439
457
  contract do
@@ -448,16 +466,17 @@ class DocContractBuilderTest < Minitest::Spec
448
466
  step Contract::Persist( method: :sync )
449
467
 
450
468
  def default_contract!(options, constant:, model:, **)
451
- constant.new(model, current_user: self["current_user"])
469
+ constant.new(model, current_user: options [:current_user])
452
470
  end
453
471
  end
454
472
  #:builder-option end
455
473
 
456
- it { Create.({}).inspect("model").must_equal %{<Result:false [#<struct DocContractBuilderTest::Song id=nil, title=nil>] >} }
457
- it { Create.({ title: 1}, "current_user" => Module).inspect("model").must_equal %{<Result:true [#<struct DocContractBuilderTest::Song id=nil, title=1>] >} }
474
+ it { Create.(params: {}).inspect(:model).must_equal %{<Result:false [#<struct DocContractBuilderTest::Song id=nil, title=nil>] >} }
475
+ it { Create.(params: { title: 1}, :current_user => Module).inspect(:model).must_equal %{<Result:true [#<struct DocContractBuilderTest::Song id=nil, title=1>] >} }
458
476
 
459
477
  #- proc
460
478
  class Update < Trailblazer::Operation
479
+ extend ClassDependencies
461
480
  extend Contract::DSL
462
481
 
463
482
  contract do
@@ -468,16 +487,16 @@ class DocContractBuilderTest < Minitest::Spec
468
487
 
469
488
  step Model( Song, :new )
470
489
  #:builder-proc
471
- step Contract::Build( builder: ->(options, constant:, model:, **) {
472
- constant.new(model, current_user: options["current_user"])
490
+ step Contract::Build( builder: ->(options, constant:raise, model:raise, **) {
491
+ constant.new(model, current_user: options[:current_user])
473
492
  })
474
493
  #:builder-proc end
475
494
  step Contract::Validate()
476
495
  step Contract::Persist( method: :sync )
477
496
  end
478
497
 
479
- it { Update.({}).inspect("model").must_equal %{<Result:false [#<struct DocContractBuilderTest::Song id=nil, title=nil>] >} }
480
- it { Update.({ title: 1}, "current_user" => Module).inspect("model").must_equal %{<Result:true [#<struct DocContractBuilderTest::Song id=nil, title=1>] >} }
498
+ it { Update.(params: {}).inspect(:model).must_equal %{<Result:false [#<struct DocContractBuilderTest::Song id=nil, title=nil>] >} }
499
+ it { Update.(params: { title: 1}, :current_user => Module).inspect(:model).must_equal %{<Result:true [#<struct DocContractBuilderTest::Song id=nil, title=1>] >} }
481
500
  end
482
501
 
483
502
  class DocContractTest < Minitest::Spec
@@ -485,6 +504,7 @@ class DocContractTest < Minitest::Spec
485
504
  #---
486
505
  # with contract block, and inheritance, the old way.
487
506
  class Block < Trailblazer::Operation
507
+ extend ClassDependencies
488
508
  extend Contract::DSL
489
509
  contract do
490
510
  property :title
@@ -496,8 +516,8 @@ class DocContractTest < Minitest::Spec
496
516
  step Contract::Persist( method: :sync )
497
517
  end
498
518
 
499
- it { Block.({}).inspect("model").must_equal %{<Result:true [#<struct DocContractTest::Song id=nil, title=nil>] >} }
500
- it { Block.({ id:1, title: "Fame" }).inspect("model").must_equal %{<Result:true [#<struct DocContractTest::Song id=nil, title="Fame">] >} }
519
+ it { Block.(params: {}).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=nil, title=nil>] >} }
520
+ it { Block.(params: { id:1, title: "Fame" }).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=nil, title="Fame">] >} }
501
521
 
502
522
  class Breach < Block
503
523
  contract do
@@ -505,7 +525,7 @@ class DocContractTest < Minitest::Spec
505
525
  end
506
526
  end
507
527
 
508
- it { Breach.({ id:1, title: "Fame" }).inspect("model").must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title="Fame">] >} }
528
+ it { Breach.(params: { id:1, title: "Fame" }).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title="Fame">] >} }
509
529
 
510
530
  #-
511
531
  # with constant.
@@ -517,7 +537,7 @@ class DocContractTest < Minitest::Spec
517
537
  contract MyContract
518
538
  end
519
539
 
520
- it { Break.({ id:1, title: "Fame" }).inspect("model").must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title=nil>] >} }
540
+ it { Break.(params: { id:1, title: "Fame" }).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title=nil>] >} }
521
541
  end
522
542
 
523
543
 
@@ -26,6 +26,6 @@ class DryContainerTest < Minitest::Spec
26
26
  end
27
27
  #:key end
28
28
 
29
- it { Create.({ title: "A" }, {}, my_container).inspect("model").must_equal %{<Result:false [#<struct DryContainerTest::Song id=nil, title=nil>] >} }
30
- it { Create.({ title: "Anthony's Song" }, {}, my_container).inspect("model").must_equal %{<Result:true [#<struct DryContainerTest::Song id=nil, title="Anthony's Song">] >} }
29
+ it { Create.({params: { title: "A" }}, my_container).inspect(:model).must_equal %{<Result:false [#<struct DryContainerTest::Song id=nil, title=nil>] >} }
30
+ it { Create.({params: { title: "Anthony's Song" }}, my_container).inspect(:model).must_equal %{<Result:true [#<struct DryContainerTest::Song id=nil, title="Anthony's Song">] >} }
31
31
  end
@@ -24,10 +24,10 @@ class DocsFailFastOptionTest < Minitest::Spec
24
24
  end
25
25
  #:ffopt end
26
26
 
27
- it { Update.(id: 1).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
27
+ it { Update.(params: {id: 1}).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
28
28
  it do
29
29
  #:ffopt-res
30
- result = Update.(id: 1)
30
+ result = Update.(params: {id: 1})
31
31
  result["result.model.song"] #=> "Something went wrong with ID 1!"
32
32
  #:ffopt-res end
33
33
  end
@@ -50,11 +50,11 @@ class DocsFailFastOptionWithStepTest < Minitest::Spec
50
50
  end
51
51
  #:ffopt-step end
52
52
 
53
- it { Update.({ id: nil }).inspect("model").must_equal %{<Result:false [nil] >} }
54
- it { Update.({ id: 1 }).inspect("model").must_equal %{<Result:true [Object] >} }
53
+ it { Update.(params: { id: nil }).inspect(:model).must_equal %{<Result:false [nil] >} }
54
+ it { Update.(params: { id: 1 }).inspect(:model).must_equal %{<Result:true [Object] >} }
55
55
  it do
56
56
  #:ffopt-step-res
57
- result = Update.({ id: nil })
57
+ result = Update.(params: { id: nil })
58
58
 
59
59
  result.failure? #=> true
60
60
  result["model"] #=> nil
@@ -85,10 +85,10 @@ class DocsPassFastWithStepOptionTest < Minitest::Spec
85
85
  end
86
86
  #:pfopt-step end
87
87
 
88
- it { Update.(id: 1).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
88
+ it { Update.(params: {id: 1}).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
89
89
  it do
90
90
  #:pfopt-step-res
91
- result = Update.(id: 1)
91
+ result = Update.(params: {id: 1})
92
92
  result["result.model.song"] #=> "Something went wrong with ID 1!"
93
93
  #:pfopt-step-res end
94
94
  end
@@ -101,7 +101,7 @@ class DocsFailFastMethodTest < Minitest::Spec
101
101
 
102
102
  #:ffmeth
103
103
  class Update < Trailblazer::Operation
104
- step :filter_params! # emits fail_fast!
104
+ step :filter_params!, fast_track: true # emits fail_fast!
105
105
  step Model( Song, :find_by )
106
106
  failure :handle_fail!
107
107
 
@@ -118,10 +118,10 @@ class DocsFailFastMethodTest < Minitest::Spec
118
118
  end
119
119
  #:ffmeth end
120
120
 
121
- it { Update.({}).inspect("result.params", "my.status").must_equal %{<Result:false [\"No ID in params!\", nil] >} }
121
+ it { Update.(params: {}).inspect("result.params", "my.status").must_equal %{<Result:false [\"No ID in params!\", nil] >} }
122
122
  it do
123
123
  #:ffmeth-res
124
- result = Update.(id: 1)
124
+ result = Update.(params: {id: 1})
125
125
  result["result.params"] #=> "No ID in params!"
126
126
  result["my.status"] #=> nil
127
127
  #:ffmeth-res end
@@ -139,7 +139,7 @@ class DocsPassFastMethodTest < Minitest::Spec
139
139
  #:pfmeth
140
140
  class Create < Trailblazer::Operation
141
141
  step Model( Song, :new )
142
- step :empty_model! # emits pass_fast!
142
+ step :empty_model!, fast_track: true # emits pass_fast!
143
143
  step Contract::Build( constant: MyContract )
144
144
  # ..
145
145
 
@@ -151,14 +151,134 @@ class DocsPassFastMethodTest < Minitest::Spec
151
151
  end
152
152
  #:pfmeth end
153
153
 
154
- it { Create.({ title: "Tyrant"}, "is_empty" => true).inspect("model").must_equal %{<Result:true [#<struct DocsPassFastMethodTest::Song id=nil, title=nil>] >} }
154
+ it { Create.(params: { title: "Tyrant"}, "is_empty" => true).inspect(:model).must_equal %{<Result:true [#<struct DocsPassFastMethodTest::Song id=nil, title=nil>] >} }
155
155
  it do
156
156
  #:pfmeth-res
157
- result = Create.({}, "is_empty" => true)
157
+ result = Create.(params: {}, "is_empty" => true)
158
158
  result["model"] #=> #<Song id=nil, title=nil>
159
159
  #:pfmeth-res end
160
160
  end
161
161
  end
162
162
 
163
+
164
+ class FastTrackWithNestedTest < Minitest::Spec
165
+ module Lib; end
166
+ module Memo; end
167
+
168
+ #:ft-nested
169
+ class Lib::Authenticate < Trailblazer::Operation
170
+ step :verify_input, fail_fast: true
171
+ step :user_ok?
172
+ #~ign
173
+ def verify_input(options, w:true, **); options[:w] = true; w; end
174
+ def user_ok?(options, u:true, **); options[:u] = true; u; end
175
+ #~ign end
176
+ end
177
+ #:ft-nested end
178
+
179
+ #:ft-create
180
+ class Memo::Create < Trailblazer::Operation
181
+ step :validate
182
+ step Nested( Lib::Authenticate ) # fail_fast goes to End.fail_fast
183
+ step :create_model
184
+ step :save
185
+ #~igncr
186
+ def validate(options, v:true, **); options[:v] = true; v; end
187
+ def create_model(options, c:true, **); options[:c] = true; c; end
188
+ def save(options, s:true, **); options[:s] = true; s; end
189
+ #~igncr end
190
+ end
191
+ #:ft-create end
192
+
193
+ it "everything goes :success ===> End.success" do
194
+ result = Memo::Create.()
195
+
196
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:true [true, true, true, true, true] >}
197
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Success
198
+ end
199
+
200
+ it "validate => failure ===> End.failure" do
201
+ result = Memo::Create.(v: false)
202
+
203
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, nil, nil, nil, nil] >}
204
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
205
+ end
206
+
207
+ it "verify_input? => fail_fast ===> End.fail_fast" do
208
+ result = Memo::Create.(w: false)
209
+
210
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, nil, nil, nil] >}
211
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::FailFast
212
+ end
213
+
214
+ it "user_ok? => fail ===> End.failure" do
215
+ result = Memo::Create.(u: false)
216
+
217
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, true, nil, nil] >}
218
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
219
+ end
220
+
221
+ it "create_model? => fail ===> End.failure" do
222
+ result = Memo::Create.(c: false)
223
+
224
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, true, true, nil] >}
225
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
226
+ end
227
+
228
+ module Rewire
229
+ module Memo; end
230
+
231
+ #:ft-rewire
232
+ class Memo::Create < Trailblazer::Operation
233
+ step :validate
234
+ step Nested( Lib::Authenticate ), Output(:fail_fast) => :failure
235
+ step :create_model
236
+ step :save
237
+ #~ignrw
238
+ def validate(options, v:true, **); options[:v] = true; v; end
239
+ def create_model(options, c:true, **); options[:c] = true; c; end
240
+ def save(options, s:true, **); options[:s] = true; s; end
241
+ #~ignrw end
242
+ end
243
+ #:ft-rewire end
244
+ end
245
+
246
+ it "everything goes :success ===> End.success" do
247
+ result = Rewire::Memo::Create.()
248
+
249
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:true [true, true, true, true, true] >}
250
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Success
251
+ end
252
+
253
+ it "validate => failure ===> End.failure" do
254
+ result = Rewire::Memo::Create.(v: false)
255
+
256
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, nil, nil, nil, nil] >}
257
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
258
+ end
259
+
260
+ # this is the only test differing.
261
+ it "verify_input? => fail_fast ===> End.failure" do
262
+ result = Rewire::Memo::Create.(w: false)
263
+
264
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, nil, nil, nil] >}
265
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
266
+ end
267
+
268
+ it "user_ok? => fail ===> End.failure" do
269
+ result = Rewire::Memo::Create.(u: false)
270
+
271
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, true, nil, nil] >}
272
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
273
+ end
274
+
275
+ it "create_model? => fail ===> End.failure" do
276
+ result = Rewire::Memo::Create.(c: false)
277
+
278
+ result.inspect(:v,:w,:u,:c,:s).must_equal %{<Result:false [true, true, true, true, nil] >}
279
+ result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
280
+ end
281
+ end
282
+
163
283
  # fail!
164
284
  # pass!