representable 1.8.5 → 2.0.0.rc1
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/.travis.yml +1 -1
- data/CHANGES.md +36 -0
- data/Gemfile +3 -3
- data/README.md +62 -2
- data/Rakefile +1 -1
- data/lib/representable.rb +32 -109
- data/lib/representable/TODO.getting_serious +7 -1
- data/lib/representable/autoload.rb +10 -0
- data/lib/representable/binding.rb +20 -16
- data/lib/representable/bindings/xml_bindings.rb +0 -1
- data/lib/representable/coercion.rb +23 -31
- data/lib/representable/config.rb +45 -46
- data/lib/representable/declarative.rb +78 -0
- data/lib/representable/decorator.rb +39 -10
- data/lib/representable/definition.rb +40 -33
- data/lib/representable/deserializer.rb +2 -0
- data/lib/representable/for_collection.rb +25 -0
- data/lib/representable/hash.rb +4 -8
- data/lib/representable/hash/collection.rb +2 -9
- data/lib/representable/hash_methods.rb +0 -7
- data/lib/representable/inheritable.rb +50 -0
- data/lib/representable/json.rb +3 -9
- data/lib/representable/json/collection.rb +1 -3
- data/lib/representable/json/hash.rb +4 -9
- data/lib/representable/mapper.rb +8 -5
- data/lib/representable/parse_strategies.rb +1 -0
- data/lib/representable/pipeline.rb +14 -0
- data/lib/representable/represent.rb +6 -0
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +3 -18
- data/lib/representable/xml/collection.rb +2 -4
- data/lib/representable/xml/hash.rb +2 -10
- data/lib/representable/yaml.rb +1 -20
- data/representable.gemspec +2 -2
- data/test/class_test.rb +5 -10
- data/test/coercion_test.rb +31 -92
- data/test/config/inherit_test.rb +128 -0
- data/test/config_test.rb +114 -80
- data/test/definition_test.rb +107 -64
- data/test/features_test.rb +41 -0
- data/test/filter_test.rb +59 -0
- data/test/for_collection_test.rb +74 -0
- data/test/inherit_test.rb +44 -3
- data/test/inheritable_test.rb +97 -0
- data/test/inline_test.rb +0 -18
- data/test/instance_test.rb +0 -19
- data/test/json_test.rb +9 -44
- data/test/lonely_test.rb +1 -0
- data/test/parse_strategy_test.rb +30 -0
- data/test/represent_test.rb +88 -0
- data/test/representable_test.rb +3 -50
- data/test/schema_test.rb +123 -0
- data/test/test_helper.rb +1 -1
- data/test/xml_test.rb +34 -38
- metadata +25 -15
- data/lib/representable/decorator/coercion.rb +0 -4
- data/lib/representable/readable_writeable.rb +0 -29
- data/test/inheritance_test.rb +0 -22
data/test/schema_test.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# Include Inherit Module And Decorator Test
|
4
|
+
class SchemaTest < MiniTest::Spec
|
5
|
+
module Genre
|
6
|
+
include Representable
|
7
|
+
property :genre
|
8
|
+
end
|
9
|
+
|
10
|
+
module LinkFeature
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(Link)
|
13
|
+
end
|
14
|
+
|
15
|
+
module Link
|
16
|
+
def link
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
module Module
|
23
|
+
include Representable::Hash
|
24
|
+
feature LinkFeature
|
25
|
+
|
26
|
+
property :title
|
27
|
+
property :label do # extend: LabelModule
|
28
|
+
property :name
|
29
|
+
link # feature
|
30
|
+
|
31
|
+
property :location do
|
32
|
+
property :city
|
33
|
+
link # feature.
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
property :album, :extend => lambda { raise "don't manifest me!" } # this is not an inline decorator, don't manifest it.
|
38
|
+
|
39
|
+
|
40
|
+
include Genre # Schema::Included::included is called!
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
class WithLocationStreetRepresenter < Representable::Decorator
|
45
|
+
include Representable::Hash
|
46
|
+
feature LinkFeature
|
47
|
+
|
48
|
+
property :title
|
49
|
+
property :label do # extend: LabelModule
|
50
|
+
property :name
|
51
|
+
link # feature
|
52
|
+
|
53
|
+
property :location do
|
54
|
+
property :city
|
55
|
+
link # feature.
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "3-level deep with features" do
|
61
|
+
let (:label) { OpenStruct.new(:name => "Epitaph", :location => OpenStruct.new(:city => "Sanfran", :name => "DON'T SHOW ME!")) }
|
62
|
+
|
63
|
+
# Module does correctly include features in inlines.
|
64
|
+
it { band.extend(Module).to_hash.must_equal({"label"=>{"name"=>"Epitaph", "location"=>{"city"=>"Sanfran"}}, "genre"=>"Punkrock"}) }
|
65
|
+
|
66
|
+
# Decorator does correctly include features in inlines.
|
67
|
+
it { Decorator.new(band).to_hash.must_equal({"label"=>{"name"=>"Epitaph", "location"=>{"city"=>"Sanfran"}}, "genre"=>"Punkrock"}) }
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
class Decorator < Representable::Decorator
|
73
|
+
feature Representable::Hash
|
74
|
+
|
75
|
+
include Module
|
76
|
+
end
|
77
|
+
|
78
|
+
# puts Decorator.representable_attrs[:definitions].inspect
|
79
|
+
|
80
|
+
let (:label) { OpenStruct.new(:name => "Fat Wreck", :city => "San Francisco", :employees => [OpenStruct.new(:name => "Mike")], :location => OpenStruct.new(:city => "Sanfran")) }
|
81
|
+
let (:band) { OpenStruct.new(:genre => "Punkrock", :label => label) }
|
82
|
+
|
83
|
+
|
84
|
+
# it { FlatlinersDecorator.new( OpenStruct.new(label: OpenStruct.new) ).
|
85
|
+
# to_hash.must_equal({}) }
|
86
|
+
it do
|
87
|
+
Decorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "location"=>{"city"=>"Sanfran"}}})
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
class InheritDecorator < Representable::Decorator
|
92
|
+
include Representable::Hash
|
93
|
+
|
94
|
+
include Module
|
95
|
+
|
96
|
+
property :label, inherit: true do # decorator.rb:27:in `initialize': superclass must be a Class (Module given)
|
97
|
+
property :city
|
98
|
+
|
99
|
+
property :location, :inherit => true do
|
100
|
+
property :city
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it do
|
106
|
+
InheritDecorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "city"=>"San Francisco", "location"=>{"city"=>"Sanfran"}}})
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
class InheritFromDecorator < InheritDecorator
|
112
|
+
|
113
|
+
property :label, inherit: true do
|
114
|
+
collection :employees do
|
115
|
+
property :name
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it do
|
121
|
+
InheritFromDecorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "city"=>"San Francisco", "employees"=>[{"name"=>"Mike"}], "location"=>{"city"=>"Sanfran"}}})
|
122
|
+
end
|
123
|
+
end
|
data/test/test_helper.rb
CHANGED
data/test/xml_test.rb
CHANGED
@@ -34,40 +34,6 @@ class XmlTest < MiniTest::Spec
|
|
34
34
|
end
|
35
35
|
|
36
36
|
|
37
|
-
describe ".from_xml" do
|
38
|
-
it "is delegated to #from_xml" do
|
39
|
-
block = lambda {|*args|}
|
40
|
-
@Band.any_instance.expects(:from_xml).with("<document>", "options") # FIXME: how to NOT expect block?
|
41
|
-
@Band.from_xml("<document>", "options", &block)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "yields new object and options to block" do
|
45
|
-
@Band.class_eval { attr_accessor :new_name }
|
46
|
-
@band = @Band.from_xml("<band/>", :new_name => "Diesel Boy") do |band, options|
|
47
|
-
band.new_name= options[:new_name]
|
48
|
-
end
|
49
|
-
assert_equal "Diesel Boy", @band.new_name
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
describe ".from_node" do
|
55
|
-
it "is delegated to #from_node" do
|
56
|
-
block = lambda {|*args|}
|
57
|
-
@Band.any_instance.expects(:from_node).with("<document>", "options") # FIXME: how to expect block?
|
58
|
-
@Band.from_node("<document>", "options", &block)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "yields new object and options to block" do
|
62
|
-
@Band.class_eval { attr_accessor :new_name }
|
63
|
-
@band = @Band.from_node(Nokogiri::XML("<band/>"), :new_name => "Diesel Boy") do |band, options|
|
64
|
-
band.new_name= options[:new_name]
|
65
|
-
end
|
66
|
-
assert_equal "Diesel Boy", @band.new_name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
37
|
describe "#from_xml" do
|
72
38
|
before do
|
73
39
|
@band = @Band.new
|
@@ -222,7 +188,7 @@ class AttributesTest < MiniTest::Spec
|
|
222
188
|
end
|
223
189
|
|
224
190
|
it "#from_xml creates correct accessors" do
|
225
|
-
link = Link.from_xml(%{
|
191
|
+
link = Link.new.from_xml(%{
|
226
192
|
<a href="http://apotomo.de" title="Home, sweet home" />
|
227
193
|
})
|
228
194
|
assert_equal "http://apotomo.de", link.href
|
@@ -238,13 +204,29 @@ class AttributesTest < MiniTest::Spec
|
|
238
204
|
end
|
239
205
|
end
|
240
206
|
|
207
|
+
|
208
|
+
class CDataBand
|
209
|
+
class CData < Representable::XML::PropertyBinding
|
210
|
+
def serialize_node(parent, value)
|
211
|
+
parent << Nokogiri::XML::CDATA.new(parent, represented.name)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
include Representable::XML
|
216
|
+
property :name, :binding => lambda { |*args| CData.new(*args) }#getter: lambda { |opt| Nokogiri::XML::CDATA.new(opt[:doc], name) }
|
217
|
+
attr_accessor :name
|
218
|
+
|
219
|
+
def initialize(name=nil)
|
220
|
+
name and self.name = name
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
241
224
|
class TypedPropertyTest < MiniTest::Spec
|
242
225
|
module AlbumRepresenter
|
243
226
|
include Representable::XML
|
244
227
|
property :band, :class => Band
|
245
228
|
end
|
246
229
|
|
247
|
-
|
248
230
|
class Album
|
249
231
|
attr_accessor :band
|
250
232
|
def initialize(band=nil)
|
@@ -288,6 +270,19 @@ class TypedPropertyTest < MiniTest::Spec
|
|
288
270
|
assert_xml_equal %{<album><band>Baaaad Religion</band></album>}, Album.new(band).extend(AlbumRepresenter).to_xml
|
289
271
|
end
|
290
272
|
end
|
273
|
+
|
274
|
+
describe "#to_xml with CDATA" do
|
275
|
+
it "wraps Band name in CDATA#to_xml" do
|
276
|
+
band = CDataBand.new("Bad Religion")
|
277
|
+
album = Album.new(band).extend(AlbumRepresenter)
|
278
|
+
|
279
|
+
assert_xml_equal %{<album>
|
280
|
+
<c_data_band>
|
281
|
+
<name><![CDATA[Bad Religion]]></name>
|
282
|
+
</c_data_band>
|
283
|
+
</album>}, album.to_xml
|
284
|
+
end
|
285
|
+
end
|
291
286
|
end
|
292
287
|
end
|
293
288
|
|
@@ -302,7 +297,7 @@ class CollectionTest < MiniTest::Spec
|
|
302
297
|
|
303
298
|
describe "#from_xml" do
|
304
299
|
it "pushes collection items to array" do
|
305
|
-
cd = Compilation.from_xml(%{
|
300
|
+
cd = Compilation.new.from_xml(%{
|
306
301
|
<compilation>
|
307
302
|
<band><name>Diesel Boy</name></band>
|
308
303
|
<band><name>Cobra Skulls</name></band>
|
@@ -390,9 +385,10 @@ class CollectionTest < MiniTest::Spec
|
|
390
385
|
module SongRepresenter
|
391
386
|
include Representable::XML
|
392
387
|
property :name
|
388
|
+
self.representation_wrap = :song
|
393
389
|
end
|
394
390
|
|
395
|
-
let (:decorator) { rpr = representer; Class.new(Representable::Decorator) { include rpr
|
391
|
+
let (:decorator) { rpr = representer; Class.new(Representable::Decorator) { include rpr } }
|
396
392
|
|
397
393
|
describe "XML::Collection" do
|
398
394
|
describe "with contained objects" do
|
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:
|
4
|
+
version: 2.0.0.rc1
|
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-
|
11
|
+
date: 2014-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: uber
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.0.7
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.0.7
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,16 +126,16 @@ dependencies:
|
|
126
126
|
name: virtus
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - '>='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0
|
131
|
+
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0
|
138
|
+
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: json
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,26 +168,30 @@ files:
|
|
168
168
|
- TODO
|
169
169
|
- lib/representable.rb
|
170
170
|
- lib/representable/TODO.getting_serious
|
171
|
+
- lib/representable/autoload.rb
|
171
172
|
- lib/representable/binding.rb
|
172
173
|
- lib/representable/bindings/hash_bindings.rb
|
173
174
|
- lib/representable/bindings/xml_bindings.rb
|
174
175
|
- lib/representable/bindings/yaml_bindings.rb
|
175
176
|
- lib/representable/coercion.rb
|
176
177
|
- lib/representable/config.rb
|
178
|
+
- lib/representable/declarative.rb
|
177
179
|
- lib/representable/decorator.rb
|
178
|
-
- lib/representable/decorator/coercion.rb
|
179
180
|
- lib/representable/definition.rb
|
180
181
|
- lib/representable/deserializer.rb
|
182
|
+
- lib/representable/for_collection.rb
|
181
183
|
- lib/representable/hash.rb
|
182
184
|
- lib/representable/hash/allow_symbols.rb
|
183
185
|
- lib/representable/hash/collection.rb
|
184
186
|
- lib/representable/hash_methods.rb
|
187
|
+
- lib/representable/inheritable.rb
|
185
188
|
- lib/representable/json.rb
|
186
189
|
- lib/representable/json/collection.rb
|
187
190
|
- lib/representable/json/hash.rb
|
188
191
|
- lib/representable/mapper.rb
|
189
192
|
- lib/representable/parse_strategies.rb
|
190
|
-
- lib/representable/
|
193
|
+
- lib/representable/pipeline.rb
|
194
|
+
- lib/representable/represent.rb
|
191
195
|
- lib/representable/serializer.rb
|
192
196
|
- lib/representable/version.rb
|
193
197
|
- lib/representable/xml.rb
|
@@ -198,19 +202,23 @@ files:
|
|
198
202
|
- test/as_test.rb
|
199
203
|
- test/class_test.rb
|
200
204
|
- test/coercion_test.rb
|
205
|
+
- test/config/inherit_test.rb
|
201
206
|
- test/config_test.rb
|
202
207
|
- test/decorator_scope_test.rb
|
203
208
|
- test/decorator_test.rb
|
204
209
|
- test/definition_test.rb
|
205
210
|
- test/example.rb
|
206
211
|
- test/exec_context_test.rb
|
212
|
+
- test/features_test.rb
|
213
|
+
- test/filter_test.rb
|
214
|
+
- test/for_collection_test.rb
|
207
215
|
- test/generic_test.rb
|
208
216
|
- test/getter_setter_test.rb
|
209
217
|
- test/hash_bindings_test.rb
|
210
218
|
- test/hash_test.rb
|
211
219
|
- test/if_test.rb
|
212
220
|
- test/inherit_test.rb
|
213
|
-
- test/
|
221
|
+
- test/inheritable_test.rb
|
214
222
|
- test/inline_test.rb
|
215
223
|
- test/instance_test.rb
|
216
224
|
- test/is_representable_test.rb
|
@@ -222,7 +230,9 @@ files:
|
|
222
230
|
- test/pass_options_test.rb
|
223
231
|
- test/prepare_test.rb
|
224
232
|
- test/reader_writer_test.rb
|
233
|
+
- test/represent_test.rb
|
225
234
|
- test/representable_test.rb
|
235
|
+
- test/schema_test.rb
|
226
236
|
- test/serialize_deserialize_test.rb
|
227
237
|
- test/stringify_hash_test.rb
|
228
238
|
- test/test_helper.rb
|
@@ -245,9 +255,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
245
255
|
version: '0'
|
246
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
257
|
requirements:
|
248
|
-
- - '
|
258
|
+
- - '>'
|
249
259
|
- !ruby/object:Gem::Version
|
250
|
-
version:
|
260
|
+
version: 1.3.1
|
251
261
|
requirements: []
|
252
262
|
rubyforge_project:
|
253
263
|
rubygems_version: 2.2.2
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Representable
|
2
|
-
module ReadableWriteable
|
3
|
-
def deserialize_property(binding, doc, options)
|
4
|
-
return unless binding.writeable?
|
5
|
-
super
|
6
|
-
end
|
7
|
-
|
8
|
-
def serialize_property(binding, doc, options)
|
9
|
-
return unless binding.readable?
|
10
|
-
super
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
# TODO: i hate monkey-patching Definition here since it globally adds this options. However, for now this should be ok :-)
|
16
|
-
Definition.class_eval do
|
17
|
-
# Checks and returns if the property is writeable
|
18
|
-
def writeable?
|
19
|
-
return self[:writeable] if self.has_key?(:writeable)
|
20
|
-
true
|
21
|
-
end
|
22
|
-
|
23
|
-
# Checks and returns if the property is readable
|
24
|
-
def readable?
|
25
|
-
return self[:readable] if self.has_key?(:readable)
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/test/inheritance_test.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class InheritanceTest < MiniTest::Spec
|
4
|
-
let (:decorator) do
|
5
|
-
Class.new(Representable::Decorator) do
|
6
|
-
property :title
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
# Decorator.new.representable_attrs != Decorator.representable_attrs
|
11
|
-
it "doesn't clone for instantiated decorator" do
|
12
|
-
instance = decorator.new(Object.new)
|
13
|
-
instance.send(:representable_attrs).first.merge!(:instance => true)
|
14
|
-
|
15
|
-
# we didn't clone and thereby change the original config:
|
16
|
-
instance.send(:representable_attrs).to_s.must_equal decorator.representable_attrs.to_s
|
17
|
-
end
|
18
|
-
|
19
|
-
# TODO: ? (performance?)
|
20
|
-
# more tests on cloning
|
21
|
-
#
|
22
|
-
end
|