representable 2.4.1 → 3.0.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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -12
  3. data/CHANGES.md +6 -27
  4. data/README.md +28 -1326
  5. data/lib/representable.rb +4 -14
  6. data/lib/representable/binding.rb +3 -7
  7. data/lib/representable/definition.rb +1 -2
  8. data/lib/representable/populator.rb +35 -0
  9. data/lib/representable/version.rb +1 -1
  10. data/test/definition_test.rb +0 -7
  11. data/test/exec_context_test.rb +2 -2
  12. data/test/instance_test.rb +0 -19
  13. data/test/realistic_benchmark.rb +0 -13
  14. data/test/representable_test.rb +0 -16
  15. data/test/skip_test.rb +1 -1
  16. data/test/test_helper.rb +0 -2
  17. metadata +3 -65
  18. data/lib/representable/deprecations.rb +0 -127
  19. data/lib/representable/parse_strategies.rb +0 -93
  20. data/test-with-deprecations/as_test.rb +0 -65
  21. data/test-with-deprecations/benchmarking.rb +0 -83
  22. data/test-with-deprecations/binding_test.rb +0 -46
  23. data/test-with-deprecations/blaaaaaaaa_test.rb +0 -69
  24. data/test-with-deprecations/cached_test.rb +0 -147
  25. data/test-with-deprecations/class_test.rb +0 -119
  26. data/test-with-deprecations/coercion_test.rb +0 -52
  27. data/test-with-deprecations/config/inherit_test.rb +0 -135
  28. data/test-with-deprecations/config_test.rb +0 -122
  29. data/test-with-deprecations/decorator_scope_test.rb +0 -28
  30. data/test-with-deprecations/decorator_test.rb +0 -96
  31. data/test-with-deprecations/default_test.rb +0 -34
  32. data/test-with-deprecations/defaults_options_test.rb +0 -93
  33. data/test-with-deprecations/definition_test.rb +0 -264
  34. data/test-with-deprecations/example.rb +0 -310
  35. data/test-with-deprecations/examples/object.rb +0 -31
  36. data/test-with-deprecations/exec_context_test.rb +0 -93
  37. data/test-with-deprecations/features_test.rb +0 -70
  38. data/test-with-deprecations/filter_test.rb +0 -57
  39. data/test-with-deprecations/for_collection_test.rb +0 -74
  40. data/test-with-deprecations/generic_test.rb +0 -116
  41. data/test-with-deprecations/getter_setter_test.rb +0 -21
  42. data/test-with-deprecations/hash_bindings_test.rb +0 -87
  43. data/test-with-deprecations/hash_test.rb +0 -160
  44. data/test-with-deprecations/heritage_test.rb +0 -62
  45. data/test-with-deprecations/if_test.rb +0 -79
  46. data/test-with-deprecations/include_exclude_test.rb +0 -88
  47. data/test-with-deprecations/inherit_test.rb +0 -159
  48. data/test-with-deprecations/inline_test.rb +0 -272
  49. data/test-with-deprecations/instance_test.rb +0 -266
  50. data/test-with-deprecations/is_representable_test.rb +0 -77
  51. data/test-with-deprecations/json_test.rb +0 -355
  52. data/test-with-deprecations/lonely_test.rb +0 -239
  53. data/test-with-deprecations/mongoid_test.rb +0 -31
  54. data/test-with-deprecations/nested_test.rb +0 -115
  55. data/test-with-deprecations/object_test.rb +0 -60
  56. data/test-with-deprecations/parse_pipeline_test.rb +0 -64
  57. data/test-with-deprecations/parse_strategy_test.rb +0 -279
  58. data/test-with-deprecations/pass_options_test.rb +0 -27
  59. data/test-with-deprecations/pipeline_test.rb +0 -277
  60. data/test-with-deprecations/populator_test.rb +0 -105
  61. data/test-with-deprecations/prepare_test.rb +0 -67
  62. data/test-with-deprecations/private_options_test.rb +0 -18
  63. data/test-with-deprecations/reader_writer_test.rb +0 -19
  64. data/test-with-deprecations/realistic_benchmark.rb +0 -115
  65. data/test-with-deprecations/render_nil_test.rb +0 -21
  66. data/test-with-deprecations/represent_test.rb +0 -88
  67. data/test-with-deprecations/representable_test.rb +0 -511
  68. data/test-with-deprecations/schema_test.rb +0 -148
  69. data/test-with-deprecations/serialize_deserialize_test.rb +0 -33
  70. data/test-with-deprecations/skip_test.rb +0 -81
  71. data/test-with-deprecations/stringify_hash_test.rb +0 -41
  72. data/test-with-deprecations/test_helper.rb +0 -135
  73. data/test-with-deprecations/test_helper_test.rb +0 -25
  74. data/test-with-deprecations/uncategorized_test.rb +0 -67
  75. data/test-with-deprecations/user_options_test.rb +0 -15
  76. data/test-with-deprecations/wrap_test.rb +0 -152
  77. data/test-with-deprecations/xml_bindings_test.rb +0 -62
  78. data/test-with-deprecations/xml_test.rb +0 -503
  79. data/test-with-deprecations/yaml_test.rb +0 -162
  80. data/test/parse_strategy_test.rb +0 -279
