representable 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -12
  3. data/CHANGES.md +6 -27
  4. data/README.md +28 -1326
  5. data/lib/representable.rb +4 -14
  6. data/lib/representable/binding.rb +3 -7
  7. data/lib/representable/definition.rb +1 -2
  8. data/lib/representable/populator.rb +35 -0
  9. data/lib/representable/version.rb +1 -1
  10. data/test/definition_test.rb +0 -7
  11. data/test/exec_context_test.rb +2 -2
  12. data/test/instance_test.rb +0 -19
  13. data/test/realistic_benchmark.rb +0 -13
  14. data/test/representable_test.rb +0 -16
  15. data/test/skip_test.rb +1 -1
  16. data/test/test_helper.rb +0 -2
  17. metadata +3 -65
  18. data/lib/representable/deprecations.rb +0 -127
  19. data/lib/representable/parse_strategies.rb +0 -93
  20. data/test-with-deprecations/as_test.rb +0 -65
  21. data/test-with-deprecations/benchmarking.rb +0 -83
  22. data/test-with-deprecations/binding_test.rb +0 -46
  23. data/test-with-deprecations/blaaaaaaaa_test.rb +0 -69
  24. data/test-with-deprecations/cached_test.rb +0 -147
  25. data/test-with-deprecations/class_test.rb +0 -119
  26. data/test-with-deprecations/coercion_test.rb +0 -52
  27. data/test-with-deprecations/config/inherit_test.rb +0 -135
  28. data/test-with-deprecations/config_test.rb +0 -122
  29. data/test-with-deprecations/decorator_scope_test.rb +0 -28
  30. data/test-with-deprecations/decorator_test.rb +0 -96
  31. data/test-with-deprecations/default_test.rb +0 -34
  32. data/test-with-deprecations/defaults_options_test.rb +0 -93
  33. data/test-with-deprecations/definition_test.rb +0 -264
  34. data/test-with-deprecations/example.rb +0 -310
  35. data/test-with-deprecations/examples/object.rb +0 -31
  36. data/test-with-deprecations/exec_context_test.rb +0 -93
  37. data/test-with-deprecations/features_test.rb +0 -70
  38. data/test-with-deprecations/filter_test.rb +0 -57
  39. data/test-with-deprecations/for_collection_test.rb +0 -74
  40. data/test-with-deprecations/generic_test.rb +0 -116
  41. data/test-with-deprecations/getter_setter_test.rb +0 -21
  42. data/test-with-deprecations/hash_bindings_test.rb +0 -87
  43. data/test-with-deprecations/hash_test.rb +0 -160
  44. data/test-with-deprecations/heritage_test.rb +0 -62
  45. data/test-with-deprecations/if_test.rb +0 -79
  46. data/test-with-deprecations/include_exclude_test.rb +0 -88
  47. data/test-with-deprecations/inherit_test.rb +0 -159
  48. data/test-with-deprecations/inline_test.rb +0 -272
  49. data/test-with-deprecations/instance_test.rb +0 -266
  50. data/test-with-deprecations/is_representable_test.rb +0 -77
  51. data/test-with-deprecations/json_test.rb +0 -355
  52. data/test-with-deprecations/lonely_test.rb +0 -239
  53. data/test-with-deprecations/mongoid_test.rb +0 -31
  54. data/test-with-deprecations/nested_test.rb +0 -115
  55. data/test-with-deprecations/object_test.rb +0 -60
  56. data/test-with-deprecations/parse_pipeline_test.rb +0 -64
  57. data/test-with-deprecations/parse_strategy_test.rb +0 -279
  58. data/test-with-deprecations/pass_options_test.rb +0 -27
  59. data/test-with-deprecations/pipeline_test.rb +0 -277
  60. data/test-with-deprecations/populator_test.rb +0 -105
  61. data/test-with-deprecations/prepare_test.rb +0 -67
  62. data/test-with-deprecations/private_options_test.rb +0 -18
  63. data/test-with-deprecations/reader_writer_test.rb +0 -19
  64. data/test-with-deprecations/realistic_benchmark.rb +0 -115
  65. data/test-with-deprecations/render_nil_test.rb +0 -21
  66. data/test-with-deprecations/represent_test.rb +0 -88
  67. data/test-with-deprecations/representable_test.rb +0 -511
  68. data/test-with-deprecations/schema_test.rb +0 -148
  69. data/test-with-deprecations/serialize_deserialize_test.rb +0 -33
  70. data/test-with-deprecations/skip_test.rb +0 -81
  71. data/test-with-deprecations/stringify_hash_test.rb +0 -41
  72. data/test-with-deprecations/test_helper.rb +0 -135
  73. data/test-with-deprecations/test_helper_test.rb +0 -25
  74. data/test-with-deprecations/uncategorized_test.rb +0 -67
  75. data/test-with-deprecations/user_options_test.rb +0 -15
  76. data/test-with-deprecations/wrap_test.rb +0 -152
  77. data/test-with-deprecations/xml_bindings_test.rb +0 -62
  78. data/test-with-deprecations/xml_test.rb +0 -503
  79. data/test-with-deprecations/yaml_test.rb +0 -162
  80. data/test/parse_strategy_test.rb +0 -279
