representable 1.7.6 → 1.7.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26bff301d2f96c009077a3675aabf598c4754a49
4
- data.tar.gz: 6b21930dea9bf7bd327e536d78d2d4b71cb46110
3
+ metadata.gz: 453857338b438b7d68ffcdc22c4a673132d3193e
4
+ data.tar.gz: 19635dc3d647a965fcfe0af872db31f3eb305db3
5
5
  SHA512:
6
- metadata.gz: f28a2101a9eeac36b6c93edc4ceae8716b2f95918ed78ee5a9179727883ff42208b0041110f1bafbc3ba5b099e3ff46f547538a0f93e07156283254f7838147a
7
- data.tar.gz: d2e5365454d29a47ee40829fbd3fe47bdbe0cccd4067493c26a4b700c50466ddb3ddece6f5e23fbb40d2d7437f928a3c051aab4256a666b1799e42ac2a2f15a8
6
+ metadata.gz: e20ce7e46c5a94ab219a8936c04fa1a6ed7c1f77f2be36fab23685b80c1fda109c950dd011ae35c5a638ba04e0ce739f64d612d4a01c826bc75bcdee16524e2b
7
+ data.tar.gz: 58791da0eef9d17e2c3f24c82fc9c532cbfdea78d159cd09be33bf91755257adb0dbf9cb889c4facc81a17a81995ae8d5e4712063aaf4549ab571db12d9426c4
data/CHANGES.md CHANGED
@@ -7,6 +7,12 @@ h2. 1.8.0
7
7
  -> make major steps lambda-able
8
8
  -> strategies for deserialization (lambda-able!)
9
9
 
10
+ h2. 1.7.7
11
+
12
+ * Parsing an empty hash with a representer having a wrap does no longer throw an exception.
13
+ * `::nested` now works in modules, too! Nests are implemented as decorator representer, not as modules, so they don't pollute the represented object.
14
+ * Introduce `:inherit` to allow inheriting+overriding properties and inline representers (and properties in inline representers - it starts getting crazy!!!).
15
+
10
16
  h2. 1.7.6
11
17
 
12
18
  * Add `::nested` to nest blocks in the document whilst still using the same represented object. Use with `Decorator` only.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Representable
2
2
 
3
- Representable maps ruby objects to documents and back.
3
+ Representable maps Ruby objects to documents and back.
4
4
 
5
5
  In other words: Take an object and decorate it with a representer module. This will allow you to render a JSON, XML or YAML document from that object. But that's only half of it! You can also use representers to parse a document and create or populate an object.
6
6
 
