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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGES.md +36 -0
  4. data/Gemfile +3 -3
  5. data/README.md +62 -2
  6. data/Rakefile +1 -1
  7. data/lib/representable.rb +32 -109
  8. data/lib/representable/TODO.getting_serious +7 -1
  9. data/lib/representable/autoload.rb +10 -0
  10. data/lib/representable/binding.rb +20 -16
  11. data/lib/representable/bindings/xml_bindings.rb +0 -1
  12. data/lib/representable/coercion.rb +23 -31
  13. data/lib/representable/config.rb +45 -46
  14. data/lib/representable/declarative.rb +78 -0
  15. data/lib/representable/decorator.rb +39 -10
  16. data/lib/representable/definition.rb +40 -33
  17. data/lib/representable/deserializer.rb +2 -0
  18. data/lib/representable/for_collection.rb +25 -0
  19. data/lib/representable/hash.rb +4 -8
  20. data/lib/representable/hash/collection.rb +2 -9
  21. data/lib/representable/hash_methods.rb +0 -7
  22. data/lib/representable/inheritable.rb +50 -0
  23. data/lib/representable/json.rb +3 -9
  24. data/lib/representable/json/collection.rb +1 -3
  25. data/lib/representable/json/hash.rb +4 -9
  26. data/lib/representable/mapper.rb +8 -5
  27. data/lib/representable/parse_strategies.rb +1 -0
  28. data/lib/representable/pipeline.rb +14 -0
  29. data/lib/representable/represent.rb +6 -0
  30. data/lib/representable/version.rb +1 -1
  31. data/lib/representable/xml.rb +3 -18
  32. data/lib/representable/xml/collection.rb +2 -4
  33. data/lib/representable/xml/hash.rb +2 -10
  34. data/lib/representable/yaml.rb +1 -20
  35. data/representable.gemspec +2 -2
  36. data/test/class_test.rb +5 -10
  37. data/test/coercion_test.rb +31 -92
  38. data/test/config/inherit_test.rb +128 -0
  39. data/test/config_test.rb +114 -80
  40. data/test/definition_test.rb +107 -64
  41. data/test/features_test.rb +41 -0
  42. data/test/filter_test.rb +59 -0
  43. data/test/for_collection_test.rb +74 -0
  44. data/test/inherit_test.rb +44 -3
  45. data/test/inheritable_test.rb +97 -0
  46. data/test/inline_test.rb +0 -18
  47. data/test/instance_test.rb +0 -19
  48. data/test/json_test.rb +9 -44
  49. data/test/lonely_test.rb +1 -0
  50. data/test/parse_strategy_test.rb +30 -0
  51. data/test/represent_test.rb +88 -0
  52. data/test/representable_test.rb +3 -50
  53. data/test/schema_test.rb +123 -0
  54. data/test/test_helper.rb +1 -1
  55. data/test/xml_test.rb +34 -38
  56. metadata +25 -15
  57. data/lib/representable/decorator/coercion.rb +0 -4
  58. data/lib/representable/readable_writeable.rb +0 -29
  59. data/test/inheritance_test.rb +0 -22
@@ -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
@@ -19,7 +19,7 @@ class Album
19
19
  end
20
20
 
21
21
  class Song
22
- attr_accessor :name, :track
22
+ attr_accessor :name, :track # never change this, track rendered with Rails#to_json.
23
23
  def initialize(name=nil, track=nil)
24
24
  @name = name
25
25
  @track = track
@@ -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; self.representation_wrap= :songs } } # FIXME: why isn't representation wrap inherited properly?
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: 1.8.5
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-06-11 00:00:00.000000000 Z
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: '0'
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: '0'
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.5.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.5.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/readable_writeable.rb
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/inheritance_test.rb
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: '0'
260
+ version: 1.3.1
251
261
  requirements: []
252
262
  rubyforge_project:
253
263
  rubygems_version: 2.2.2
@@ -1,4 +0,0 @@
1
- require 'representable/coercion'
2
-
3
- # TODO: deprecate for 1.7.
4
- Representable::Decorator::Coercion = Representable::Coercion
@@ -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
@@ -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