representable 0.11.0 → 0.12.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.
- 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
|