trailblazer 2.1.0.beta4 → 2.1.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +194 -502
  3. data/CHANGES.md +4 -0
  4. data/CONTRIBUTING.md +170 -0
  5. data/Gemfile +4 -1
  6. data/README.md +183 -40
  7. data/Rakefile +6 -2
  8. data/lib/trailblazer/version.rb +1 -1
  9. data/lib/trailblazer.rb +3 -12
  10. data/test/{operation/dsl → dsl}/contract_test.rb +2 -2
  11. data/trailblazer.gemspec +3 -3
  12. metadata +17 -63
  13. data/lib/trailblazer/operation/contract.rb +0 -82
  14. data/lib/trailblazer/operation/guard.rb +0 -18
  15. data/lib/trailblazer/operation/model.rb +0 -65
  16. data/lib/trailblazer/operation/nested.rb +0 -91
  17. data/lib/trailblazer/operation/persist.rb +0 -14
  18. data/lib/trailblazer/operation/policy.rb +0 -44
  19. data/lib/trailblazer/operation/pundit.rb +0 -38
  20. data/lib/trailblazer/operation/representer.rb +0 -36
  21. data/lib/trailblazer/operation/rescue.rb +0 -24
  22. data/lib/trailblazer/operation/validate.rb +0 -74
  23. data/lib/trailblazer/operation/wrap.rb +0 -64
  24. data/test/docs/contract_test.rb +0 -545
  25. data/test/docs/dry_test.rb +0 -31
  26. data/test/docs/guard_test.rb +0 -162
  27. data/test/docs/macro_test.rb +0 -36
  28. data/test/docs/model_test.rb +0 -75
  29. data/test/docs/nested_test.rb +0 -300
  30. data/test/docs/policy_test.rb +0 -2
  31. data/test/docs/pundit_test.rb +0 -133
  32. data/test/docs/representer_test.rb +0 -268
  33. data/test/docs/rescue_test.rb +0 -154
  34. data/test/docs/wrap_test.rb +0 -219
  35. data/test/nested_test.rb +0 -293
  36. data/test/operation/contract_test.rb +0 -290
  37. data/test/operation/dsl/representer_test.rb +0 -169
  38. data/test/operation/model_test.rb +0 -54
  39. data/test/operation/persist_test.rb +0 -51
  40. data/test/operation/pundit_test.rb +0 -106
  41. data/test/operation/representer_test.rb +0 -254
