representable 2.4.1 → 3.0.0

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 (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