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.
- checksums.yaml +4 -4
- data/CHANGES.md +35 -1
- data/Gemfile +6 -12
- data/README.md +3 -1
- data/Rakefile +6 -17
- data/lib/trailblazer.rb +7 -4
- data/lib/trailblazer/deprecation/call.rb +46 -0
- data/lib/trailblazer/deprecation/context.rb +43 -0
- data/lib/trailblazer/operation/contract.rb +40 -9
- data/lib/trailblazer/operation/deprecations.rb +21 -0
- data/lib/trailblazer/operation/guard.rb +5 -5
- data/lib/trailblazer/operation/model.rb +15 -10
- data/lib/trailblazer/operation/nested.rb +56 -85
- data/lib/trailblazer/operation/persist.rb +4 -2
- data/lib/trailblazer/operation/policy.rb +16 -7
- data/lib/trailblazer/operation/pundit.rb +3 -3
- data/lib/trailblazer/operation/representer.rb +5 -0
- data/lib/trailblazer/operation/rescue.rb +12 -9
- data/lib/trailblazer/operation/validate.rb +36 -29
- data/lib/trailblazer/operation/wrap.rb +49 -11
- data/lib/trailblazer/task.rb +20 -0
- data/lib/trailblazer/version.rb +1 -1
- data/test/benchmark.rb +63 -0
- data/test/deprecation/call_test.rb +42 -0
- data/test/deprecation/context_test.rb +19 -0
- data/test/docs/contract_test.rb +73 -53
- data/test/docs/dry_test.rb +2 -2
- data/test/docs/fast_test.rb +133 -13
- data/test/docs/guard_test.rb +28 -35
- data/test/docs/macro_test.rb +1 -1
- data/test/docs/model_test.rb +13 -13
- data/test/docs/nested_test.rb +54 -122
- data/test/docs/operation_test.rb +42 -43
- data/test/docs/pundit_test.rb +16 -16
- data/test/docs/representer_test.rb +18 -18
- data/test/docs/rescue_test.rb +29 -29
- data/test/docs/trace_test.rb +82 -0
- data/test/docs/wrap_test.rb +59 -26
- data/test/module_test.rb +75 -75
- data/test/nested_test.rb +293 -0
- data/test/operation/contract_test.rb +23 -153
- data/test/operation/dsl/contract_test.rb +9 -9
- data/test/operation/dsl/representer_test.rb +169 -169
- data/test/operation/model_test.rb +15 -21
- data/test/operation/persist_test.rb +18 -11
- data/test/operation/pundit_test.rb +25 -23
- data/test/operation/representer_test.rb +254 -254
- data/test/test_helper.rb +5 -2
- data/test/variables_test.rb +158 -0
- data/trailblazer.gemspec +1 -1
- data/untitled +33 -0
- metadata +25 -27
- data/lib/trailblazer/operation/callback.rb +0 -35
- data/lib/trailblazer/operation/procedural/contract.rb +0 -15
- data/lib/trailblazer/operation/procedural/validate.rb +0 -22
- data/test/operation/callback_test.rb +0 -70
- data/test/operation/dsl/callback_test.rb +0 -106
- data/test/operation/params_test.rb +0 -36
- data/test/operation/pipedream_test.rb +0 -59
- data/test/operation/pipetree_test.rb +0 -104
- data/test/operation/present_test.rb +0 -24
- data/test/operation/resolver_test.rb +0 -47
- data/test/operation_test.rb +0 -143
data/test/test_helper.rb
CHANGED
@@ -8,8 +8,7 @@ Reform::Form.class_eval do
|
|
8
8
|
include Reform::Form::ActiveModel::Validations
|
9
9
|
end
|
10
10
|
|
11
|
-
require "trailblazer/
|
12
|
-
require "trailblazer/operation/procedural/validate"
|
11
|
+
# require "trailblazer/deprecation/context.rb"
|
13
12
|
|
14
13
|
module Mock
|
15
14
|
class Result
|
@@ -27,3 +26,7 @@ module Test
|
|
27
26
|
end
|
28
27
|
ReturnResult = ->(last, input, options) { input }
|
29
28
|
end
|
29
|
+
|
30
|
+
require "pp"
|
31
|
+
|
32
|
+
Minitest::Spec::Operation = Trailblazer::Operation
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class VariablesTest < Minitest::Spec
|
4
|
+
# Nested op copies values and modifies/amplifies some of them.
|
5
|
+
class Whistleblower < Trailblazer::Operation
|
6
|
+
step ->(options, public_opinion:, **) { options["edward.public_opinion"] = public_opinion.upcase } , id: "edward.public_opinion"
|
7
|
+
step ->(options, secret:, **) { options["edward.secret"] = secret } , id: "edward.secret"
|
8
|
+
step ->(options, rumours:, **) { rumours.nil? ? rumours : options["edward.rumours"] = rumours*2 } , id: "edward.test"
|
9
|
+
pass ->(options, **) { options["edward.public_knowledge"] = options["public_knowledge"] }, id: "edward.read.public_knowledge"
|
10
|
+
end
|
11
|
+
|
12
|
+
=begin
|
13
|
+
Everything public. options are simply passed on.
|
14
|
+
|
15
|
+
Both Org and Edward write and read from the same Context instance.
|
16
|
+
=end
|
17
|
+
class OpenOrganization < Trailblazer::Operation
|
18
|
+
step ->(options, **) { options["rumours"] = "Bla" }
|
19
|
+
step ->(options, **) { options["secret"] = "Psst!" }
|
20
|
+
|
21
|
+
step Nested( Whistleblower )
|
22
|
+
|
23
|
+
step ->(options, **) { options["org.rumours"] = options["edward.rumours"] } # what can we see from Edward?
|
24
|
+
step ->(options, **) { options["org.secret"] = options["edward.secret"] } # what can we see from Edward?
|
25
|
+
end
|
26
|
+
|
27
|
+
it do
|
28
|
+
result = OpenOrganization.("public_opinion" => "Freedom!", "public_knowledge" => true)
|
29
|
+
|
30
|
+
result.inspect("public_opinion", "rumours", "secret", "edward.public_opinion", "edward.secret", "edward.rumours", "edward.public_knowledge").
|
31
|
+
must_equal %{<Result:true ["Freedom!", "Bla", "Psst!", "FREEDOM!", "Psst!", "BlaBla", true] >}
|
32
|
+
end
|
33
|
+
|
34
|
+
#---
|
35
|
+
#- simply passes on the context
|
36
|
+
class ConsideringButOpenOrganization < Trailblazer::Operation
|
37
|
+
step ->(options, **) { options["rumours"] = "Bla" }
|
38
|
+
step ->(options, **) { options["secret"] = "Psst!" }
|
39
|
+
|
40
|
+
step Nested( Whistleblower, input: :input! )
|
41
|
+
|
42
|
+
step ->(options, **) { options["org.rumours"] = options["edward.rumours"] } # what can we see from Edward?
|
43
|
+
step ->(options, **) { options["org.secret"] = options["edward.secret"] } # what can we see from Edward?
|
44
|
+
|
45
|
+
def input!(options, **)
|
46
|
+
options
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it do
|
51
|
+
result = ConsideringButOpenOrganization.("public_opinion" => "Freedom!")
|
52
|
+
|
53
|
+
result.inspect("public_opinion", "rumours", "secret", "edward.public_opinion", "edward.secret", "edward.rumours").
|
54
|
+
must_equal %{<Result:true ["Freedom!", "Bla", "Psst!", "FREEDOM!", "Psst!", "BlaBla"] >}
|
55
|
+
end
|
56
|
+
|
57
|
+
=begin
|
58
|
+
Explicitely passes allowed variables, only.
|
59
|
+
|
60
|
+
Edward can only read those three variables and can't see "public_knowledge" or others.
|
61
|
+
=end
|
62
|
+
class ProtectedOrganization < ConsideringButOpenOrganization
|
63
|
+
def input!(options, **)
|
64
|
+
{
|
65
|
+
"public_opinion" => options["public_opinion"],
|
66
|
+
"secret" => 0,
|
67
|
+
"rumours" => 0.0
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it do
|
73
|
+
result = ProtectedOrganization.( {}, "public_opinion" => "Freedom!", "public_knowledge" => true )
|
74
|
+
|
75
|
+
result.inspect("public_opinion", "rumours", "secret", "edward.public_opinion", "edward.secret", "edward.rumours", "edward.public_knowledge").
|
76
|
+
must_equal %{<Result:true ["Freedom!", "Bla", "Psst!", "FREEDOM!", 0, 0.0, nil] >}
|
77
|
+
end
|
78
|
+
|
79
|
+
#---
|
80
|
+
#- new ctx
|
81
|
+
=begin
|
82
|
+
:input produces a differing value for an existing key "secret"
|
83
|
+
this should only be visible in the nested activity, and the original
|
84
|
+
"secret" must be what it was before (unless :output would change that.)
|
85
|
+
|
86
|
+
NOTE: i decided it's better to not even allow Context#merge because it
|
87
|
+
defeats the idea of hiding information via :input and overcomplicates
|
88
|
+
the scoping.
|
89
|
+
=end
|
90
|
+
class EncryptedOrganization < ConsideringButOpenOrganization
|
91
|
+
def input!(options, **)
|
92
|
+
options.merge( "secret" => options["secret"]+"XxX" )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it do
|
97
|
+
skip "no options.merge until we know we actually need it"
|
98
|
+
result = EncryptedOrganization.("public_opinion" => "Freedom!")
|
99
|
+
|
100
|
+
result.inspect("public_opinion", "rumours", "secret", "edward.public_opinion", "edward.secret", "edward.rumours").
|
101
|
+
must_equal %{<Result:true ["Freedom!", "Bla", "Psst!", "FREEDOM!", "Psst!XxX", "BlaBla"] >}
|
102
|
+
end
|
103
|
+
|
104
|
+
# TODO write to options and get error
|
105
|
+
|
106
|
+
=begin
|
107
|
+
Simply passes on the context to Edward, but applies an :output filter,
|
108
|
+
so that Org can't see several nested values such as "edward.public_knowledge"
|
109
|
+
or "edward.rumours" (see steps in #read-section).
|
110
|
+
=end
|
111
|
+
class DiscreetOrganization < Trailblazer::Operation
|
112
|
+
step ->(options, **) { options["rumours"] = "Bla" }, id: "set.rumours"
|
113
|
+
step ->(options, **) { options["secret"] = "Psst!" }, id: "set.secret"
|
114
|
+
|
115
|
+
step Nested( Whistleblower, input: :input!, output: :output! )
|
116
|
+
|
117
|
+
#read-section
|
118
|
+
pass ->(options, **) { options["org.rumours"] = options["edward.rumours"] }, id: "read.edward.rumours" # what can we see from Edward?
|
119
|
+
step ->(options, **) { options["org.secret"] = options["edward.secret"] }, id: "read.edward.secret" # what can we see from Edward?
|
120
|
+
|
121
|
+
def input!(options, **)
|
122
|
+
options
|
123
|
+
end
|
124
|
+
|
125
|
+
def output!(options, **)
|
126
|
+
{
|
127
|
+
"out.keys" => options.keys,
|
128
|
+
"out.rumours" => options["edward.rumours"].slice(0..2),
|
129
|
+
"out.secret" => options["edward.secret"].reverse,
|
130
|
+
}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it do
|
135
|
+
result = DiscreetOrganization.("public_opinion" => "Freedom!", "public_knowledge" => true)
|
136
|
+
|
137
|
+
result.inspect("public_opinion", "rumours", "secret", "edward.public_opinion", "edward.secret", "edward.rumours", "out.keys", "out.rumours", "out.secret", "org.rumours", "org.secret", "public_knowledge", "edward.public_knowledge").
|
138
|
+
must_equal %{<Result:false [\"Freedom!\", \"Bla\", \"Psst!\", nil, nil, nil, [\"edward.public_opinion\", \"edward.secret\", \"edward.rumours\", \"edward.public_knowledge\"], \"Bla\", \"!tssP\", nil, nil, true, nil] >}
|
139
|
+
end
|
140
|
+
|
141
|
+
it "with tracing" do
|
142
|
+
result = DiscreetOrganization.trace("public_opinion" => "Freedom!")
|
143
|
+
|
144
|
+
result.wtf.gsub(/0x\w+/, "").gsub(/\d+/, "").must_equal %{|-- #<Trailblazer::Activity::Start:>
|
145
|
+
|-- set.rumours
|
146
|
+
|-- set.secret
|
147
|
+
|-- Nested(VariablesTest::Whistleblower)
|
148
|
+
| |-- #<Trailblazer::Activity::Start:>
|
149
|
+
| |-- edward.public_opinion
|
150
|
+
| |-- edward.secret
|
151
|
+
| |-- edward.test
|
152
|
+
| |-- edward.read.public_knowledge
|
153
|
+
| `-- #<Trailblazer::Operation::Railway::End::Success:>
|
154
|
+
|-- read.edward.rumours
|
155
|
+
|-- read.edward.secret
|
156
|
+
`-- #<Trailblazer::Operation::Railway::End::Failure:>}
|
157
|
+
end
|
158
|
+
end
|
data/trailblazer.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "trailblazer-operation", ">= 0.
|
20
|
+
spec.add_dependency "trailblazer-operation", ">= 0.1.2", "< 0.2.0"
|
21
21
|
spec.add_dependency "reform", ">= 2.2.0", "< 3.0.0"
|
22
22
|
spec.add_dependency "declarative"
|
23
23
|
|
data/untitled
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
__call__
|
3
|
+
:params => {}
|
4
|
+
:current_user => ,
|
5
|
+
"contract.default.class" =>
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
skills = Skill(container, container)
|
12
|
+
skill[:a]
|
13
|
+
READ-ONLY
|
14
|
+
|
15
|
+
ctx = Context(skills) => Context.new(Skill.new {}, skills)
|
16
|
+
ctx[:a] => <skill>
|
17
|
+
ctx[:a]= 1
|
18
|
+
ctx.merge => new Context
|
19
|
+
|
20
|
+
ctx.to_hash
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
step(Context options, **)
|
25
|
+
|
26
|
+
|
27
|
+
input(Context options, **, Hash::Immutable mutable:, Skill runtime:)
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
Hash::Immutable
|
32
|
+
|
33
|
+
Skills < Hash::Immutable
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.1.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trailblazer-operation
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.1.2
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.2.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.1.2
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.2.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: reform
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,25 +169,29 @@ files:
|
|
169
169
|
- doc/operation-2017.png
|
170
170
|
- doc/trb.jpg
|
171
171
|
- lib/trailblazer.rb
|
172
|
+
- lib/trailblazer/deprecation/call.rb
|
173
|
+
- lib/trailblazer/deprecation/context.rb
|
172
174
|
- lib/trailblazer/dsl.rb
|
173
175
|
- lib/trailblazer/operation/auto_inject.rb
|
174
|
-
- lib/trailblazer/operation/callback.rb
|
175
176
|
- lib/trailblazer/operation/contract.rb
|
177
|
+
- lib/trailblazer/operation/deprecations.rb
|
176
178
|
- lib/trailblazer/operation/guard.rb
|
177
179
|
- lib/trailblazer/operation/model.rb
|
178
180
|
- lib/trailblazer/operation/module.rb
|
179
181
|
- lib/trailblazer/operation/nested.rb
|
180
182
|
- lib/trailblazer/operation/persist.rb
|
181
183
|
- lib/trailblazer/operation/policy.rb
|
182
|
-
- lib/trailblazer/operation/procedural/contract.rb
|
183
|
-
- lib/trailblazer/operation/procedural/validate.rb
|
184
184
|
- lib/trailblazer/operation/pundit.rb
|
185
185
|
- lib/trailblazer/operation/representer.rb
|
186
186
|
- lib/trailblazer/operation/rescue.rb
|
187
187
|
- lib/trailblazer/operation/test.rb
|
188
188
|
- lib/trailblazer/operation/validate.rb
|
189
189
|
- lib/trailblazer/operation/wrap.rb
|
190
|
+
- lib/trailblazer/task.rb
|
190
191
|
- lib/trailblazer/version.rb
|
192
|
+
- test/benchmark.rb
|
193
|
+
- test/deprecation/call_test.rb
|
194
|
+
- test/deprecation/context_test.rb
|
191
195
|
- test/docs/auto_inject_test.rb
|
192
196
|
- test/docs/contract_test.rb
|
193
197
|
- test/docs/dry_test.rb
|
@@ -201,28 +205,24 @@ files:
|
|
201
205
|
- test/docs/pundit_test.rb
|
202
206
|
- test/docs/representer_test.rb
|
203
207
|
- test/docs/rescue_test.rb
|
208
|
+
- test/docs/trace_test.rb
|
204
209
|
- test/docs/wrap_test.rb
|
205
210
|
- test/gemfiles/Gemfile.ruby-1.9
|
206
211
|
- test/gemfiles/Gemfile.ruby-2.0
|
207
212
|
- test/gemfiles/Gemfile.ruby-2.3
|
208
213
|
- test/module_test.rb
|
209
|
-
- test/
|
214
|
+
- test/nested_test.rb
|
210
215
|
- test/operation/contract_test.rb
|
211
|
-
- test/operation/dsl/callback_test.rb
|
212
216
|
- test/operation/dsl/contract_test.rb
|
213
217
|
- test/operation/dsl/representer_test.rb
|
214
218
|
- test/operation/model_test.rb
|
215
|
-
- test/operation/params_test.rb
|
216
219
|
- test/operation/persist_test.rb
|
217
|
-
- test/operation/pipedream_test.rb
|
218
|
-
- test/operation/pipetree_test.rb
|
219
|
-
- test/operation/present_test.rb
|
220
220
|
- test/operation/pundit_test.rb
|
221
221
|
- test/operation/representer_test.rb
|
222
|
-
- test/operation/resolver_test.rb
|
223
|
-
- test/operation_test.rb
|
224
222
|
- test/test_helper.rb
|
223
|
+
- test/variables_test.rb
|
225
224
|
- trailblazer.gemspec
|
225
|
+
- untitled
|
226
226
|
homepage: http://trailblazer.to
|
227
227
|
licenses:
|
228
228
|
- LGPL-3.0
|
@@ -238,9 +238,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
238
238
|
version: 2.0.0
|
239
239
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
240
240
|
requirements:
|
241
|
-
- - "
|
241
|
+
- - ">"
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version:
|
243
|
+
version: 1.3.1
|
244
244
|
requirements: []
|
245
245
|
rubyforge_project:
|
246
246
|
rubygems_version: 2.6.8
|
@@ -248,6 +248,9 @@ signing_key:
|
|
248
248
|
specification_version: 4
|
249
249
|
summary: A high-level architecture for Ruby and Rails.
|
250
250
|
test_files:
|
251
|
+
- test/benchmark.rb
|
252
|
+
- test/deprecation/call_test.rb
|
253
|
+
- test/deprecation/context_test.rb
|
251
254
|
- test/docs/auto_inject_test.rb
|
252
255
|
- test/docs/contract_test.rb
|
253
256
|
- test/docs/dry_test.rb
|
@@ -261,24 +264,19 @@ test_files:
|
|
261
264
|
- test/docs/pundit_test.rb
|
262
265
|
- test/docs/representer_test.rb
|
263
266
|
- test/docs/rescue_test.rb
|
267
|
+
- test/docs/trace_test.rb
|
264
268
|
- test/docs/wrap_test.rb
|
265
269
|
- test/gemfiles/Gemfile.ruby-1.9
|
266
270
|
- test/gemfiles/Gemfile.ruby-2.0
|
267
271
|
- test/gemfiles/Gemfile.ruby-2.3
|
268
272
|
- test/module_test.rb
|
269
|
-
- test/
|
273
|
+
- test/nested_test.rb
|
270
274
|
- test/operation/contract_test.rb
|
271
|
-
- test/operation/dsl/callback_test.rb
|
272
275
|
- test/operation/dsl/contract_test.rb
|
273
276
|
- test/operation/dsl/representer_test.rb
|
274
277
|
- test/operation/model_test.rb
|
275
|
-
- test/operation/params_test.rb
|
276
278
|
- test/operation/persist_test.rb
|
277
|
-
- test/operation/pipedream_test.rb
|
278
|
-
- test/operation/pipetree_test.rb
|
279
|
-
- test/operation/present_test.rb
|
280
279
|
- test/operation/pundit_test.rb
|
281
280
|
- test/operation/representer_test.rb
|
282
|
-
- test/operation/resolver_test.rb
|
283
|
-
- test/operation_test.rb
|
284
281
|
- test/test_helper.rb
|
282
|
+
- test/variables_test.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require "disposable/callback"
|
2
|
-
|
3
|
-
class Trailblazer::Operation
|
4
|
-
def self.Callback(group)
|
5
|
-
step = ->(input, options) { Callback.(group, input, options) }
|
6
|
-
|
7
|
-
[ step, name: "callback.#{group}" ]
|
8
|
-
end
|
9
|
-
|
10
|
-
module Callback
|
11
|
-
def self.call(name=:default, operation, options)
|
12
|
-
config = options["callback.#{name}.class"] || raise #.fetch(name) # TODO: test exception
|
13
|
-
group = config[:group].new(options["contract.default"])
|
14
|
-
|
15
|
-
options[:context] ||= (config[:context] == :operation ? operation : group)
|
16
|
-
group.(options)
|
17
|
-
|
18
|
-
options["result.callback.#{name}"] = group
|
19
|
-
end
|
20
|
-
|
21
|
-
module DSL
|
22
|
-
def callback(name=:default, constant=nil, &block)
|
23
|
-
heritage.record(:callback, name, constant, &block)
|
24
|
-
|
25
|
-
# FIXME: make this nicer. we want to extend same-named callback groups.
|
26
|
-
# TODO: allow the same with contract, or better, test it!
|
27
|
-
extended = self["callback.#{name}.class"] && self["callback.#{name}.class"]
|
28
|
-
|
29
|
-
path, group_class = Trailblazer::DSL::Build.new.({ prefix: :callback, class: Disposable::Callback::Group, container: self }, name, constant, block) { |extended| extended[:group] }
|
30
|
-
|
31
|
-
self[path] = { group: group_class, context: constant ? nil : :operation }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Trailblazer::Operation::Procedural
|
2
|
-
# THIS IS UNTESTED, PRIVATE API AND WILL BE REMOVED SOON.
|
3
|
-
module Contract
|
4
|
-
# Instantiate the contract, either by using the user's contract passed into #validate
|
5
|
-
# or infer the Operation contract.
|
6
|
-
def contract_for(model:self["model"], options:{}, contract_class:self["contract.default.class"])
|
7
|
-
contract!(model: model, options: options, contract_class: contract_class)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Override to construct your own contract.
|
11
|
-
def contract!(model:nil, options:{}, contract_class:nil)
|
12
|
-
contract_class.new(model, options)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Trailblazer::Operation::Procedural
|
2
|
-
module Validate
|
3
|
-
def validate(params, contract:self["contract.default"], path:"contract.default") # :params
|
4
|
-
# DISCUSS: should we only have path here and then look up contract ourselves?
|
5
|
-
result = validate_contract(contract, params) # run validation. # FIXME: must be overridable.
|
6
|
-
|
7
|
-
self["result.#{path}"] = result
|
8
|
-
|
9
|
-
if valid = result.success? # FIXME: to_bool or success?
|
10
|
-
yield result if block_given?
|
11
|
-
else
|
12
|
-
# self["errors.#{path}"] = result.errors # TODO: remove me
|
13
|
-
end
|
14
|
-
|
15
|
-
valid
|
16
|
-
end
|
17
|
-
|
18
|
-
def validate_contract(contract, params)
|
19
|
-
contract.(params)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|