7
- Representable is helpful for all kind of rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead.
7
+ Representable is helpful for all kind of rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [Roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead.
8
8
 
9
9
 
10
10
  ## Installation
@@ -264,7 +264,7 @@ end
264
264
 
265
265
  Just use an inline representer or the `extend:` option to define nested properties. Accessors for nested properties will still be called on the outer object (here, `song`). And as always, this works both ways for rendering and parsing.
266
266
 
267
- Note that `nested` works with decorators, only. We might add it for modules soon.
267
+ Note that `::nested` internally is implemented using `Decorator`. When adding methods inside the `nested` block, make sure to use `represented` (`self` will point to the decorator instance).
268
268
 
269
269
 
270
270
  ## Decorator vs. Extend
@@ -452,6 +452,15 @@ Song.new(:title => "Truth Hits Everybody", :copyright => "The Police").
452
452
  #=> {"title":"Truth Hits Everybody","copyright":"The Police"}
453
453
  ```
454
454
 
455
+ With decorators, you - surprisingly - use class inheritance.
456
+
457
+ ```ruby
458
+ class HitRepresenter < SongRepresenter
459
+ collection :airplays
460
+ ```
461
+
462
+
463
+
455
464
  ## Overriding Properties
456
465
 
457
466
  You might want to override a particular property in an inheriting representer. Successively calling `property(name)` will override the former definition for `name` just as you know it from overriding methods.
@@ -468,6 +477,90 @@ end
468
477
  This behaviour was added in 1.7.
469
478
 
470
479
 
480
+ ## Partly Overriding Properties
481
+
482
+ If you wanna override only certain options of the property, use `:inherit`.
483
+
484
+ ```ruby
485
+ module SongRepresenter
486
+ include Representable::JSON
487
+
488
+ property :title, as: :known_as
489
+ end
490
+ ```
491
+
492
+ You can now inherit but still override or add options.
493
+
494
+ ```ruby
495
+ module CoverSongRepresenter
496
+ include Representable::JSON
497
+ include SongRepresenter
498
+
499
+ property :title, getter: lambda { Title.random }, inherit: true
500
+ end
501
+ ```
502
+
503
+ This will result in a property having the following options.
504
+
505
+ ```ruby
506
+ property :title,
507
+ as: :known_as, # inherited from SongRepresenter
508
+ getter: lambda { .. } # added in inheriting representer.
509
+ end
510
+ ```
511
+
512
+ ## Inheritance With Inline Representers
513
+
514
+ Inheriting also works for inline representers.
515
+
516
+ ```ruby
517
+ module SongRepresenter
518
+ include Representable::JSON
519
+
520
+ property :title
521
+ property :label do
522
+ property :name
523
+ end
524
+ end
525
+ ```
526
+
527
+ You can now override or add properties with the inline representer.
528
+
529
+ ```ruby
530
+ module HitRepresenter
531
+ include Representable::JSON
532
+ include SongRepresenter
533
+
534
+ property :label, inherit: true do
535
+ property :country
536
+ end
537
+ end
538
+ ```
539
+
540
+ Results in a combined inline representer as it inherits.
541
+
542
+ ```ruby
543
+ property :label do
544
+ property :name
545
+ property :country
546
+ end
547
+ ```
548
+
549
+ Note that the following also works.
550
+
551
+ ```ruby
552
+ module HitRepresenter
553
+ include Representable::JSON
554
+ include SongRepresenter
555
+
556
+ property :label, as: :company, inherit: true
557
+ end
558
+ ```
559
+
560
+ This renames the property but still inherits all the inlined configuration.
561
+
562
+ Basically, `:inherit` copies the configuration from the parent property, then merges it your options from the inheriting representer. It exposes the same behaviour as `super` in Ruby - when using `:inherit` the property must exist in the parent representer.
563
+
471
564
  ## Polymorphic Extend
472
565
 
473
566
  Sometimes heterogenous collections of objects from different classes must be represented. Or you don't know which representer to use at compile-time and need to delay the computation until runtime. This is why `:extend` accepts a lambda, too.
@@ -874,6 +967,16 @@ hit.to_json # this will call hit.song.to_json
874
967
 
875
968
  Rendering `collection`s works the same. Parsing doesn't work out-of-the-box, currently, as we're still unsure how to map items to fragments.
876
969
 
970
+ ### Decorator In Module
971
+
972
+ Inline representers defined in a module can be implemented as a decorator, thus wrapping the represented object without pollution.
973
+
974
+ ```ruby
975
+ property :label, decorator: true do
976
+ ...
977
+ end
978
+ ```
979
+
877
980
  ## Copyright
878
981
 
879
982
  Representable started as a heavily simplified fork of the ROXML gem. Big thanks to Ben Woosley for his inspiring work.
@@ -152,23 +152,49 @@ private
152
152
 
153
153
  # Internal module for DSL sugar that should not go into the core library.
154
154
  module DSLAdditions
155
+ # Allows you to nest a block of properties in a separate section while still mapping them to the outer object.
156
+ def nested(name, options={}, &block)
157
+ options = options.merge(
158
+ :decorator => true,
159
+ :getter => lambda { |*| self },
160
+ :setter => lambda { |*| },
161
+ :instance => lambda { |*| self }
162
+ )
163
+
164
+ property(name, options, &block)
165
+ end
166
+
155
167
  def property(name, options={}, &block)
156
- return super unless block_given?
168
+ parent = representable_attrs[name]
157
169
 
158
- inline = inline_representer(representer_engine, name, options, &block)
159
- inline.module_eval { include options[:extend] } if options[:extend]
170
+ if block_given?
171
+ options[:extend] = inline_representer_for(parent, name, options, &block) # FIXME: passing parent sucks since we don't use it all the time.
172
+ end
173
+
174
+ if options[:inherit]
175
+ parent.options.merge!(options) and return parent
176
+ end # FIXME: can we handle this in super/Definition.new ?
160
177
 
161
- options[:extend] = inline
162
178
  super
163
179
  end
164
180
 
165
- private
166
181
  def inline_representer(base_module, name, options, &block) # DISCUSS: separate module?
167
182
  Module.new do
168
- include base_module
183
+ include *base_module # Representable::JSON or similar.
169
184
  instance_exec &block
170
185
  end
171
186
  end
187
+
188
+ private
189
+ def inline_representer_for(parent, name, options, &block)
190
+ representer = options[:decorator] ? Decorator : self
191
+
192
+ modules = [representer_engine]
193
+ modules << parent.representer_module if options[:inherit]
194
+ modules << options[:extend]
195
+
196
+ representer.inline_representer(modules.compact.reverse, name, options, &block)
197
+ end
172
198
  end # DSLAdditions
173
199
  end
174
200
 
@@ -65,6 +65,8 @@ module Representable
65
65
  read(doc)
66
66
  end
67
67
 
68
+ # concept: Option#call(*args) => send(string)/lambda()
69
+ # dynamic string
68
70
  def get
69
71
  represented_exec_for(:getter) do
70
72
  exec_context.send(getter)
@@ -15,24 +15,12 @@ module Representable
15
15
  representable_attrs.clear
16
16
  representable_attrs.inheritable_arrays.clear
17
17
 
18
- include base_module
18
+ include *base_module
19
19
  instance_exec &block
20
20
  end
21
21
  end
22
22
  end
23
23
 
24
- # Allows you to nest a block of properties in a separate section while still mapping them to the outer object.
25
- def self.nested(name, options={}, &block)
26
- options = options.merge(
27
- :nested => true,
28
- :getter => lambda { |*| self },
29
- :setter => lambda { |*| },
30
- :instance => lambda { |*| self }
31
- )
32
-
33
- property(name, options, &block)
34
- end
35
-
36
24
  include Representable # include after class methods so Decorator::prepare can't be overwritten by Representable::prepare.
37
25
 
38
26
  def initialize(represented)
@@ -28,7 +28,7 @@ module Representable
28
28
 
29
29
  def from_hash(data, options={}, binding_builder=PropertyBinding)
30
30
  if wrap = options[:wrap] || representation_wrap
31
- data = data[wrap.to_s]
31
+ data = data[wrap.to_s] || {} # DISCUSS: don't initialize this more than once. # TODO: this should be done with #read.
32
32
  end
33
33
 
34
34
  update_properties_from(data, options, binding_builder)
@@ -1,3 +1,3 @@
1
1
  module Representable
2
- VERSION = "1.7.6"
2
+ VERSION = "1.7.7"
3
3
  end
@@ -225,4 +225,25 @@ class GenericTest < MiniTest::Spec
225
225
  must_equal({"song"=>{"artist"=>"Strung Out", "title"=>"The Fever And The Sound"}})
226
226
  end
227
227
  end
228
+
229
+
230
+ # wrap_test
231
+ for_formats(
232
+ :hash => [Representable::Hash, {}],
233
+ # :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"],
234
+ # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
235
+ ) do |format, mod, input|
236
+
237
+ describe "parsing [#{format}] with wrap where wrap is missing" do
238
+ representer!(:module => mod) do
239
+ self.representation_wrap = :song
240
+
241
+ property :title
242
+ end
243
+
244
+ it "doesn't change represented object" do
245
+ song.extend(representer).send("from_#{format}", input).title.must_equal "Resist Stance"
246
+ end
247
+ end
248
+ end
228
249
  end
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+
3
+ class InheritTest < MiniTest::Spec
4
+ module SongRepresenter # it's important to have a global module so we can test if stuff gets overridden in the original module.
5
+ include Representable::Hash
6
+ property :name, :as => :title do
7
+ property :string, :as => :str
8
+ end
9
+
10
+ property :track, :as => :no
11
+ end
12
+
13
+ let (:song) { Song.new(Struct.new(:string).new("Roxanne"), 1) }
14
+
15
+ describe ":inherit plain property" do
16
+ representer! do
17
+ include SongRepresenter
18
+
19
+ property :track, :inherit => true, :getter => lambda { |*| "n/a" }
20
+ end
21
+
22
+ it { SongRepresenter.prepare(song).to_hash.must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>1}) }
23
+ it { representer.prepare(song).to_hash.must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>"n/a"}) } # as: inherited.
24
+ end
25
+
26
+ describe ":inherit with empty inline representer" do
27
+ representer! do
28
+ include SongRepresenter
29
+
30
+ property :name, :inherit => true do # inherit as: title
31
+ # that doesn't make sense.
32
+ end
33
+ end
34
+
35
+ it { SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
36
+ it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
37
+ end
38
+
39
+ describe ":inherit with overriding inline representer" do
40
+ representer! do
41
+ include SongRepresenter
42
+
43
+ property :name, :inherit => true do # inherit as: title
44
+ property :string, :as => :s
45
+ property :length
46
+ end
47
+ end
48
+
49
+ it { representer.prepare( Song.new(Struct.new(:string, :length).new("Believe It", 10), 1)).to_hash.must_equal({"title"=>{"s"=>"Believe It","length"=>10}, "no"=>1}) }
50
+ end
51
+
52
+ describe ":inherit with empty inline and options" do
53
+ representer! do
54
+ include SongRepresenter
55
+
56
+ property :name, :inherit => true, :as => :name do # inherit module, only.
57
+ # that doesn't make sense.
58
+ end
59
+ end
60
+
61
+ it { SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
62
+ it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
63
+ end
64
+
65
+ describe ":inherit with inline without block but options" do
66
+ representer! do
67
+ include SongRepresenter
68
+
69
+ property :name, :inherit => true, :as => :name
70
+ end
71
+
72
+ it { SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
73
+ it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
74
+ end
75
+
76
+ end
@@ -18,4 +18,5 @@ class InheritanceTest < MiniTest::Spec
18
18
 
19
19
  # TODO: ? (performance?)
20
20
  # more tests on cloning
21
- end
21
+ #
22
+ end
@@ -57,28 +57,55 @@ class InlineTest < MiniTest::Spec
57
57
  it { request.to_hash.must_equal({"song"=>{"name"=>"Alive"}}) }
58
58
  end
59
59
 
60
- describe "decorator" do
61
- let (:request) { representer.prepare(OpenStruct.new(:song => song, :who => "Josephine")) }
62
60
 
63
- let (:representer) do
64
- Class.new(Representable::Decorator) do
65
- include Representable::Hash
61
+ for_formats(
62
+ :hash => [Representable::Hash, {}],
63
+ # :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"],
64
+ # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
65
+ ) do |format, mod, input|
66
+
67
+ describe "parsing [#{format}] where nested property missing" do
68
+ representer!(:module => mod) do
69
+ property :song do
70
+ property :name
71
+ end
72
+ end
73
+
74
+ it "doesn't change represented object" do
75
+ request.send("from_#{format}", input).song.must_equal song
76
+ end
77
+ end
78
+ end
66
79
 
67
- property :who
80
+
81
+ describe "inheriting from outer representer" do
82
+ let (:request) { Struct.new(:song, :requester).new(song, "Josephine") }
83
+
84
+ [false, true].each do |is_decorator| # test for module and decorator.
85
+ representer!(:decorator => is_decorator) do
86
+ property :requester
68
87
 
69
88
  property :song, :class => Song do
70
89
  property :name
71
90
  end
72
-
73
- self
74
91
  end
92
+
93
+ let (:decorator) { representer.prepare(request) }
94
+
95
+ it { decorator.to_hash.must_equal({"requester"=>"Josephine", "song"=>{"name"=>"Alive"}}) }
96
+ it { decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name.must_equal "You've Taken Everything"}
75
97
  end
98
+ end
76
99
 
77
- it { request.to_hash.must_equal({"who"=>"Josephine", "song"=>{"name"=>"Alive"}}) }
78
- it { request.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name.must_equal "You've Taken Everything"}
100
+ describe "object pollution" do
101
+ representer!(:decorator => true) do
102
+ property :song do
103
+ property :name
104
+ end
105
+ end
79
106
 
80
- it "uses an inline decorator" do
81
- request.to_hash
107
+ it "uses an inline decorator and doesn't alter represented" do
108
+ representer.prepare(Struct.new(:song).new(song)).to_hash
82
109
  song.wont_be_kind_of Representable
83
110
  end
84
111
  end
@@ -141,4 +168,38 @@ class InlineTest < MiniTest::Spec
141
168
  end
142
169
  end
143
170
  end
171
+
172
+
173
+ # test helper methods within inline representer
174
+ for_formats({
175
+ :hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}],
176
+ :xml => [Representable::XML, "<request>\n <song>\n <name>ALIVE</name>\n </song>\n</request>"],
177
+ :yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"],
178
+ }) do |format, mod, output|
179
+
180
+ describe "helper method within inline representer [#{format}]" do
181
+ let (:format) { format }
182
+
183
+ representer!(:module => mod, :decorator => true) do
184
+ self.representation_wrap = :request if format == :xml
185
+
186
+ property :requester
187
+ property :song do
188
+ property :name, :decorator_scope => true
189
+
190
+ define_method :name do
191
+ represented.name.upcase
192
+ end
193
+
194
+ self.representation_wrap = :song if format == :xml
195
+ end
196
+ end
197
+
198
+ let (:request) { representer.prepare(OpenStruct.new(:song => Song.new("Alive"))) }
199
+
200
+ it do
201
+ render(request).must_equal_document output
202
+ end
203
+ end
204
+ end
144
205
  end
@@ -1,41 +1,46 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class NestedTest < MiniTest::Spec
4
- Album = Struct.new(:label, :owner)
4
+ Album = Struct.new(:label, :owner, :amount)
5
5
 
6
6
  for_formats(
7
- :hash => [Representable::Hash, {"label" => {"label"=>"Epitaph", "owner"=>"Brett Gurewitz"}}],
7
+ :hash => [Representable::Hash, {"label" => {"label"=>"Epitaph", "owner"=>"Brett Gurewitz", "releases"=>{"amount"=>19}}}],
8
8
  # :xml => [Representable::XML, "<open_struct></open_struct>"],
9
- :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
9
+ :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n releases:\n amount: 19\n"]
10
10
  ) do |format, mod, output, input|
11
11
 
12
- # describe "::nested with inline representer" do
13
- # let (:format) { format }
12
+ [false, true].each do |is_decorator|
13
+ describe "::nested with (inline representer|decorator): #{is_decorator}" do
14
+ let (:format) { format }
14
15
 
15
- # representer!(:module => mod) do
16
- # nested :label do
17
- # property :label
18
- # property :owner
16
+ representer!(:module => mod, :decorator => is_decorator) do
17
+ nested :label do
18
+ property :label
19
+ property :owner
19
20
 
20
- # # self.representation_wrap = nil if format == :xml
21
- # end
21
+ # self.representation_wrap = nil if format == :xml
22
+ nested :releases do
23
+ property :amount
24
+ end
25
+ end
22
26
 
27
+ # self.representation_wrap = :album if format == :xml
28
+ end
23
29
 
24
- # self.representation_wrap = :album if format == :xml
25
- # end
30
+ let (:album) { representer.prepare(Album.new("Epitaph", "Brett Gurewitz", 19)) }
26
31
 
27
- # let (:album) { Album.new("Epitaph", "Brett Gurewitz").extend(representer) }
32
+ it "renders nested Album-properties in separate section" do
33
+ render(album).must_equal_document output
34
+ end
28
35
 
29
- # it "renders nested Album-properties in separate section" do
30
- # render(album).must_equal_document output
31
- # end
36
+ it "parses nested properties to Album instance" do
37
+ album = parse(representer.prepare(Album.new), output)
38
+ album.label.must_equal "Epitaph"
39
+ album.owner.must_equal "Brett Gurewitz"
40
+ end
41
+ end
42
+ end
32
43
 
33
- # it "parses nested properties to Album instance" do
34
- # album = parse(Album.new.extend(representer), output)
35
- # album.label.must_equal "Epitaph"
36
- # album.owner.must_equal "Brett Gurewitz"
37
- # end
38
- # end
39
44
 
40
45
  describe "Decorator ::nested with extend:" do
41
46
  let (:format) { format }
@@ -44,6 +49,10 @@ class NestedTest < MiniTest::Spec
44
49
  include mod
45
50
  property :label
46
51
  property :owner
52
+
53
+ nested :releases do # DISCUSS: do we need to test this?
54
+ property :amount
55
+ end
47
56
  end
48
57
 
49
58
  representer!(:module => mod, :decorator => true, :inject => :label_rpr) do
@@ -52,7 +61,7 @@ class NestedTest < MiniTest::Spec
52
61
  self.representation_wrap = :album if format == :xml
53
62
  end
54
63
 
55
- let (:album) { representer.prepare(Album.new("Epitaph", "Brett Gurewitz")) }
64
+ let (:album) { representer.prepare(Album.new("Epitaph", "Brett Gurewitz", 19)) }
56
65
 
57
66
  # TODO: shared example with above.
58
67
  it "renders nested Album-properties in separate section" do
@@ -63,34 +72,7 @@ class NestedTest < MiniTest::Spec
63
72
  album = parse(representer.prepare(Album.new), output)
64
73
  album.label.must_equal "Epitaph"
65
74
  album.owner.must_equal "Brett Gurewitz"
66
- end
67
- end
68
-
69
- describe "Decorator ::nested" do
70
- let (:format) { format }
71
-
72
- representer!(:module => mod, :decorator => true) do
73
- nested :label do
74
- property :label
75
- property :owner
76
-
77
- # self.representation_wrap = nil if format == :xml
78
- end
79
-
80
-
81
- self.representation_wrap = :album if format == :xml
82
- end
83
-
84
- let (:album) { representer.prepare(Album.new("Epitaph", "Brett Gurewitz")) }
85
-
86
- it "renders nested Album-properties in separate section" do
87
- render(album).must_equal_document output
88
- end
89
-
90
- it "parses nested properties to Album instance" do
91
- album = parse(representer.prepare(Album.new), output)
92
- album.label.must_equal "Epitaph"
93
- album.owner.must_equal "Brett Gurewitz"
75
+ album.amount.must_equal 19
94
76
  end
95
77
  end
96
78
  end
metadata CHANGED
@@ -1,153 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: representable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.6
4
+ version: 1.7.7
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-02-19 00:00:00.000000000 Z
11
+ date: 2014-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: test_xml
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.1.6
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.1.6
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: minitest
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: 5.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: 5.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: mocha
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: 0.13.0
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
96
  version: 0.13.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: mongoid
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: virtus
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ~>
116
116
  - !ruby/object:Gem::Version
117
117
  version: 0.5.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ~>
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.5.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: yajl-ruby
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - '>='
130
130
  - !ruby/object:Gem::Version
131
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
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: json
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ~>
144
144
  - !ruby/object:Gem::Version
145
145
  version: 1.7.7
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ~>
151
151
  - !ruby/object:Gem::Version
152
152
  version: 1.7.7
153
153
  description: Renders and parses JSON/XML/YAML documents from and to Ruby objects.
@@ -158,8 +158,8 @@ executables: []
158
158
  extensions: []
159
159
  extra_rdoc_files: []
160
160
  files:
161
- - ".gitignore"
162
- - ".travis.yml"
161
+ - .gitignore
162
+ - .travis.yml
163
163
  - CHANGES.md
164
164
  - Gemfile
165
165
  - LICENSE
@@ -202,6 +202,7 @@ files:
202
202
  - test/generic_test.rb
203
203
  - test/hash_bindings_test.rb
204
204
  - test/hash_test.rb
205
+ - test/inherit_test.rb
205
206
  - test/inheritance_test.rb
206
207
  - test/inline_test.rb
207
208
  - test/json_test.rb
@@ -222,38 +223,19 @@ require_paths:
222
223
  - lib
223
224
  required_ruby_version: !ruby/object:Gem::Requirement
224
225
  requirements:
225
- - - ">="
226
+ - - '>='
226
227
  - !ruby/object:Gem::Version
227
228
  version: '0'
228
229
  required_rubygems_version: !ruby/object:Gem::Requirement
229
230
  requirements:
230
- - - ">="
231
+ - - '>='
231
232
  - !ruby/object:Gem::Version
232
233
  version: '0'
233
234
  requirements: []
234
235
  rubyforge_project:
235
- rubygems_version: 2.2.1
236
+ rubygems_version: 2.0.2
236
237
  signing_key:
237
238
  specification_version: 4
238
239
  summary: Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes
239
240
  plain properties, collections, nesting, coercion and more.
240
- test_files:
241
- - test/coercion_test.rb
242
- - test/config_test.rb
243
- - test/decorator_test.rb
244
- - test/definition_test.rb
245
- - test/example.rb
246
- - test/generic_test.rb
247
- - test/hash_bindings_test.rb
248
- - test/hash_test.rb
249
- - test/inheritance_test.rb
250
- - test/inline_test.rb
251
- - test/json_test.rb
252
- - test/mongoid_test.rb
253
- - test/nested_test.rb
254
- - test/representable_test.rb
255
- - test/test_helper.rb
256
- - test/test_helper_test.rb
257
- - test/xml_bindings_test.rb
258
- - test/xml_test.rb
259
- - test/yaml_test.rb
241
+ test_files: []