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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +7 -2
  3. data/Rakefile +6 -0
  4. data/lib/representable.rb +21 -17
  5. data/lib/representable/binding.rb +3 -2
  6. data/lib/representable/definition.rb +1 -1
  7. data/lib/representable/deprecations.rb +31 -5
  8. data/lib/representable/deserializer.rb +24 -34
  9. data/lib/representable/hash/collection.rb +9 -2
  10. data/lib/representable/hash_methods.rb +2 -2
  11. data/lib/representable/parse_strategies.rb +6 -7
  12. data/lib/representable/pipeline.rb +12 -1
  13. data/lib/representable/pipeline_factories.rb +9 -2
  14. data/lib/representable/serializer.rb +3 -3
  15. data/lib/representable/version.rb +1 -1
  16. data/test-with-deprecations/as_test.rb +65 -0
  17. data/test-with-deprecations/benchmarking.rb +83 -0
  18. data/test-with-deprecations/binding_test.rb +46 -0
  19. data/test-with-deprecations/blaaaaaaaa_test.rb +69 -0
  20. data/test-with-deprecations/cached_test.rb +147 -0
  21. data/test-with-deprecations/class_test.rb +119 -0
  22. data/test-with-deprecations/coercion_test.rb +52 -0
  23. data/test-with-deprecations/config/inherit_test.rb +135 -0
  24. data/test-with-deprecations/config_test.rb +122 -0
  25. data/test-with-deprecations/decorator_scope_test.rb +28 -0
  26. data/test-with-deprecations/decorator_test.rb +96 -0
  27. data/test-with-deprecations/default_test.rb +34 -0
  28. data/test-with-deprecations/defaults_options_test.rb +93 -0
  29. data/test-with-deprecations/definition_test.rb +264 -0
  30. data/test-with-deprecations/example.rb +310 -0
  31. data/test-with-deprecations/examples/object.rb +31 -0
  32. data/test-with-deprecations/exec_context_test.rb +93 -0
  33. data/test-with-deprecations/features_test.rb +70 -0
  34. data/test-with-deprecations/filter_test.rb +57 -0
  35. data/test-with-deprecations/for_collection_test.rb +74 -0
  36. data/test-with-deprecations/generic_test.rb +116 -0
  37. data/test-with-deprecations/getter_setter_test.rb +21 -0
  38. data/test-with-deprecations/hash_bindings_test.rb +87 -0
  39. data/test-with-deprecations/hash_test.rb +160 -0
  40. data/test-with-deprecations/heritage_test.rb +62 -0
  41. data/test-with-deprecations/if_test.rb +79 -0
  42. data/test-with-deprecations/include_exclude_test.rb +88 -0
  43. data/test-with-deprecations/inherit_test.rb +159 -0
  44. data/test-with-deprecations/inline_test.rb +272 -0
  45. data/test-with-deprecations/instance_test.rb +266 -0
  46. data/test-with-deprecations/is_representable_test.rb +77 -0
  47. data/test-with-deprecations/json_test.rb +355 -0
  48. data/test-with-deprecations/lonely_test.rb +239 -0
  49. data/test-with-deprecations/mongoid_test.rb +31 -0
  50. data/test-with-deprecations/nested_test.rb +115 -0
  51. data/test-with-deprecations/object_test.rb +60 -0
  52. data/{test/---deserialize-pipeline_test.rb → test-with-deprecations/parse_pipeline_test.rb} +29 -2
  53. data/test-with-deprecations/parse_strategy_test.rb +279 -0
  54. data/{test → test-with-deprecations}/pass_options_test.rb +0 -0
  55. data/test-with-deprecations/pipeline_test.rb +277 -0
  56. data/test-with-deprecations/populator_test.rb +105 -0
  57. data/test-with-deprecations/prepare_test.rb +67 -0
  58. data/test-with-deprecations/private_options_test.rb +18 -0
  59. data/test-with-deprecations/reader_writer_test.rb +19 -0
  60. data/test-with-deprecations/realistic_benchmark.rb +115 -0
  61. data/test-with-deprecations/render_nil_test.rb +21 -0
  62. data/test-with-deprecations/represent_test.rb +88 -0
  63. data/test-with-deprecations/representable_test.rb +511 -0
  64. data/test-with-deprecations/schema_test.rb +148 -0
  65. data/test-with-deprecations/serialize_deserialize_test.rb +33 -0
  66. data/test-with-deprecations/skip_test.rb +81 -0
  67. data/test-with-deprecations/stringify_hash_test.rb +41 -0
  68. data/test-with-deprecations/test_helper.rb +135 -0
  69. data/test-with-deprecations/test_helper_test.rb +25 -0
  70. data/test-with-deprecations/uncategorized_test.rb +67 -0
  71. data/test-with-deprecations/user_options_test.rb +15 -0
  72. data/test-with-deprecations/wrap_test.rb +152 -0
  73. data/test-with-deprecations/xml_bindings_test.rb +62 -0
  74. data/test-with-deprecations/xml_test.rb +503 -0
  75. data/test-with-deprecations/yaml_test.rb +162 -0
  76. data/test/as_test.rb +3 -3
  77. data/test/cached_test.rb +2 -2
  78. data/test/class_test.rb +5 -5
  79. data/test/exec_context_test.rb +2 -2
  80. data/test/filter_test.rb +1 -1
  81. data/test/getter_setter_test.rb +4 -4
  82. data/test/if_test.rb +2 -2
  83. data/test/include_exclude_test.rb +88 -0
  84. data/test/instance_test.rb +15 -15
  85. data/test/lonely_test.rb +18 -2
  86. data/test/object_test.rb +4 -4
  87. data/test/parse_pipeline_test.rb +64 -0
  88. data/test/parse_strategy_test.rb +3 -3
  89. data/test/pipeline_test.rb +8 -12
  90. data/test/prepare_test.rb +2 -3
  91. data/test/reader_writer_test.rb +3 -3
  92. data/test/representable_test.rb +12 -48
  93. data/test/serialize_deserialize_test.rb +9 -9
  94. data/test/skip_test.rb +11 -11
  95. data/test/test_helper.rb +2 -0
  96. data/test/uncategorized_test.rb +10 -10
  97. data/test/user_options_test.rb +15 -0
  98. data/test/wrap_test.rb +1 -1
  99. 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