trailblazer 1.1.2 → 2.0.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/.travis.yml +10 -7
- data/CHANGES.md +108 -0
- data/COMM-LICENSE +91 -0
- data/Gemfile +18 -4
- data/LICENSE.txt +7 -20
- data/README.md +55 -15
- data/Rakefile +21 -2
- data/draft-1.2.rb +7 -0
- data/lib/trailblazer.rb +17 -4
- data/lib/trailblazer/dsl.rb +47 -0
- data/lib/trailblazer/operation/auto_inject.rb +47 -0
- data/lib/trailblazer/operation/builder.rb +18 -18
- data/lib/trailblazer/operation/callback.rb +31 -38
- data/lib/trailblazer/operation/contract.rb +46 -0
- data/lib/trailblazer/operation/controller.rb +45 -27
- data/lib/trailblazer/operation/guard.rb +24 -0
- data/lib/trailblazer/operation/model.rb +41 -33
- data/lib/trailblazer/operation/nested.rb +43 -0
- data/lib/trailblazer/operation/params.rb +13 -0
- data/lib/trailblazer/operation/persist.rb +13 -0
- data/lib/trailblazer/operation/policy.rb +26 -72
- data/lib/trailblazer/operation/present.rb +19 -0
- data/lib/trailblazer/operation/procedural/contract.rb +15 -0
- data/lib/trailblazer/operation/procedural/validate.rb +22 -0
- data/lib/trailblazer/operation/pundit.rb +42 -0
- data/lib/trailblazer/operation/representer.rb +25 -92
- data/lib/trailblazer/operation/rescue.rb +23 -0
- data/lib/trailblazer/operation/resolver.rb +18 -24
- data/lib/trailblazer/operation/validate.rb +50 -0
- data/lib/trailblazer/operation/wrap.rb +37 -0
- data/lib/trailblazer/version.rb +1 -1
- data/test/{operation/controller_test.rb → controller_test.rb} +8 -4
- data/test/docs/auto_inject_test.rb +30 -0
- data/test/docs/contract_test.rb +429 -0
- data/test/docs/dry_test.rb +31 -0
- data/test/docs/guard_test.rb +143 -0
- data/test/docs/nested_test.rb +117 -0
- data/test/docs/policy_test.rb +2 -0
- data/test/docs/pundit_test.rb +109 -0
- data/test/docs/representer_test.rb +268 -0
- data/test/docs/rescue_test.rb +153 -0
- data/test/docs/wrap_test.rb +174 -0
- data/test/gemfiles/Gemfile.ruby-1.9 +3 -0
- data/test/gemfiles/Gemfile.ruby-2.0 +12 -0
- data/test/gemfiles/Gemfile.ruby-2.3 +12 -0
- data/test/module_test.rb +22 -15
- data/test/operation/builder_test.rb +66 -18
- data/test/operation/callback_test.rb +70 -0
- data/test/operation/contract_test.rb +385 -15
- data/test/operation/dsl/callback_test.rb +18 -30
- data/test/operation/dsl/contract_test.rb +209 -19
- data/test/operation/dsl/representer_test.rb +42 -15
- data/test/operation/guard_test.rb +1 -147
- data/test/operation/model_test.rb +105 -0
- data/test/operation/params_test.rb +36 -0
- data/test/operation/persist_test.rb +44 -0
- data/test/operation/pipedream_test.rb +59 -0
- data/test/operation/pipetree_test.rb +104 -0
- data/test/operation/present_test.rb +24 -0
- data/test/operation/pundit_test.rb +104 -0
- data/test/{representer_test.rb → operation/representer_test.rb} +58 -42
- data/test/operation/resolver_test.rb +34 -70
- data/test/operation_test.rb +57 -189
- data/test/test_helper.rb +23 -3
- data/trailblazer.gemspec +8 -7
- metadata +91 -59
- data/gemfiles/Gemfile.rails.lock +0 -130
- data/gemfiles/Gemfile.reform-2.0 +0 -6
- data/gemfiles/Gemfile.reform-2.1 +0 -7
- data/lib/trailblazer/autoloading.rb +0 -15
- data/lib/trailblazer/endpoint.rb +0 -31
- data/lib/trailblazer/operation.rb +0 -175
- data/lib/trailblazer/operation/collection.rb +0 -6
- data/lib/trailblazer/operation/dispatch.rb +0 -3
- data/lib/trailblazer/operation/model/dsl.rb +0 -29
- data/lib/trailblazer/operation/model/external.rb +0 -34
- data/lib/trailblazer/operation/policy/guard.rb +0 -35
- data/lib/trailblazer/operation/uploaded_file.rb +0 -77
- data/test/callback_test.rb +0 -104
- data/test/collection_test.rb +0 -57
- data/test/model_test.rb +0 -148
- data/test/operation/external_model_test.rb +0 -71
- data/test/operation/policy_test.rb +0 -97
- data/test/operation/reject_test.rb +0 -34
- data/test/rollback_test.rb +0 -47
@@ -1,28 +1,26 @@
|
|
1
1
|
require "test_helper"
|
2
|
-
require "trailblazer/operation/dispatch"
|
3
|
-
|
4
2
|
|
5
3
|
class DslCallbackTest < MiniTest::Spec
|
6
4
|
module SongProcess
|
7
|
-
def process(params)
|
8
|
-
contract(OpenStruct.new).validate(params)
|
9
|
-
dispatch!
|
10
|
-
end
|
11
|
-
|
12
5
|
def _invocations
|
13
|
-
|
6
|
+
self["x"] ||= []
|
14
7
|
end
|
15
8
|
|
16
9
|
def self.included(includer)
|
10
|
+
includer.extend Trailblazer::Operation::Contract::DSL
|
17
11
|
includer.contract do
|
18
12
|
property :title
|
19
13
|
end
|
14
|
+
includer.| Trailblazer::Operation::Model[OpenStruct, :new]
|
15
|
+
includer.| Trailblazer::Operation::Contract::Build[includer["contract.default.class"]]
|
16
|
+
includer.| Trailblazer::Operation::Contract::Validate[]
|
17
|
+
includer.| Trailblazer::Operation::Callback[:default]
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
21
|
describe "inheritance across operations" do
|
24
22
|
class Operation < Trailblazer::Operation
|
25
|
-
|
23
|
+
extend Callback::DSL
|
26
24
|
include SongProcess
|
27
25
|
|
28
26
|
callback do
|
@@ -39,21 +37,14 @@ class DslCallbackTest < MiniTest::Spec
|
|
39
37
|
def admin_default!(*); _invocations << :admin_default!; end
|
40
38
|
def after_save!(*); _invocations << :after_save!; end
|
41
39
|
|
42
|
-
|
43
|
-
super
|
44
|
-
dispatch!(:after_save)
|
45
|
-
end
|
40
|
+
self.| Trailblazer::Operation::Callback[:after_save]
|
46
41
|
end
|
47
42
|
|
48
43
|
def default!(*); _invocations << :default!; end
|
49
44
|
end
|
50
45
|
|
51
|
-
it { Operation.({"title"=> "Love-less"}).
|
52
|
-
it { Operation::Admin.({"title"=> "Love-less"}).
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "Op.callback" do
|
56
|
-
it { Operation.callback(:default).must_equal Operation.callbacks[:default][:group] }
|
46
|
+
it { Operation.({"title"=> "Love-less"})["x"].must_equal([:default!]) }
|
47
|
+
it { Operation::Admin.({"title"=> "Love-less"})["x"].must_equal([:default!, :admin_default!, :after_save!]) }
|
57
48
|
end
|
58
49
|
|
59
50
|
describe "Op.callback :after_save, AfterSaveCallback" do
|
@@ -66,17 +57,14 @@ class DslCallbackTest < MiniTest::Spec
|
|
66
57
|
end
|
67
58
|
|
68
59
|
class OpWithExternalCallback < Trailblazer::Operation
|
69
|
-
include Dispatch
|
70
60
|
include SongProcess
|
61
|
+
extend Callback::DSL
|
71
62
|
callback :after_save, AfterSaveCallback
|
72
63
|
|
73
|
-
|
74
|
-
contract(OpenStruct.new).validate(params)
|
75
|
-
dispatch!(:after_save)
|
76
|
-
end
|
64
|
+
self.| Callback[:after_save]
|
77
65
|
end
|
78
66
|
|
79
|
-
it { OpWithExternalCallback.("title"=>"Thunder Rising").
|
67
|
+
it { OpWithExternalCallback.("title"=>"Thunder Rising").must_equal([:after_save!]) }
|
80
68
|
end
|
81
69
|
|
82
70
|
describe "Op.callback :after_save, AfterSaveCallback do .. end" do
|
@@ -89,13 +77,13 @@ class DslCallbackTest < MiniTest::Spec
|
|
89
77
|
end
|
90
78
|
|
91
79
|
class OpUsingCallback < Trailblazer::Operation
|
92
|
-
|
80
|
+
extend Callback::DSL
|
93
81
|
include SongProcess
|
94
82
|
callback :default, DefaultCallback
|
95
83
|
end
|
96
84
|
|
97
85
|
class OpExtendingCallback < Trailblazer::Operation
|
98
|
-
|
86
|
+
extend Callback::DSL
|
99
87
|
include SongProcess
|
100
88
|
callback :default, DefaultCallback do
|
101
89
|
on_change :after_save!
|
@@ -111,8 +99,8 @@ class DslCallbackTest < MiniTest::Spec
|
|
111
99
|
end
|
112
100
|
|
113
101
|
# this operation copies DefaultCallback and shouldn't run #after_save!.
|
114
|
-
it { OpUsingCallback.(title: "Thunder Rising").
|
102
|
+
it { OpUsingCallback.(title: "Thunder Rising")["x"].must_equal([:default!]) }
|
115
103
|
# this operation copies DefaultCallback, extends it and runs #after_save!.
|
116
|
-
it { OpExtendingCallback.(title: "Thunder Rising").
|
104
|
+
it { OpExtendingCallback.(title: "Thunder Rising")["x"].must_equal([:extended_default!, :after_save!]) }
|
117
105
|
end
|
118
|
-
end
|
106
|
+
end
|
@@ -1,16 +1,165 @@
|
|
1
1
|
require "test_helper"
|
2
|
+
require "trailblazer/operation/contract"
|
3
|
+
|
4
|
+
# contract Constant # new
|
5
|
+
# contract Constant, inherit: true # extend existing
|
6
|
+
# contract do end # extend existing || new
|
7
|
+
# contract Constant do .. end # new, extend new
|
2
8
|
|
3
|
-
# ::contract builds Reform::Form class
|
4
9
|
class DslContractTest < MiniTest::Spec
|
5
|
-
module
|
6
|
-
def
|
7
|
-
validate(params,
|
10
|
+
module Call
|
11
|
+
def call(params)
|
12
|
+
validate(params, model: model=OpenStruct.new) { contract.sync }
|
13
|
+
model
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(includer)
|
17
|
+
includer.| Trailblazer::Operation::Model( OpenStruct, :new )
|
18
|
+
includer.| Trailblazer::Operation::Contract::Build()
|
19
|
+
includer.| Trailblazer::Operation::Contract::Validate()
|
20
|
+
includer.| Trailblazer::Operation::Persist( save_method: :sync )
|
21
|
+
# includer.> ->(op, *) { op["x"] = [] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# ---
|
26
|
+
# Operation::["contract.default.class"]
|
27
|
+
# Operation::["contract.default.class"]=
|
28
|
+
class Create < Trailblazer::Operation
|
29
|
+
include Contract
|
30
|
+
self["contract.default.class"] = String
|
31
|
+
end
|
32
|
+
|
33
|
+
# reader method.
|
34
|
+
# no subclassing.
|
35
|
+
it { Create["contract.default.class"].must_equal String }
|
36
|
+
|
37
|
+
class CreateOrFind < Create
|
38
|
+
end
|
39
|
+
|
40
|
+
# no inheritance with setter.
|
41
|
+
it { CreateOrFind["contract.default.class"].must_equal nil }
|
42
|
+
|
43
|
+
# ---
|
44
|
+
# Op::contract Constant
|
45
|
+
class Update < Trailblazer::Operation
|
46
|
+
class IdContract < Reform::Form
|
47
|
+
property :id
|
48
|
+
end
|
49
|
+
|
50
|
+
extend Contract::DSL
|
51
|
+
contract IdContract
|
52
|
+
|
53
|
+
include Call
|
54
|
+
end
|
55
|
+
|
56
|
+
# UT: subclasses contract.
|
57
|
+
it { Update["contract.default.class"].superclass.must_equal Update::IdContract }
|
58
|
+
# IT: only knows `id`.
|
59
|
+
it { Update.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct id=1>} }
|
60
|
+
|
61
|
+
# Op::contract with inheritance
|
62
|
+
# no ::contract call.
|
63
|
+
class Upgrade < Update
|
64
|
+
end
|
65
|
+
|
66
|
+
# UT: subclasses contract but doesn't share with parent.
|
67
|
+
it { Upgrade["contract.default.class"].superclass.must_equal Update::IdContract }
|
68
|
+
it { Upgrade["contract.default.class"].wont_equal Update["contract.default.class"] }
|
69
|
+
# IT: only knows `id`.
|
70
|
+
it { Upgrade.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct id=1>} }
|
71
|
+
|
72
|
+
# ::contract B overrides old A contract.
|
73
|
+
# this makes sure when calling contract(Constant), the old class gets wiped and is replaced with the new constant.
|
74
|
+
class Upsert < Update
|
75
|
+
class TitleContract < Reform::Form
|
76
|
+
property :title
|
77
|
+
end
|
78
|
+
|
79
|
+
contract TitleContract
|
80
|
+
end
|
81
|
+
|
82
|
+
# UT: subclasses contract.
|
83
|
+
it { Upsert["contract.default.class"].superclass.must_equal Upsert::TitleContract }
|
84
|
+
# IT: only knows `title`.
|
85
|
+
it { Upsert.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct title="Coaster">} }
|
86
|
+
|
87
|
+
# ::contract B do ..end overrides and extends new.
|
88
|
+
# using a constant will wipe out the existing class.
|
89
|
+
class Upside < Update
|
90
|
+
contract Upsert::TitleContract do
|
91
|
+
property :id
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# UT: subclasses contract.
|
96
|
+
it { Upside["contract.default.class"].superclass.must_equal Upsert::TitleContract }
|
97
|
+
# IT: only knows `title`.
|
98
|
+
it { Upside.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct title="Coaster", id=1>} }
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
#---
|
103
|
+
# contract do .. end
|
104
|
+
# (with block)
|
105
|
+
class Delete < Trailblazer::Operation
|
106
|
+
include Call
|
107
|
+
extend Contract::DSL
|
108
|
+
contract do
|
109
|
+
property :title
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# UT: contract path is "contract.default.class"
|
114
|
+
it { Delete["contract.default.class"].definitions.keys.must_equal ["title"] }
|
115
|
+
# IT: knows `title`.
|
116
|
+
it { Delete.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct title=\"Coaster\">} }
|
117
|
+
|
118
|
+
class Wipe < Trailblazer::Operation
|
119
|
+
extend Contract::DSL
|
120
|
+
|
121
|
+
self["x"] = contract do end
|
122
|
+
end
|
123
|
+
# UT: ::contract returns form class
|
124
|
+
it { Wipe["x"].superclass.must_equal Reform::Form }
|
125
|
+
|
126
|
+
# subsequent calls merge.
|
127
|
+
class Remove < Trailblazer::Operation
|
128
|
+
extend Contract::DSL
|
129
|
+
include Call
|
130
|
+
|
131
|
+
contract do
|
132
|
+
property :title
|
133
|
+
end
|
134
|
+
|
135
|
+
contract do
|
136
|
+
property :id
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# IT: knows `title` and `id`, since contracts get merged.
|
141
|
+
it { Remove.(id: 1, title: "Coaster")["model"].inspect.must_equal %{#<OpenStruct title=\"Coaster\", id=1>} }
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
# Operation::["contract.default.class"]
|
149
|
+
# Operation::["contract.default.class"]=
|
150
|
+
describe %{Operation::["contract.default.class"]} do
|
151
|
+
|
152
|
+
class Update2 < Trailblazer::Operation
|
153
|
+
self["contract.default.class"] = String
|
8
154
|
end
|
155
|
+
|
156
|
+
it { Update2["contract.default.class"].must_equal String }
|
9
157
|
end
|
10
158
|
|
11
159
|
describe "inheritance across operations" do
|
12
160
|
# inheritance
|
13
161
|
class Operation < Trailblazer::Operation
|
162
|
+
extend Contract::DSL
|
14
163
|
contract do
|
15
164
|
property :title
|
16
165
|
property :band
|
@@ -22,24 +171,28 @@ class DslContractTest < MiniTest::Spec
|
|
22
171
|
property :band, virtual: true
|
23
172
|
end
|
24
173
|
end
|
174
|
+
|
175
|
+
class XML < self
|
176
|
+
end
|
25
177
|
end
|
26
178
|
|
27
179
|
# inherits subclassed Contract.
|
28
|
-
it { Operation.
|
180
|
+
it { Operation["contract.default.class"].wont_equal Operation::JSON["contract.default.class"] }
|
181
|
+
it { Operation::XML["contract.default.class"].superclass.must_equal Reform::Form }
|
29
182
|
|
30
183
|
it do
|
31
|
-
form = Operation.
|
184
|
+
form = Operation["contract.default.class"].new(OpenStruct.new)
|
32
185
|
form.validate({})#.must_equal true
|
33
186
|
form.errors.to_s.must_equal "{}"
|
34
187
|
|
35
|
-
form = Operation::JSON.
|
188
|
+
form = Operation::JSON["contract.default.class"].new(OpenStruct.new)
|
36
189
|
form.validate({})#.must_equal true
|
37
190
|
form.errors.to_s.must_equal "{:genre=>[\"can't be blank\"]}"
|
38
191
|
end
|
39
192
|
|
40
193
|
# allows overriding options
|
41
194
|
it do
|
42
|
-
form = Operation::JSON.
|
195
|
+
form = Operation::JSON["contract.default.class"].new(song = OpenStruct.new)
|
43
196
|
form.validate({genre: "Punkrock", band: "Osker"}).must_equal true
|
44
197
|
form.sync
|
45
198
|
|
@@ -48,21 +201,18 @@ class DslContractTest < MiniTest::Spec
|
|
48
201
|
end
|
49
202
|
end
|
50
203
|
|
51
|
-
describe "Op.contract" do
|
52
|
-
it { Operation.contract.must_equal Operation.contract_class }
|
53
|
-
end
|
54
|
-
|
55
204
|
describe "Op.contract CommentForm" do
|
56
205
|
class SongForm < Reform::Form
|
57
206
|
property :songTitle, validates: {presence: true}
|
58
207
|
end
|
59
208
|
|
60
209
|
class OpWithExternalContract < Trailblazer::Operation
|
210
|
+
extend Contract::DSL
|
61
211
|
contract SongForm
|
62
|
-
include
|
212
|
+
include Call
|
63
213
|
end
|
64
214
|
|
65
|
-
it { OpWithExternalContract.("songTitle"=> "Monsterparty")
|
215
|
+
it { OpWithExternalContract.("songTitle"=> "Monsterparty")["contract.default"].songTitle.must_equal "Monsterparty" }
|
66
216
|
end
|
67
217
|
|
68
218
|
describe "Op.contract CommentForm do .. end" do
|
@@ -71,27 +221,29 @@ class DslContractTest < MiniTest::Spec
|
|
71
221
|
end
|
72
222
|
|
73
223
|
class OpNotExtendingContract < Trailblazer::Operation
|
224
|
+
extend Contract::DSL
|
74
225
|
contract DifferentSongForm
|
75
|
-
include
|
226
|
+
include Call
|
76
227
|
end
|
77
228
|
|
78
229
|
class OpExtendingContract < Trailblazer::Operation
|
230
|
+
extend Contract::DSL
|
79
231
|
contract DifferentSongForm do
|
80
232
|
property :genre
|
81
233
|
end
|
82
|
-
include
|
234
|
+
include Call
|
83
235
|
end
|
84
236
|
|
85
237
|
# this operation copies DifferentSongForm and shouldn't have `genre`.
|
86
238
|
it do
|
87
|
-
contract = OpNotExtendingContract.("songTitle"=>"Monsterparty", "genre"=>"Punk").
|
239
|
+
contract = OpNotExtendingContract.("songTitle"=>"Monsterparty", "genre"=>"Punk")["contract.default"]
|
88
240
|
contract.songTitle.must_equal "Monsterparty"
|
89
241
|
assert_raises(NoMethodError) { contract.genre }
|
90
242
|
end
|
91
243
|
|
92
244
|
# this operation copies DifferentSongForm and extends it with the property `genre`.
|
93
245
|
it do
|
94
|
-
contract = OpExtendingContract.("songTitle"=>"Monsterparty", "genre"=>"Punk").
|
246
|
+
contract = OpExtendingContract.("songTitle"=>"Monsterparty", "genre"=>"Punk")["contract.default"]
|
95
247
|
contract.songTitle.must_equal "Monsterparty"
|
96
248
|
contract.genre.must_equal "Punk"
|
97
249
|
end
|
@@ -101,4 +253,42 @@ class DslContractTest < MiniTest::Spec
|
|
101
253
|
assert_raises(NoMethodError) { DifferentSongForm.new(OpenStruct.new).genre }
|
102
254
|
end
|
103
255
|
end
|
104
|
-
|
256
|
+
|
257
|
+
describe "Op.contract :name, Form" do
|
258
|
+
class Follow < Trailblazer::Operation
|
259
|
+
ParamsForm = Class.new
|
260
|
+
|
261
|
+
extend Contract::DSL
|
262
|
+
contract :params, ParamsForm
|
263
|
+
end
|
264
|
+
|
265
|
+
it { Follow["contract.params.class"].superclass.must_equal Follow::ParamsForm }
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "Op.contract :name do..end" do
|
269
|
+
class Unfollow < Trailblazer::Operation
|
270
|
+
extend Contract::DSL
|
271
|
+
contract :params do
|
272
|
+
property :title
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
it { Unfollow["contract.params.class"].superclass.must_equal Reform::Form }
|
277
|
+
end
|
278
|
+
|
279
|
+
# multiple ::contract calls.
|
280
|
+
describe "multiple ::contract calls" do
|
281
|
+
class Star < Trailblazer::Operation
|
282
|
+
extend Contract::DSL
|
283
|
+
contract do
|
284
|
+
property :title
|
285
|
+
end
|
286
|
+
|
287
|
+
contract do
|
288
|
+
property :id
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
it { Star["contract.default.class"].definitions.keys.must_equal ["title", "id"] }
|
293
|
+
end
|
294
|
+
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
require "representable/json"
|
3
3
|
require "trailblazer/operation/representer"
|
4
|
+
require "trailblazer/operation/contract"
|
4
5
|
|
5
6
|
class DslRepresenterTest < MiniTest::Spec
|
6
7
|
module SongProcess
|
7
8
|
def process(params)
|
8
|
-
|
9
|
+
self["model"] = OpenStruct.new(params)
|
9
10
|
end
|
10
11
|
|
11
12
|
def represented
|
12
|
-
model
|
13
|
+
self["model"]
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -34,10 +35,6 @@ class DslRepresenterTest < MiniTest::Spec
|
|
34
35
|
it { Operation::JSON.(title: "Nothing To Lose", band: "Gary Moore").to_json.must_equal %{{"title":"Nothing To Lose","band":"Gary Moore"}} }
|
35
36
|
end
|
36
37
|
|
37
|
-
describe "Op.representer" do
|
38
|
-
it { Operation.representer.must_equal Operation.representer_class }
|
39
|
-
end
|
40
|
-
|
41
38
|
describe "Op.representer CommentRepresenter" do
|
42
39
|
class SongRepresenter < Representable::Decorator
|
43
40
|
include Representable::JSON
|
@@ -53,6 +50,32 @@ class DslRepresenterTest < MiniTest::Spec
|
|
53
50
|
it { OpWithExternalRepresenter.("songTitle"=>"Listen To Your Heartbeat").to_json.must_equal %{{"songTitle":"Listen To Your Heartbeat"}} }
|
54
51
|
end
|
55
52
|
|
53
|
+
# name for representer
|
54
|
+
describe "1) Op.representer :parse, Representer" do
|
55
|
+
class Op1 < Trailblazer::Operation
|
56
|
+
include Representer
|
57
|
+
representer :parse, String
|
58
|
+
end
|
59
|
+
|
60
|
+
it { Op1["representer.parse.class"].superclass.must_equal String }
|
61
|
+
it { Op1.({})["representer.parse.class"].superclass.must_equal String }
|
62
|
+
end
|
63
|
+
|
64
|
+
# name for default representer
|
65
|
+
describe "2) Op.representer Representer" do
|
66
|
+
class Op2 < Trailblazer::Operation
|
67
|
+
include Representer
|
68
|
+
representer String
|
69
|
+
def call(*); self; end
|
70
|
+
end
|
71
|
+
|
72
|
+
it { Op2["representer.default.class"].superclass.must_equal String }
|
73
|
+
it { Op2.({})["representer.default.class"].superclass.must_equal String }
|
74
|
+
it { Op2.({}, "representer.default.class" => Integer)["representer.default.class"].must_equal Integer }
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
56
79
|
describe "Op.representer CommentRepresenter do .. end" do
|
57
80
|
class HitRepresenter < Representable::Decorator
|
58
81
|
include Representable::JSON
|
@@ -90,28 +113,32 @@ class DslRepresenterTest < MiniTest::Spec
|
|
90
113
|
end
|
91
114
|
|
92
115
|
describe "Op.representer (inferring)" do
|
93
|
-
class
|
116
|
+
class ContractOperation < Trailblazer::Operation
|
94
117
|
include Representer
|
118
|
+
include Representer::InferFromContract
|
95
119
|
include SongProcess
|
120
|
+
include Contract::Explicit
|
96
121
|
|
97
122
|
contract do
|
98
123
|
property :songTitle
|
99
124
|
end
|
100
125
|
end
|
101
126
|
|
102
|
-
class
|
127
|
+
class ContractOperation2 < Trailblazer::Operation
|
103
128
|
include Representer
|
104
129
|
include SongProcess
|
130
|
+
include Contract::Explicit
|
131
|
+
include Representer::InferFromContract
|
132
|
+
contract ContractOperation["contract.default.class"]
|
105
133
|
|
106
|
-
contract OpWithContract.contract
|
107
134
|
representer do
|
108
135
|
property :genre
|
109
136
|
end
|
110
137
|
end
|
111
138
|
|
112
|
-
it {
|
139
|
+
it { ContractOperation.("songTitle"=>"Monsterparty", "genre"=>"Punk").to_json.must_equal %{{"songTitle":"Monsterparty"}} }
|
113
140
|
# this representer block extends the inferred from contract.
|
114
|
-
it {
|
141
|
+
it { ContractOperation2.("songTitle"=>"Monsterparty", "genre"=>"Punk").to_json.must_equal %{{"songTitle":"Monsterparty","genre":"Punk"}} }
|
115
142
|
end
|
116
143
|
|
117
144
|
describe "Op.representer_class" do
|
@@ -123,20 +150,20 @@ class DslRepresenterTest < MiniTest::Spec
|
|
123
150
|
class OpSettingRepresenter < Trailblazer::Operation
|
124
151
|
include Representer
|
125
152
|
include SongProcess
|
126
|
-
self.
|
153
|
+
self["representer.default.class"] = PlayRepresenter
|
127
154
|
end
|
128
155
|
|
129
156
|
class OpExtendRepresenter < Trailblazer::Operation
|
130
157
|
include Representer
|
131
158
|
include SongProcess
|
132
|
-
self.
|
159
|
+
self["representer.default.class"] = PlayRepresenter
|
133
160
|
representer do
|
134
161
|
property :genre
|
135
162
|
end
|
136
163
|
end
|
137
164
|
|
138
165
|
# both operations produce the same as the representer is shared, not copied.
|
139
|
-
it { OpSettingRepresenter.("title"=>"Monsterparty", "genre"=>"Punk").to_json.must_equal %{{"title":"Monsterparty","genre":"Punk"}} }
|
166
|
+
it { skip; OpSettingRepresenter.("title"=>"Monsterparty", "genre"=>"Punk").to_json.must_equal %{{"title":"Monsterparty","genre":"Punk"}} }
|
140
167
|
it { OpExtendRepresenter.("title"=>"Monsterparty", "genre"=>"Punk").to_json.must_equal %{{"title":"Monsterparty","genre":"Punk"}} }
|
141
168
|
end
|
142
|
-
end
|
169
|
+
end
|