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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +194 -502
- data/CHANGES.md +4 -0
- data/CONTRIBUTING.md +170 -0
- data/Gemfile +4 -1
- data/README.md +183 -40
- data/Rakefile +6 -2
- data/lib/trailblazer/version.rb +1 -1
- data/lib/trailblazer.rb +3 -12
- data/test/{operation/dsl → dsl}/contract_test.rb +2 -2
- data/trailblazer.gemspec +3 -3
- metadata +17 -63
- data/lib/trailblazer/operation/contract.rb +0 -82
- data/lib/trailblazer/operation/guard.rb +0 -18
- data/lib/trailblazer/operation/model.rb +0 -65
- data/lib/trailblazer/operation/nested.rb +0 -91
- data/lib/trailblazer/operation/persist.rb +0 -14
- data/lib/trailblazer/operation/policy.rb +0 -44
- data/lib/trailblazer/operation/pundit.rb +0 -38
- data/lib/trailblazer/operation/representer.rb +0 -36
- data/lib/trailblazer/operation/rescue.rb +0 -24
- data/lib/trailblazer/operation/validate.rb +0 -74
- data/lib/trailblazer/operation/wrap.rb +0 -64
- data/test/docs/contract_test.rb +0 -545
- data/test/docs/dry_test.rb +0 -31
- data/test/docs/guard_test.rb +0 -162
- data/test/docs/macro_test.rb +0 -36
- data/test/docs/model_test.rb +0 -75
- data/test/docs/nested_test.rb +0 -300
- data/test/docs/policy_test.rb +0 -2
- data/test/docs/pundit_test.rb +0 -133
- data/test/docs/representer_test.rb +0 -268
- data/test/docs/rescue_test.rb +0 -154
- data/test/docs/wrap_test.rb +0 -219
- data/test/nested_test.rb +0 -293
- data/test/operation/contract_test.rb +0 -290
- data/test/operation/dsl/representer_test.rb +0 -169
- data/test/operation/model_test.rb +0 -54
- data/test/operation/persist_test.rb +0 -51
- data/test/operation/pundit_test.rb +0 -106
- 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)
|
data/test/docs/contract_test.rb
DELETED
@@ -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
|
-
|
data/test/docs/dry_test.rb
DELETED
@@ -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
|