representable 2.0.4 → 2.1.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.
- checksums.yaml +4 -4
- data/CHANGES.md +17 -0
- data/README.md +20 -1
- data/lib/representable.rb +2 -1
- data/lib/representable/binding.rb +115 -59
- data/lib/representable/config.rb +8 -0
- data/lib/representable/definition.rb +10 -14
- data/lib/representable/deserializer.rb +64 -25
- data/lib/representable/hash.rb +3 -3
- data/lib/representable/hash/binding.rb +40 -0
- data/lib/representable/hash/collection.rb +3 -2
- data/lib/representable/hash_methods.rb +4 -2
- data/lib/representable/mapper.rb +1 -1
- data/lib/representable/populator.rb +59 -0
- data/lib/representable/serializer.rb +24 -13
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +3 -3
- data/lib/representable/xml/binding.rb +171 -0
- data/lib/representable/yaml.rb +3 -3
- data/lib/representable/yaml/binding.rb +48 -0
- data/representable.gemspec +1 -1
- data/test/benchmarking.rb +83 -0
- data/test/binding_test.rb +46 -0
- data/test/definition_test.rb +5 -58
- data/test/exec_context_test.rb +4 -4
- data/test/hash_bindings_test.rb +4 -52
- data/test/hash_test.rb +6 -6
- data/test/json_test.rb +8 -8
- data/test/lonely_test.rb +1 -1
- data/test/realistic_benchmark.rb +83 -0
- data/test/skip_test.rb +28 -0
- data/test/xml_bindings_test.rb +2 -109
- data/test/xml_test.rb +61 -23
- data/test/yaml_test.rb +5 -8
- metadata +19 -11
- data/lib/representable/bindings/hash_bindings.rb +0 -64
- data/lib/representable/bindings/xml_bindings.rb +0 -172
- data/lib/representable/bindings/yaml_bindings.rb +0 -49
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: minitest
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 5.
|
89
|
+
version: 5.4.1
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 5.
|
96
|
+
version: 5.4.1
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: mocha
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,9 +170,6 @@ files:
|
|
170
170
|
- lib/representable/TODO.getting_serious
|
171
171
|
- lib/representable/autoload.rb
|
172
172
|
- lib/representable/binding.rb
|
173
|
-
- lib/representable/bindings/hash_bindings.rb
|
174
|
-
- lib/representable/bindings/xml_bindings.rb
|
175
|
-
- lib/representable/bindings/yaml_bindings.rb
|
176
173
|
- lib/representable/coercion.rb
|
177
174
|
- lib/representable/config.rb
|
178
175
|
- lib/representable/declarative.rb
|
@@ -182,6 +179,7 @@ files:
|
|
182
179
|
- lib/representable/for_collection.rb
|
183
180
|
- lib/representable/hash.rb
|
184
181
|
- lib/representable/hash/allow_symbols.rb
|
182
|
+
- lib/representable/hash/binding.rb
|
185
183
|
- lib/representable/hash/collection.rb
|
186
184
|
- lib/representable/hash_methods.rb
|
187
185
|
- lib/representable/inheritable.rb
|
@@ -191,15 +189,20 @@ files:
|
|
191
189
|
- lib/representable/mapper.rb
|
192
190
|
- lib/representable/parse_strategies.rb
|
193
191
|
- lib/representable/pipeline.rb
|
192
|
+
- lib/representable/populator.rb
|
194
193
|
- lib/representable/represent.rb
|
195
194
|
- lib/representable/serializer.rb
|
196
195
|
- lib/representable/version.rb
|
197
196
|
- lib/representable/xml.rb
|
197
|
+
- lib/representable/xml/binding.rb
|
198
198
|
- lib/representable/xml/collection.rb
|
199
199
|
- lib/representable/xml/hash.rb
|
200
200
|
- lib/representable/yaml.rb
|
201
|
+
- lib/representable/yaml/binding.rb
|
201
202
|
- representable.gemspec
|
202
203
|
- test/as_test.rb
|
204
|
+
- test/benchmarking.rb
|
205
|
+
- test/binding_test.rb
|
203
206
|
- test/class_test.rb
|
204
207
|
- test/coercion_test.rb
|
205
208
|
- test/config/inherit_test.rb
|
@@ -230,10 +233,12 @@ files:
|
|
230
233
|
- test/pass_options_test.rb
|
231
234
|
- test/prepare_test.rb
|
232
235
|
- test/reader_writer_test.rb
|
236
|
+
- test/realistic_benchmark.rb
|
233
237
|
- test/represent_test.rb
|
234
238
|
- test/representable_test.rb
|
235
239
|
- test/schema_test.rb
|
236
240
|
- test/serialize_deserialize_test.rb
|
241
|
+
- test/skip_test.rb
|
237
242
|
- test/stringify_hash_test.rb
|
238
243
|
- test/test_helper.rb
|
239
244
|
- test/test_helper_test.rb
|
@@ -260,13 +265,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
265
|
version: '0'
|
261
266
|
requirements: []
|
262
267
|
rubyforge_project:
|
263
|
-
rubygems_version: 2.2.
|
268
|
+
rubygems_version: 2.2.2
|
264
269
|
signing_key:
|
265
270
|
specification_version: 4
|
266
271
|
summary: Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes
|
267
272
|
plain properties, collections, nesting, coercion and more.
|
268
273
|
test_files:
|
269
274
|
- test/as_test.rb
|
275
|
+
- test/benchmarking.rb
|
276
|
+
- test/binding_test.rb
|
270
277
|
- test/class_test.rb
|
271
278
|
- test/coercion_test.rb
|
272
279
|
- test/config/inherit_test.rb
|
@@ -297,10 +304,12 @@ test_files:
|
|
297
304
|
- test/pass_options_test.rb
|
298
305
|
- test/prepare_test.rb
|
299
306
|
- test/reader_writer_test.rb
|
307
|
+
- test/realistic_benchmark.rb
|
300
308
|
- test/represent_test.rb
|
301
309
|
- test/representable_test.rb
|
302
310
|
- test/schema_test.rb
|
303
311
|
- test/serialize_deserialize_test.rb
|
312
|
+
- test/skip_test.rb
|
304
313
|
- test/stringify_hash_test.rb
|
305
314
|
- test/test_helper.rb
|
306
315
|
- test/test_helper_test.rb
|
@@ -308,4 +317,3 @@ test_files:
|
|
308
317
|
- test/xml_bindings_test.rb
|
309
318
|
- test/xml_test.rb
|
310
319
|
- test/yaml_test.rb
|
311
|
-
has_rdoc:
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'representable/binding'
|
2
|
-
|
3
|
-
module Representable
|
4
|
-
module Hash
|
5
|
-
class PropertyBinding < Representable::Binding
|
6
|
-
include Binding::Object
|
7
|
-
|
8
|
-
def self.build_for(definition, *args) # TODO: remove default arg.
|
9
|
-
return CollectionBinding.new(definition, *args) if definition.array?
|
10
|
-
return HashBinding.new(definition, *args) if definition.hash?
|
11
|
-
new(definition, *args)
|
12
|
-
end
|
13
|
-
|
14
|
-
def read(hash)
|
15
|
-
return FragmentNotFound unless hash.has_key?(as) # DISCUSS: put it all in #read for performance. not really sure if i like returning that special thing.
|
16
|
-
|
17
|
-
fragment = hash[as]
|
18
|
-
deserialize(fragment)
|
19
|
-
end
|
20
|
-
|
21
|
-
def write(hash, value)
|
22
|
-
hash[as] = serialize(value)
|
23
|
-
end
|
24
|
-
|
25
|
-
def deserialize_from(fragment)
|
26
|
-
deserialize(fragment)
|
27
|
-
end
|
28
|
-
|
29
|
-
def serialize_method
|
30
|
-
:to_hash
|
31
|
-
end
|
32
|
-
|
33
|
-
def deserialize_method
|
34
|
-
:from_hash
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class CollectionBinding < PropertyBinding
|
39
|
-
def serialize(value)
|
40
|
-
value.collect { |item| super(item) } # TODO: i don't want Array but Forms here - what now?
|
41
|
-
end
|
42
|
-
|
43
|
-
def deserialize(fragment)
|
44
|
-
CollectionDeserializer.new(self).deserialize(fragment)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
class HashBinding < PropertyBinding
|
50
|
-
def serialize(value)
|
51
|
-
# requires value to respond to #each with two block parameters.
|
52
|
-
{}.tap do |hsh|
|
53
|
-
value.each { |key, obj| hsh[key] = super(obj) }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def deserialize(fragment)
|
58
|
-
{}.tap do |hsh|
|
59
|
-
fragment.each { |key, item_fragment| hsh[key] = super(item_fragment) }
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
require 'representable/binding'
|
2
|
-
require 'representable/bindings/hash_bindings.rb'
|
3
|
-
|
4
|
-
module Representable
|
5
|
-
module XML
|
6
|
-
class PropertyBinding < Binding
|
7
|
-
include Binding::Object
|
8
|
-
|
9
|
-
def self.build_for(definition, *args)
|
10
|
-
return CollectionBinding.new(definition, *args) if definition.array?
|
11
|
-
return HashBinding.new(definition, *args) if definition.hash? and not definition[:use_attributes] # FIXME: hate this.
|
12
|
-
return AttributeHashBinding.new(definition, *args) if definition.hash? and definition[:use_attributes]
|
13
|
-
return AttributeBinding.new(definition, *args) if definition[:attribute]
|
14
|
-
return ContentBinding.new(definition, *args) if definition[:content]
|
15
|
-
new(definition, *args)
|
16
|
-
end
|
17
|
-
|
18
|
-
def write(parent, value)
|
19
|
-
wrap_node = parent
|
20
|
-
|
21
|
-
if wrap = self[:wrap]
|
22
|
-
parent << wrap_node = node_for(parent, wrap)
|
23
|
-
end
|
24
|
-
|
25
|
-
wrap_node << serialize_for(value, parent)
|
26
|
-
end
|
27
|
-
|
28
|
-
def read(node)
|
29
|
-
nodes = find_nodes(node)
|
30
|
-
return FragmentNotFound if nodes.size == 0 # TODO: write dedicated test!
|
31
|
-
|
32
|
-
deserialize_from(nodes)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Creates wrapped node for the property.
|
36
|
-
def serialize_for(value, parent)
|
37
|
-
node = node_for(parent, as)
|
38
|
-
serialize_node(node, value)
|
39
|
-
end
|
40
|
-
|
41
|
-
def serialize_node(node, value)
|
42
|
-
return serialize(value) if typed?
|
43
|
-
|
44
|
-
node.content = serialize(value)
|
45
|
-
node
|
46
|
-
end
|
47
|
-
|
48
|
-
def deserialize_from(nodes)
|
49
|
-
content_for deserialize(nodes.first)
|
50
|
-
#deserialize(nodes.first)
|
51
|
-
end
|
52
|
-
|
53
|
-
# DISCUSS: why is this public?
|
54
|
-
def serialize_method
|
55
|
-
:to_node
|
56
|
-
end
|
57
|
-
|
58
|
-
def deserialize_method
|
59
|
-
:from_node
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
def xpath
|
64
|
-
as
|
65
|
-
end
|
66
|
-
|
67
|
-
def find_nodes(doc)
|
68
|
-
selector = xpath
|
69
|
-
selector = "#{self[:wrap]}/#{xpath}" if self[:wrap]
|
70
|
-
nodes = doc.xpath(selector)
|
71
|
-
end
|
72
|
-
|
73
|
-
def node_for(parent, name)
|
74
|
-
Nokogiri::XML::Node.new(name.to_s, parent.document)
|
75
|
-
end
|
76
|
-
|
77
|
-
def content_for(node) # TODO: move this into a ScalarDecorator.
|
78
|
-
return node if typed?
|
79
|
-
|
80
|
-
node.content
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class CollectionBinding < PropertyBinding
|
85
|
-
def serialize_for(value, parent)
|
86
|
-
# return NodeSet so << works.
|
87
|
-
set_for(parent, value.collect { |item| super(item, parent) })
|
88
|
-
end
|
89
|
-
|
90
|
-
def deserialize_from(nodes)
|
91
|
-
content_nodes = nodes.collect do |item| # TODO: move this to Node?
|
92
|
-
content_for(item)
|
93
|
-
end
|
94
|
-
|
95
|
-
# *Deserializer doesn't want anything format specific!
|
96
|
-
CollectionDeserializer.new(self).deserialize(content_nodes)
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
def set_for(parent, nodes)
|
101
|
-
Nokogiri::XML::NodeSet.new(parent.document, nodes)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
class HashBinding < CollectionBinding
|
107
|
-
def serialize_for(value, parent)
|
108
|
-
set_for(parent, value.collect do |k, v|
|
109
|
-
node = node_for(parent, k)
|
110
|
-
serialize_node(node, v)
|
111
|
-
end)
|
112
|
-
end
|
113
|
-
|
114
|
-
def deserialize_from(nodes)
|
115
|
-
{}.tap do |hash|
|
116
|
-
nodes.children.each do |node|
|
117
|
-
hash[node.name] = deserialize(content_for node)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
class AttributeHashBinding < CollectionBinding
|
124
|
-
# DISCUSS: use AttributeBinding here?
|
125
|
-
def write(parent, value) # DISCUSS: is it correct overriding #write here?
|
126
|
-
value.collect do |k, v|
|
127
|
-
parent[k] = serialize(v.to_s)
|
128
|
-
end
|
129
|
-
parent
|
130
|
-
end
|
131
|
-
|
132
|
-
def deserialize_from(node)
|
133
|
-
{}.tap do |hash|
|
134
|
-
node.each do |k,v|
|
135
|
-
hash[k] = deserialize(v)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
# Represents a tag attribute. Currently this only works on the top-level tag.
|
143
|
-
class AttributeBinding < PropertyBinding
|
144
|
-
def read(node)
|
145
|
-
deserialize(node[as])
|
146
|
-
end
|
147
|
-
|
148
|
-
def serialize_for(value, parent)
|
149
|
-
parent[as] = serialize(value.to_s)
|
150
|
-
end
|
151
|
-
|
152
|
-
def write(parent, value)
|
153
|
-
serialize_for(value, parent)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# Represents tag content.
|
158
|
-
class ContentBinding < PropertyBinding
|
159
|
-
def read(node)
|
160
|
-
node.content
|
161
|
-
end
|
162
|
-
|
163
|
-
def serialize_for(value, parent)
|
164
|
-
parent.content = serialize(value.to_s)
|
165
|
-
end
|
166
|
-
|
167
|
-
def write(parent, value)
|
168
|
-
serialize_for(value, parent)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'representable/binding'
|
2
|
-
|
3
|
-
module Representable
|
4
|
-
module YAML
|
5
|
-
class PropertyBinding < Representable::Hash::PropertyBinding
|
6
|
-
def self.build_for(definition, *args)
|
7
|
-
return CollectionBinding.new(definition, *args) if definition.array?
|
8
|
-
new(definition, *args)
|
9
|
-
end
|
10
|
-
|
11
|
-
def write(map, value)
|
12
|
-
map.children << Psych::Nodes::Scalar.new(as)
|
13
|
-
map.children << serialize(value) # FIXME: should be serialize.
|
14
|
-
end
|
15
|
-
|
16
|
-
def serialize(value)
|
17
|
-
write_scalar super(value)
|
18
|
-
end
|
19
|
-
|
20
|
-
def write_scalar(value)
|
21
|
-
return value if typed?
|
22
|
-
|
23
|
-
Psych::Nodes::Scalar.new(value.to_s)
|
24
|
-
end
|
25
|
-
|
26
|
-
def serialize_method
|
27
|
-
:to_ast
|
28
|
-
end
|
29
|
-
|
30
|
-
def deserialize_method
|
31
|
-
:from_hash
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
class CollectionBinding < PropertyBinding
|
37
|
-
def serialize(value)
|
38
|
-
Psych::Nodes::Sequence.new.tap do |seq|
|
39
|
-
seq.style = Psych::Nodes::Sequence::FLOW if self[:style] == :flow
|
40
|
-
value.each { |obj| seq.children << super(obj) }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def deserialize(fragment) # FIXME: redundant from Hash::Bindings
|
45
|
-
CollectionDeserializer.new(self).deserialize(fragment)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|