@@ -1,266 +0,0 @@
1
- require 'test_helper'
2
-
3
- class InstanceTest < BaseTest
4
- Song = Struct.new(:id, :title)
5
- Song.class_eval do
6
- def self.find(id)
7
- new(id, "Invincible")
8
- end
9
- end
10
-
11
- describe "lambda { fragment } (new way of class: lambda { nil })" do
12
- representer! do
13
- property :title, :instance => lambda { |fragment, args| fragment }
14
- end
15
-
16
- it "skips creating new instance" do
17
- object = Object.new
18
- object.instance_eval do
19
- def from_hash(hash, *args)
20
- hash
21
- end
22
- end
23
-
24
- song = OpenStruct.new.extend(representer).from_hash(hash = {"title" => object})
25
- song.title.must_equal object
26
- end
27
- end
28
-
29
-
30
- # TODO: use *args in from_hash.
31
- # DISCUSS: do we need parse_strategy?
32
- describe "property with :instance" do
33
- representer!(:inject => :song_representer) do
34
- property :song,
35
- :instance => lambda { |fragment, *args| fragment["id"] == song.id ? song : Song.find(fragment["id"]) },
36
- :extend => song_representer
37
- end
38
-
39
- it( "xxx") { OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer).
40
- from_hash("song" => {"id" => 1}).song.must_equal Song.new(1, "The Answer Is Still No") }
41
-
42
- it { OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer).
43
- from_hash("song" => {"id" => 2}).song.must_equal Song.new(2, "Invincible") }
44
- end
45
-
46
-
47
- describe "collection with :instance" do
48
- representer!(:inject => :song_representer) do
49
- collection :songs,
50
- :instance => lambda { |fragment, i, *args|
51
- fragment["id"] == songs[i].id ? songs[i] : Song.find(fragment["id"])
52
- }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync.
53
-
54
- :extend => song_representer
55
- end
56
-
57
- it {
58
- album= Struct.new(:songs).new(songs = [
59
- Song.new(1, "The Answer Is Still No"),
60
- Song.new(2, "")])
61
-
62
- album.
63
- extend(representer).
64
- from_hash("songs" => [{"id" => 2},{"id" => 2, "title"=>"The Answer Is Still No"}]).songs.must_equal [
65
- Song.new(2, "Invincible"), Song.new(2, "The Answer Is Still No")]
66
- }
67
- end
68
-
69
- describe "property with lambda receiving fragment and args" do
70
- representer!(:inject => :song_representer) do
71
- property :song, :instance => lambda { |fragment, args| Struct.new(:args, :id).new([fragment, args]) }, :extend => song_representer
72
- end
73
-
74
- it { OpenStruct.new(:song => Song.new(1, "The Answer Is Still No")).extend(representer).
75
- from_hash({"song" => {"id" => 1}}, {:volume => 1}).song.args.must_equal([{"id"=>1}, {:volume=>1}]) }
76
- end
77
-
78
- # TODO: raise and test instance:{nil}
79
- # describe "property with instance: { nil }" do # TODO: introduce :representable option?
80
- # representer!(:inject => :song_representer) do
81
- # property :song, :instance => lambda { |*| nil }, :extend => song_representer
82
- # end
83
-
84
- # let (:hit) { hit = OpenStruct.new(:song => song).extend(representer) }
85
-
86
- # it "calls #to_hash on song instance, nothing else" do
87
- # hit.to_hash.must_equal("song"=>{"title"=>"Resist Stance"})
88
- # end
89
-
90
- # it "calls #from_hash on the existing song instance, nothing else" do
91
- # song_id = hit.song.object_id
92
- # hit.from_hash("song"=>{"title"=>"Suffer"})
93
- # hit.song.title.must_equal "Suffer"
94
- # hit.song.object_id.must_equal song_id
95
- # end
96
- # end
97
-
98
- # lambda { |fragment, i, Context(binding: <..>, args: [..])| }
99
-
100
- describe "sync" do
101
- representer!(:inject => :song_representer) do
102
- collection :songs,
103
- :instance => lambda { |fragment, i, *args|
104
- songs[i]
105
- },
106
- :extend => song_representer,
107
- # :parse_strategy => :sync
108
- :setter => lambda { |*| }
109
- end
110
-
111
- it {
112
- album= Struct.new(:songs).new(songs = [
113
- Song.new(1, "The Answer Is Still No"),
114
- Song.new(2, "Invncble")])
115
-
116
- album.
117
- extend(representer).
118
- from_hash("songs" => [{"title" => "The Answer Is Still No"}, {"title" => "Invincible"}])
119
-
120
- album.songs.must_equal [
121
- Song.new(1, "The Answer Is Still No"),
122
- Song.new(2, "Invincible")]
123
-
124
- songs.object_id.must_equal album.songs.object_id
125
- songs[0].object_id.must_equal album.songs[0].object_id
126
- songs[1].object_id.must_equal album.songs[1].object_id
127
- }
128
- end
129
-
130
- describe "update existing elements, only" do
131
- representer!(:inject => :song_representer) do
132
- collection :songs,
133
- :instance => lambda { |fragment, i, *args|
134
-
135
- #fragment["id"] == songs[i].id ? songs[i] : Song.find(fragment["id"])
136
- songs.find { |s| s.id == fragment["id"] }
137
- }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync.
138
-
139
- :extend => song_representer,
140
- # :parse_strategy => :sync
141
- :setter => lambda { |*| }
142
- end
143
-
144
- it("hooray") {
145
- album= Struct.new(:songs).new(songs = [
146
- Song.new(1, "The Answer Is Still No"),
147
- Song.new(2, "Invncble")])
148
-
149
- album.
150
- extend(representer).
151
- from_hash("songs" => [{"id" => 2, "title" => "Invincible"}]).
152
- songs.must_equal [
153
- Song.new(1, "The Answer Is Still No"),
154
- Song.new(2, "Invincible")]
155
- # TODO: check elements object_id!
156
-
157
- songs.object_id.must_equal album.songs.object_id
158
- songs[0].object_id.must_equal album.songs[0].object_id
159
- songs[1].object_id.must_equal album.songs[1].object_id
160
- }
161
- end
162
-
163
-
164
- describe "add incoming elements, only" do
165
- representer!(:inject => :song_representer) do
166
- collection :songs,
167
- :instance => lambda { |fragment, i, *args|
168
- songs << song=Song.new(2)
169
- song
170
- }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync.
171
-
172
- :extend => song_representer,
173
- # :parse_strategy => :sync
174
- :setter => lambda { |*| }
175
- end
176
-
177
- it {
178
- album= Struct.new(:songs).new(songs = [
179
- Song.new(1, "The Answer Is Still No")])
180
-
181
- album.
182
- extend(representer).
183
- from_hash("songs" => [{"title" => "Invincible"}]).
184
- songs.must_equal [
185
- Song.new(1, "The Answer Is Still No"),
186
- Song.new(2, "Invincible")]
187
-
188
- songs.object_id.must_equal album.songs.object_id
189
- songs[0].object_id.must_equal album.songs[0].object_id
190
- }
191
- end
192
-
193
-
194
- # not sure if this must be a library strategy
195
- describe "replace existing element" do
196
- representer!(:inject => :song_representer) do
197
- collection :songs,
198
- :instance => lambda { |fragment, i, *args|
199
- id = fragment.delete("replace_id")
200
- replaced = songs.find { |s| s.id == id }
201
- songs[songs.index(replaced)] = song=Song.new(3)
202
- song
203
- }, # let's not allow returning nil anymore. make sure we can still do everything as with nil. also, let's remove parse_strategy: sync.
204
-
205
- :extend => song_representer,
206
- # :parse_strategy => :sync
207
- :setter => lambda { |*| }
208
- end
209
-
210
- it {
211
- album= Struct.new(:songs).new(songs = [
212
- Song.new(1, "The Answer Is Still No"),
213
- Song.new(2, "Invincible")])
214
-
215
- album.
216
- extend(representer).
217
- from_hash("songs" => [{"replace_id"=>2, "id" => 3, "title" => "Soulmate"}]).
218
- songs.must_equal [
219
- Song.new(1, "The Answer Is Still No"),
220
- Song.new(3, "Soulmate")]
221
-
222
- songs.object_id.must_equal album.songs.object_id
223
- songs[0].object_id.must_equal album.songs[0].object_id
224
- }
225
- end
226
-
227
-
228
- describe "replace collection" do
229
- representer!(:inject => :song_representer) do
230
- collection :songs,
231
- :extend => song_representer, :class => Song
232
- end
233
-
234
- it {
235
- album= Struct.new(:songs).new(songs = [
236
- Song.new(1, "The Answer Is Still No")])
237
-
238
- album.
239
- extend(representer).
240
- from_hash("songs" => [{"title" => "Invincible"}]).
241
- songs.must_equal [
242
- Song.new(nil, "Invincible")]
243
-
244
- songs.object_id.wont_equal album.songs.object_id
245
- }
246
- end
247
-
248
-
249
- describe "new syntax for instance: true" do
250
- representer!(:inject => :song_representer) do
251
- property :song, :pass_options => true,
252
- :extend => song_representer, :instance => lambda { |fragment, args| args.binding.get(represented: args.represented) }
253
- end
254
-
255
- it "uses Binding#get instead of creating an instance, but deprecates" do
256
- album= Struct.new(:song).new(song = Song.new(1, "The Answer Is Still No"))
257
-
258
- album.
259
- extend(representer).
260
- from_hash("song" => {"title" => "Invincible"}).
261
- song.must_equal Song.new(1, "Invincible")
262
-
263
- album.song.object_id.must_equal song.object_id
264
- end
265
- end
266
- end
@@ -1,77 +0,0 @@
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
@@ -1,355 +0,0 @@
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