representable 2.4.0.rc3 → 2.4.0.rc4
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 +7 -2
- data/Rakefile +6 -0
- data/lib/representable.rb +21 -17
- data/lib/representable/binding.rb +3 -2
- data/lib/representable/definition.rb +1 -1
- data/lib/representable/deprecations.rb +31 -5
- data/lib/representable/deserializer.rb +24 -34
- data/lib/representable/hash/collection.rb +9 -2
- data/lib/representable/hash_methods.rb +2 -2
- data/lib/representable/parse_strategies.rb +6 -7
- data/lib/representable/pipeline.rb +12 -1
- data/lib/representable/pipeline_factories.rb +9 -2
- data/lib/representable/serializer.rb +3 -3
- data/lib/representable/version.rb +1 -1
- data/test-with-deprecations/as_test.rb +65 -0
- data/test-with-deprecations/benchmarking.rb +83 -0
- data/test-with-deprecations/binding_test.rb +46 -0
- data/test-with-deprecations/blaaaaaaaa_test.rb +69 -0
- data/test-with-deprecations/cached_test.rb +147 -0
- data/test-with-deprecations/class_test.rb +119 -0
- data/test-with-deprecations/coercion_test.rb +52 -0
- data/test-with-deprecations/config/inherit_test.rb +135 -0
- data/test-with-deprecations/config_test.rb +122 -0
- data/test-with-deprecations/decorator_scope_test.rb +28 -0
- data/test-with-deprecations/decorator_test.rb +96 -0
- data/test-with-deprecations/default_test.rb +34 -0
- data/test-with-deprecations/defaults_options_test.rb +93 -0
- data/test-with-deprecations/definition_test.rb +264 -0
- data/test-with-deprecations/example.rb +310 -0
- data/test-with-deprecations/examples/object.rb +31 -0
- data/test-with-deprecations/exec_context_test.rb +93 -0
- data/test-with-deprecations/features_test.rb +70 -0
- data/test-with-deprecations/filter_test.rb +57 -0
- data/test-with-deprecations/for_collection_test.rb +74 -0
- data/test-with-deprecations/generic_test.rb +116 -0
- data/test-with-deprecations/getter_setter_test.rb +21 -0
- data/test-with-deprecations/hash_bindings_test.rb +87 -0
- data/test-with-deprecations/hash_test.rb +160 -0
- data/test-with-deprecations/heritage_test.rb +62 -0
- data/test-with-deprecations/if_test.rb +79 -0
- data/test-with-deprecations/include_exclude_test.rb +88 -0
- data/test-with-deprecations/inherit_test.rb +159 -0
- data/test-with-deprecations/inline_test.rb +272 -0
- data/test-with-deprecations/instance_test.rb +266 -0
- data/test-with-deprecations/is_representable_test.rb +77 -0
- data/test-with-deprecations/json_test.rb +355 -0
- data/test-with-deprecations/lonely_test.rb +239 -0
- data/test-with-deprecations/mongoid_test.rb +31 -0
- data/test-with-deprecations/nested_test.rb +115 -0
- data/test-with-deprecations/object_test.rb +60 -0
- data/{test/---deserialize-pipeline_test.rb → test-with-deprecations/parse_pipeline_test.rb} +29 -2
- data/test-with-deprecations/parse_strategy_test.rb +279 -0
- data/{test → test-with-deprecations}/pass_options_test.rb +0 -0
- data/test-with-deprecations/pipeline_test.rb +277 -0
- data/test-with-deprecations/populator_test.rb +105 -0
- data/test-with-deprecations/prepare_test.rb +67 -0
- data/test-with-deprecations/private_options_test.rb +18 -0
- data/test-with-deprecations/reader_writer_test.rb +19 -0
- data/test-with-deprecations/realistic_benchmark.rb +115 -0
- data/test-with-deprecations/render_nil_test.rb +21 -0
- data/test-with-deprecations/represent_test.rb +88 -0
- data/test-with-deprecations/representable_test.rb +511 -0
- data/test-with-deprecations/schema_test.rb +148 -0
- data/test-with-deprecations/serialize_deserialize_test.rb +33 -0
- data/test-with-deprecations/skip_test.rb +81 -0
- data/test-with-deprecations/stringify_hash_test.rb +41 -0
- data/test-with-deprecations/test_helper.rb +135 -0
- data/test-with-deprecations/test_helper_test.rb +25 -0
- data/test-with-deprecations/uncategorized_test.rb +67 -0
- data/test-with-deprecations/user_options_test.rb +15 -0
- data/test-with-deprecations/wrap_test.rb +152 -0
- data/test-with-deprecations/xml_bindings_test.rb +62 -0
- data/test-with-deprecations/xml_test.rb +503 -0
- data/test-with-deprecations/yaml_test.rb +162 -0
- data/test/as_test.rb +3 -3
- data/test/cached_test.rb +2 -2
- data/test/class_test.rb +5 -5
- data/test/exec_context_test.rb +2 -2
- data/test/filter_test.rb +1 -1
- data/test/getter_setter_test.rb +4 -4
- data/test/if_test.rb +2 -2
- data/test/include_exclude_test.rb +88 -0
- data/test/instance_test.rb +15 -15
- data/test/lonely_test.rb +18 -2
- data/test/object_test.rb +4 -4
- data/test/parse_pipeline_test.rb +64 -0
- data/test/parse_strategy_test.rb +3 -3
- data/test/pipeline_test.rb +8 -12
- data/test/prepare_test.rb +2 -3
- data/test/reader_writer_test.rb +3 -3
- data/test/representable_test.rb +12 -48
- data/test/serialize_deserialize_test.rb +9 -9
- data/test/skip_test.rb +11 -11
- data/test/test_helper.rb +2 -0
- data/test/uncategorized_test.rb +10 -10
- data/test/user_options_test.rb +15 -0
- data/test/wrap_test.rb +1 -1
- metadata +65 -4
@@ -0,0 +1,31 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
require "ostruct"
|
4
|
+
require "pp"
|
5
|
+
|
6
|
+
|
7
|
+
source = OpenStruct.new(name: "30 Years Live", songs: [
|
8
|
+
OpenStruct.new(id: 1, title: "Dear Beloved"), OpenStruct.new(id: 2, title: "Fuck Armageddon")])
|
9
|
+
|
10
|
+
pp source
|
11
|
+
|
12
|
+
require "representable/object"
|
13
|
+
|
14
|
+
class AlbumRepresenter < Representable::Decorator
|
15
|
+
include Representable::Object
|
16
|
+
|
17
|
+
property :name
|
18
|
+
collection :songs, instance: ->(fragment, *) { Song.new } do
|
19
|
+
property :title
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
Album = Struct.new(:name, :songs)
|
25
|
+
Song = Struct.new(:title)
|
26
|
+
|
27
|
+
target = Album.new
|
28
|
+
|
29
|
+
AlbumRepresenter.new(target).from_object(source)
|
30
|
+
|
31
|
+
pp target
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExecContextTest < MiniTest::Spec
|
4
|
+
for_formats(
|
5
|
+
:hash => [Representable::Hash, {Song => "Rebel Fate"}, {Song=>"Timing"}],
|
6
|
+
# :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>"],
|
7
|
+
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
8
|
+
) do |format, mod, input, output|
|
9
|
+
|
10
|
+
let (:song) { representer.prepare(Song.new("Timing")) }
|
11
|
+
let (:format) { format }
|
12
|
+
|
13
|
+
|
14
|
+
describe "exec_context: nil" do
|
15
|
+
representer!(:module => mod) do
|
16
|
+
property :name, :as => lambda { |*| self.class }
|
17
|
+
end
|
18
|
+
|
19
|
+
it { render(song).must_equal_document output }
|
20
|
+
it { parse(song, input).name.must_equal "Rebel Fate" }
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe "exec_context: :decorator" do
|
25
|
+
representer!(:module => mod) do
|
26
|
+
property :name, :as => lambda { |*| self.class }, :exec_context => :decorator
|
27
|
+
end
|
28
|
+
|
29
|
+
it { render(song).must_equal_document output }
|
30
|
+
it { parse(song, input).name.must_equal "Rebel Fate" }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe "exec_context: :binding" do
|
35
|
+
representer!(:module => mod) do
|
36
|
+
property :name,
|
37
|
+
:as => lambda { |*| self.class }, # to actually test
|
38
|
+
:exec_context => :binding,
|
39
|
+
:setter => lambda { |v, *args| represented.name = v # to make parsing work.
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) }
|
44
|
+
it { parse(song, {Representable::Hash::Binding => "Rebel Fate"}).name.must_equal "Rebel Fate" }
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
describe "Decorator" do
|
49
|
+
# DISCUSS: do we need this test?
|
50
|
+
describe "exec_context: nil" do
|
51
|
+
representer!(:module => mod, :decorator => true) do
|
52
|
+
property :name, :as => lambda { |*| self.class }
|
53
|
+
end
|
54
|
+
|
55
|
+
it { render(song).must_equal_document output }
|
56
|
+
it { parse(song, input).name.must_equal "Rebel Fate" }
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
describe "exec_context: :decorator" do # this tests if lambdas are run in the right context, if methods are called in the right context and if we can access the represented object.
|
61
|
+
representer!(:module => mod, :decorator => true) do
|
62
|
+
property :name, :as => lambda { |*| self.class.superclass }, :exec_context => :decorator
|
63
|
+
|
64
|
+
define_method :name do # def in Decorator class.
|
65
|
+
"Timebomb"
|
66
|
+
end
|
67
|
+
|
68
|
+
define_method :"name=" do |v| # def in Decorator class.
|
69
|
+
represented.name = v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it { render(song).must_equal_document({Representable::Decorator=>"Timebomb"}) }
|
74
|
+
it { parse(song, {Representable::Decorator=>"Listless"}).name.must_equal "Listless" }
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# DISCUSS: do we need this test?
|
79
|
+
describe "exec_context: :binding" do
|
80
|
+
representer!(:module => mod, :decorator => true) do
|
81
|
+
property :name,
|
82
|
+
:as => lambda { |*| self.class }, # to actually test
|
83
|
+
:exec_context => :binding,
|
84
|
+
:setter => lambda { |v, *args| represented.name = v # to make parsing work.
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
it { render(song).must_equal_document({Representable::Hash::Binding => "name"}) }
|
89
|
+
it("xxx") { parse(song, {Representable::Hash::Binding => "Rebel Fate"}).name.must_equal "Rebel Fate" }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FeaturesTest < MiniTest::Spec
|
4
|
+
module Title
|
5
|
+
def title; "Is It A Lie"; end
|
6
|
+
end
|
7
|
+
module Length
|
8
|
+
def length; "2:31"; end
|
9
|
+
end
|
10
|
+
|
11
|
+
definition = lambda {
|
12
|
+
feature Title
|
13
|
+
feature Length
|
14
|
+
|
15
|
+
# exec_context: :decorator, so the readers are called on the Decorator instance (which gets readers from features!).
|
16
|
+
property :title, exec_context: :decorator
|
17
|
+
property :length, exec_context: :decorator
|
18
|
+
property :details do
|
19
|
+
property :title, exec_context: :decorator
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
let (:song) { OpenStruct.new(:details => Object.new) }
|
24
|
+
|
25
|
+
describe "Module" do
|
26
|
+
representer! do
|
27
|
+
instance_exec &definition
|
28
|
+
end
|
29
|
+
|
30
|
+
it { song.extend(representer).to_hash.must_equal({"title"=>"Is It A Lie", "length"=>"2:31", "details"=>{"title"=>"Is It A Lie"}}) }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe "Decorator" do
|
35
|
+
representer!(:decorator => true) do
|
36
|
+
instance_exec &definition
|
37
|
+
end
|
38
|
+
|
39
|
+
it { representer.new(song).to_hash.must_equal({"title"=>"Is It A Lie", "length"=>"2:31", "details"=>{"title"=>"Is It A Lie"}}) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class FeatureInclusionOrderTest < MiniTest::Spec
|
44
|
+
module Title
|
45
|
+
def title
|
46
|
+
"I was first!"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module OverridingTitle
|
51
|
+
def title
|
52
|
+
"I am number two, " + super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
representer!(decorator: true) do
|
57
|
+
feature Title
|
58
|
+
feature OverridingTitle
|
59
|
+
|
60
|
+
property :title, exec_context: :decorator
|
61
|
+
|
62
|
+
property :song do
|
63
|
+
property :title, exec_context: :decorator
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it do
|
68
|
+
representer.new(OpenStruct.new(song: Object)).to_hash.must_equal({"title"=>"I am number two, I was first!", "song"=>{"title"=>"I am number two, I was first!"}})
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FilterPipelineTest < MiniTest::Spec
|
4
|
+
let (:block1) { lambda { |input, options| "1: #{input}" } }
|
5
|
+
let (:block2) { lambda { |input, options| "2: #{input}" } }
|
6
|
+
|
7
|
+
subject { Representable::Pipeline[block1, block2] }
|
8
|
+
|
9
|
+
it { subject.call("Horowitz", {}).must_equal "2: 1: Horowitz" }
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
class FilterTest < MiniTest::Spec
|
14
|
+
representer! do
|
15
|
+
property :title
|
16
|
+
|
17
|
+
property :track,
|
18
|
+
:parse_filter => lambda { |input, options| "#{input.downcase},#{options[:doc]}" },
|
19
|
+
:render_filter => lambda { |val, options| "#{val.upcase},#{options[:doc]},#{options[:options][:user_options]}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
# gets doc and options.
|
23
|
+
it {
|
24
|
+
song = OpenStruct.new.extend(representer).from_hash("title" => "VULCAN EARS", "track" => "Nine")
|
25
|
+
song.title.must_equal "VULCAN EARS"
|
26
|
+
song.track.must_equal "nine,{\"title\"=>\"VULCAN EARS\", \"track\"=>\"Nine\"}"
|
27
|
+
}
|
28
|
+
|
29
|
+
it { OpenStruct.new("title" => "vulcan ears", "track" => "Nine").extend(representer).to_hash.must_equal( {"title"=>"vulcan ears", "track"=>"NINE,{\"title\"=>\"vulcan ears\"},{}"}) }
|
30
|
+
|
31
|
+
|
32
|
+
describe "#parse_filter" do
|
33
|
+
representer! do
|
34
|
+
property :track,
|
35
|
+
:parse_filter => [
|
36
|
+
lambda { |input, options| "#{input}-1" },
|
37
|
+
lambda { |input, options| "#{input}-2" }],
|
38
|
+
:render_filter => [
|
39
|
+
lambda { |val, options| "#{val}-1" },
|
40
|
+
lambda { |val, options| "#{val}-2" }]
|
41
|
+
end
|
42
|
+
|
43
|
+
# order matters.
|
44
|
+
it { OpenStruct.new.extend(representer).from_hash("track" => "Nine").track.must_equal "Nine-1-2" }
|
45
|
+
it { OpenStruct.new("track" => "Nine").extend(representer).to_hash.must_equal({"track"=>"Nine-1-2"}) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# class RenderFilterTest < MiniTest::Spec
|
51
|
+
# representer! do
|
52
|
+
# property :track, :render_filter => [lambda { |val, options| "#{val}-1" } ]
|
53
|
+
# property :track, :render_filter => [lambda { |val, options| "#{val}-2" } ], :inherit => true
|
54
|
+
# end
|
55
|
+
|
56
|
+
# it { OpenStruct.new("track" => "Nine").extend(representer).to_hash.must_equal({"track"=>"Nine-1-2"}) }
|
57
|
+
# end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ForCollectionTest < MiniTest::Spec
|
4
|
+
module SongRepresenter
|
5
|
+
include Representable::JSON
|
6
|
+
|
7
|
+
property :name
|
8
|
+
end
|
9
|
+
|
10
|
+
let (:songs) { [Song.new("Days Go By"), Song.new("Can't Take Them All")] }
|
11
|
+
let (:json) { "[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]" }
|
12
|
+
|
13
|
+
|
14
|
+
# Module.for_collection
|
15
|
+
# Decorator.for_collection
|
16
|
+
for_formats(
|
17
|
+
:hash => [Representable::Hash, out=[{"name" => "Days Go By"}, {"name"=>"Can't Take Them All"}], out],
|
18
|
+
:json => [Representable::JSON, out="[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]", out],
|
19
|
+
# :xml => [Representable::XML, out="<a><song></song><song></song></a>", out]
|
20
|
+
) do |format, mod, output, input|
|
21
|
+
|
22
|
+
describe "Module::for_collection [#{format}]" do
|
23
|
+
let (:format) { format }
|
24
|
+
|
25
|
+
let (:representer) {
|
26
|
+
Module.new do
|
27
|
+
include mod
|
28
|
+
property :name#, :as => :title
|
29
|
+
|
30
|
+
collection_representer :class => Song
|
31
|
+
|
32
|
+
# self.representation_wrap = :songs if format == :xml
|
33
|
+
end
|
34
|
+
}
|
35
|
+
|
36
|
+
it { render(songs.extend(representer.for_collection)).must_equal_document output }
|
37
|
+
it { render(representer.for_collection.prepare(songs)).must_equal_document output }
|
38
|
+
# parsing needs the class set, at least
|
39
|
+
it { parse([].extend(representer.for_collection), input).must_equal songs }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "Module::for_collection without configuration [#{format}]" do
|
43
|
+
let (:format) { format }
|
44
|
+
|
45
|
+
let (:representer) {
|
46
|
+
Module.new do
|
47
|
+
include mod
|
48
|
+
property :name
|
49
|
+
end
|
50
|
+
}
|
51
|
+
|
52
|
+
# rendering works out of the box, no config necessary
|
53
|
+
it { render(songs.extend(representer.for_collection)).must_equal_document output }
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
describe "Decorator::for_collection [#{format}]" do
|
58
|
+
let (:format) { format }
|
59
|
+
let (:representer) {
|
60
|
+
Class.new(Representable::Decorator) do
|
61
|
+
include mod
|
62
|
+
property :name
|
63
|
+
|
64
|
+
collection_representer :class => Song
|
65
|
+
end
|
66
|
+
}
|
67
|
+
|
68
|
+
it { render(representer.for_collection.new(songs)).must_equal_document output }
|
69
|
+
it { parse(representer.for_collection.new([]), input).must_equal songs }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# with module including module
|
74
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GenericTest < MiniTest::Spec # TODO: rename/restructure to CollectionTest.
|
4
|
+
let (:new_album) { OpenStruct.new.extend(representer) }
|
5
|
+
let (:album) { OpenStruct.new(:songs => ["Fuck Armageddon"]).extend(representer) }
|
6
|
+
let (:song) { OpenStruct.new(:title => "Resist Stance") }
|
7
|
+
let (:song_representer) { Module.new do include Representable::Hash; property :title end }
|
8
|
+
|
9
|
+
|
10
|
+
describe "::collection" do
|
11
|
+
representer! do
|
12
|
+
collection :songs
|
13
|
+
end
|
14
|
+
|
15
|
+
it "doesn't initialize property" do
|
16
|
+
new_album.from_hash({})
|
17
|
+
new_album.songs.must_equal nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "leaves properties untouched" do
|
21
|
+
album.from_hash({})
|
22
|
+
# TODO: test property.
|
23
|
+
album.songs.must_equal ["Fuck Armageddon"] # when the collection is not present in the incoming hash, this propery stays untouched.
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# when collection is nil, it doesn't get rendered:
|
28
|
+
for_formats(
|
29
|
+
:hash => [Representable::Hash, {}],
|
30
|
+
:xml => [Representable::XML, "<open_struct></open_struct>"],
|
31
|
+
:yaml => [Representable::YAML, "--- {}\n"], # FIXME: this doesn't look right.
|
32
|
+
) do |format, mod, output, input|
|
33
|
+
|
34
|
+
describe "nil collections" do
|
35
|
+
let (:format) { format }
|
36
|
+
|
37
|
+
representer!(:module => mod) do
|
38
|
+
collection :songs
|
39
|
+
self.representation_wrap = :album if format == :xml
|
40
|
+
end
|
41
|
+
|
42
|
+
let (:album) { Album.new.extend(representer) }
|
43
|
+
|
44
|
+
it "doesn't render collection in #{format}" do
|
45
|
+
render(album).must_equal_document output
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# when collection is set but empty, render the empty collection.
|
51
|
+
for_formats(
|
52
|
+
:hash => [Representable::Hash, {"songs" => []}],
|
53
|
+
#:xml => [Representable::XML, "<open_struct><songs/></open_struct>"],
|
54
|
+
:yaml => [Representable::YAML, "---\nsongs: []\n"],
|
55
|
+
) do |format, mod, output, input|
|
56
|
+
|
57
|
+
describe "empty collections" do
|
58
|
+
let (:format) { format }
|
59
|
+
|
60
|
+
representer!(:module => mod) do
|
61
|
+
collection :songs
|
62
|
+
self.representation_wrap = :album if format == :xml
|
63
|
+
end
|
64
|
+
|
65
|
+
let (:album) { OpenStruct.new(:songs => []).extend(representer) }
|
66
|
+
|
67
|
+
it "renders empty collection in #{format}" do
|
68
|
+
render(album).must_equal_document output
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# when collection is [], suppress rendering when render_empty: false.
|
75
|
+
for_formats(
|
76
|
+
:hash => [Representable::Hash, {}],
|
77
|
+
#:xml => [Representable::XML, "<open_struct><songs/></open_struct>"],
|
78
|
+
:yaml => [Representable::YAML, "--- {}\n"],
|
79
|
+
) do |format, mod, output, input|
|
80
|
+
|
81
|
+
describe "render_empty [#{format}]" do
|
82
|
+
let (:format) { format }
|
83
|
+
|
84
|
+
representer!(:module => mod) do
|
85
|
+
collection :songs, :render_empty => false
|
86
|
+
self.representation_wrap = :album if format == :xml
|
87
|
+
end
|
88
|
+
|
89
|
+
let (:album) { OpenStruct.new(:songs => []).extend(representer) }
|
90
|
+
|
91
|
+
it { render(album).must_equal_document output }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# wrap_test
|
98
|
+
for_formats(
|
99
|
+
:hash => [Representable::Hash, {}],
|
100
|
+
# :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>"],
|
101
|
+
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
102
|
+
) do |format, mod, input|
|
103
|
+
|
104
|
+
describe "parsing [#{format}] with wrap where wrap is missing" do
|
105
|
+
representer!(:module => mod) do
|
106
|
+
self.representation_wrap = :song
|
107
|
+
|
108
|
+
property :title
|
109
|
+
end
|
110
|
+
|
111
|
+
it "doesn't change represented object" do
|
112
|
+
song.extend(representer).send("from_#{format}", input).title.must_equal "Resist Stance"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|