representable 0.10.3 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.textile +4 -0
- data/lib/representable.rb +34 -30
- data/lib/representable/json.rb +2 -2
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +1 -1
- data/test/representable_test.rb +48 -12
- metadata +4 -4
data/CHANGES.textile
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
h2. 0.11.0
|
2
|
+
|
3
|
+
* Representer modules can now be injected into objects using @#extend@.
|
4
|
+
|
1
5
|
h2. 0.10.3
|
2
6
|
|
3
7
|
* Added @representable_property :default => ...@ option which is considered for both serialization and deserialization. The default is applied when the value is @nil@. Note that an empty string ain't @nil@.
|
data/lib/representable.rb
CHANGED
@@ -9,6 +9,14 @@ module Representable
|
|
9
9
|
def self.included(base)
|
10
10
|
base.representable_attrs.push(*representable_attrs) # "inherit".
|
11
11
|
end
|
12
|
+
|
13
|
+
# Copies the representable_attrs to the extended object.
|
14
|
+
def self.extended(object)
|
15
|
+
attrs = representable_attrs
|
16
|
+
object.instance_eval do
|
17
|
+
@representable_attrs = attrs
|
18
|
+
end
|
19
|
+
end
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
@@ -50,6 +58,11 @@ private
|
|
50
58
|
representable_attrs.map {|attr| binding_for_definition(attr) }
|
51
59
|
end
|
52
60
|
|
61
|
+
# Returns the wrapper for the representation. Mostly used in XML.
|
62
|
+
def representation_wrap
|
63
|
+
representable_attrs.wrap_for(self.class.name)
|
64
|
+
end
|
65
|
+
|
53
66
|
|
54
67
|
module ClassMethods # :nodoc:
|
55
68
|
module Declarations
|
@@ -57,11 +70,6 @@ private
|
|
57
70
|
Definition
|
58
71
|
end
|
59
72
|
|
60
|
-
# Returns bindings for all properties.
|
61
|
-
def representable_bindings
|
62
|
-
representable_attrs.map {|attr| binding_for_definition(attr) }
|
63
|
-
end
|
64
|
-
|
65
73
|
# Declares a represented document node, which is usually a XML tag or a JSON key.
|
66
74
|
#
|
67
75
|
# Examples:
|
@@ -100,35 +108,31 @@ private
|
|
100
108
|
|
101
109
|
module Accessors
|
102
110
|
def representable_attrs
|
103
|
-
@representable_attrs ||=
|
104
|
-
end
|
105
|
-
|
106
|
-
def representable_wrap
|
107
|
-
@representable_wrap ||= false
|
108
|
-
end
|
109
|
-
|
110
|
-
def representable_wrap=(name)
|
111
|
-
@representable_wrap = name
|
111
|
+
@representable_attrs ||= Config.new
|
112
112
|
end
|
113
113
|
|
114
114
|
def representation_wrap=(name)
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
# Returns the wrapper for the representation. Mostly used in XML.
|
119
|
-
def representation_wrap
|
120
|
-
return unless representable_wrap
|
121
|
-
return infer_representation_name if representable_wrap === true
|
122
|
-
representable_wrap
|
123
|
-
end
|
124
|
-
|
125
|
-
private
|
126
|
-
def infer_representation_name
|
127
|
-
name.split('::').last.
|
128
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
129
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
130
|
-
downcase
|
115
|
+
representable_attrs.wrap = name
|
131
116
|
end
|
132
117
|
end
|
133
118
|
end
|
119
|
+
|
120
|
+
class Config < Array
|
121
|
+
attr_accessor :wrap
|
122
|
+
|
123
|
+
# Computes the wrap string or returns false.
|
124
|
+
def wrap_for(name)
|
125
|
+
return unless wrap
|
126
|
+
return infer_name_for(name) if wrap === true
|
127
|
+
wrap
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
def infer_name_for(name)
|
132
|
+
name.to_s.split('::').last.
|
133
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
134
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
135
|
+
downcase
|
136
|
+
end
|
137
|
+
end
|
134
138
|
end
|
data/lib/representable/json.rb
CHANGED
@@ -38,7 +38,7 @@ module Representable
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def from_hash(data, options={}, &block)
|
41
|
-
if wrap = options[:wrap] ||
|
41
|
+
if wrap = options[:wrap] || representation_wrap
|
42
42
|
data = data[wrap.to_s]
|
43
43
|
end
|
44
44
|
|
@@ -48,7 +48,7 @@ module Representable
|
|
48
48
|
def to_hash(options={}, &block)
|
49
49
|
hash = create_representation_with({}, &block)
|
50
50
|
|
51
|
-
return hash unless wrap = options[:wrap] ||
|
51
|
+
return hash unless wrap = options[:wrap] || representation_wrap
|
52
52
|
|
53
53
|
{wrap => hash}
|
54
54
|
end
|
data/lib/representable/xml.rb
CHANGED
@@ -47,7 +47,7 @@ module Representable
|
|
47
47
|
|
48
48
|
# Returns a Nokogiri::XML object representing this object.
|
49
49
|
def to_node(options={}, &block)
|
50
|
-
root_tag = options[:wrap] ||
|
50
|
+
root_tag = options[:wrap] || representation_wrap
|
51
51
|
|
52
52
|
create_representation_with(Nokogiri::XML::Node.new(root_tag.to_s, Nokogiri::XML::Document.new), &block)
|
53
53
|
end
|
data/test/representable_test.rb
CHANGED
@@ -77,6 +77,23 @@ 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.
|
80
97
|
end
|
81
98
|
|
82
99
|
|
@@ -123,10 +140,6 @@ class RepresentableTest < MiniTest::Spec
|
|
123
140
|
|
124
141
|
|
125
142
|
describe "#representation_wrap" do
|
126
|
-
class SoundSystem
|
127
|
-
include Representable
|
128
|
-
end
|
129
|
-
|
130
143
|
class HardcoreBand
|
131
144
|
include Representable
|
132
145
|
end
|
@@ -134,23 +147,23 @@ class RepresentableTest < MiniTest::Spec
|
|
134
147
|
class SoftcoreBand < HardcoreBand
|
135
148
|
end
|
136
149
|
|
150
|
+
before do
|
151
|
+
@band = HardcoreBand.new
|
152
|
+
end
|
153
|
+
|
154
|
+
|
137
155
|
it "returns false per default" do
|
138
|
-
assert_equal nil,
|
156
|
+
assert_equal nil, SoftcoreBand.new.send(:representation_wrap)
|
139
157
|
end
|
140
158
|
|
141
159
|
it "infers a printable class name if set to true" do
|
142
160
|
HardcoreBand.representation_wrap = true
|
143
|
-
assert_equal "hardcore_band",
|
161
|
+
assert_equal "hardcore_band", @band.send(:representation_wrap)
|
144
162
|
end
|
145
163
|
|
146
164
|
it "can be set explicitely" do
|
147
165
|
HardcoreBand.representation_wrap = "breach"
|
148
|
-
assert_equal "breach",
|
149
|
-
end
|
150
|
-
|
151
|
-
it "doesn't inherit correctly" do
|
152
|
-
HardcoreBand.representation_wrap = "breach"
|
153
|
-
assert_equal nil, SoftcoreBand.representation_wrap
|
166
|
+
assert_equal "breach", @band.send(:representation_wrap)
|
154
167
|
end
|
155
168
|
end
|
156
169
|
|
@@ -208,4 +221,27 @@ class RepresentableTest < MiniTest::Spec
|
|
208
221
|
end
|
209
222
|
end
|
210
223
|
|
224
|
+
describe "Config" do
|
225
|
+
before do
|
226
|
+
@config = Representable::Config.new
|
227
|
+
PunkRock = Class.new
|
228
|
+
end
|
229
|
+
|
230
|
+
describe "wrapping" do
|
231
|
+
it "returns false per default" do
|
232
|
+
assert_equal nil, @config.wrap_for("Punk")
|
233
|
+
end
|
234
|
+
|
235
|
+
it "infers a printable class name if set to true" do
|
236
|
+
@config.wrap = true
|
237
|
+
assert_equal "punk_rock", @config.wrap_for(PunkRock)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "can be set explicitely" do
|
241
|
+
@config.wrap = "Descendents"
|
242
|
+
assert_equal "Descendents", @config.wrap_for(PunkRock)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
211
247
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 11
|
8
|
+
- 0
|
9
|
+
version: 0.11.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Sutterer
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-12-
|
17
|
+
date: 2011-12-09 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|