representable 1.5.2 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|