representable 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.textile +7 -0
- data/README.rdoc +60 -36
- data/lib/representable.rb +46 -23
- data/lib/representable/binding.rb +47 -0
- data/lib/representable/bindings/json_bindings.rb +19 -21
- data/lib/representable/bindings/xml_bindings.rb +13 -18
- data/lib/representable/definition.rb +8 -7
- data/lib/representable/json.rb +12 -11
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +10 -10
- data/test/definition_test.rb +10 -3
- data/test/json_test.rb +88 -52
- data/test/representable_test.rb +55 -46
- data/test/test_helper.rb +13 -0
- data/test/xml_test.rb +103 -55
- metadata +4 -3
data/test/representable_test.rb
CHANGED
@@ -3,24 +3,24 @@ require 'test_helper'
|
|
3
3
|
class RepresentableTest < MiniTest::Spec
|
4
4
|
class Band
|
5
5
|
include Representable
|
6
|
-
|
6
|
+
property :name
|
7
7
|
end
|
8
8
|
|
9
9
|
class PunkBand < Band
|
10
|
-
|
10
|
+
property :street_cred
|
11
11
|
end
|
12
12
|
|
13
13
|
module BandRepresentation
|
14
14
|
include Representable
|
15
15
|
|
16
|
-
|
16
|
+
property :name
|
17
17
|
end
|
18
18
|
|
19
19
|
module PunkBandRepresentation
|
20
20
|
include Representable
|
21
21
|
include BandRepresentation
|
22
22
|
|
23
|
-
|
23
|
+
property :street_cred
|
24
24
|
end
|
25
25
|
|
26
26
|
|
@@ -68,7 +68,7 @@ class RepresentableTest < MiniTest::Spec
|
|
68
68
|
# require 'representable/json'
|
69
69
|
# module RockBandRepresentation
|
70
70
|
# include Representable::JSON
|
71
|
-
#
|
71
|
+
# property :name
|
72
72
|
# end
|
73
73
|
# vd = class VH
|
74
74
|
# include RockBandRepresentation
|
@@ -77,27 +77,10 @@ class RepresentableTest < MiniTest::Spec
|
|
77
77
|
# assert_equal "{\"name\":\"Van Halen\"}", vd.to_json
|
78
78
|
#end
|
79
79
|
end
|
80
|
-
|
81
|
-
it "allows adding the representer by using #extend" do
|
82
|
-
module BandRepresenter
|
83
|
-
include Representable::JSON
|
84
|
-
representable_property :name
|
85
|
-
end
|
86
|
-
|
87
|
-
civ = Object.new
|
88
|
-
civ.instance_eval do
|
89
|
-
def name; "CIV"; end
|
90
|
-
end
|
91
|
-
|
92
|
-
civ.extend(BandRepresenter)
|
93
|
-
assert_equal "{\"name\":\"CIV\"}", civ.to_json
|
94
|
-
end
|
95
|
-
|
96
|
-
# TODO: add test for nested setup.
|
97
80
|
end
|
98
81
|
|
99
82
|
|
100
|
-
describe "#
|
83
|
+
describe "#property" do
|
101
84
|
it "creates accessors for the attribute" do
|
102
85
|
@band = PunkBand.new
|
103
86
|
assert @band.name = "Bad Religion"
|
@@ -107,19 +90,19 @@ class RepresentableTest < MiniTest::Spec
|
|
107
90
|
describe ":from" do
|
108
91
|
# TODO: do this with all options.
|
109
92
|
it "can be set explicitly" do
|
110
|
-
band = Class.new(Band) {
|
93
|
+
band = Class.new(Band) { property :friends, :from => :friend }
|
111
94
|
assert_equal "friend", band.representable_attrs.last.from
|
112
95
|
end
|
113
96
|
|
114
97
|
it "is infered from the name implicitly" do
|
115
|
-
band = Class.new(Band) {
|
98
|
+
band = Class.new(Band) { property :friends }
|
116
99
|
assert_equal "friends", band.representable_attrs.last.from
|
117
100
|
end
|
118
101
|
end
|
119
102
|
|
120
103
|
describe ":accessor" do
|
121
104
|
it "doesn't add methods when false" do
|
122
|
-
klass = Class.new(Band) {
|
105
|
+
klass = Class.new(Band) { property :friends, :accessors => false }
|
123
106
|
band = klass.new
|
124
107
|
assert ! band.respond_to?(:friends)
|
125
108
|
assert ! band.respond_to?("friends=")
|
@@ -127,9 +110,9 @@ class RepresentableTest < MiniTest::Spec
|
|
127
110
|
end
|
128
111
|
end
|
129
112
|
|
130
|
-
describe "#
|
113
|
+
describe "#collection" do
|
131
114
|
class RockBand < Band
|
132
|
-
|
115
|
+
collection :albums
|
133
116
|
end
|
134
117
|
|
135
118
|
it "creates correct Definition" do
|
@@ -178,30 +161,35 @@ class RepresentableTest < MiniTest::Spec
|
|
178
161
|
require 'representable/json' # DISCUSS: i don't like the JSON requirement here, what about some generic test module?
|
179
162
|
class PopBand
|
180
163
|
include Representable::JSON
|
181
|
-
|
182
|
-
|
164
|
+
property :name
|
165
|
+
property :groupies
|
183
166
|
end
|
184
167
|
|
185
168
|
describe "#update_properties_from" do
|
169
|
+
before do
|
170
|
+
@band = PopBand.new
|
171
|
+
end
|
172
|
+
|
186
173
|
it "copies values from document to object" do
|
187
|
-
band
|
188
|
-
|
189
|
-
assert_equal
|
190
|
-
assert_equal 2, band.groupies
|
174
|
+
@band.update_properties_from({"name"=>"No One's Choice", "groupies"=>2}, {})
|
175
|
+
assert_equal "No One's Choice", @band.name
|
176
|
+
assert_equal 2, @band.groupies
|
191
177
|
end
|
192
178
|
|
193
|
-
it "
|
194
|
-
band
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
179
|
+
it "accepts :except option" do
|
180
|
+
@band.update_properties_from({"name"=>"No One's Choice", "groupies"=>2}, :except => [:groupies])
|
181
|
+
assert_equal "No One's Choice", @band.name
|
182
|
+
assert_equal nil, @band.groupies
|
183
|
+
end
|
184
|
+
|
185
|
+
it "accepts :include option" do
|
186
|
+
@band.update_properties_from({"name"=>"No One's Choice", "groupies"=>2}, :include => [:groupies])
|
187
|
+
assert_equal 2, @band.groupies
|
188
|
+
assert_equal nil, @band.name
|
200
189
|
end
|
201
190
|
|
202
191
|
it "always returns self" do
|
203
|
-
band
|
204
|
-
assert_equal band, band.update_properties_from({"name"=>"Nofx"})
|
192
|
+
assert_equal @band, @band.update_properties_from({"name"=>"Nofx"}, {})
|
205
193
|
end
|
206
194
|
end
|
207
195
|
|
@@ -213,14 +201,21 @@ class RepresentableTest < MiniTest::Spec
|
|
213
201
|
end
|
214
202
|
|
215
203
|
it "compiles document from properties in object" do
|
216
|
-
assert_equal({"name"=>"No One's Choice", "groupies"=>2}, @band.send(:create_representation_with, {}))
|
204
|
+
assert_equal({"name"=>"No One's Choice", "groupies"=>2}, @band.send(:create_representation_with, {}, {}))
|
205
|
+
end
|
206
|
+
|
207
|
+
it "accepts :except option" do
|
208
|
+
hash = @band.send(:create_representation_with, {}, :except => [:groupies])
|
209
|
+
assert_equal({"name"=>"No One's Choice"}, hash)
|
217
210
|
end
|
218
211
|
|
219
|
-
it "
|
220
|
-
|
212
|
+
it "accepts :include option" do
|
213
|
+
hash = @band.send(:create_representation_with, {}, :include => [:groupies])
|
214
|
+
assert_equal({"groupies"=>2}, hash)
|
221
215
|
end
|
222
216
|
end
|
223
217
|
|
218
|
+
|
224
219
|
describe "Config" do
|
225
220
|
before do
|
226
221
|
@config = Representable::Config.new
|
@@ -244,4 +239,18 @@ class RepresentableTest < MiniTest::Spec
|
|
244
239
|
end
|
245
240
|
end
|
246
241
|
|
242
|
+
describe "Represents" do
|
243
|
+
before do
|
244
|
+
@class = Class.new do
|
245
|
+
extend Representable::Represents
|
246
|
+
represents :json, :with => :whatever
|
247
|
+
represents "application/order-json", :with => :special
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
it "allows mapping formats to representers" do
|
252
|
+
assert_equal :whatever, @class.representer[:json]
|
253
|
+
assert_equal :special, @class.representer["application/order-json"]
|
254
|
+
end
|
255
|
+
end
|
247
256
|
end
|
data/test/test_helper.rb
CHANGED
@@ -8,3 +8,16 @@ require 'minitest/spec'
|
|
8
8
|
require 'minitest/autorun'
|
9
9
|
require 'test_xml/mini_test'
|
10
10
|
require 'mocha'
|
11
|
+
|
12
|
+
class Album
|
13
|
+
def initialize(*songs)
|
14
|
+
@songs = songs
|
15
|
+
@best_song = songs.last
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Song
|
20
|
+
def initialize(name=nil)
|
21
|
+
@name = name
|
22
|
+
end
|
23
|
+
end
|
data/test/xml_test.rb
CHANGED
@@ -3,21 +3,14 @@ require 'representable/xml'
|
|
3
3
|
|
4
4
|
class Band
|
5
5
|
include Representable::XML
|
6
|
-
|
6
|
+
property :name
|
7
7
|
|
8
8
|
def initialize(name=nil)
|
9
9
|
name and self.name = name
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
include Representable::XML
|
15
|
-
representable_property :band, :as => Band
|
16
|
-
|
17
|
-
def initialize(band=nil)
|
18
|
-
band and self.band = band
|
19
|
-
end
|
20
|
-
end
|
13
|
+
|
21
14
|
|
22
15
|
|
23
16
|
class XmlTest < MiniTest::Spec
|
@@ -29,8 +22,8 @@ class XmlTest < MiniTest::Spec
|
|
29
22
|
@Band = Class.new do
|
30
23
|
include Representable::XML
|
31
24
|
self.representation_wrap = :band
|
32
|
-
|
33
|
-
|
25
|
+
property :name
|
26
|
+
property :label
|
34
27
|
end
|
35
28
|
|
36
29
|
@band = @Band.new
|
@@ -39,18 +32,34 @@ class XmlTest < MiniTest::Spec
|
|
39
32
|
|
40
33
|
describe ".from_xml" do
|
41
34
|
it "is delegated to #from_xml" do
|
42
|
-
block = lambda {|
|
43
|
-
@Band.any_instance.expects(:from_xml).with("
|
44
|
-
@Band.from_xml("
|
35
|
+
block = lambda {|*args|}
|
36
|
+
@Band.any_instance.expects(:from_xml).with("<document>", "options") # FIXME: how to NOT expect block?
|
37
|
+
@Band.from_xml("<document>", "options", &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "yields new object and options to block" do
|
41
|
+
@Band.class_eval { attr_accessor :new_name }
|
42
|
+
@band = @Band.from_xml("<band/>", :new_name => "Diesel Boy") do |band, options|
|
43
|
+
band.new_name= options[:new_name]
|
44
|
+
end
|
45
|
+
assert_equal "Diesel Boy", @band.new_name
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
48
49
|
|
49
50
|
describe ".from_node" do
|
50
51
|
it "is delegated to #from_node" do
|
51
|
-
block = lambda {|
|
52
|
-
@Band.any_instance.expects(:from_node).with("
|
53
|
-
@Band.from_node("
|
52
|
+
block = lambda {|*args|}
|
53
|
+
@Band.any_instance.expects(:from_node).with("<document>", "options") # FIXME: how to expect block?
|
54
|
+
@Band.from_node("<document>", "options", &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "yields new object and options to block" do
|
58
|
+
@Band.class_eval { attr_accessor :new_name }
|
59
|
+
@band = @Band.from_node(Nokogiri::XML("<band/>"), :new_name => "Diesel Boy") do |band, options|
|
60
|
+
band.new_name= options[:new_name]
|
61
|
+
end
|
62
|
+
assert_equal "Diesel Boy", @band.new_name
|
54
63
|
end
|
55
64
|
end
|
56
65
|
|
@@ -65,14 +74,6 @@ class XmlTest < MiniTest::Spec
|
|
65
74
|
@band.from_xml(@xml)
|
66
75
|
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
67
76
|
end
|
68
|
-
|
69
|
-
it "forwards block to #from_node" do
|
70
|
-
@band.from_xml(@xml) do |name|
|
71
|
-
name == :name
|
72
|
-
end
|
73
|
-
|
74
|
-
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
75
|
-
end
|
76
77
|
end
|
77
78
|
|
78
79
|
|
@@ -86,14 +87,6 @@ class XmlTest < MiniTest::Spec
|
|
86
87
|
@band.from_node(@xml)
|
87
88
|
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
88
89
|
end
|
89
|
-
|
90
|
-
it "forwards block to #update_properties_from" do
|
91
|
-
@band.from_node(@xml) do |name|
|
92
|
-
name == :name
|
93
|
-
end
|
94
|
-
|
95
|
-
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
96
|
-
end
|
97
90
|
end
|
98
91
|
|
99
92
|
|
@@ -101,17 +94,6 @@ class XmlTest < MiniTest::Spec
|
|
101
94
|
it "delegates to #to_node and returns string" do
|
102
95
|
assert_xml_equal "<band><name>Rise Against</name></band>", Band.new("Rise Against").to_xml
|
103
96
|
end
|
104
|
-
|
105
|
-
it "forwards block to #to_node" do
|
106
|
-
band = @Band.new
|
107
|
-
band.name = "The Guinea Pigs"
|
108
|
-
band.label = "n/a"
|
109
|
-
xml = band.to_xml do |name|
|
110
|
-
name == :name
|
111
|
-
end
|
112
|
-
|
113
|
-
assert_xml_equal "<band><name>The Guinea Pigs</name></band>", xml
|
114
|
-
end
|
115
97
|
end
|
116
98
|
|
117
99
|
|
@@ -129,7 +111,7 @@ class XmlTest < MiniTest::Spec
|
|
129
111
|
it "respects #representation_wrap=" do
|
130
112
|
klass = Class.new(Band) do
|
131
113
|
include Representable
|
132
|
-
|
114
|
+
property :name
|
133
115
|
end
|
134
116
|
|
135
117
|
klass.representation_wrap = :group
|
@@ -144,13 +126,64 @@ class XmlTest < MiniTest::Spec
|
|
144
126
|
end
|
145
127
|
|
146
128
|
it "returns ObjectBinding" do
|
147
|
-
assert_kind_of XML::ObjectBinding, @band.binding_for_definition(Def.new(:band, :
|
129
|
+
assert_kind_of XML::ObjectBinding, @band.binding_for_definition(Def.new(:band, :class => Hash))
|
148
130
|
end
|
149
131
|
|
150
132
|
it "returns TextBinding" do
|
151
133
|
assert_kind_of XML::TextBinding, @band.binding_for_definition(Def.new(:band, :from => :content))
|
152
134
|
end
|
153
135
|
end
|
136
|
+
|
137
|
+
|
138
|
+
describe "DCI" do
|
139
|
+
module SongRepresenter
|
140
|
+
include Representable::XML
|
141
|
+
property :name
|
142
|
+
representation_wrap = :song
|
143
|
+
end
|
144
|
+
|
145
|
+
module AlbumRepresenter
|
146
|
+
include Representable::XML
|
147
|
+
property :best_song, :class => Song, :extend => SongRepresenter
|
148
|
+
collection :songs, :class => Song, :from => :song, :extend => SongRepresenter
|
149
|
+
representation_wrap = :album
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
it "allows adding the representer by using #extend" do
|
154
|
+
module BandRepresenter
|
155
|
+
include Representable::XML
|
156
|
+
property :name
|
157
|
+
end
|
158
|
+
|
159
|
+
civ = Object.new
|
160
|
+
civ.instance_eval do
|
161
|
+
def name; "CIV"; end
|
162
|
+
end
|
163
|
+
|
164
|
+
civ.extend(BandRepresenter)
|
165
|
+
assert_xml_equal "<object><name>CIV</name></object>", civ.to_xml
|
166
|
+
end
|
167
|
+
|
168
|
+
it "extends contained models when serializing" do
|
169
|
+
@album = Album.new(Song.new("I Hate My Brain"), Song.new("Mr. Charisma"))
|
170
|
+
@album.extend(AlbumRepresenter)
|
171
|
+
|
172
|
+
assert_xml_equal "<album>
|
173
|
+
<song><name>Mr. Charisma</name></song>
|
174
|
+
<song><name>I Hate My Brain</name></song>
|
175
|
+
<song><name>Mr. Charisma</name></song>
|
176
|
+
</album>", @album.to_xml
|
177
|
+
end
|
178
|
+
|
179
|
+
it "extends contained models when deserializing" do
|
180
|
+
@album = Album.new
|
181
|
+
@album.extend(AlbumRepresenter)
|
182
|
+
|
183
|
+
@album.from_xml("<album><best_song><name>Mr. Charisma</name></best_song><song><name>I Hate My Brain</name></song><song><name>Mr. Charisma</name></song></album>")
|
184
|
+
assert_equal "Mr. Charisma", @album.best_song.name
|
185
|
+
end
|
186
|
+
end
|
154
187
|
end
|
155
188
|
end
|
156
189
|
|
@@ -159,8 +192,8 @@ class AttributesTest < MiniTest::Spec
|
|
159
192
|
describe ":from => @rel" do
|
160
193
|
class Link
|
161
194
|
include Representable::XML
|
162
|
-
|
163
|
-
|
195
|
+
property :href, :from => "@href"
|
196
|
+
property :title, :from => "@title"
|
164
197
|
end
|
165
198
|
|
166
199
|
it "#from_xml creates correct accessors" do
|
@@ -181,9 +214,24 @@ class AttributesTest < MiniTest::Spec
|
|
181
214
|
end
|
182
215
|
|
183
216
|
class TypedPropertyTest < MiniTest::Spec
|
184
|
-
|
217
|
+
module AlbumRepresenter
|
218
|
+
include Representable::XML
|
219
|
+
property :band, :class => Band
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
class Album
|
224
|
+
def initialize(band=nil)
|
225
|
+
@band = band
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# TODO:property :group, :class => Band
|
230
|
+
# :class
|
231
|
+
# where to mixin DCI?
|
232
|
+
describe ":class => Item" do
|
185
233
|
it "#from_xml creates one Item instance" do
|
186
|
-
album = Album.from_xml(%{
|
234
|
+
album = Album.new.extend(AlbumRepresenter).from_xml(%{
|
187
235
|
<album>
|
188
236
|
<band><name>Bad Religion</name></band>
|
189
237
|
</album>
|
@@ -194,7 +242,7 @@ class TypedPropertyTest < MiniTest::Spec
|
|
194
242
|
describe "#to_xml" do
|
195
243
|
it "doesn't escape xml from Band#to_xml" do
|
196
244
|
band = Band.new("Bad Religion")
|
197
|
-
album = Album.new(band)
|
245
|
+
album = Album.new(band).extend(AlbumRepresenter)
|
198
246
|
|
199
247
|
assert_xml_equal %{<album>
|
200
248
|
<band>
|
@@ -211,7 +259,7 @@ class TypedPropertyTest < MiniTest::Spec
|
|
211
259
|
end
|
212
260
|
end
|
213
261
|
|
214
|
-
assert_xml_equal %{<album><band>Baaaad Religion</band></album>}, Album.new(band).to_xml
|
262
|
+
assert_xml_equal %{<album><band>Baaaad Religion</band></album>}, Album.new(band).extend(AlbumRepresenter).to_xml
|
215
263
|
end
|
216
264
|
end
|
217
265
|
end
|
@@ -219,10 +267,10 @@ end
|
|
219
267
|
|
220
268
|
|
221
269
|
class CollectionTest < MiniTest::Spec
|
222
|
-
describe ":
|
270
|
+
describe ":class => Band, :from => :band, :collection => true" do
|
223
271
|
class Compilation
|
224
272
|
include Representable::XML
|
225
|
-
|
273
|
+
collection :bands, :class => Band, :from => :band
|
226
274
|
end
|
227
275
|
|
228
276
|
describe "#from_xml" do
|
@@ -260,7 +308,7 @@ class CollectionTest < MiniTest::Spec
|
|
260
308
|
describe ":from" do
|
261
309
|
class Album
|
262
310
|
include Representable::XML
|
263
|
-
|
311
|
+
collection :songs, :from => :song
|
264
312
|
end
|
265
313
|
|
266
314
|
it "collects untyped items" do
|