trailblazer 2.1.0.beta4 → 2.1.0.beta5

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 (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