representable 2.4.0.rc3 → 2.4.0.rc4
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 +7 -2
- data/Rakefile +6 -0
- data/lib/representable.rb +21 -17
- data/lib/representable/binding.rb +3 -2
- data/lib/representable/definition.rb +1 -1
- data/lib/representable/deprecations.rb +31 -5
- data/lib/representable/deserializer.rb +24 -34
- data/lib/representable/hash/collection.rb +9 -2
- data/lib/representable/hash_methods.rb +2 -2
- data/lib/representable/parse_strategies.rb +6 -7
- data/lib/representable/pipeline.rb +12 -1
- data/lib/representable/pipeline_factories.rb +9 -2
- data/lib/representable/serializer.rb +3 -3
- data/lib/representable/version.rb +1 -1
- data/test-with-deprecations/as_test.rb +65 -0
- data/test-with-deprecations/benchmarking.rb +83 -0
- data/test-with-deprecations/binding_test.rb +46 -0
- data/test-with-deprecations/blaaaaaaaa_test.rb +69 -0
- data/test-with-deprecations/cached_test.rb +147 -0
- data/test-with-deprecations/class_test.rb +119 -0
- data/test-with-deprecations/coercion_test.rb +52 -0
- data/test-with-deprecations/config/inherit_test.rb +135 -0
- data/test-with-deprecations/config_test.rb +122 -0
- data/test-with-deprecations/decorator_scope_test.rb +28 -0
- data/test-with-deprecations/decorator_test.rb +96 -0
- data/test-with-deprecations/default_test.rb +34 -0
- data/test-with-deprecations/defaults_options_test.rb +93 -0
- data/test-with-deprecations/definition_test.rb +264 -0
- data/test-with-deprecations/example.rb +310 -0
- data/test-with-deprecations/examples/object.rb +31 -0
- data/test-with-deprecations/exec_context_test.rb +93 -0
- data/test-with-deprecations/features_test.rb +70 -0
- data/test-with-deprecations/filter_test.rb +57 -0
- data/test-with-deprecations/for_collection_test.rb +74 -0
- data/test-with-deprecations/generic_test.rb +116 -0
- data/test-with-deprecations/getter_setter_test.rb +21 -0
- data/test-with-deprecations/hash_bindings_test.rb +87 -0
- data/test-with-deprecations/hash_test.rb +160 -0
- data/test-with-deprecations/heritage_test.rb +62 -0
- data/test-with-deprecations/if_test.rb +79 -0
- data/test-with-deprecations/include_exclude_test.rb +88 -0
- data/test-with-deprecations/inherit_test.rb +159 -0
- data/test-with-deprecations/inline_test.rb +272 -0
- data/test-with-deprecations/instance_test.rb +266 -0
- data/test-with-deprecations/is_representable_test.rb +77 -0
- data/test-with-deprecations/json_test.rb +355 -0
- data/test-with-deprecations/lonely_test.rb +239 -0
- data/test-with-deprecations/mongoid_test.rb +31 -0
- data/test-with-deprecations/nested_test.rb +115 -0
- data/test-with-deprecations/object_test.rb +60 -0
- data/{test/---deserialize-pipeline_test.rb → test-with-deprecations/parse_pipeline_test.rb} +29 -2
- data/test-with-deprecations/parse_strategy_test.rb +279 -0
- data/{test → test-with-deprecations}/pass_options_test.rb +0 -0
- data/test-with-deprecations/pipeline_test.rb +277 -0
- data/test-with-deprecations/populator_test.rb +105 -0
- data/test-with-deprecations/prepare_test.rb +67 -0
- data/test-with-deprecations/private_options_test.rb +18 -0
- data/test-with-deprecations/reader_writer_test.rb +19 -0
- data/test-with-deprecations/realistic_benchmark.rb +115 -0
- data/test-with-deprecations/render_nil_test.rb +21 -0
- data/test-with-deprecations/represent_test.rb +88 -0
- data/test-with-deprecations/representable_test.rb +511 -0
- data/test-with-deprecations/schema_test.rb +148 -0
- data/test-with-deprecations/serialize_deserialize_test.rb +33 -0
- data/test-with-deprecations/skip_test.rb +81 -0
- data/test-with-deprecations/stringify_hash_test.rb +41 -0
- data/test-with-deprecations/test_helper.rb +135 -0
- data/test-with-deprecations/test_helper_test.rb +25 -0
- data/test-with-deprecations/uncategorized_test.rb +67 -0
- data/test-with-deprecations/user_options_test.rb +15 -0
- data/test-with-deprecations/wrap_test.rb +152 -0
- data/test-with-deprecations/xml_bindings_test.rb +62 -0
- data/test-with-deprecations/xml_test.rb +503 -0
- data/test-with-deprecations/yaml_test.rb +162 -0
- data/test/as_test.rb +3 -3
- data/test/cached_test.rb +2 -2
- data/test/class_test.rb +5 -5
- data/test/exec_context_test.rb +2 -2
- data/test/filter_test.rb +1 -1
- data/test/getter_setter_test.rb +4 -4
- data/test/if_test.rb +2 -2
- data/test/include_exclude_test.rb +88 -0
- data/test/instance_test.rb +15 -15
- data/test/lonely_test.rb +18 -2
- data/test/object_test.rb +4 -4
- data/test/parse_pipeline_test.rb +64 -0
- data/test/parse_strategy_test.rb +3 -3
- data/test/pipeline_test.rb +8 -12
- data/test/prepare_test.rb +2 -3
- data/test/reader_writer_test.rb +3 -3
- data/test/representable_test.rb +12 -48
- data/test/serialize_deserialize_test.rb +9 -9
- data/test/skip_test.rb +11 -11
- data/test/test_helper.rb +2 -0
- data/test/uncategorized_test.rb +10 -10
- data/test/user_options_test.rb +15 -0
- data/test/wrap_test.rb +1 -1
- metadata +65 -4
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IsRepresentableTest < BaseTest
|
4
|
+
describe "representable: false, extend:" do
|
5
|
+
representer!(:inject => :song_representer) do
|
6
|
+
property :song,
|
7
|
+
:representable => false,
|
8
|
+
:extend => song_representer
|
9
|
+
end
|
10
|
+
|
11
|
+
it "does extend but doesn't call #to_hash" do
|
12
|
+
Struct.new(:song).new(song = Object.new).extend(representer).
|
13
|
+
to_hash.must_equal("song" => song)
|
14
|
+
song.must_be_kind_of Representable::Hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "representable: true, no extend:" do
|
20
|
+
representer!(:inject => :song_representer) do
|
21
|
+
property :song,
|
22
|
+
:representable => true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "doesn't extend but calls #to_hash" do
|
26
|
+
song = Object.new
|
27
|
+
song.instance_eval do
|
28
|
+
def to_hash(*)
|
29
|
+
1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Struct.new(:song).new(song).extend(representer).
|
34
|
+
to_hash.must_equal("song" => 1)
|
35
|
+
song.wont_be_kind_of Representable::Hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: TEST implement for from_hash.
|
40
|
+
|
41
|
+
describe "representable: false, with class:" do
|
42
|
+
representer!(:inject => :song_representer) do
|
43
|
+
property :song,
|
44
|
+
:representable => false, :class => OpenStruct, :extend => song_representer
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does extend but doesn't call #from_hash" do
|
48
|
+
hit = Struct.new(:song).new.extend(representer).
|
49
|
+
from_hash("song" => 1)
|
50
|
+
|
51
|
+
hit.song.must_equal OpenStruct.new
|
52
|
+
hit.song.must_be_kind_of Representable::Hash
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
describe "representable: true, without extend: but class:" do
|
58
|
+
SongReader = Class.new do
|
59
|
+
def from_hash(*)
|
60
|
+
"Piano?"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
representer!(:inject => :song_representer) do
|
65
|
+
property :song,
|
66
|
+
:representable => true, :class => SongReader
|
67
|
+
end
|
68
|
+
|
69
|
+
it "doesn't extend but calls #from_hash" do
|
70
|
+
hit = Struct.new(:song).new.extend(representer).
|
71
|
+
from_hash("song" => "Sonata No.2")
|
72
|
+
|
73
|
+
hit.song.must_equal "Piano?"
|
74
|
+
hit.song.wont_be_kind_of Representable::Hash
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,355 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module JsonTest
|
4
|
+
class APITest < MiniTest::Spec
|
5
|
+
Json = Representable::JSON
|
6
|
+
Def = Representable::Definition
|
7
|
+
|
8
|
+
describe "JSON module" do
|
9
|
+
before do
|
10
|
+
@Band = Class.new do
|
11
|
+
include Representable::JSON
|
12
|
+
property :name
|
13
|
+
property :label
|
14
|
+
attr_accessor :name, :label
|
15
|
+
|
16
|
+
def initialize(name=nil)
|
17
|
+
self.name = name if name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@band = @Band.new
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "#from_json" do
|
26
|
+
before do
|
27
|
+
@band = @Band.new
|
28
|
+
@json = {:name => "Nofx", :label => "NOFX"}.to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
it "parses JSON and assigns properties" do
|
32
|
+
@band.from_json(@json)
|
33
|
+
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe "#from_hash" do
|
39
|
+
before do
|
40
|
+
@band = @Band.new
|
41
|
+
@hash = {"name" => "Nofx", "label" => "NOFX"}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "receives hash and assigns properties" do
|
45
|
+
@band.from_hash(@hash)
|
46
|
+
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "respects :wrap option" do
|
50
|
+
@band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band)
|
51
|
+
assert_equal "This Is A Standoff", @band.name
|
52
|
+
end
|
53
|
+
|
54
|
+
it "respects :wrap option over representation_wrap" do
|
55
|
+
@Band.class_eval do
|
56
|
+
self.representation_wrap = :group
|
57
|
+
end
|
58
|
+
@band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band)
|
59
|
+
assert_equal "This Is A Standoff", @band.name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
describe "#to_json" do
|
65
|
+
it "delegates to #to_hash and returns string" do
|
66
|
+
assert_json "{\"name\":\"Rise Against\"}", @Band.new("Rise Against").to_json
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
describe "#to_hash" do
|
72
|
+
it "returns unwrapped hash" do
|
73
|
+
hash = @Band.new("Rise Against").to_hash
|
74
|
+
assert_equal({"name"=>"Rise Against"}, hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "respects :wrap option" do
|
78
|
+
assert_equal({:band=>{"name"=>"NOFX"}}, @Band.new("NOFX").to_hash(:wrap => :band))
|
79
|
+
end
|
80
|
+
|
81
|
+
it "respects :wrap option over representation_wrap" do
|
82
|
+
@Band.class_eval do
|
83
|
+
self.representation_wrap = :group
|
84
|
+
end
|
85
|
+
assert_equal({:band=>{"name"=>"Rise Against"}}, @Band.new("Rise Against").to_hash(:wrap => :band))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#build_for" do
|
90
|
+
it "returns TextBinding" do
|
91
|
+
assert_kind_of Representable::Hash::Binding, Representable::Hash::Binding.build_for(Def.new(:band))
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns CollectionBinding" do
|
95
|
+
assert_kind_of Representable::Hash::Binding::Collection, Representable::Hash::Binding.build_for(Def.new(:band, :collection => true))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
describe "DCI" do
|
102
|
+
module SongRepresenter
|
103
|
+
include Representable::JSON
|
104
|
+
property :name
|
105
|
+
end
|
106
|
+
|
107
|
+
module AlbumRepresenter
|
108
|
+
include Representable::JSON
|
109
|
+
property :best_song, :class => Song, :extend => SongRepresenter
|
110
|
+
collection :songs, :class => Song, :extend => SongRepresenter
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
it "allows adding the representer by using #extend" do
|
115
|
+
module BandRepresenter
|
116
|
+
include Representable::JSON
|
117
|
+
property :name
|
118
|
+
end
|
119
|
+
|
120
|
+
civ = Object.new
|
121
|
+
civ.instance_eval do
|
122
|
+
def name; "CIV"; end
|
123
|
+
def name=(v)
|
124
|
+
@name = v
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
civ.extend(BandRepresenter)
|
129
|
+
assert_json "{\"name\":\"CIV\"}", civ.to_json
|
130
|
+
end
|
131
|
+
|
132
|
+
it "extends contained models when serializing" do
|
133
|
+
@album = Album.new([Song.new("I Hate My Brain"), mr=Song.new("Mr. Charisma")], mr)
|
134
|
+
@album.extend(AlbumRepresenter)
|
135
|
+
|
136
|
+
assert_json "{\"best_song\":{\"name\":\"Mr. Charisma\"},\"songs\":[{\"name\":\"I Hate My Brain\"},{\"name\":\"Mr. Charisma\"}]}", @album.to_json
|
137
|
+
end
|
138
|
+
|
139
|
+
it "extends contained models when deserializing" do
|
140
|
+
#@album = Album.new(Song.new("I Hate My Brain"), Song.new("Mr. Charisma"))
|
141
|
+
@album = Album.new
|
142
|
+
@album.extend(AlbumRepresenter)
|
143
|
+
|
144
|
+
@album.from_json("{\"best_song\":{\"name\":\"Mr. Charisma\"},\"songs\":[{\"name\":\"I Hate My Brain\"},{\"name\":\"Mr. Charisma\"}]}")
|
145
|
+
assert_equal "Mr. Charisma", @album.best_song.name
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
class PropertyTest < MiniTest::Spec
|
152
|
+
describe "property :name" do
|
153
|
+
class Band
|
154
|
+
include Representable::JSON
|
155
|
+
property :name
|
156
|
+
attr_accessor :name
|
157
|
+
end
|
158
|
+
|
159
|
+
it "#from_json creates correct accessors" do
|
160
|
+
band = Band.new.from_json({:name => "Bombshell Rocks"}.to_json)
|
161
|
+
assert_equal "Bombshell Rocks", band.name
|
162
|
+
end
|
163
|
+
|
164
|
+
it "#to_json serializes correctly" do
|
165
|
+
band = Band.new
|
166
|
+
band.name = "Cigar"
|
167
|
+
|
168
|
+
assert_json '{"name":"Cigar"}', band.to_json
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe ":class => Item" do
|
173
|
+
class Label
|
174
|
+
include Representable::JSON
|
175
|
+
property :name
|
176
|
+
attr_accessor :name
|
177
|
+
end
|
178
|
+
|
179
|
+
class Album
|
180
|
+
include Representable::JSON
|
181
|
+
property :label, :class => Label
|
182
|
+
attr_accessor :label
|
183
|
+
end
|
184
|
+
|
185
|
+
it "#from_json creates one Item instance" do
|
186
|
+
album = Album.new.from_json('{"label":{"name":"Fat Wreck"}}')
|
187
|
+
assert_equal "Fat Wreck", album.label.name
|
188
|
+
end
|
189
|
+
|
190
|
+
it "#to_json serializes" do
|
191
|
+
label = Label.new; label.name = "Fat Wreck"
|
192
|
+
album = Album.new; album.label = label
|
193
|
+
|
194
|
+
assert_json '{"label":{"name":"Fat Wreck"}}', album.to_json
|
195
|
+
end
|
196
|
+
|
197
|
+
describe ":different_name, :class => Label" do
|
198
|
+
before do
|
199
|
+
@Album = Class.new do
|
200
|
+
include Representable::JSON
|
201
|
+
property :seller, :class => Label
|
202
|
+
attr_accessor :seller
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "#to_xml respects the different name" do
|
207
|
+
label = Label.new; label.name = "Fat Wreck"
|
208
|
+
album = @Album.new; album.seller = label
|
209
|
+
|
210
|
+
assert_json "{\"seller\":{\"name\":\"Fat Wreck\"}}", album.to_json(:wrap => false)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe ":as => :songName" do
|
216
|
+
class Song
|
217
|
+
include Representable::JSON
|
218
|
+
property :name, :as => :songName
|
219
|
+
attr_accessor :name
|
220
|
+
end
|
221
|
+
|
222
|
+
it "respects :as in #from_json" do
|
223
|
+
song = Song.new.from_json({:songName => "Run To The Hills"}.to_json)
|
224
|
+
assert_equal "Run To The Hills", song.name
|
225
|
+
end
|
226
|
+
|
227
|
+
it "respects :as in #to_json" do
|
228
|
+
song = Song.new; song.name = "22 Acacia Avenue"
|
229
|
+
assert_json '{"songName":"22 Acacia Avenue"}', song.to_json
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
class CollectionTest < MiniTest::Spec
|
237
|
+
describe "collection :name" do
|
238
|
+
class CD
|
239
|
+
include Representable::JSON
|
240
|
+
collection :songs
|
241
|
+
attr_accessor :songs
|
242
|
+
end
|
243
|
+
|
244
|
+
it "#from_json creates correct accessors" do
|
245
|
+
cd = CD.new.from_json({:songs => ["Out in the cold", "Microphone"]}.to_json)
|
246
|
+
assert_equal ["Out in the cold", "Microphone"], cd.songs
|
247
|
+
end
|
248
|
+
|
249
|
+
it "zzz#to_json serializes correctly" do
|
250
|
+
cd = CD.new
|
251
|
+
cd.songs = ["Out in the cold", "Microphone"]
|
252
|
+
|
253
|
+
assert_json '{"songs":["Out in the cold","Microphone"]}', cd.to_json
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe "collection :name, :class => Band" do
|
258
|
+
class Band
|
259
|
+
include Representable::JSON
|
260
|
+
property :name
|
261
|
+
attr_accessor :name
|
262
|
+
|
263
|
+
def initialize(name="")
|
264
|
+
self.name = name
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
class Compilation
|
269
|
+
include Representable::JSON
|
270
|
+
collection :bands, :class => Band
|
271
|
+
attr_accessor :bands
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "#from_json" do
|
275
|
+
it "pushes collection items to array" do
|
276
|
+
cd = Compilation.new.from_json({:bands => [
|
277
|
+
{:name => "Cobra Skulls"},
|
278
|
+
{:name => "Diesel Boy"}]}.to_json)
|
279
|
+
assert_equal ["Cobra Skulls", "Diesel Boy"], cd.bands.map(&:name).sort
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
it "responds to #to_json" do
|
284
|
+
cd = Compilation.new
|
285
|
+
cd.bands = [Band.new("Diesel Boy"), Band.new("Bad Religion")]
|
286
|
+
|
287
|
+
assert_json '{"bands":[{"name":"Diesel Boy"},{"name":"Bad Religion"}]}', cd.to_json
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
describe ":as => :songList" do
|
293
|
+
class Songs
|
294
|
+
include Representable::JSON
|
295
|
+
collection :tracks, :as => :songList
|
296
|
+
attr_accessor :tracks
|
297
|
+
end
|
298
|
+
|
299
|
+
it "respects :as in #from_json" do
|
300
|
+
songs = Songs.new.from_json({:songList => ["Out in the cold", "Microphone"]}.to_json)
|
301
|
+
assert_equal ["Out in the cold", "Microphone"], songs.tracks
|
302
|
+
end
|
303
|
+
|
304
|
+
it "respects option in #to_json" do
|
305
|
+
songs = Songs.new
|
306
|
+
songs.tracks = ["Out in the cold", "Microphone"]
|
307
|
+
|
308
|
+
assert_json '{"songList":["Out in the cold","Microphone"]}', songs.to_json
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
class HashTest < MiniTest::Spec
|
314
|
+
describe "hash :songs" do
|
315
|
+
representer!(:module => Representable::JSON) do
|
316
|
+
hash :songs
|
317
|
+
end
|
318
|
+
|
319
|
+
subject { OpenStruct.new.extend(representer) }
|
320
|
+
|
321
|
+
it "renders with #to_json" do
|
322
|
+
subject.songs = {:one => "65", :two => "Emo Boy"}
|
323
|
+
assert_json "{\"songs\":{\"one\":\"65\",\"two\":\"Emo Boy\"}}", subject.to_json
|
324
|
+
end
|
325
|
+
|
326
|
+
it "parses with #from_json" do
|
327
|
+
assert_equal({"one" => "65", "two" => ["Emo Boy"]}, subject.from_json("{\"songs\":{\"one\":\"65\",\"two\":[\"Emo Boy\"]}}").songs)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
describe "hash :songs, :class => Song" do
|
332
|
+
representer!(:module => Representable::JSON) do
|
333
|
+
hash :songs, :extend => Module.new { include Representable::JSON; property :name }, :class => Song
|
334
|
+
end
|
335
|
+
|
336
|
+
it "renders" do
|
337
|
+
OpenStruct.new(:songs => {"7" => Song.new("Contemplation")}).extend(representer).to_hash.must_equal("songs"=>{"7"=>{"name"=>"Contemplation"}})
|
338
|
+
end
|
339
|
+
|
340
|
+
describe "parsing" do
|
341
|
+
subject { OpenStruct.new.extend(representer) }
|
342
|
+
let (:hsh) { {"7"=>{"name"=>"Contemplation"}} }
|
343
|
+
|
344
|
+
it "parses incoming hash" do
|
345
|
+
subject.from_hash("songs"=>hsh).songs.must_equal({"7"=>Song.new("Contemplation")})
|
346
|
+
end
|
347
|
+
|
348
|
+
it "doesn't modify the incoming hash" do
|
349
|
+
subject.from_hash("songs"=> incoming_hash = hsh.dup)
|
350
|
+
hsh.must_equal incoming_hash
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'representable/json/hash'
|
4
|
+
|
5
|
+
class LonelyRepresenterTest < MiniTest::Spec
|
6
|
+
|
7
|
+
# test ::items without arguments, render-only.
|
8
|
+
for_formats(
|
9
|
+
:hash => [Representable::Hash::Collection, [{"name"=>"Resist Stance"}, {"name"=>"Suffer"}]],
|
10
|
+
:json => [Representable::JSON::Collection, "[{\"name\":\"Resist Stance\"},{\"name\":\"Suffer\"}]"],
|
11
|
+
:xml => [Representable::XML::Collection, "<array><song><name>Resist Stance</name></song><song><name>Suffer</name></song></array>"],
|
12
|
+
) do |format, mod, output, input|
|
13
|
+
|
14
|
+
describe "[#{format}] lonely collection, render-only" do # TODO: introduce :representable option?
|
15
|
+
let (:format) { format }
|
16
|
+
|
17
|
+
representer!(module: mod) do
|
18
|
+
items do
|
19
|
+
property :name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
let (:album) { [Song.new("Resist Stance"), Song.new("Suffer")].extend(representer) }
|
24
|
+
|
25
|
+
it "calls #to_hash on song instances, nothing else" do
|
26
|
+
render(album).must_equal_document(output)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
module SongRepresenter
|
34
|
+
include Representable::JSON
|
35
|
+
|
36
|
+
property :name
|
37
|
+
end
|
38
|
+
|
39
|
+
let (:decorator) { rpr = representer; Class.new(Representable::Decorator) { include Representable::Hash; include rpr } }
|
40
|
+
|
41
|
+
describe "JSON::Collection" do
|
42
|
+
let (:songs) { [Song.new("Days Go By"), Song.new("Can't Take Them All")] }
|
43
|
+
let (:json) { "[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]" }
|
44
|
+
|
45
|
+
describe "with contained objects" do
|
46
|
+
let (:representer) {
|
47
|
+
Module.new do
|
48
|
+
include Representable::JSON::Collection
|
49
|
+
items :class => Song, :extend => SongRepresenter
|
50
|
+
end
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
it "renders array" do
|
55
|
+
assert_json json, songs.extend(representer).to_json
|
56
|
+
end
|
57
|
+
|
58
|
+
it "renders array with decorator" do
|
59
|
+
assert_json json, decorator.new(songs).to_json
|
60
|
+
end
|
61
|
+
|
62
|
+
it "parses array" do
|
63
|
+
[].extend(representer).from_json(json).must_equal songs
|
64
|
+
end
|
65
|
+
|
66
|
+
it "parses array with decorator" do
|
67
|
+
decorator.new([]).from_json(json).must_equal songs
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "with inline representer" do
|
72
|
+
representer!(:module => Representable::JSON::Collection) do
|
73
|
+
items :class => Song do
|
74
|
+
property :name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it { songs.extend(representer).to_json.must_equal json }
|
79
|
+
it { [].extend(representer).from_json(json).must_equal songs }
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "with contained text" do
|
83
|
+
let (:representer) {
|
84
|
+
Module.new do
|
85
|
+
include Representable::JSON::Collection
|
86
|
+
end
|
87
|
+
}
|
88
|
+
let (:songs) { ["Days Go By", "Can't Take Them All"] }
|
89
|
+
let (:json) { "[\"Days Go By\",\"Can't Take Them All\"]" }
|
90
|
+
|
91
|
+
it "renders contained items #to_json" do
|
92
|
+
assert_json json, songs.extend(representer).to_json
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns objects array from #from_json" do
|
96
|
+
[].extend(representer).from_json(json).must_equal songs
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "Hash::Collection with dynamic options" do
|
102
|
+
class One < Representable::Decorator
|
103
|
+
def to_hash(*); "One: #{represented}"; end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Two < Representable::Decorator
|
107
|
+
def to_hash(*); "Two: #{represented}"; end
|
108
|
+
end
|
109
|
+
|
110
|
+
representer!(module: Representable::Hash::Collection) do
|
111
|
+
items extend: ->(options) { options[:input] == 1 ? options[:user_options][:one] : options[:user_options][:two] }
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
it { [1,2].extend(representer).to_hash(one: One, two: Two).must_equal(["One: 1", "Two: 2"]) }
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
describe "JSON::Hash" do # TODO: move to HashTest.
|
120
|
+
describe "with contained objects" do
|
121
|
+
let (:representer) {
|
122
|
+
Module.new do
|
123
|
+
include Representable::JSON::Hash
|
124
|
+
values :class => Song, :extend => SongRepresenter
|
125
|
+
end
|
126
|
+
}
|
127
|
+
let (:json) { "{\"one\":{\"name\":\"Days Go By\"},\"two\":{\"name\":\"Can't Take Them All\"}}" }
|
128
|
+
let (:songs) { {"one" => Song.new("Days Go By"), "two" => Song.new("Can't Take Them All")} }
|
129
|
+
|
130
|
+
describe "#to_json" do
|
131
|
+
it "renders hash" do
|
132
|
+
songs.extend(representer).to_json.must_equal json
|
133
|
+
end
|
134
|
+
|
135
|
+
it "renders hash with decorator" do
|
136
|
+
decorator.new(songs).to_json.must_equal json
|
137
|
+
end
|
138
|
+
|
139
|
+
it "respects :exclude" do
|
140
|
+
assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", {:one => Song.new("Days Go By"), :two => Song.new("Can't Take Them All")}.extend(representer).to_json(:exclude => [:one])
|
141
|
+
end
|
142
|
+
|
143
|
+
it "respects :include" do
|
144
|
+
assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", {:one => Song.new("Days Go By"), :two => Song.new("Can't Take Them All")}.extend(representer).to_json(:include => [:two])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#from_json" do
|
149
|
+
it "returns objects array" do
|
150
|
+
{}.extend(representer).from_json(json).must_equal songs
|
151
|
+
end
|
152
|
+
|
153
|
+
it "parses hash with decorator" do
|
154
|
+
decorator.new({}).from_json(json).must_equal songs
|
155
|
+
end
|
156
|
+
|
157
|
+
it "respects :exclude" do
|
158
|
+
assert_equal({"two" => Song.new("Can't Take Them All")}, {}.extend(representer).from_json(json, :exclude => [:one]))
|
159
|
+
end
|
160
|
+
|
161
|
+
it "respects :include" do
|
162
|
+
assert_equal({"one" => Song.new("Days Go By")}, {}.extend(representer).from_json(json, :include => [:one]))
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
describe "with inline representer" do
|
168
|
+
representer!(:module => Representable::JSON::Hash) do
|
169
|
+
values :class => Song do
|
170
|
+
property :name
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
it { songs.extend(representer).to_json.must_equal json }
|
175
|
+
it { {}.extend(representer).from_json(json).must_equal songs }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
describe "with scalar" do
|
181
|
+
let (:representer) {
|
182
|
+
Module.new do
|
183
|
+
include Representable::JSON::Hash
|
184
|
+
end
|
185
|
+
}
|
186
|
+
let (:json) { %{{"one":1,"two":2}} }
|
187
|
+
let (:data) { {one: 2, two: 3} }
|
188
|
+
|
189
|
+
describe "#to_json" do
|
190
|
+
it { data.extend(representer).to_json.must_equal %{{"one":2,"two":3}} }
|
191
|
+
|
192
|
+
# it "respects :exclude" do
|
193
|
+
# assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", {:one => Song.new("Days Go By"), :two => Song.new("Can't Take Them All")}.extend(representer).to_json(:exclude => [:one])
|
194
|
+
# end
|
195
|
+
|
196
|
+
# it "respects :include" do
|
197
|
+
# assert_json "{\"two\":{\"name\":\"Can't Take Them All\"}}", {:one => Song.new("Days Go By"), :two => Song.new("Can't Take Them All")}.extend(representer).to_json(:include => [:two])
|
198
|
+
# end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "#from_json" do # FIXME: what's the point of this?
|
202
|
+
it { data.extend(representer).from_hash(data).must_equal data }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
describe "with contained text" do
|
208
|
+
before do
|
209
|
+
@songs_representer = Module.new do
|
210
|
+
include Representable::JSON::Collection
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
it "renders contained items #to_json" do
|
215
|
+
assert_json "[\"Days Go By\",\"Can't Take Them All\"]", ["Days Go By", "Can't Take Them All"].extend(@songs_representer).to_json
|
216
|
+
end
|
217
|
+
|
218
|
+
it "returns objects array from #from_json" do
|
219
|
+
assert_equal ["Days Go By", "Can't Take Them All"], [].extend(@songs_representer).from_json("[\"Days Go By\",\"Can't Take Them All\"]")
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
# describe "Hash::Collection with :include" do
|
227
|
+
class CollectionWithIncludeTest < MiniTest::Spec
|
228
|
+
Song = Struct.new(:id, :title)
|
229
|
+
|
230
|
+
representer!(decorator: true, module: Representable::Hash::Collection) do
|
231
|
+
items do
|
232
|
+
property :id
|
233
|
+
property :title
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
it { representer.new([Song.new(1, "ACAB")]).to_hash.must_equal([{"id"=>1, "title"=>"ACAB"}]) }
|
238
|
+
it { representer.new([Song.new(1, "ACAB")]).to_hash(include: [:title]).must_equal([{"title"=>"ACAB"}]) }
|
239
|
+
end
|