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
@@ -9,21 +9,24 @@ class ModelTest < Minitest::Spec
|
|
9
9
|
#---
|
10
10
|
# use Model semantics, no customizations.
|
11
11
|
class Create < Trailblazer::Operation
|
12
|
-
step Model Song, :new
|
12
|
+
step Model( Song, :new )
|
13
13
|
end
|
14
14
|
|
15
15
|
# :new new.
|
16
|
-
it { Create.({})[
|
16
|
+
it { Create.(params: {})[:model].inspect.must_equal %{#<struct ModelTest::Song id=nil>} }
|
17
17
|
|
18
18
|
class Update < Create
|
19
19
|
step Model( Song, :find ), override: true
|
20
20
|
end
|
21
21
|
|
22
|
+
#---
|
23
|
+
#- inheritance
|
24
|
+
|
22
25
|
# :find it
|
23
|
-
it { Update.({ id: 1 })[
|
26
|
+
it { Update.(params: { id: 1 })[:model].inspect.must_equal %{#<struct ModelTest::Song id=1>} }
|
24
27
|
|
25
|
-
|
26
|
-
it { Update
|
28
|
+
# inherited inspect is ok
|
29
|
+
it { Trailblazer::Operation::Inspect.(Update).must_equal %{[>model.build]} }
|
27
30
|
|
28
31
|
#---
|
29
32
|
# :find_by, exceptionless.
|
@@ -31,30 +34,21 @@ class ModelTest < Minitest::Spec
|
|
31
34
|
step Model Song, :find_by
|
32
35
|
step :process
|
33
36
|
|
34
|
-
def process(
|
37
|
+
def process(options, **); options["x"] = true end
|
35
38
|
end
|
36
39
|
|
37
40
|
# can't find model.
|
38
41
|
#- result object, model
|
39
42
|
it do
|
40
|
-
Find.(id: nil)["result.model"].failure?.must_equal true
|
41
|
-
Find.(id: nil)["x"].
|
42
|
-
Find.(id: nil).failure?.must_equal true
|
43
|
+
Find.(params: {id: nil})["result.model"].failure?.must_equal true
|
44
|
+
Find.(params: {id: nil})["x"].must_be_nil
|
45
|
+
Find.(params: {id: nil}).failure?.must_equal true
|
43
46
|
end
|
44
47
|
|
45
48
|
#- result object, model
|
46
49
|
it do
|
47
|
-
Find.(id: 9)["result.model"].success?.must_equal true
|
48
|
-
Find.(id: 9)["x"].must_equal true
|
49
|
-
Find.(id: 9)[
|
50
|
+
Find.(params: {id: 9})["result.model"].success?.must_equal true
|
51
|
+
Find.(params: {id: 9})["x"].must_equal true
|
52
|
+
Find.(params: {id: 9})[:model].inspect.must_equal %{#<struct ModelTest::Song id=9>}
|
50
53
|
end
|
51
|
-
|
52
|
-
# #---
|
53
|
-
# # creating the model before operation instantiation (ex Model::External)
|
54
|
-
# class Show < Create
|
55
|
-
# extend Model::BuildMethods # FIXME: how do we communicate that and prevent the include from Model[] ?
|
56
|
-
# step Model( Song, :update ), before: "operation.new"
|
57
|
-
# end
|
58
|
-
|
59
|
-
# it { Show.({id: 1})["model"].inspect.must_equal %{#<struct ModelTest::Song id=1>} }
|
60
54
|
end
|
@@ -6,26 +6,33 @@ class PersistTest < Minitest::Spec
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class Create < Trailblazer::Operation
|
9
|
-
|
10
|
-
contract do
|
9
|
+
class Form < Reform::Form
|
11
10
|
property :title
|
12
11
|
end
|
13
12
|
|
13
|
+
class Fail1
|
14
|
+
def self.call(options, **); options["1. fail"] = "Validate" end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Fail2
|
18
|
+
def self.call(options, **); options["2. fail"] = "Persist" end
|
19
|
+
end
|
20
|
+
|
14
21
|
step Model( Song, :new )
|
15
|
-
step Contract::Build()
|
22
|
+
step Contract::Build( constant: Form )
|
16
23
|
step Contract::Validate()
|
17
|
-
|
24
|
+
fail Fail1
|
18
25
|
step Contract::Persist()
|
19
|
-
|
26
|
+
fail Fail2
|
20
27
|
end
|
21
28
|
|
22
|
-
it { Create.(title: "In Recital")[
|
23
|
-
it { Create.(title: "In Recital")[
|
29
|
+
it { Create.(params: {title: "In Recital"})[:model].title.must_equal "In Recital" }
|
30
|
+
it { Create.(params: {title: "In Recital"})[:model].saved.must_equal true }
|
24
31
|
# failure
|
25
32
|
it do
|
26
|
-
result = Create.(title: "Fail!")
|
27
|
-
result[
|
28
|
-
result[
|
33
|
+
result = Create.(params: {title: "Fail!"})
|
34
|
+
result[:model].saved.must_be_nil
|
35
|
+
result[:model].title.must_equal "Fail!"
|
29
36
|
result["2. fail"].must_equal "Persist"
|
30
37
|
result.success?.must_equal false
|
31
38
|
end
|
@@ -35,7 +42,7 @@ class PersistTest < Minitest::Spec
|
|
35
42
|
class Update < Create
|
36
43
|
end
|
37
44
|
|
38
|
-
it { Update
|
45
|
+
it { Operation::Inspect.( Update ).must_equal %{[>model.build,>contract.build,>contract.default.validate,<<PersistTest::Create::Fail1,>persist.save,<<PersistTest::Create::Fail2]} }
|
39
46
|
|
40
47
|
#---
|
41
48
|
it do
|
@@ -20,31 +20,31 @@ class PolicyTest < Minitest::Spec
|
|
20
20
|
step Policy::Pundit( Auth, :only_user? )
|
21
21
|
step :process
|
22
22
|
|
23
|
-
def process(
|
24
|
-
|
23
|
+
def process(options, **)
|
24
|
+
options["process"] = true
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
# successful.
|
29
29
|
it do
|
30
|
-
result = Create.({},
|
30
|
+
result = Create.(params: {}, current_user: Module)
|
31
31
|
result["process"].must_equal true
|
32
32
|
#- result object, policy
|
33
33
|
result["result.policy.default"].success?.must_equal true
|
34
|
-
result["result.policy.default"]["message"].
|
35
|
-
# result[:valid].
|
34
|
+
result["result.policy.default"]["message"].must_be_nil
|
35
|
+
# result[:valid].must_be_nil
|
36
36
|
result["policy.default"].inspect.must_equal %{<Auth: user:Module, model:nil>}
|
37
37
|
end
|
38
38
|
# breach.
|
39
39
|
it do
|
40
|
-
result = Create.({},
|
41
|
-
result["process"].
|
40
|
+
result = Create.(params: {}, current_user: nil)
|
41
|
+
result["process"].must_be_nil
|
42
42
|
#- result object, policy
|
43
43
|
result["result.policy.default"].success?.must_equal false
|
44
44
|
result["result.policy.default"]["message"].must_equal "Breach"
|
45
45
|
end
|
46
|
-
# inject different policy.Condition it { Create.({},
|
47
|
-
it { Create.({},
|
46
|
+
# inject different policy.Condition it { Create.(params: {}, current_user: Object, "policy.default.eval" => Trailblazer::Operation::Policy::Pundit::Condition.new(Auth, :user_object?))["process"].must_equal true }
|
47
|
+
it { Create.(params: {}, current_user: Module, "policy.default.eval" => Trailblazer::Operation::Policy::Pundit::Condition.new(Auth, :user_object?))["process"].must_be_nil }
|
48
48
|
|
49
49
|
|
50
50
|
#---
|
@@ -53,22 +53,22 @@ class PolicyTest < Minitest::Spec
|
|
53
53
|
step Model( Song, :new ), before: "policy.default.eval"
|
54
54
|
end
|
55
55
|
|
56
|
-
it { Show
|
56
|
+
it { Trailblazer::Operation::Inspect.(Show).must_equal %{[>model.build,>policy.default.eval,>process]} }
|
57
57
|
|
58
58
|
# invalid because user AND model.
|
59
59
|
it do
|
60
|
-
result = Show.({},
|
61
|
-
result["process"].
|
62
|
-
result[
|
60
|
+
result = Show.(params: {}, current_user: Module)
|
61
|
+
result["process"].must_be_nil
|
62
|
+
result[:model].inspect.must_equal %{#<struct PolicyTest::Song id=nil>}
|
63
63
|
# result["policy"].inspect.must_equal %{#<struct PolicyTest::Song id=nil>}
|
64
64
|
end
|
65
65
|
|
66
66
|
# valid because new policy.
|
67
67
|
it do
|
68
68
|
# puts Show["pipetree"].inspect
|
69
|
-
result = Show.({},
|
69
|
+
result = Show.(params: {}, current_user: Module, "policy.default.eval" => Trailblazer::Operation::Policy::Pundit::Condition.new(Auth, :user_and_model?))
|
70
70
|
result["process"].must_equal true
|
71
|
-
result[
|
71
|
+
result[:model].inspect.must_equal %{#<struct PolicyTest::Song id=nil>}
|
72
72
|
result["policy.default"].inspect.must_equal %{<Auth: user:Module, model:#<struct PolicyTest::Song id=nil>>}
|
73
73
|
end
|
74
74
|
|
@@ -79,25 +79,27 @@ class PolicyTest < Minitest::Spec
|
|
79
79
|
step Policy::Pundit( Auth, :user_and_model? )
|
80
80
|
step :process
|
81
81
|
|
82
|
-
def process(
|
82
|
+
def process(options, **)
|
83
|
+
options["process"] = true
|
84
|
+
end
|
83
85
|
end
|
84
86
|
|
85
87
|
# successful.
|
86
88
|
it do
|
87
|
-
result = Edit.({ id: 1 },
|
89
|
+
result = Edit.(params: { id: 1 }, current_user: Module)
|
88
90
|
result["process"].must_equal true
|
89
|
-
result[
|
91
|
+
result[:model].inspect.must_equal %{#<struct PolicyTest::Song id=1>}
|
90
92
|
result["result.policy.default"].success?.must_equal true
|
91
|
-
result["result.policy.default"]["message"].
|
92
|
-
# result[:valid].
|
93
|
+
result["result.policy.default"]["message"].must_be_nil
|
94
|
+
# result[:valid].must_be_nil
|
93
95
|
result["policy.default"].inspect.must_equal %{<Auth: user:Module, model:#<struct PolicyTest::Song id=1>>}
|
94
96
|
end
|
95
97
|
|
96
98
|
# breach.
|
97
99
|
it do
|
98
|
-
result = Edit.({ id: 4 },
|
99
|
-
result[
|
100
|
-
result["process"].
|
100
|
+
result = Edit.(params: { id: 4 }, current_user: nil)
|
101
|
+
result[:model].inspect.must_equal %{#<struct PolicyTest::Song id=4>}
|
102
|
+
result["process"].must_be_nil
|
101
103
|
result["result.policy.default"].success?.must_equal false
|
102
104
|
result["result.policy.default"]["message"].must_equal "Breach"
|
103
105
|
end
|
@@ -1,254 +1,254 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
require "representable/json"
|
3
|
-
|
4
|
-
class RepresenterTest < MiniTest::Spec
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
class InternalRepresenterAPITest < MiniTest::Spec
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
end
|
191
|
-
|
192
|
-
class DifferentParseAndRenderingRepresenterTest < MiniTest::Spec
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
1
|
+
# require "test_helper"
|
2
|
+
# require "representable/json"
|
3
|
+
|
4
|
+
# class RepresenterTest < MiniTest::Spec
|
5
|
+
# Album = Struct.new(:title, :artist)
|
6
|
+
# Artist = Struct.new(:name)
|
7
|
+
|
8
|
+
# class Create < Trailblazer::Operation
|
9
|
+
# include Contract
|
10
|
+
# include Representer
|
11
|
+
# include Representer::InferFromContract
|
12
|
+
# attr_reader :model # FIXME: all we want is #model.
|
13
|
+
|
14
|
+
# contract do
|
15
|
+
# property :title
|
16
|
+
# validates :title, presence: true
|
17
|
+
# property :artist, populate_if_empty: Artist do
|
18
|
+
# property :name
|
19
|
+
# validates :name, presence: true
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
|
23
|
+
# def call(params)
|
24
|
+
# self["model"] = Album.new # NO artist!!!
|
25
|
+
# validate(params[:album], model: self["model"])
|
26
|
+
# self
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
|
31
|
+
# # Infers representer from contract, no customization.
|
32
|
+
# class Show < Create
|
33
|
+
# def call(params)
|
34
|
+
# self["model"] = Album.new("After The War", Artist.new("Gary Moore"))
|
35
|
+
# self
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
|
39
|
+
|
40
|
+
# # Infers representer, adds hypermedia.
|
41
|
+
# require "roar/json/hal"
|
42
|
+
# class HypermediaCreate < Create
|
43
|
+
# representer do
|
44
|
+
# include Roar::JSON::HAL
|
45
|
+
|
46
|
+
# link(:self) { "//album/#{represented.title}" }
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
# class HypermediaShow < HypermediaCreate
|
51
|
+
# def call(params)
|
52
|
+
# self["model"] = Album.new("After The War", Artist.new("Gary Moore"))
|
53
|
+
# self
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
|
57
|
+
|
58
|
+
# # rendering
|
59
|
+
# # generic contract -> representer
|
60
|
+
# it { Show.().to_json.must_equal %{{"title":"After The War","artist":{"name":"Gary Moore"}}} }
|
61
|
+
|
62
|
+
# # contract -> representer with hypermedia
|
63
|
+
# it do
|
64
|
+
# HypermediaShow.().to_json.must_equal %{{"title":"After The War","artist":{"name":"Gary Moore"},"_links":{"self":{"href":"//album/After The War"}}}}
|
65
|
+
# end
|
66
|
+
|
67
|
+
|
68
|
+
# # parsing
|
69
|
+
# it do
|
70
|
+
# op = Create.(album: %{{"title":"Run For Cover","artist":{"name":"Gary Moore"}}})
|
71
|
+
# op.contract.title.must_equal "Run For Cover"
|
72
|
+
# op.contract.artist.name.must_equal "Gary Moore"
|
73
|
+
# end
|
74
|
+
|
75
|
+
# it do
|
76
|
+
# op = HypermediaCreate.(album: %{{"title":"After The War","artist":{"name":"Gary Moore"},"_links":{"self":{"href":"//album/After The War"}}}})
|
77
|
+
# op.contract.title.must_equal "After The War"
|
78
|
+
# op.contract.artist.name.must_equal "Gary Moore"
|
79
|
+
# end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
# # explicit representer set with ::representer_class=.
|
86
|
+
# require "roar/decorator"
|
87
|
+
# class JsonApiCreate < Trailblazer::Operation
|
88
|
+
# include Contract
|
89
|
+
# include Representer
|
90
|
+
# attr_reader :model
|
91
|
+
|
92
|
+
# contract do # we still need contract as the representer writes to the contract twin.
|
93
|
+
# property :title
|
94
|
+
# end
|
95
|
+
|
96
|
+
# class AlbumRepresenter < Roar::Decorator
|
97
|
+
# include Roar::JSON
|
98
|
+
# property :title
|
99
|
+
# end
|
100
|
+
|
101
|
+
# # FIXME: this won't inherit, of course.
|
102
|
+
# # self["representer.class"] = AlbumRepresenter
|
103
|
+
# representer AlbumRepresenter
|
104
|
+
|
105
|
+
# def call(params)
|
106
|
+
# self["model"] = Album.new # NO artist!!!
|
107
|
+
# validate(params[:album], model: self["model"])
|
108
|
+
# self
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
|
112
|
+
# class JsonApiShow < JsonApiCreate
|
113
|
+
# def call(params)
|
114
|
+
# self["model"] = Album.new("After The War", Artist.new("Gary Moore"))
|
115
|
+
# self
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
|
119
|
+
# # render.
|
120
|
+
# it do
|
121
|
+
# JsonApiShow.().to_json.must_equal %{{"title":"After The War"}}
|
122
|
+
# end
|
123
|
+
|
124
|
+
# # parse.
|
125
|
+
# it do
|
126
|
+
# JsonApiCreate.(album: %{{"title":"Run For Cover"}}).contract.title.must_equal "Run For Cover"
|
127
|
+
# end
|
128
|
+
# end
|
129
|
+
|
130
|
+
# class InternalRepresenterAPITest < MiniTest::Spec
|
131
|
+
# Song = Struct.new(:id)
|
132
|
+
|
133
|
+
# describe "#represented" do
|
134
|
+
# class Show < Trailblazer::Operation
|
135
|
+
# include Contract
|
136
|
+
# include Representer, Model
|
137
|
+
# model Song, :create
|
138
|
+
|
139
|
+
# representer do
|
140
|
+
# property :class
|
141
|
+
# end
|
142
|
+
|
143
|
+
# def call(*)
|
144
|
+
# self
|
145
|
+
# end
|
146
|
+
|
147
|
+
# def model # FIXME.
|
148
|
+
# self["model"]
|
149
|
+
# end
|
150
|
+
# end
|
151
|
+
|
152
|
+
# it "uses #model as represented, per default" do
|
153
|
+
# Show.({}).to_json.must_equal '{"class":"InternalRepresenterAPITest::Song"}'
|
154
|
+
# end
|
155
|
+
|
156
|
+
# class ShowContract < Show
|
157
|
+
# def represented
|
158
|
+
# "Object"
|
159
|
+
# end
|
160
|
+
# end
|
161
|
+
|
162
|
+
# it "can be overriden to use the contract" do
|
163
|
+
# ShowContract.({}).to_json.must_equal %{{"class":"String"}}
|
164
|
+
# end
|
165
|
+
# end
|
166
|
+
|
167
|
+
# describe "#to_json" do
|
168
|
+
# class OptionsShow < Trailblazer::Operation
|
169
|
+
# include Representer
|
170
|
+
|
171
|
+
# representer do
|
172
|
+
# property :class
|
173
|
+
# property :id
|
174
|
+
# end
|
175
|
+
|
176
|
+
# def to_json(*)
|
177
|
+
# super(self["params"])
|
178
|
+
# end
|
179
|
+
|
180
|
+
# include Model::Builder
|
181
|
+
# def model!(*)
|
182
|
+
# Song.new(1)
|
183
|
+
# end
|
184
|
+
# end
|
185
|
+
|
186
|
+
# it "allows to pass options to #to_json" do
|
187
|
+
# OptionsShow.(include: [:id]).to_json.must_equal %{{"id":1}}
|
188
|
+
# end
|
189
|
+
# end
|
190
|
+
# end
|
191
|
+
|
192
|
+
# class DifferentParseAndRenderingRepresenterTest < MiniTest::Spec
|
193
|
+
# Album = Struct.new(:title)
|
194
|
+
|
195
|
+
# # rendering
|
196
|
+
# class Create < Trailblazer::Operation
|
197
|
+
# include Contract
|
198
|
+
# extend Representer::DSL
|
199
|
+
# include Representer::Rendering # no Deserializer::Hash here or anything.
|
200
|
+
|
201
|
+
# contract do
|
202
|
+
# property :title
|
203
|
+
# end
|
204
|
+
|
205
|
+
# representer do
|
206
|
+
# property :title, as: :Title
|
207
|
+
# end
|
208
|
+
|
209
|
+
# def call(params)
|
210
|
+
# self["model"] = Album.new
|
211
|
+
# validate(params) do
|
212
|
+
# contract.sync
|
213
|
+
# end
|
214
|
+
# self
|
215
|
+
# end
|
216
|
+
# end
|
217
|
+
|
218
|
+
# it do
|
219
|
+
# Create.(title: "The Kids").to_json.must_equal %{{"Title":"The Kids"}}
|
220
|
+
# end
|
221
|
+
|
222
|
+
# # parsing
|
223
|
+
# class Update < Trailblazer::Operation
|
224
|
+
# include Contract
|
225
|
+
# extend Representer::DSL
|
226
|
+
# include Representer::Deserializer::Hash # no Rendering.
|
227
|
+
|
228
|
+
# representer do
|
229
|
+
# property :title, as: :Title
|
230
|
+
# end
|
231
|
+
|
232
|
+
# contract do
|
233
|
+
# property :title
|
234
|
+
# end
|
235
|
+
|
236
|
+
# def call(params)
|
237
|
+
# self["model"] = Album.new
|
238
|
+
|
239
|
+
# validate(params) do
|
240
|
+
# contract.sync
|
241
|
+
# end
|
242
|
+
|
243
|
+
# self
|
244
|
+
# end
|
245
|
+
|
246
|
+
# def to_json(*)
|
247
|
+
# %{{"title": "#{self["model"].title}"}}
|
248
|
+
# end
|
249
|
+
# end
|
250
|
+
|
251
|
+
# it do
|
252
|
+
# Update.("Title" => "The Kids").to_json.must_equal %{{"title": "The Kids"}}
|
253
|
+
# end
|
254
|
+
# end
|