representable 1.5.2 → 1.5.3
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.
- data/CHANGES.textile +6 -0
- data/Gemfile +1 -0
- data/lib/representable.rb +1 -1
- data/lib/representable/decorator/coercion.rb +16 -2
- data/lib/representable/version.rb +1 -1
- data/test/coercion_test.rb +22 -5
- data/test/decorator_test.rb +45 -0
- data/test/representable_test.rb +9 -36
- metadata +3 -2
data/CHANGES.textile
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
h2. 1.5.3
|
2
|
+
|
3
|
+
* `Representable#update_properties_from` now always returns `represented`, which is `self` in a module representer and the decorated object in a decorator (only the latter changed).
|
4
|
+
* Coercion in decorators should work now as expected.
|
5
|
+
* Fixed a require bug.
|
6
|
+
|
1
7
|
h2. 1.5.2
|
2
8
|
|
3
9
|
* Rename `:representer_exec` to `:decorator_scope` and make it a documented (!) feature.
|
data/Gemfile
CHANGED
data/lib/representable.rb
CHANGED
@@ -1,13 +1,27 @@
|
|
1
|
+
require 'representable/coercion'
|
2
|
+
|
1
3
|
class Representable::Decorator
|
2
4
|
module Coercion
|
3
5
|
def self.included(base)
|
4
6
|
base.class_eval do
|
7
|
+
# DISCUSS: this assumes we have a Representer included, yet.
|
8
|
+
alias_method :representable_initialize, :initialize
|
9
|
+
alias_method :representable_to_hash, :to_hash
|
10
|
+
|
11
|
+
# FIXME: allow including coercion only from virtus.
|
5
12
|
include Virtus
|
13
|
+
undef_method(:initialize)
|
14
|
+
undef_method(:to_hash)
|
15
|
+
|
6
16
|
extend Representable::Coercion::ClassMethods
|
7
17
|
extend ClassMethods
|
8
18
|
|
9
|
-
def initialize(
|
10
|
-
|
19
|
+
def initialize(*args) # override Virtus' #initialize.
|
20
|
+
representable_initialize(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash(*args) # override Virtus' #to_hash.
|
24
|
+
representable_to_hash(*args)
|
11
25
|
end
|
12
26
|
end
|
13
27
|
end
|
data/test/coercion_test.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'representable/coercion'
|
3
|
+
require 'representable/decorator/coercion'
|
3
4
|
|
4
5
|
class VirtusCoercionTest < MiniTest::Spec
|
5
6
|
class Song # note that we don't define accessors for the properties here.
|
7
|
+
attr_accessor :title
|
6
8
|
end
|
7
9
|
|
8
10
|
describe "Coercion with Virtus" do
|
@@ -12,14 +14,22 @@ class VirtusCoercionTest < MiniTest::Spec
|
|
12
14
|
include Representable::Coercion
|
13
15
|
property :composed_at, :type => DateTime
|
14
16
|
property :track, :type => Integer
|
17
|
+
property :title # no coercion.
|
15
18
|
end
|
16
19
|
|
17
20
|
it "coerces properties in #from_json" do
|
18
|
-
song = Song.new.extend(SongRepresenter).from_json(
|
21
|
+
song = Song.new.extend(SongRepresenter).from_json('{"composed_at":"November 18th, 1983","track":"18","title":"Scarified"}')
|
19
22
|
assert_kind_of DateTime, song.composed_at
|
20
|
-
assert_equal 18, song.track
|
21
23
|
assert_equal DateTime.parse("Fri, 18 Nov 1983 00:00:00 +0000"), song.composed_at
|
24
|
+
assert_equal 18, song.track
|
25
|
+
song.title.must_equal "Scarified"
|
22
26
|
end
|
27
|
+
|
28
|
+
# it "coerces when rendering" do
|
29
|
+
# song = Song.new
|
30
|
+
# song.title = "Scarified"
|
31
|
+
# song.to_json.must_equal ''
|
32
|
+
# end
|
23
33
|
end
|
24
34
|
|
25
35
|
|
@@ -45,22 +55,29 @@ class VirtusCoercionTest < MiniTest::Spec
|
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
48
|
-
require 'representable/decorator/coercion'
|
49
58
|
describe "on decorator" do
|
50
59
|
class SongRepresentation < Representable::Decorator
|
51
60
|
include Representable::JSON
|
52
61
|
include Representable::Decorator::Coercion
|
53
62
|
|
54
63
|
property :composed_at, :type => DateTime
|
64
|
+
property :title
|
55
65
|
end
|
56
66
|
|
57
67
|
it "coerces when parsing" do
|
58
|
-
song = SongRepresentation.new(OpenStruct.new).from_json("{\"composed_at\":\"November 18th, 1983\"}")
|
68
|
+
song = SongRepresentation.new(OpenStruct.new).from_json("{\"composed_at\":\"November 18th, 1983\", \"title\": \"Scarified\"}")
|
69
|
+
song.must_be_kind_of OpenStruct
|
59
70
|
song.composed_at.must_equal DateTime.parse("Fri, 18 Nov 1983")
|
71
|
+
song.title.must_equal "Scarified"
|
60
72
|
end
|
61
73
|
|
62
74
|
it "coerces when rendering" do
|
63
|
-
SongRepresentation.new(
|
75
|
+
SongRepresentation.new(
|
76
|
+
OpenStruct.new(
|
77
|
+
:composed_at => "November 18th, 1983",
|
78
|
+
:title => "Scarified"
|
79
|
+
)
|
80
|
+
).to_hash.must_equal({"composed_at"=>DateTime.parse("Fri, 18 Nov 1983"), "title"=>"Scarified"})
|
64
81
|
end
|
65
82
|
end
|
66
83
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DecoratorTest < MiniTest::Spec
|
4
|
+
# TODO: Move to global place since it's used twice.
|
5
|
+
class SongRepresentation < Representable::Decorator
|
6
|
+
include Representable::JSON
|
7
|
+
property :name
|
8
|
+
end
|
9
|
+
|
10
|
+
class AlbumRepresentation < Representable::Decorator
|
11
|
+
include Representable::JSON
|
12
|
+
|
13
|
+
collection :songs, :class => Song, :extend => SongRepresentation
|
14
|
+
end
|
15
|
+
|
16
|
+
let (:song) { Song.new("Mama, I'm Coming Home") }
|
17
|
+
let (:album) { Album.new([song]) }
|
18
|
+
let (:decorator) { AlbumRepresentation.new(album) }
|
19
|
+
|
20
|
+
it "renders" do
|
21
|
+
decorator.to_hash.must_equal({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]})
|
22
|
+
album.wont_respond_to :to_hash
|
23
|
+
song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#from_hash" do
|
27
|
+
it "returns represented" do
|
28
|
+
decorator.from_hash({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]}).must_equal album
|
29
|
+
end
|
30
|
+
|
31
|
+
it "parses" do
|
32
|
+
decorator.from_hash({"songs"=>[{"name"=>"Atomic Garden"}]})
|
33
|
+
album.songs.first.must_be_kind_of Song
|
34
|
+
album.songs.must_equal [Song.new("Atomic Garden")]
|
35
|
+
album.wont_respond_to :to_hash
|
36
|
+
song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#decorated" do
|
41
|
+
it "is aliased to #represented" do
|
42
|
+
AlbumRepresentation.prepare(album).decorated.must_equal album
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/test/representable_test.rb
CHANGED
@@ -266,7 +266,7 @@ class RepresentableTest < MiniTest::Spec
|
|
266
266
|
assert_equal nil, @band.founders
|
267
267
|
end
|
268
268
|
|
269
|
-
it "always returns
|
269
|
+
it "always returns the represented" do
|
270
270
|
assert_equal @band, @band.update_properties_from({"name"=>"Nofx"}, {}, Representable::Hash::PropertyBinding)
|
271
271
|
end
|
272
272
|
|
@@ -740,42 +740,15 @@ class RepresentableTest < MiniTest::Spec
|
|
740
740
|
end
|
741
741
|
end
|
742
742
|
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
class AlbumRepresentation < Representable::Decorator
|
751
|
-
include Representable::JSON
|
752
|
-
|
753
|
-
collection :songs, :class => Song, :extend => SongRepresentation
|
754
|
-
end
|
755
|
-
|
756
|
-
let (:song) { Song.new("Mama, I'm Coming Home") }
|
757
|
-
let (:album) { Album.new([song]) }
|
758
|
-
let (:decorator) { AlbumRepresentation.new(album) }
|
759
|
-
|
760
|
-
it "renders" do
|
761
|
-
decorator.to_hash.must_equal({"songs"=>[{"name"=>"Mama, I'm Coming Home"}]})
|
762
|
-
album.wont_respond_to :to_hash
|
763
|
-
song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
|
764
|
-
end
|
765
|
-
|
766
|
-
it "parses" do
|
767
|
-
decorator.from_hash({"songs"=>[{"name"=>"Atomic Garden"}]})
|
768
|
-
album.songs.first.must_be_kind_of Song
|
769
|
-
album.songs.must_equal [Song.new("Atomic Garden")]
|
770
|
-
album.wont_respond_to :to_hash
|
771
|
-
song.wont_respond_to :to_hash # DISCUSS: weak test, how to assert blank slate?
|
772
|
-
end
|
743
|
+
# TODO: Move to global place since it's used twice.
|
744
|
+
class SongRepresentation < Representable::Decorator
|
745
|
+
include Representable::JSON
|
746
|
+
property :name
|
747
|
+
end
|
748
|
+
class AlbumRepresentation < Representable::Decorator
|
749
|
+
include Representable::JSON
|
773
750
|
|
774
|
-
|
775
|
-
it "is aliased to #represented" do
|
776
|
-
AlbumRepresentation.prepare(album).decorated.must_equal album
|
777
|
-
end
|
778
|
-
end
|
751
|
+
collection :songs, :class => Song, :extend => SongRepresentation
|
779
752
|
end
|
780
753
|
|
781
754
|
describe "::prepare" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- lib/representable/yaml.rb
|
211
211
|
- representable.gemspec
|
212
212
|
- test/coercion_test.rb
|
213
|
+
- test/decorator_test.rb
|
213
214
|
- test/definition_test.rb
|
214
215
|
- test/example.rb
|
215
216
|
- test/hash_bindings_test.rb
|