representable 0.10.0 → 0.10.1
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 +5 -0
- data/README.rdoc +164 -48
- data/lib/representable.rb +17 -10
- data/lib/representable/json.rb +6 -5
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +1 -0
- data/test/json_test.rb +84 -80
- data/test/representable_test.rb +3 -3
- data/test/test_helper.rb +2 -0
- data/test/xml_test.rb +6 -6
- metadata +80 -111
data/CHANGES.textile
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
h2. 0.10.1
|
2
|
+
|
3
|
+
* The block in @to_*@ and @from_*@ now yields the symbolized property name. If you need the binding/definition you gotta get it yourself.
|
4
|
+
* Runs with Ruby 1.8 and 1.9.
|
5
|
+
|
1
6
|
h2. 0.10.0
|
2
7
|
|
3
8
|
* Wrapping can now be set through @Representable.representation_wrap=@. Possible values are:
|
data/README.rdoc
CHANGED
@@ -5,9 +5,9 @@
|
|
5
5
|
|
6
6
|
== Introduction
|
7
7
|
|
8
|
-
_Representable_ maps fragments in documents to attributes in Ruby objects and back. It allows parsing representations
|
8
|
+
_Representable_ maps fragments in documents to attributes in Ruby objects and back. It allows parsing representations giving an object-oriented interface to the document. But that's only half of it! Representable can also render documents from an object instance.
|
9
9
|
|
10
|
-
This
|
10
|
+
This keeps your representation knowledge in one place when implementing REST services and clients.
|
11
11
|
|
12
12
|
|
13
13
|
== Features
|
@@ -19,86 +19,202 @@ This is especially helpful when implementing REST services and clients and keeps
|
|
19
19
|
|
20
20
|
== Example
|
21
21
|
|
22
|
+
Since you keep forgetting the heroes of your childhood you decide to implement a REST service for storing and querying those. You choose representable for handling representations.
|
22
23
|
|
24
|
+
gem 'representable'
|
23
25
|
|
24
|
-
When writing a REST service you'd have to parse and extract data from an incoming representation document manually. Given the following XML document which represents an order.
|
25
26
|
|
26
|
-
|
27
|
-
<id>1</id>
|
28
|
-
<item>
|
29
|
-
<name>Chocolate Cookie</name>
|
30
|
-
</item>
|
31
|
-
<item>
|
32
|
-
<name>Vanilla Muffin</name>
|
33
|
-
</item>
|
34
|
-
</order>
|
27
|
+
== Defining Representations
|
35
28
|
|
36
|
-
|
29
|
+
require 'representable/json'
|
37
30
|
|
38
|
-
class
|
39
|
-
include Representable::
|
31
|
+
class Hero
|
32
|
+
include Representable::JSON
|
40
33
|
|
41
|
-
representable_property :
|
42
|
-
|
34
|
+
representable_property :forename
|
35
|
+
representable_property :surename
|
43
36
|
end
|
37
|
+
|
38
|
+
This declares two simple properties. Representable will automatically add accessors to the class.
|
39
|
+
|
40
|
+
== Rendering
|
41
|
+
|
42
|
+
Now let's create and render our first hero.
|
43
|
+
|
44
|
+
peter = Hero.new
|
45
|
+
peter.forename = "Peter"
|
46
|
+
peter.surename = "Pan"
|
47
|
+
|
48
|
+
peter.to_json
|
49
|
+
#=> {"forename":"Peter","surename":"Pan"}
|
50
|
+
|
51
|
+
Those two properties are considered when rendering in #to_json.
|
52
|
+
|
53
|
+
== Parsing
|
54
|
+
|
55
|
+
The cool thing about Representable is: it works bidirectional. By declaring properties you can not only render but also parse!
|
56
|
+
|
57
|
+
hook = Hero.from_json('{"forename":"Captain","surename":"Hook"}')
|
58
|
+
hook.forename #=> "Captain"
|
44
59
|
|
45
|
-
|
46
|
-
|
60
|
+
See how easy this is? You can use an object-oriented method to read from the document.
|
61
|
+
|
62
|
+
== Nesting
|
63
|
+
|
64
|
+
You need a second domain object. Every hero has a place he comes from.
|
65
|
+
|
66
|
+
class Location
|
67
|
+
include Representable::JSON
|
47
68
|
|
48
|
-
representable_property :
|
69
|
+
representable_property :title
|
49
70
|
end
|
50
|
-
|
51
|
-
== Consuming Representations
|
52
71
|
|
53
|
-
|
72
|
+
Peter, where ya' from?
|
73
|
+
|
74
|
+
neverland = Location.new
|
75
|
+
neverland.title = "Neverland"
|
76
|
+
|
77
|
+
It makes sense to embed the location in the hero's document.
|
54
78
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@order.items.first.name # => "Chocolate Cookie"
|
79
|
+
class Hero
|
80
|
+
representable_property :origin, :as => Location
|
81
|
+
end
|
59
82
|
|
83
|
+
Using the +:as+ option allows you to include other representable objects.
|
60
84
|
|
61
|
-
|
85
|
+
peter.origin = neverland
|
86
|
+
peter.to_json
|
87
|
+
#=> {"forename":"Peter","surename":"Pan","origin":{"title":"Neverland"}}
|
62
88
|
|
63
|
-
The cool thing with object-oriented representations is: you can treat them just like any other object in Ruby and extend them dynamically - which is impossible with plain hashes.
|
64
89
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
90
|
+
== Parsing Nested Documents
|
91
|
+
|
92
|
+
Don't forget how easy it is to parse nested representations.
|
93
|
+
|
94
|
+
hook = Hero.from_json('{"name":"Captain","surename":"Hook","origin":{"title":"Dark Ocean"}}')
|
95
|
+
hook.origin.inspect #=> #<Location:0x910d7c8 @title="Dark Ocean">
|
96
|
+
hook.origin.title #=> "Dark Ocean"
|
97
|
+
|
98
|
+
Representable just creates objects from the parsed document - nothing more and nothing less.
|
99
|
+
|
100
|
+
== Simple Collections
|
101
|
+
|
102
|
+
Heroes have features, special abilities that make 'em a superhero.
|
103
|
+
|
104
|
+
class Hero
|
105
|
+
representable_collection :features
|
106
|
+
end
|
107
|
+
|
108
|
+
The second API method is +representable_collection+ and, well, declares a collection.
|
109
|
+
|
110
|
+
peter.features = ["stays young", "can fly"]
|
111
|
+
peter.to_json
|
112
|
+
#=> {"forename":"Peter","surename":"Pan","origin":{"title":"Neverland"},"features":["stays young","can fly"]}
|
113
|
+
|
114
|
+
|
115
|
+
== Typed Collections
|
71
116
|
|
117
|
+
Ok, things start working out. Your hero has a name, an origin and a list of features so far. Why not allows adding friends to Peter - nobody wants to be alone!
|
72
118
|
|
73
|
-
|
119
|
+
class Hero
|
120
|
+
representable_collection :friends, :as => Hero
|
121
|
+
end
|
122
|
+
|
123
|
+
Again, we type the collection by using the +:as+ option.
|
124
|
+
|
125
|
+
nick = Hero.new
|
126
|
+
nick.forename = "Nick"
|
127
|
+
|
128
|
+
el = Hero.new
|
129
|
+
el.forename = "El"
|
130
|
+
|
131
|
+
peter.friends = [nick, el]
|
132
|
+
|
133
|
+
I always wanted to be Peter's bro... in this example it is possible!
|
134
|
+
|
135
|
+
peter.to_json
|
136
|
+
#=> {"forename":"Peter","surename":"Pan","origin":{"title":"Neverland"},"features":["stays young","can fly"],"friends":[{"name":"Nick"},{"name":"El"}]}
|
137
|
+
|
138
|
+
|
139
|
+
== Customizing
|
140
|
+
|
141
|
+
=== Wrapping
|
142
|
+
|
143
|
+
Representable is designed to be very simple. However, a few tweaks are available. What if you want to wrap your document?
|
144
|
+
|
145
|
+
class Hero
|
146
|
+
self.representation_wrap = true
|
147
|
+
end
|
148
|
+
|
149
|
+
peter.to_json #=> {"hero":{"name":"Peter","surename":"Pan"}}
|
150
|
+
|
151
|
+
You can also provide a custom wrapper.
|
74
152
|
|
75
|
-
|
153
|
+
class Hero
|
154
|
+
self.representation_wrap = :boy
|
155
|
+
end
|
156
|
+
|
157
|
+
peter.to_json #=> {"boy":{"name":"Peter","surename":"Pan"}}
|
158
|
+
|
159
|
+
|
160
|
+
=== Mapping
|
76
161
|
|
77
|
-
|
162
|
+
If your accessor name doesn't match the attribute name in the document, use the +:from+ matcher.
|
163
|
+
|
164
|
+
class Hero
|
165
|
+
representable_property :forename, :from => :name
|
166
|
+
end
|
78
167
|
|
79
|
-
|
168
|
+
peter.to_json #=> {"name":"Peter","surename":"Pan"}
|
80
169
|
|
81
|
-
Order.new(:id => 2, :items => [candy]).to_xml
|
82
170
|
|
171
|
+
=== Filtering
|
83
172
|
|
84
|
-
Representable
|
173
|
+
Representable allows you to skip properties when rendering or parsing.
|
85
174
|
|
175
|
+
peter.to_json do |name|
|
176
|
+
name == :forename
|
177
|
+
end
|
86
178
|
|
87
|
-
|
179
|
+
#=> {"forename":"Peter"}
|
88
180
|
|
89
|
-
|
181
|
+
|
182
|
+
== XML support
|
183
|
+
|
184
|
+
Representable allows declaring a document's syntax and structure while having different formats. Currently, it ships with JSON and XML bindings.
|
185
|
+
|
186
|
+
class Hero
|
187
|
+
include Representable::XML
|
188
|
+
end
|
189
|
+
|
190
|
+
peter.to_xml
|
191
|
+
#=> <hero>
|
192
|
+
<name>Peter</name>
|
193
|
+
<surename>Pan</surename>
|
194
|
+
<location>
|
195
|
+
<title>Neverland</title>
|
196
|
+
</location>
|
197
|
+
<hero>
|
198
|
+
<name>Nick</name>
|
199
|
+
</hero>
|
200
|
+
<hero>
|
201
|
+
<name>El</name>
|
202
|
+
</hero>
|
203
|
+
</hero>
|
204
|
+
|
205
|
+
The #to_xml method gives us an XML representation of Peter - great!
|
90
206
|
|
91
207
|
|
92
208
|
== More
|
93
209
|
|
94
|
-
|
210
|
+
Instead of spreading knowledge about your representations about the entire framework, Representable keeps rendering and parsing representations in one single, testable asset. It is a new abstraction layer missing in many "RESTful" frameworks.
|
95
211
|
|
96
|
-
Representable
|
212
|
+
Representable was written with REST representations in mind. However, it is a generic module for working with documents. If you do consider using it for a REST project, check out the {Roar framework}[http://github.com/apotonick/roar], which comes with representers, built-in hypermedia support and more. It internally uses Representable and streamlines the process for building hypermedia-driven REST applications.
|
97
213
|
|
98
214
|
|
99
215
|
== Copyright
|
100
216
|
|
101
|
-
Representable is a simplified fork of the ROXML gem. Big thanks to Ben Woosley for his work.
|
217
|
+
Representable is a heavily simplified fork of the ROXML gem. Big thanks to Ben Woosley for his work.
|
102
218
|
|
103
|
-
Copyright (c) 2011 Nick Sutterer <apotonick@gmail.com>
|
104
|
-
Copyright (c) 2004-2009 Ben Woosley, Zak Mandhro and Anders Engstrom.
|
219
|
+
* Copyright (c) 2011 Nick Sutterer <apotonick@gmail.com>
|
220
|
+
* Copyright (c) 2004-2009 Ben Woosley, Zak Mandhro and Anders Engstrom.
|
data/lib/representable.rb
CHANGED
@@ -16,28 +16,35 @@ module Representable
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Reads values from +doc+ and sets properties accordingly.
|
19
|
-
def update_properties_from(doc)
|
20
|
-
self.class.representable_bindings.each do |
|
21
|
-
next if
|
19
|
+
def update_properties_from(doc, &block)
|
20
|
+
self.class.representable_bindings.each do |bin|
|
21
|
+
next if eval_property_block(bin, &block) # skip if block is false.
|
22
22
|
|
23
|
-
value =
|
24
|
-
send(
|
23
|
+
value = bin.read(doc)
|
24
|
+
send(bin.definition.setter, value)
|
25
25
|
end
|
26
26
|
self
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
# Compiles the document going through all properties.
|
31
|
-
def create_representation_with(doc)
|
32
|
-
self.class.representable_bindings.each do |
|
33
|
-
next if
|
31
|
+
def create_representation_with(doc, &block)
|
32
|
+
self.class.representable_bindings.each do |bin|
|
33
|
+
next if eval_property_block(bin, &block) # skip if block is false.
|
34
34
|
|
35
|
-
value =
|
36
|
-
|
35
|
+
value = send(bin.definition.getter) # DISCUSS: eventually move back to Ref.
|
36
|
+
bin.write(doc, value) if value
|
37
37
|
end
|
38
38
|
doc
|
39
39
|
end
|
40
40
|
|
41
|
+
# Returns true unless a eventually given block returns false. Yields the symbolized
|
42
|
+
# property name.
|
43
|
+
def eval_property_block(binding)
|
44
|
+
# TODO: no magic symbol conversion!
|
45
|
+
block_given? and not yield binding.definition.name.to_sym
|
46
|
+
end
|
47
|
+
|
41
48
|
|
42
49
|
module ClassMethods # :nodoc:
|
43
50
|
module Declarations
|
data/lib/representable/json.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'representable'
|
2
2
|
require 'representable/bindings/json_bindings'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Representable
|
5
6
|
# Brings #to_xml, #to_hash, #from_xml and #from_hash to your object.
|
@@ -48,8 +49,8 @@ module Representable
|
|
48
49
|
update_properties_from(data, &block)
|
49
50
|
end
|
50
51
|
|
51
|
-
def to_hash(options={})
|
52
|
-
hash = create_representation_with({})
|
52
|
+
def to_hash(options={}, &block)
|
53
|
+
hash = create_representation_with({}, &block)
|
53
54
|
|
54
55
|
return hash unless wrap = options[:wrap] || self.class.representation_wrap
|
55
56
|
|
@@ -57,8 +58,8 @@ module Representable
|
|
57
58
|
end
|
58
59
|
|
59
60
|
# Returns a JSON string representing this object.
|
60
|
-
def to_json(
|
61
|
-
to_hash(
|
61
|
+
def to_json(*args, &block)
|
62
|
+
to_hash(*args, &block).to_json
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
data/lib/representable/xml.rb
CHANGED
data/test/json_test.rb
CHANGED
@@ -8,142 +8,146 @@ module JsonTest
|
|
8
8
|
|
9
9
|
describe "JSON module" do
|
10
10
|
before do
|
11
|
-
@Band = Class.new
|
11
|
+
@Band = Class.new do
|
12
|
+
include Representable::JSON
|
13
|
+
representable_property :name
|
12
14
|
representable_property :label
|
15
|
+
|
16
|
+
def initialize(name=nil)
|
17
|
+
self.name = name if name
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
it "returns ObjectBinding" do
|
23
|
-
assert_kind_of Json::ObjectBinding, Band.binding_for_definition(Def.new(:band, :as => Hash))
|
24
|
-
end
|
25
|
-
|
26
|
-
it "returns TextBinding" do
|
27
|
-
assert_kind_of Json::TextBinding, Band.binding_for_definition(Def.new(:band))
|
21
|
+
|
22
|
+
|
23
|
+
describe ".from_json" do
|
24
|
+
it "is delegated to #from_json" do
|
25
|
+
block = lambda {|bind|}
|
26
|
+
@Band.any_instance.expects(:from_json).with("{}", "yo") # FIXME: how to expect block?
|
27
|
+
@Band.from_json("{}", "yo", &block)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
|
32
|
+
describe ".from_hash" do
|
33
|
+
it "is delegated to #from_hash" do
|
34
|
+
block = lambda {|bind|}
|
35
|
+
@Band.any_instance.expects(:from_hash).with("{}", "yo") # FIXME: how to expect block?
|
36
|
+
@Band.from_hash("{}", "yo", &block)
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
40
|
+
|
38
41
|
describe "#from_json" do
|
39
42
|
before do
|
40
43
|
@band = @Band.new
|
44
|
+
@json = {:name => "Nofx", :label => "NOFX"}.to_json
|
41
45
|
end
|
42
46
|
|
43
|
-
it "
|
44
|
-
@band.from_json(
|
47
|
+
it "parses JSON and assigns properties" do
|
48
|
+
@band.from_json(@json)
|
45
49
|
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
46
50
|
end
|
47
51
|
|
48
|
-
it "forwards block to #
|
49
|
-
@band.from_json(
|
50
|
-
|
52
|
+
it "forwards block to #from_hash" do
|
53
|
+
@band.from_json(@json) do |name|
|
54
|
+
name == :name
|
51
55
|
end
|
52
56
|
|
53
57
|
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
54
58
|
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
describe "#from_hash" do
|
63
|
+
before do
|
64
|
+
@band = @Band.new
|
65
|
+
@hash = {"name" => "Nofx", "label" => "NOFX"}
|
66
|
+
end
|
55
67
|
|
68
|
+
it "receives hash and assigns properties" do
|
69
|
+
@band.from_hash(@hash)
|
70
|
+
assert_equal ["Nofx", "NOFX"], [@band.name, @band.label]
|
71
|
+
end
|
56
72
|
|
57
|
-
it "
|
58
|
-
@band.
|
59
|
-
|
73
|
+
it "forwards block to #update_properties_from" do
|
74
|
+
@band.from_hash(@hash) do |name|
|
75
|
+
name == :name
|
76
|
+
end
|
77
|
+
|
78
|
+
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
60
79
|
end
|
61
80
|
|
62
81
|
it "respects :wrap option" do
|
63
|
-
@band.
|
82
|
+
@band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band)
|
64
83
|
assert_equal "This Is A Standoff", @band.name
|
65
84
|
end
|
66
|
-
|
85
|
+
|
67
86
|
it "respects :wrap option over representation_wrap" do
|
68
87
|
@Band.class_eval do
|
69
88
|
self.representation_wrap = :group
|
70
89
|
end
|
71
|
-
@band.
|
72
|
-
assert_equal "This Is A Standoff", @band.name
|
73
|
-
end
|
74
|
-
|
75
|
-
it "respects representation_wrap" do
|
76
|
-
@Band.class_eval do
|
77
|
-
self.representation_wrap = :group
|
78
|
-
end
|
79
|
-
@band.from_json({:group => {:name => "This Is A Standoff"}}.to_json)
|
90
|
+
@band.from_hash({"band" => {"name" => "This Is A Standoff"}}, :wrap => :band)
|
80
91
|
assert_equal "This Is A Standoff", @band.name
|
81
92
|
end
|
82
93
|
end
|
83
94
|
|
84
95
|
|
85
|
-
describe "
|
86
|
-
it "delegates to #
|
87
|
-
|
88
|
-
assert_equal ["Nofx", nil], [band.name, band.label]
|
89
|
-
end
|
90
|
-
|
91
|
-
it "passes all args to #from_json" do
|
92
|
-
block = lambda {|a,b|}
|
93
|
-
@Band.any_instance.expects(:from_json).with("{}", "yo") # FIXME: how to expect block?
|
94
|
-
@Band.from_json("{}", "yo", &block)
|
96
|
+
describe "#to_json" do
|
97
|
+
it "delegates to #to_hash and returns string" do
|
98
|
+
assert_equal "{\"name\":\"Rise Against\"}", @Band.new("Rise Against").to_json
|
95
99
|
end
|
96
100
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
it "forwards block to #to_hash" do
|
102
|
+
band = @Band.new
|
103
|
+
band.name = "The Guinea Pigs"
|
104
|
+
band.label = "n/a"
|
105
|
+
json = band.to_json do |name|
|
106
|
+
name == :name
|
101
107
|
end
|
102
|
-
|
103
|
-
|
104
|
-
it "returns empty hash with inappropriate hash" do
|
105
|
-
assert Band.from_json({:song => "Message In A Bottle"}.to_json)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "generates warning with inappropriate hash in debugging mode" do
|
108
|
+
|
109
|
+
assert_equal "{\"name\":\"The Guinea Pigs\"}", json
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
112
113
|
|
113
|
-
describe "
|
114
|
-
it "
|
115
|
-
|
116
|
-
assert_equal
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
describe "#to_json" do
|
122
|
-
before do
|
123
|
-
@band = @Band.new
|
124
|
-
@band.label = "Fat"
|
114
|
+
describe "#to_hash" do
|
115
|
+
it "returns unwrapped hash" do
|
116
|
+
hash = @Band.new("Rise Against").to_hash
|
117
|
+
assert_equal({"name"=>"Rise Against"}, hash)
|
125
118
|
end
|
126
119
|
|
127
|
-
it "
|
128
|
-
|
120
|
+
it "respects #representation_wrap=" do
|
121
|
+
@Band.representation_wrap = :group
|
122
|
+
assert_equal({:group=>{"name"=>"Rise Against"}}, @Band.new("Rise Against").to_hash)
|
129
123
|
end
|
130
124
|
|
131
125
|
it "respects :wrap option" do
|
132
|
-
assert_equal
|
126
|
+
assert_equal({:band=>{"name"=>"NOFX"}}, @Band.new("NOFX").to_hash(:wrap => :band))
|
133
127
|
end
|
134
|
-
|
128
|
+
|
135
129
|
it "respects :wrap option over representation_wrap" do
|
136
130
|
@Band.class_eval do
|
137
131
|
self.representation_wrap = :group
|
138
132
|
end
|
139
|
-
assert_equal
|
133
|
+
assert_equal({:band=>{"name"=>"Rise Against"}}, @Band.new("Rise Against").to_hash(:wrap => :band))
|
140
134
|
end
|
135
|
+
end
|
141
136
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
137
|
+
describe "#binding_for_definition" do
|
138
|
+
it "returns ObjectBinding" do
|
139
|
+
assert_kind_of Json::ObjectBinding, @Band.binding_for_definition(Def.new(:band, :as => Hash))
|
140
|
+
end
|
141
|
+
|
142
|
+
it "returns TextBinding" do
|
143
|
+
assert_kind_of Json::TextBinding, @Band.binding_for_definition(Def.new(:band))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#representable_bindings" do
|
148
|
+
it "returns bindings for each property" do
|
149
|
+
assert_equal 2, @Band.representable_bindings.size
|
150
|
+
assert_equal "name", @Band.representable_bindings.first.definition.name
|
147
151
|
end
|
148
152
|
end
|
149
153
|
end
|
data/test/representable_test.rb
CHANGED
@@ -116,8 +116,8 @@ class RepresentableTest < MiniTest::Spec
|
|
116
116
|
|
117
117
|
it "skips elements when block returns false" do
|
118
118
|
band = PopBand.new
|
119
|
-
band.update_properties_from({"name"=>"No One's Choice", "groupies"=>2}) do |
|
120
|
-
|
119
|
+
band.update_properties_from({"name"=>"No One's Choice", "groupies"=>2}) do |name|
|
120
|
+
name == :name
|
121
121
|
end
|
122
122
|
assert_equal "No One's Choice", band.name
|
123
123
|
assert_equal nil, band.groupies
|
@@ -141,7 +141,7 @@ class RepresentableTest < MiniTest::Spec
|
|
141
141
|
end
|
142
142
|
|
143
143
|
it "skips elements when block returns false" do
|
144
|
-
assert_equal({"name"=>"No One's Choice"}, @band.send(:create_representation_with, {}) do |
|
144
|
+
assert_equal({"name"=>"No One's Choice"}, @band.send(:create_representation_with, {}) do |name| name == :name end)
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
data/test/test_helper.rb
CHANGED
data/test/xml_test.rb
CHANGED
@@ -65,8 +65,8 @@ class XmlTest < MiniTest::Spec
|
|
65
65
|
end
|
66
66
|
|
67
67
|
it "forwards block to #from_node" do
|
68
|
-
@band.from_xml(@xml) do |
|
69
|
-
|
68
|
+
@band.from_xml(@xml) do |name|
|
69
|
+
name == :name
|
70
70
|
end
|
71
71
|
|
72
72
|
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
@@ -86,8 +86,8 @@ class XmlTest < MiniTest::Spec
|
|
86
86
|
end
|
87
87
|
|
88
88
|
it "forwards block to #update_properties_from" do
|
89
|
-
@band.from_node(@xml) do |
|
90
|
-
|
89
|
+
@band.from_node(@xml) do |name|
|
90
|
+
name == :name
|
91
91
|
end
|
92
92
|
|
93
93
|
assert_equal ["Nofx", nil], [@band.name, @band.label]
|
@@ -104,8 +104,8 @@ class XmlTest < MiniTest::Spec
|
|
104
104
|
band = @Band.new
|
105
105
|
band.name = "The Guinea Pigs"
|
106
106
|
band.label = "n/a"
|
107
|
-
xml = band.to_xml do |
|
108
|
-
|
107
|
+
xml = band.to_xml do |name|
|
108
|
+
name == :name
|
109
109
|
end
|
110
110
|
|
111
111
|
assert_xml_equal "<band><name>The Guinea Pigs</name></band>", xml
|
metadata
CHANGED
@@ -1,124 +1,101 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 10
|
8
|
-
- 0
|
9
|
-
version: 0.10.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.1
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Nick Sutterer
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-12-01 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: hooks
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &72137670 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 0
|
30
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
31
22
|
type: :runtime
|
32
|
-
version_requirements: *id001
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: nokogiri
|
35
23
|
prerelease: false
|
36
|
-
|
24
|
+
version_requirements: *72137670
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &72137450 !ruby/object:Gem::Requirement
|
37
28
|
none: false
|
38
|
-
requirements:
|
39
|
-
- -
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
|
42
|
-
- 0
|
43
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
44
33
|
type: :runtime
|
45
|
-
version_requirements: *id002
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: json
|
48
34
|
prerelease: false
|
49
|
-
|
35
|
+
version_requirements: *72137450
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: json
|
38
|
+
requirement: &72137230 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
55
|
-
- 0
|
56
|
-
version: "0"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
57
44
|
type: :runtime
|
58
|
-
version_requirements: *id003
|
59
|
-
- !ruby/object:Gem::Dependency
|
60
|
-
name: rake
|
61
45
|
prerelease: false
|
62
|
-
|
46
|
+
version_requirements: *72137230
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &72137010 !ruby/object:Gem::Requirement
|
63
50
|
none: false
|
64
|
-
requirements:
|
65
|
-
- -
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
|
68
|
-
- 0
|
69
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
70
55
|
type: :development
|
71
|
-
version_requirements: *id004
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
|
-
name: test_xml
|
74
56
|
prerelease: false
|
75
|
-
|
57
|
+
version_requirements: *72137010
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: test_xml
|
60
|
+
requirement: &72136800 !ruby/object:Gem::Requirement
|
76
61
|
none: false
|
77
|
-
requirements:
|
78
|
-
- -
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
|
81
|
-
- 0
|
82
|
-
version: "0"
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
83
66
|
type: :development
|
84
|
-
version_requirements: *id005
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: minitest
|
87
67
|
prerelease: false
|
88
|
-
|
68
|
+
version_requirements: *72136800
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: &72136530 !ruby/object:Gem::Requirement
|
89
72
|
none: false
|
90
|
-
requirements:
|
73
|
+
requirements:
|
91
74
|
- - ~>
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
- 2
|
95
|
-
- 8
|
96
|
-
version: "2.8"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.8'
|
97
77
|
type: :development
|
98
|
-
version_requirements: *id006
|
99
|
-
- !ruby/object:Gem::Dependency
|
100
|
-
name: mocha
|
101
78
|
prerelease: false
|
102
|
-
|
79
|
+
version_requirements: *72136530
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: mocha
|
82
|
+
requirement: &72136320 !ruby/object:Gem::Requirement
|
103
83
|
none: false
|
104
|
-
requirements:
|
105
|
-
- -
|
106
|
-
- !ruby/object:Gem::Version
|
107
|
-
|
108
|
-
- 0
|
109
|
-
version: "0"
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
110
88
|
type: :development
|
111
|
-
|
112
|
-
|
113
|
-
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *72136320
|
91
|
+
description: Maps representation documents from and to Ruby objects. Includes XML
|
92
|
+
and JSON support, plain properties and compositions.
|
93
|
+
email:
|
114
94
|
- apotonick@gmail.com
|
115
95
|
executables: []
|
116
|
-
|
117
96
|
extensions: []
|
118
|
-
|
119
97
|
extra_rdoc_files: []
|
120
|
-
|
121
|
-
files:
|
98
|
+
files:
|
122
99
|
- .gitignore
|
123
100
|
- .gitmodules
|
124
101
|
- .rspec
|
@@ -142,37 +119,29 @@ files:
|
|
142
119
|
- test/representable_test.rb
|
143
120
|
- test/test_helper.rb
|
144
121
|
- test/xml_test.rb
|
145
|
-
has_rdoc: true
|
146
122
|
homepage: http://representable.apotomo.de
|
147
123
|
licenses: []
|
148
|
-
|
149
124
|
post_install_message:
|
150
125
|
rdoc_options: []
|
151
|
-
|
152
|
-
require_paths:
|
126
|
+
require_paths:
|
153
127
|
- lib
|
154
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
129
|
none: false
|
156
|
-
requirements:
|
157
|
-
- -
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
|
160
|
-
|
161
|
-
version: "0"
|
162
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
135
|
none: false
|
164
|
-
requirements:
|
165
|
-
- -
|
166
|
-
- !ruby/object:Gem::Version
|
167
|
-
|
168
|
-
- 0
|
169
|
-
version: "0"
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
170
140
|
requirements: []
|
171
|
-
|
172
141
|
rubyforge_project:
|
173
|
-
rubygems_version: 1.
|
142
|
+
rubygems_version: 1.8.10
|
174
143
|
signing_key:
|
175
144
|
specification_version: 3
|
176
|
-
summary: Maps representation documents from and to Ruby objects. Includes XML and
|
145
|
+
summary: Maps representation documents from and to Ruby objects. Includes XML and
|
146
|
+
JSON support, plain properties and compositions.
|
177
147
|
test_files: []
|
178
|
-
|