@@ -1,62 +0,0 @@
1
- require "test_helper"
2
-
3
- class HeritageTest < Minitest::Spec
4
- module Hello
5
- def hello
6
- puts "Hello!"
7
- end
8
- end
9
- module Ciao
10
- def ciao
11
- puts "Ciao!"
12
- end
13
- end
14
-
15
-
16
- class A < Representable::Decorator
17
- include Representable::Hash
18
-
19
- feature Hello
20
-
21
- property :id do
22
- end
23
- end
24
-
25
- class B < A
26
- feature Ciao # does NOT extend id, of course.
27
-
28
- property :id, inherit: true do
29
-
30
- end
31
- end
32
-
33
- class C < A
34
- property :id do end # overwrite old :id.
35
- end
36
-
37
- it do
38
- # puts A.heritage.inspect
39
- # puts B.heritage.inspect
40
-
41
- puts B.representable_attrs.get(:id)[:extend].(nil).new(nil).hello
42
- puts B.representable_attrs.get(:id)[:extend].(nil).new(nil).ciao
43
-
44
- # feature Hello must be "inherited" from A and included in new C properties, too.
45
- puts C.representable_attrs.get(:id)[:extend].(nil).new(nil).hello
46
- end
47
-
48
- module M
49
- include Representable
50
- feature Hello
51
- end
52
-
53
- module N
54
- include Representable
55
- include M
56
- feature Ciao
57
- end
58
-
59
- it do
60
- Object.new.extend(N).hello
61
- end
62
- end
@@ -1,79 +0,0 @@
1
- require 'test_helper'
2
-
3
- class IfTest < MiniTest::Spec
4
- let (:band_class) { Class.new do
5
- include Representable::Hash
6
- attr_accessor :fame
7
- self
8
- end }
9
-
10
- it "respects property when condition true" do
11
- band_class.class_eval { property :fame, :if => lambda { |*| true } }
12
- band = band_class.new
13
- band.from_hash({"fame"=>"oh yes"})
14
- assert_equal "oh yes", band.fame
15
- end
16
-
17
- it "ignores property when condition false" do
18
- band_class.class_eval { property :fame, :if => lambda { |*| false } }
19
- band = band_class.new
20
- band.from_hash({"fame"=>"oh yes"})
21
- assert_equal nil, band.fame
22
- end
23
-
24
- it "ignores property when :exclude'ed even when condition is true" do
25
- band_class.class_eval { property :fame, :if => lambda { |*| true } }
26
- band = band_class.new
27
- band.from_hash({"fame"=>"oh yes"}, {:exclude => [:fame]})
28
- assert_equal nil, band.fame
29
- end
30
-
31
- it "executes block in instance context" do
32
- band_class.class_eval { property :fame, :if => lambda { |*| groupies }; attr_accessor :groupies }
33
- band = band_class.new
34
- band.groupies = true
35
- band.from_hash({"fame"=>"oh yes"})
36
- assert_equal "oh yes", band.fame
37
- end
38
-
39
- describe "executing :if lambda in represented instance context" do
40
- representer! do
41
- property :label, :if => lambda { |*| signed_contract }
42
- end
43
-
44
- subject { OpenStruct.new(:signed_contract => false, :label => "Fat") }
45
-
46
- it "skips when false" do
47
- subject.extend(representer).to_hash.must_equal({})
48
- end
49
-
50
- it "represents when true" do
51
- subject.signed_contract= true
52
- subject.extend(representer).to_hash.must_equal({"label"=>"Fat"})
53
- end
54
-
55
- it "works with decorator" do
56
- rpr = representer
57
- Class.new(Representable::Decorator) do
58
- include Representable::Hash
59
- include rpr
60
- end.new(subject).to_hash.must_equal({})
61
- end
62
- end
63
-
64
-
65
- describe "propagating user options to the block" do
66
- representer! do
67
- property :name, :if => lambda { |opts| opts[:include_name] }
68
- end
69
- subject { OpenStruct.new(:name => "Outbound").extend(representer) }
70
-
71
- it "works without specifying options" do
72
- subject.to_hash.must_equal({})
73
- end
74
-
75
- it "passes user options to block" do
76
- subject.to_hash(:include_name => true).must_equal({"name" => "Outbound"})
77
- end
78
- end
79
- end
@@ -1,88 +0,0 @@
1
- require "test_helper"
2
-
3
- class IncludeExcludeTest < Minitest::Spec
4
- Song = Struct.new(:title, :artist, :id)
5
- Artist = Struct.new(:name, :id, :songs)
6
-
7
- representer!(decorator: true) do
8
- property :title
9
- property :artist, class: Artist do
10
- property :name
11
- property :id
12
-
13
- collection :songs, class: Song do
14
- property :title
15
- property :id
16
- end
17
- end
18
- end
19
-
20
- let (:song) { Song.new("Listless", Artist.new("7yearsbadluck", 1 )) }
21
- let (:decorator) { representer.new(song) }
22
-
23
- describe "#from_hash" do
24
- it "accepts :exclude option" do
25
- decorator.from_hash({"title"=>"Don't Smile In Trouble", "artist"=>{"id"=>2}}, exclude: [:title])
26
-
27
- song.title.must_equal "Listless"
28
- song.artist.must_equal Artist.new(nil, 2)
29
- end
30
-
31
- it "accepts :include option" do
32
- decorator.from_hash({"title"=>"Don't Smile In Trouble", "artist"=>{"id"=>2}}, include: [:title])
33
-
34
- song.title.must_equal "Don't Smile In Trouble"
35
- song.artist.must_equal Artist.new("7yearsbadluck", 1)
36
- end
37
-
38
- it "accepts nested :exclude/:include option" do
39
- decorator.from_hash({"title"=>"Don't Smile In Trouble", "artist"=>{"name"=>"Foo", "id"=>2, "songs"=>[{"id"=>1, "title"=>"Listless"}]}},
40
- exclude: [:title],
41
- artist: {
42
- exclude: [:id],
43
- songs: { include: [:title] }
44
- }
45
- )
46
-
47
- song.title.must_equal "Listless"
48
- song.artist.must_equal Artist.new("Foo", nil, [Song.new("Listless", nil, nil)])
49
- end
50
- end
51
-
52
- describe "#to_hash" do
53
- it "accepts :exclude option" do
54
- decorator.to_hash(exclude: [:title]).must_equal({"artist"=>{"name"=>"7yearsbadluck", "id"=>1}})
55
- end
56
-
57
- it "accepts :include option" do
58
- decorator.to_hash(include: [:title]).must_equal({"title"=>"Listless"})
59
- end
60
-
61
- it "accepts nested :exclude/:include option" do
62
- decorator = representer.new(Song.new("Listless", Artist.new("7yearsbadluck", 1, [Song.new("C.O.A.B.I.E.T.L.")])))
63
-
64
- decorator.to_hash(
65
- exclude: [:title],
66
- artist: {
67
- exclude: [:id],
68
- songs: { include: [:title] }
69
- }
70
- ).must_equal({"artist"=>{"name"=>"7yearsbadluck", "songs"=>[{"title"=>"C.O.A.B.I.E.T.L."}]}})
71
- end
72
- end
73
-
74
- it "xdoes not propagate private options to nested objects" do
75
- Cover = Struct.new(:title, :original)
76
-
77
- cover_rpr = Module.new do
78
- include Representable::Hash
79
- property :title
80
- property :original, extend: self
81
- end
82
-
83
- # FIXME: we should test all representable-options (:include, :exclude, ?)
84
-
85
- Cover.new("Roxanne", Cover.new("Roxanne (Don't Put On The Red Light)")).extend(cover_rpr).
86
- to_hash(:include => [:original]).must_equal({"original"=>{"title"=>"Roxanne (Don't Put On The Red Light)"}})
87
- end
88
- end
@@ -1,159 +0,0 @@
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
- # the block doesn't override the inline representer.
37
- it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
38
- end
39
-
40
- describe ":inherit with overriding inline representer" do
41
- representer! do
42
- include SongRepresenter
43
-
44
- puts "passing block"
45
- property :name, :inherit => true do # inherit as: title
46
- property :string, :as => :s
47
- property :length
48
- end
49
- end
50
-
51
- 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}) }
52
- end
53
-
54
- describe ":inherit with empty inline and options" do
55
- representer! do
56
- include SongRepresenter
57
-
58
- property :name, inherit: true, as: :name do # inherit module, only.
59
- # that doesn't make sense. but it should simply inherit the old nested properties.
60
- end
61
- end
62
-
63
- it { SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
64
- it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
65
- end
66
-
67
- describe ":inherit with inline without block but options" do
68
- representer! do
69
- include SongRepresenter
70
-
71
- property :name, :inherit => true, :as => :name # FIXME: add :getter or something else dynamic since this is double-wrapped.
72
- end
73
-
74
- it { SongRepresenter.prepare(Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
75
- it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"name"=>{"str"=>"Believe It"}, "no"=>1}) }
76
- end
77
-
78
-
79
-
80
- # no :inherit
81
- describe "overwriting without :inherit" do
82
- representer! do
83
- include SongRepresenter
84
-
85
- property :track, :representable => true
86
- end
87
-
88
- it "replaces inherited property" do
89
- representer.representable_attrs.size.must_equal 2
90
-
91
- definition = representer.representable_attrs.get(:track) # TODO: find a better way to assert Definition identity.
92
- # definition.keys.size.must_equal 2
93
- definition[:representable]. must_equal true
94
- definition.name.must_equal "track" # was "no".
95
- end
96
- end
97
-
98
-
99
- # decorator
100
- describe ":inherit with decorator" do
101
- representer!(:decorator => true) do
102
- property :hit do
103
- property :title, exec_context: :decorator
104
-
105
- def title
106
- "Cheap Transistor Radio"
107
- end
108
- end
109
- end
110
-
111
- let (:inheriting) {
112
- class InheritingDecorator < representer
113
- include Representable::Debug
114
- property :hit, :inherit => true do
115
- include Representable::Debug
116
- property :length
117
- end
118
- self
119
- end
120
- }
121
-
122
- it { representer.new(OpenStruct.new(hit: OpenStruct.new(title: "I WILL BE OVERRIDDEN", :length => "2:59"))).to_hash.must_equal(
123
- {"hit"=>{"title"=>"Cheap Transistor Radio"}}) }
124
-
125
- # inheriting decorator inherits inline representer class (InlineRepresenter#title).
126
- # inheriting decorator adds :length.
127
- it { inheriting.new(OpenStruct.new(:hit => OpenStruct.new(:title => "Hole In Your Soul", :length => "2:59"))).to_hash.must_equal(
128
- {"hit"=>{"title"=>"Cheap Transistor Radio", "length"=>"2:59"}}) }
129
- end
130
-
131
-
132
- # :inherit when property doesn't exist, yet.
133
- describe ":inherit without inheritable property" do
134
- representer! do
135
- property :name, :inherit => true
136
- end
137
-
138
- it { representer.prepare(Song.new("The Beginning")).to_hash.must_equal({"name"=>"The Beginning"})}
139
- end
140
- end
141
-
142
-
143
- # class InheritancingTest < MiniTest::Spec
144
- # class SongDecorator < Representable::Decorator
145
- # include Representable::Hash
146
- # property :album do
147
- # # does have Hash.
148
- # property :title
149
- # end
150
- # end
151
-
152
- # class JsonSongDecorator < SongDecorator
153
- # include Representable::XML
154
- # end
155
-
156
- # it do
157
- # puts JsonSongDecorator.new(OpenStruct.new(:album => OpenStruct.new(:title => "Erotic Cakes", :tracks => nil))).to_xml
158
- # end
159
- # end
@@ -1,272 +0,0 @@
1
- require 'test_helper'
2
-
3
- class InlineTest < MiniTest::Spec
4
- let (:song) { Song.new("Alive") }
5
- let (:request) { representer.prepare(OpenStruct.new(:song => song)) }
6
-
7
- {
8
- :hash => [Representable::Hash, {"song"=>{"name"=>"Alive"}}, {"song"=>{"name"=>"You've Taken Everything"}}],
9
- :json => [Representable::JSON, "{\"song\":{\"name\":\"Alive\"}}", "{\"song\":{\"name\":\"You've Taken Everything\"}}"],
10
- :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>"],
11
- :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
12
- }.each do |format, cfg|
13
- mod, output, input = cfg
14
-
15
- describe "[#{format}] with :class" do
16
- representer!(:module => mod) do
17
- property :song, :class => Song do
18
- property :name
19
- end
20
- end
21
-
22
- let (:format) { format }
23
-
24
- it { render(request).must_equal_document output }
25
- it { parse(request, input).song.name.must_equal "You've Taken Everything"}
26
- end
27
- end
28
-
29
- {
30
- :hash => [Representable::Hash, {"songs"=>[{"name"=>"Alive"}]}, {"songs"=>[{"name"=>"You've Taken Everything"}]}],
31
- :json => [Representable::JSON, "{\"songs\":[{\"name\":\"Alive\"}]}", "{\"songs\":[{\"name\":\"You've Taken Everything\"}]}"],
32
- :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>", { :as => :song }],
33
- :yaml => [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"],
34
- }.each do |format, cfg|
35
- mod, output, input, collection_options = cfg
36
- collection_options ||= {}
37
-
38
- describe "[#{format}] collection with :class" do
39
- let (:request) { representer.prepare(OpenStruct.new(:songs => [song])) }
40
-
41
- representer!(:module => mod) do
42
- collection :songs, collection_options.merge(:class => Song) do
43
- property :name
44
- end
45
- end
46
-
47
- let (:format) { format } # FIXME: why do we have to define this?
48
-
49
- it { render(request).must_equal_document output }
50
- it { parse(request, input).songs.first.name.must_equal "You've Taken Everything"}
51
- end
52
- end
53
-
54
- describe "without :class" do
55
- representer! do
56
- property :song do
57
- property :name
58
- end
59
- end
60
-
61
- it { request.to_hash.must_equal({"song"=>{"name"=>"Alive"}}) }
62
- end
63
-
64
-
65
- for_formats(
66
- :hash => [Representable::Hash, {}],
67
- # :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>"],
68
- # :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
69
- ) do |format, mod, input|
70
-
71
- describe "parsing [#{format}] where nested property missing" do
72
- representer!(:module => mod) do
73
- property :song do
74
- property :name
75
- end
76
- end
77
-
78
- it "doesn't change represented object" do
79
- request.send("from_#{format}", input).song.must_equal song
80
- end
81
- end
82
- end
83
-
84
-
85
- describe "inheriting from outer representer" do
86
- let (:request) { Struct.new(:song, :requester).new(song, "Josephine") }
87
-
88
- [false, true].each do |is_decorator| # test for module and decorator.
89
- representer!(:decorator => is_decorator) do
90
- property :requester
91
-
92
- property :song, :class => Song do
93
- property :name
94
- end
95
- end
96
-
97
- let (:decorator) { representer.prepare(request) }
98
-
99
- it { decorator.to_hash.must_equal({"requester"=>"Josephine", "song"=>{"name"=>"Alive"}}) }
100
- it { decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name.must_equal "You've Taken Everything"}
101
- end
102
- end
103
-
104
- describe "object pollution" do
105
- representer!(:decorator => true) do
106
- property :song do
107
- property :name
108
- end
109
- end
110
-
111
- it "uses an inline decorator and doesn't alter represented" do
112
- representer.prepare(Struct.new(:song).new(song)).to_hash
113
- song.wont_be_kind_of Representable
114
- end
115
- end
116
-
117
- # TODO: should be in extend:/decorator: test.
118
- # FIXME: this tests :getter{represented}+:extend - represented gets extended twice and the inline decorator overrides original config.
119
- # for_formats(
120
- # :hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}],
121
- # # :xml => [Representable::XML, "<open_struct></open_struct>"],
122
- # #:yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
123
- # ) do |format, mod, output, input|
124
-
125
- # module ArtistRepresenter
126
- # include Representable::JSON
127
- # property :label
128
- # end
129
-
130
- # describe ":getter with inline representer" do
131
- # let (:format) { format }
132
-
133
- # representer!(:module => mod) do
134
- # self.representation_wrap = :album
135
-
136
- # property :artist, :getter => lambda { |args| represented }, :extend => ArtistRepresenter
137
- # end
138
-
139
- # let (:album) { OpenStruct.new(:label => "Epitaph").extend(representer) }
140
-
141
- # it "renders nested Album-properties in separate section" do
142
- # render(album).must_equal_document output
143
- # end
144
- # end
145
- # end
146
-
147
-
148
- for_formats({
149
- :hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}],
150
- # :xml => [Representable::XML, "<open_struct></open_struct>"],
151
- #:yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
152
- }) do |format, mod, output, input|
153
-
154
- class ArtistDecorator < Representable::Decorator
155
- include Representable::JSON
156
- property :label
157
- end
158
-
159
- describe ":getter with :decorator" do
160
- let (:format) { format }
161
-
162
- representer!(:module => mod) do
163
- self.representation_wrap = "album"
164
-
165
- property :artist, :getter => lambda { |args| represented }, :decorator => ArtistDecorator
166
- end
167
-
168
- let (:album) { OpenStruct.new(:label => "Epitaph").extend(representer) }
169
-
170
- it "renders nested Album-properties in separate section" do
171
- render(album).must_equal_document output
172
- end
173
- end
174
- end
175
-
176
-
177
- # test helper methods within inline representer
178
- for_formats({
179
- :hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}],
180
- :xml => [Representable::XML, "<request>\n <song>\n <name>ALIVE</name>\n </song>\n</request>"],
181
- :yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"],
182
- }) do |format, mod, output|
183
-
184
- describe "helper method within inline representer [#{format}]" do
185
- let (:format) { format }
186
-
187
- representer!(:module => mod, :decorator => true) do
188
- self.representation_wrap = :request if format == :xml
189
-
190
- property :requester
191
- property :song do
192
- property :name, :exec_context => :decorator
193
-
194
- define_method :name do
195
- represented.name.upcase
196
- end
197
-
198
- self.representation_wrap = :song if format == :xml
199
- end
200
- end
201
-
202
- let (:request) { representer.prepare(OpenStruct.new(:song => Song.new("Alive"))) }
203
-
204
- it do
205
- render(request).must_equal_document output
206
- end
207
- end
208
- end
209
-
210
-
211
- describe "include module in inline representers" do
212
- representer! do
213
- extension = Module.new do
214
- include Representable::Hash
215
- property :title
216
- end
217
-
218
- property :song do
219
- include extension
220
- property :artist
221
- end
222
- end
223
-
224
- it do OpenStruct.new(:song => OpenStruct.new(:title => "The Fever And The Sound", :artist => "Strung Out")).extend(representer).
225
- to_hash.
226
- must_equal({"song"=>{"artist"=>"Strung Out", "title"=>"The Fever And The Sound"}})
227
- end
228
- end
229
-
230
-
231
- # define method in inline representer
232
- describe "define method in inline representer" do
233
- Mod = Module.new do
234
- include Representable::Hash
235
-
236
- def song
237
- "Object.new"
238
- end
239
-
240
- property :song do
241
- property :duration
242
-
243
- def duration
244
- "6:53"
245
- end
246
- end
247
- end
248
-
249
- it { Object.new.extend(Mod).to_hash.must_equal("song"=>{"duration"=>"6:53"}) }
250
- end
251
-
252
- # define method inline with Decorator
253
- describe "define method inline with Decorator" do
254
- dec = Class.new(Representable::Decorator) do
255
- include Representable::Hash
256
-
257
- def song
258
- "Object.new"
259
- end
260
-
261
- property :song, :exec_context => :decorator do
262
- property :duration, :exec_context => :decorator
263
-
264
- def duration
265
- "6:53"
266
- end
267
- end
268
- end
269
-
270
- it { dec.new(Object.new).to_hash.must_equal("song"=>{"duration"=>"6:53"}) }
271
- end
272
- end