@@ -1,64 +0,0 @@
1
- class Trailblazer::Operation
2
-
3
- # false is automatically connected to End.failure.
4
-
5
- def self.Wrap(user_wrap, id: "Wrap/#{rand(100)}", &block)
6
- operation_class = Wrap.create_operation(block)
7
- wrapped = Wrap::Wrapped.new(operation_class, user_wrap)
8
-
9
- # connect `false` as an end event, when an exception stopped the wrap, for example.
10
-
11
- { task: wrapped, id: id, outputs: operation_class.outputs }
12
- # TODO: Nested could have a better API and do the "merge" for us!
13
- end
14
-
15
- module Wrap
16
- def self.create_operation(block)
17
- Class.new( Nested.operation_class, &block ) # Usually resolves to Trailblazer::Operation.
18
- end
19
-
20
- # behaves like an operation so it plays with Nested and simply calls the operation in the user-provided block.
21
- class Wrapped #< Trailblazer::Operation # FIXME: the inheritance is only to satisfy Nested( Wrapped.new )
22
- include Trailblazer::Activity::Interface
23
-
24
- def initialize(operation, user_wrap)
25
- @operation = operation
26
- @user_wrap = user_wrap
27
- end
28
-
29
- def call( (options, flow_options), **circuit_options )
30
- block_calling_wrapped = -> {
31
- activity = @operation.to_h[:activity]
32
-
33
- activity.( [options, flow_options], **circuit_options )
34
- }
35
-
36
- # call the user's Wrap {} block in the operation.
37
- # This will invoke block_calling_wrapped above if the user block yields.
38
- returned = @user_wrap.( options, flow_options, **circuit_options, &block_calling_wrapped )
39
-
40
- # returned could be
41
- # 1. the 1..>=3 Task interface result
42
- # 2. false
43
- # 3. true or something else, but not the Task interface (when rescue isn't needed)
44
-
45
- # legacy outcome.
46
- # FIXME: we *might* return some "older version" of options here!
47
- if returned === false
48
- return @operation.outputs[:failure].signal, [options, flow_options]
49
- elsif returned === true
50
- return @operation.outputs[:success].signal, [options, flow_options]
51
- end
52
-
53
- returned # let's hope returned is one of activity's Ends.
54
- end
55
-
56
- def outputs
57
- @operation.outputs # FIXME: we don't map false, yet
58
- end
59
- end
60
- end # Wrap
61
- end
62
-
63
- # (options, *) => (options, operation, bla)
64
- # (*, params:, **) => (options, operation, bla, options)
@@ -1,545 +0,0 @@
1
- require "test_helper"
2
-
3
- class DocsContractOverviewTest < Minitest::Spec
4
- Song = Struct.new(:length, :title)
5
-
6
- #:overv-reform
7
- # app/concepts/song/create.rb
8
- class Create < Trailblazer::Operation
9
- #~bla
10
- extend ClassDependencies
11
- extend Contract::DSL
12
-
13
- contract do
14
- property :title
15
- #~contractonly
16
- property :length
17
-
18
- validates :title, presence: true
19
- validates :length, numericality: true
20
- #~contractonly end
21
- end
22
- #~contractonly
23
-
24
- #~bla end
25
- step Model( Song, :new )
26
- step Contract::Build()
27
- step Contract::Validate()
28
- step Contract::Persist( method: :sync )
29
- #~contractonly end
30
- end
31
- #:overv-reform end
32
-
33
- puts Trailblazer::Operation::Inspect.(Create, style: :rows)
34
-
35
- =begin
36
- #:overv-reform-pipe
37
- 0 ==========================&model.build
38
- 1 =======================>contract.build
39
- 2 ==============&validate.params.extract
40
- 3 ====================&contract.validate
41
- 4 =========================&persist.save
42
- #:overv-reform-pipe end
43
- =end
44
-
45
- it do
46
- assert Create["contract.default.class"] < Reform::Form
47
- end
48
-
49
- #- result
50
- it do
51
- #:result
52
- result = Create.(params: { length: "A" })
53
-
54
- result["result.contract.default"].success? #=> false
55
- result["result.contract.default"].errors #=> Errors object
56
- result["result.contract.default"].errors.messages #=> {:length=>["is not a number"]}
57
-
58
- #:result end
59
- result["result.contract.default"].success?.must_equal false
60
- result["result.contract.default"].errors.messages.must_equal ({:title=>["can't be blank"], :length=>["is not a number"]})
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 semantic=:default>
66
- |-- model.build
67
- |-- contract.build
68
- |-- contract.default.validate
69
- | |-- #<Trailblazer::Activity::Start semantic=:default>
70
- | |-- contract.default.params_extract
71
- | |-- contract.default.call
72
- | `-- #<Trailblazer::Activity::End semantic=:failure>
73
- `-- #<Trailblazer::Operation::Railway::End::Failure semantic=:failure>}
74
- end
75
- end
76
-
77
- class DocsContractNameTest < Minitest::Spec
78
- Song = Struct.new(:length, :title)
79
-
80
- #:contract-name
81
- # app/concepts/comment/update.rb
82
- class Update < Trailblazer::Operation
83
- #~contract
84
- extend Contract::DSL
85
-
86
- contract :params do
87
- property :id
88
- validates :id, presence: true
89
- end
90
- #~contract end
91
- #~pipe
92
- step Model( Song, :new )
93
- step Contract::Build( name: "params" )
94
- step Contract::Validate( name: "params" )
95
- #~pipe end
96
- end
97
- #:contract-name end
98
- end
99
-
100
- class DocsContractReferenceTest < Minitest::Spec
101
- MyContract = Class.new
102
- #:contract-ref
103
- # app/concepts/comment/update.rb
104
- class Update < Trailblazer::Operation
105
- #~contract
106
- extend Contract::DSL
107
- contract :user, MyContract
108
- end
109
- #:contract-ref end
110
- end
111
-
112
- #---
113
- # contract MyContract
114
- class DocsContractExplicitTest < Minitest::Spec
115
- Song = Struct.new(:length, :title)
116
-
117
- #:reform-inline
118
- class MyContract < Reform::Form
119
- property :title
120
- property :length
121
-
122
- validates :title, presence: true
123
- validates :length, numericality: true
124
- end
125
- #:reform-inline end
126
-
127
- #:reform-inline-op
128
- # app/concepts/comment/create.rb
129
- class Create < Trailblazer::Operation
130
- extend Contract::DSL
131
-
132
- contract MyContract
133
-
134
- step Model( Song, :new )
135
- step Contract::Build()
136
- step Contract::Validate()
137
- step Contract::Persist( method: :sync )
138
- end
139
- #:reform-inline-op end
140
- end
141
-
142
- #- Validate with manual key extraction
143
- class DocsContractSeparateKeyTest < Minitest::Spec
144
- Song = Struct.new(:id, :title)
145
- #:key-extr
146
- class Create < Trailblazer::Operation
147
- extend ClassDependencies
148
- extend Contract::DSL
149
-
150
- contract do
151
- property :title
152
- end
153
-
154
- def type
155
- "evergreen" # this is how you could do polymorphic lookups.
156
- end
157
-
158
- step Model( Song, :new )
159
- step Contract::Build()
160
- step :extract_params!
161
- step Contract::Validate( skip_extract: true )
162
- step Contract::Persist( method: :sync )
163
-
164
- def extract_params!(options, **)
165
- options["contract.default.params"] = options[:params][type]
166
- end
167
- end
168
- #:key-extr end
169
-
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">] >} }
172
- end
173
-
174
- #---
175
- #- Contract::Build( constant: XXX )
176
- class ContractConstantTest < Minitest::Spec
177
- Song = Struct.new(:title, :length) do
178
- def save
179
- true
180
- end
181
- end
182
-
183
- #:constant-contract
184
- # app/concepts/song/contract/create.rb
185
- module Song::Contract
186
- class Create < Reform::Form
187
- property :title
188
- property :length
189
-
190
- validates :title, length: 2..33
191
- validates :length, numericality: true
192
- end
193
- end
194
- #:constant-contract end
195
-
196
- #:constant
197
- class Song::Create < Trailblazer::Operation
198
- step Model( Song, :new )
199
- step Contract::Build( constant: Song::Contract::Create )
200
- step Contract::Validate()
201
- step Contract::Persist()
202
- end
203
- #:constant end
204
-
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>] >} }
207
- it do
208
- #:constant-result
209
- result = Song::Create.(params: { title: "A" })
210
- result.success? #=> false
211
- result["contract.default"].errors.messages
212
- #=> {:title=>["is too short (minimum is 2 characters)"], :length=>["is not a number"]}
213
- #:constant-result end
214
-
215
- #:constant-result-true
216
- result = Song::Create.(params: { title: "Rising Force", length: 13 })
217
- result.success? #=> true
218
- result["model"] #=> #<Song title="Rising Force", length=13>
219
- #:constant-result-true end
220
- end
221
-
222
- #---
223
- # Song::New
224
- #:constant-new
225
- class Song::New < Trailblazer::Operation
226
- step Model( Song, :new )
227
- step Contract::Build( constant: Song::Contract::Create )
228
- end
229
- #:constant-new end
230
-
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>} }
233
- it do
234
- #:constant-new-result
235
- result = Song::New.(params: {})
236
- result["model"] #=> #<struct Song title=nil, length=nil>
237
- result["contract.default"]
238
- #=> #<Song::Contract::Create model=#<struct Song title=nil, length=nil>>
239
- #:constant-new-result end
240
- end
241
-
242
- #---
243
- #:validate-only
244
- class Song::ValidateOnly < Trailblazer::Operation
245
- step Model( Song, :new )
246
- step Contract::Build( constant: Song::Contract::Create )
247
- step Contract::Validate()
248
- end
249
- #:validate-only end
250
-
251
- it { Song::ValidateOnly.(params: {}).inspect(:model).must_equal %{<Result:false [#<struct ContractConstantTest::Song title=nil, length=nil>] >} }
252
- it do
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>] >}
255
- end
256
-
257
- it do
258
- #:validate-only-result-false
259
- result = Song::ValidateOnly.(params: {}) # empty params
260
- result.success? #=> false
261
- #:validate-only-result-false end
262
- end
263
-
264
- it do
265
- #:validate-only-result
266
- result = Song::ValidateOnly.(params: { title: "Rising Force", length: 13 })
267
-
268
- result.success? #=> true
269
- result["model"] #=> #<struct Song title=nil, length=nil>
270
- result["contract.default"].title #=> "Rising Force"
271
- #:validate-only-result end
272
- end
273
- end
274
-
275
- #---
276
- #- Validate( key: :song )
277
- class DocsContractKeyTest < Minitest::Spec
278
- Song = Class.new(ContractConstantTest::Song)
279
-
280
- module Song::Contract
281
- Create = ContractConstantTest::Song::Contract::Create
282
- end
283
-
284
- #:key
285
- class Song::Create < Trailblazer::Operation
286
- step Model( Song, :new )
287
- step Contract::Build( constant: Song::Contract::Create )
288
- step Contract::Validate( key: "song" )
289
- step Contract::Persist( )
290
- end
291
- #:key end
292
-
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>] >} }
295
- it do
296
- #:key-res
297
- result = Song::Create.(params: { "song" => { title: "Rising Force", length: 13 } })
298
- result.success? #=> true
299
- #:key-res end
300
-
301
- #:key-res-false
302
- result = Song::Create.(params: { title: "Rising Force", length: 13 })
303
- result.success? #=> false
304
- #:key-res-false end
305
- end
306
- end
307
-
308
- #- Contract::Build[ constant: XXX, name: AAA ]
309
- class ContractNamedConstantTest < Minitest::Spec
310
- Song = Class.new(ContractConstantTest::Song)
311
-
312
- module Song::Contract
313
- Create = ContractConstantTest::Song::Contract::Create
314
- end
315
-
316
- #:constant-name
317
- class Song::Create < Trailblazer::Operation
318
- step Model( Song, :new )
319
- step Contract::Build( name: "form", constant: Song::Contract::Create )
320
- step Contract::Validate( name: "form" )
321
- step Contract::Persist( name: "form" )
322
- end
323
- #:constant-name end
324
-
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>] >} }
327
-
328
- it do
329
- #:name-res
330
- result = Song::Create.(params: { title: "A" })
331
- result["contract.form"].errors.messages #=> {:title=>["is too short (minimum is 2 ch...
332
- #:name-res end
333
- end
334
- end
335
-
336
- #---
337
- #- dependency injection
338
- #- contract class
339
- class ContractInjectConstantTest < Minitest::Spec
340
- Song = Struct.new(:id, :title)
341
- #:di-constant-contract
342
- class MyContract < Reform::Form
343
- property :title
344
- validates :title, length: 2..33
345
- end
346
- #:di-constant-contract end
347
- #:di-constant
348
- class Create < Trailblazer::Operation
349
- step Model( Song, :new )
350
- step Contract::Build()
351
- step Contract::Validate()
352
- step Contract::Persist( method: :sync )
353
- end
354
- #:di-constant end
355
-
356
- it do
357
- #:di-contract-call
358
- Create.(
359
- params: { title: "Anthony's Song" },
360
- "contract.default.class" => MyContract
361
- )
362
- #:di-contract-call end
363
- end
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">] >} }
366
- end
367
-
368
- class DryValidationContractTest < Minitest::Spec
369
- Song = Struct.new(:id, :title)
370
- #---
371
- # DRY-validation params validation before op,
372
- # plus main contract.
373
- #- result.path
374
- #:dry-schema
375
- require "dry/validation"
376
- class Create < Trailblazer::Operation
377
- extend ClassDependencies
378
- extend Contract::DSL
379
-
380
- # contract to verify params formally.
381
- contract "params", (Dry::Validation.Schema do
382
- required(:id).filled
383
- end)
384
- #~form
385
- # domain validations.
386
- contract "form" do
387
- property :title
388
- validates :title, length: 1..3
389
- end
390
- #~form end
391
-
392
- step Contract::Validate( name: "params" )
393
- #~form
394
- step Model( Song, :new ) # create the op's main model.
395
- step Contract::Build( name: "form" ) # create the Reform contract.
396
- step Contract::Validate( name: "form" ) # validate the Reform contract.
397
- step Contract::Persist( method: :sync, name: "form" ) # persist the contract's data via the model.
398
- #~form end
399
- end
400
- #:dry-schema end
401
-
402
- puts "@@@@@ #{Trailblazer::Operation::Inspect.(Create, style: :rows)}"
403
-
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">] >} }
409
-
410
- #:dry-schema-first
411
- require "dry/validation"
412
- class Delete < Trailblazer::Operation
413
- extend ClassDependencies
414
- extend Contract::DSL
415
-
416
- contract "params", (Dry::Validation.Schema do
417
- required(:id).filled
418
- end)
419
-
420
- step Contract::Validate( name: "params" )#, prepend: true
421
- #~more
422
- #~more end
423
- end
424
- #:dry-schema-first end
425
- end
426
-
427
- class DryExplicitSchemaTest < Minitest::Spec
428
- #:dry-schema-explsch
429
- # app/concepts/comment/contract/params.rb
430
- require "dry/validation"
431
- MySchema = Dry::Validation.Schema do
432
- required(:id).filled
433
- end
434
- #:dry-schema-explsch end
435
-
436
- #:dry-schema-expl
437
- # app/concepts/comment/delete.rb
438
- class Delete < Trailblazer::Operation
439
- extend ClassDependencies
440
- extend Contract::DSL
441
- contract "params", MySchema
442
-
443
- step Contract::Validate( name: "params" )#, prepend: true
444
- end
445
- #:dry-schema-expl end
446
- end
447
-
448
- class DocContractBuilderTest < Minitest::Spec
449
- Song = Struct.new(:id, :title)
450
- #---
451
- #- builder:
452
- #:builder-option
453
- class Create < Trailblazer::Operation
454
- extend ClassDependencies
455
- extend Contract::DSL
456
-
457
- contract do
458
- property :title
459
- property :current_user, virtual: true
460
- validates :current_user, presence: true
461
- end
462
-
463
- step Model( Song, :new )
464
- step Contract::Build( builder: :default_contract! )
465
- step Contract::Validate()
466
- step Contract::Persist( method: :sync )
467
-
468
- def default_contract!(options, constant:, model:, **)
469
- constant.new(model, current_user: options [:current_user])
470
- end
471
- end
472
- #:builder-option end
473
-
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>] >} }
476
-
477
- #- proc
478
- class Update < Trailblazer::Operation
479
- extend ClassDependencies
480
- extend Contract::DSL
481
-
482
- contract do
483
- property :title
484
- property :current_user, virtual: true
485
- validates :current_user, presence: true
486
- end
487
-
488
- step Model( Song, :new )
489
- #:builder-proc
490
- step Contract::Build( builder: ->(options, constant:raise, model:raise, **) {
491
- constant.new(model, current_user: options[:current_user])
492
- })
493
- #:builder-proc end
494
- step Contract::Validate()
495
- step Contract::Persist( method: :sync )
496
- end
497
-
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>] >} }
500
- end
501
-
502
- class DocContractTest < Minitest::Spec
503
- Song = Struct.new(:id, :title)
504
- #---
505
- # with contract block, and inheritance, the old way.
506
- class Block < Trailblazer::Operation
507
- extend ClassDependencies
508
- extend Contract::DSL
509
- contract do
510
- property :title
511
- end
512
-
513
- step Model( Song, :new )
514
- step Contract::Build() # resolves to "contract.class.default" and is resolved at runtime.
515
- step Contract::Validate()
516
- step Contract::Persist( method: :sync )
517
- end
518
-
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">] >} }
521
-
522
- class Breach < Block
523
- contract do
524
- property :id
525
- end
526
- end
527
-
528
- it { Breach.(params: { id:1, title: "Fame" }).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title="Fame">] >} }
529
-
530
- #-
531
- # with constant.
532
- class Break < Block
533
- class MyContract < Reform::Form
534
- property :id
535
- end
536
- # override the original block as if it's never been there.
537
- contract MyContract
538
- end
539
-
540
- it { Break.(params: { id:1, title: "Fame" }).inspect(:model).must_equal %{<Result:true [#<struct DocContractTest::Song id=1, title=nil>] >} }
541
- end
542
-
543
-
544
-
545
-
@@ -1,31 +0,0 @@
1
- require "test_helper"
2
- require "dry/container"
3
-
4
- class DryContainerTest < Minitest::Spec
5
- Song = Struct.new(:id, :title)
6
-
7
- class MyContract < Reform::Form
8
- property :title
9
- validates :title, length: 2..33
10
- end
11
-
12
- my_container = Dry::Container.new
13
- my_container.register("contract.default.class", MyContract)
14
- # my_container.namespace("contract") do
15
- # register("create") { Array }
16
- # end
17
-
18
- #---
19
- #- dependency injection
20
- #- with Dry-container
21
- class Create < Trailblazer::Operation
22
- step Model( Song, :new )
23
- step Contract::Build()
24
- step Contract::Validate()
25
- step Contract::Persist( method: :sync )
26
- end
27
- #:key end
28
-
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
- end