representable 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +25 -0
- data/lib/representable.rb +2 -0
- data/lib/representable/apply.rb +13 -0
- data/lib/representable/binding.rb +1 -1
- data/lib/representable/config.rb +5 -1
- data/lib/representable/debug.rb +95 -0
- data/lib/representable/definition.rb +6 -0
- data/lib/representable/deserializer.rb +5 -1
- data/lib/representable/populator.rb +10 -2
- data/lib/representable/serializer.rb +5 -1
- data/lib/representable/version.rb +1 -1
- data/test/config_test.rb +25 -9
- data/test/definition_test.rb +10 -0
- data/test/schema_test.rb +35 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4c1cc5843478c8c3c889dabd023eca71e622da8
|
4
|
+
data.tar.gz: c8b2850a2418de5d94dbc1024f5d84c93a979976
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8447a73176a4dfd5cc11d7767721e083757e2c9eeeb9e0bde32d73b17fea141fd6954ca05ce45f9e88c8393d9341981cce7b4e5fc4836f7eaed39d05a0890bc8
|
7
|
+
data.tar.gz: a4175164b4f3eb64db40630b7d9fcc4e1574cc075268f87e6cdafbe2a8648861a07f0302fbbc54431ac6bb5934b4c3f12e704a3459a4b3c134acf029ff794496
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
# 2.1.1
|
2
|
+
|
3
|
+
* Added `Definition#delete!` to remove options.
|
4
|
+
* Added `Representable::apply` do iterate and change schemas.
|
5
|
+
* Added `Config.remove` to remove properties.
|
6
|
+
* Added `Representable::Debug` which just has to be included into your represented object.
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
song.extend(SongRepresenter).extend(Representable::Debug).from_json("..")
|
10
|
+
song.extend(SongRepresenter).extend(Representable::Debug).to_json("..")
|
11
|
+
```
|
12
|
+
|
13
|
+
It can also be included statically into your representer or decorator.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class SongRepresenter < Representable::Decorator
|
17
|
+
include Representable::JSON
|
18
|
+
include Representable::Debug
|
19
|
+
|
20
|
+
property :title
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
It is great.
|
25
|
+
|
1
26
|
# 2.1.0
|
2
27
|
|
3
28
|
## Breaking Changes
|
data/lib/representable.rb
CHANGED
@@ -7,6 +7,7 @@ require 'representable/mapper'
|
|
7
7
|
require 'representable/for_collection'
|
8
8
|
require 'representable/represent'
|
9
9
|
require 'representable/declarative'
|
10
|
+
require 'representable/apply'
|
10
11
|
|
11
12
|
|
12
13
|
require 'uber/callable'
|
@@ -23,6 +24,7 @@ module Representable
|
|
23
24
|
extend Feature
|
24
25
|
extend ForCollection
|
25
26
|
extend Represent
|
27
|
+
extend Apply
|
26
28
|
# register_feature Representable # Representable gets included automatically when creating inline representer.
|
27
29
|
end
|
28
30
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Representable
|
2
|
+
module Apply
|
3
|
+
# Iterates over all property/collection definitions and yields the Definition instance.
|
4
|
+
def apply(&block)
|
5
|
+
representable_attrs.each do |dfn|
|
6
|
+
block.call(dfn)
|
7
|
+
dfn.representer_module.extend(Apply).apply(&block) if dfn.representer_module # nested.
|
8
|
+
end
|
9
|
+
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/representable/config.rb
CHANGED
@@ -39,6 +39,10 @@ module Representable
|
|
39
39
|
self[name.to_s]
|
40
40
|
end
|
41
41
|
|
42
|
+
def remove(name)
|
43
|
+
delete(name.to_s)
|
44
|
+
end
|
45
|
+
|
42
46
|
extend Forwardable
|
43
47
|
def_delegators :values, :each # so we look like an array. this is only used in Mapper. we could change that so we don't need to hide the hash.
|
44
48
|
|
@@ -63,7 +67,7 @@ module Representable
|
|
63
67
|
|
64
68
|
# delegate #collect etc to Definitions instance.
|
65
69
|
extend Forwardable
|
66
|
-
def_delegators :@definitions, :get, :add, :each, :size
|
70
|
+
def_delegators :@definitions, :get, :add, :each, :size, :remove
|
67
71
|
# #collect comes from Hash and then gets delegated to @definitions. don't like that.
|
68
72
|
|
69
73
|
def wrap=(value)
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Representable
|
2
|
+
module Debug
|
3
|
+
def self.extended(represented)
|
4
|
+
represented.extend Representable
|
5
|
+
end
|
6
|
+
|
7
|
+
module Representable
|
8
|
+
def update_properties_from(doc, options, format)
|
9
|
+
puts
|
10
|
+
puts "[Deserialize]........."
|
11
|
+
puts "[Deserialize] document #{doc.inspect}"
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_representation_with(doc, options, format)
|
16
|
+
puts
|
17
|
+
puts "[Serialize]........."
|
18
|
+
puts "[Serialize]"
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def representable_mapper(*args)
|
23
|
+
super.extend(Mapper)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Binding
|
28
|
+
def read(doc)
|
29
|
+
value = super
|
30
|
+
puts " #read --> #{value.inspect}"
|
31
|
+
value
|
32
|
+
end
|
33
|
+
|
34
|
+
def evaluate_option(name, *args, &block)
|
35
|
+
puts "=====#{self[name]}" if name ==:prepare
|
36
|
+
puts (evaled = self[name]) ?
|
37
|
+
" #evaluate_option [#{name}]: eval!!!" :
|
38
|
+
" #evaluate_option [#{name}]: skipping"
|
39
|
+
value = super
|
40
|
+
puts " #evaluate_option [#{name}]: --> #{value}" if evaled
|
41
|
+
puts " #evaluate_option [#{name}]: -->= #{args.first}" if name == :setter
|
42
|
+
value
|
43
|
+
end
|
44
|
+
|
45
|
+
def populator
|
46
|
+
super.extend(Populator)
|
47
|
+
end
|
48
|
+
|
49
|
+
def serializer
|
50
|
+
super.extend(Serializer)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module Populator
|
55
|
+
def deserialize(fragment)
|
56
|
+
puts " Populator#deserialize: #{fragment.inspect}"
|
57
|
+
puts " : typed? is false, skipping Deserializer." if ! @binding.typed?
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
def deserializer
|
62
|
+
super.extend(Deserializer)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module Deserializer
|
67
|
+
def create_object(fragment, *args)
|
68
|
+
value = super
|
69
|
+
puts " Deserializer#create_object: --> #{value.inspect}"
|
70
|
+
value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module Serializer
|
75
|
+
def marshal(object, user_options)
|
76
|
+
puts " Serializer#marshal: --> #{object.inspect}"
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module Mapper
|
82
|
+
def uncompile_fragment(bin, doc)
|
83
|
+
bin.extend(Binding)
|
84
|
+
puts " uncompile_fragment: #{bin.name}"
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
def compile_fragment(bin, doc)
|
89
|
+
bin.extend(Binding)
|
90
|
+
puts " compile_fragment: #{bin.name}"
|
91
|
+
super
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -28,10 +28,14 @@ module Representable
|
|
28
28
|
return object unless @binding.representable?
|
29
29
|
|
30
30
|
@binding.evaluate_option(:deserialize, object, fragment) do
|
31
|
-
object
|
31
|
+
demarshal(object, fragment, options)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def demarshal(object, fragment, options)
|
36
|
+
object.send(@binding.deserialize_method, fragment, options)
|
37
|
+
end
|
38
|
+
|
35
39
|
def prepare(object)
|
36
40
|
@binding.evaluate_option(:prepare, object) do
|
37
41
|
prepare!(object)
|
@@ -31,13 +31,17 @@ module Representable
|
|
31
31
|
return yield if @binding.evaluate_option(:skip_parse, fragment) # TODO: move this into Deserializer.
|
32
32
|
|
33
33
|
# use a Deserializer to transform fragment to/into object.
|
34
|
-
|
34
|
+
deserializer.call(fragment) # CollectionDeserializer/HashDeserializer/etc.
|
35
35
|
end
|
36
36
|
|
37
37
|
def deserializer_class
|
38
38
|
Deserializer
|
39
39
|
end
|
40
40
|
|
41
|
+
def deserializer
|
42
|
+
deserializer_class.new(@binding)
|
43
|
+
end
|
44
|
+
|
41
45
|
|
42
46
|
# A separated collection deserializer/populator allows us better dealing with populating/modifying
|
43
47
|
# collections of models. (e.g. replace, update, push, etc.).
|
@@ -45,7 +49,11 @@ module Representable
|
|
45
49
|
class Collection < self
|
46
50
|
private
|
47
51
|
def deserialize(fragment)
|
48
|
-
return
|
52
|
+
return deserializer.call(fragment)
|
53
|
+
end
|
54
|
+
|
55
|
+
def deserializer
|
56
|
+
Deserializer::Collection.new(@binding)
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|
@@ -16,10 +16,14 @@ module Representable
|
|
16
16
|
return object unless @binding.representable?
|
17
17
|
|
18
18
|
@binding.evaluate_option(:serialize, object) do
|
19
|
-
object
|
19
|
+
marshal(object, user_options)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def marshal(object, user_options)
|
24
|
+
object.send(@binding.serialize_method, user_options.merge!({:wrap => false}))
|
25
|
+
end
|
26
|
+
|
23
27
|
|
24
28
|
class Collection < self
|
25
29
|
def serialize(array, *args)
|
data/test/config_test.rb
CHANGED
@@ -39,6 +39,16 @@ class ConfigTest < MiniTest::Spec
|
|
39
39
|
# forwarded to Config#definitions
|
40
40
|
# that goes to ConfigDefinitionsTest
|
41
41
|
describe "#add" do
|
42
|
+
describe "returns" do
|
43
|
+
it do
|
44
|
+
# #add returns Definition.`
|
45
|
+
subject = Representable::Config.new.add(:title, {:me => true})
|
46
|
+
|
47
|
+
subject.must_be_kind_of Representable::Definition
|
48
|
+
subject[:me].must_equal true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
42
52
|
before { subject.add(:title, {:me => true}) }
|
43
53
|
|
44
54
|
# must be kind of Definition
|
@@ -65,6 +75,20 @@ class ConfigTest < MiniTest::Spec
|
|
65
75
|
end
|
66
76
|
|
67
77
|
|
78
|
+
describe "#remove" do
|
79
|
+
subject { Representable::Config.new }
|
80
|
+
|
81
|
+
it do
|
82
|
+
subject.add(:title, {:me => true})
|
83
|
+
subject.add(:genre, {})
|
84
|
+
subject.get(:genre).must_be_kind_of Representable::Definition
|
85
|
+
|
86
|
+
subject.remove(:genre)
|
87
|
+
subject.get(:genre).must_equal nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
68
92
|
describe "#each" do
|
69
93
|
before { subject.add(:title, {:me => true}) }
|
70
94
|
|
@@ -84,14 +108,6 @@ class ConfigTest < MiniTest::Spec
|
|
84
108
|
end
|
85
109
|
end
|
86
110
|
|
87
|
-
|
88
|
-
describe "#add" do
|
89
|
-
subject { Representable::Config.new.add(:title, {:me => true}) }
|
90
|
-
|
91
|
-
it { subject.must_be_kind_of Representable::Definition }
|
92
|
-
it { subject[:me].must_equal true }
|
93
|
-
end
|
94
|
-
|
95
111
|
describe "#get" do
|
96
112
|
subject { Representable::Config.new }
|
97
113
|
|
@@ -105,7 +121,7 @@ class ConfigTest < MiniTest::Spec
|
|
105
121
|
end
|
106
122
|
|
107
123
|
|
108
|
-
describe "
|
124
|
+
describe "#inherit!" do
|
109
125
|
let (:title) { Definition.new(:title) }
|
110
126
|
let (:length) { Definition.new(:length) }
|
111
127
|
let (:stars) { Definition.new(:stars) }
|
data/test/definition_test.rb
CHANGED
@@ -88,6 +88,16 @@ class DefinitionTest < MiniTest::Spec
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
+
|
92
|
+
# delete!
|
93
|
+
describe "#delete!" do
|
94
|
+
let (:definition) { Definition.new(:song, serialize: "remove me!") }
|
95
|
+
|
96
|
+
before { definition[:serialize].evaluate(nil).must_equal "remove me!" }
|
97
|
+
|
98
|
+
it { definition.delete!(:serialize)[:serialize].must_equal nil }
|
99
|
+
end
|
100
|
+
|
91
101
|
# #inspect
|
92
102
|
describe "#inspect" do
|
93
103
|
it { Definition.new(:songs).inspect.must_equal "#<Representable::Definition ==>songs @options={:parse_filter=>[], :render_filter=>[], :as=>\"songs\"}>" }
|
data/test/schema_test.rb
CHANGED
@@ -120,4 +120,39 @@ class SchemaTest < MiniTest::Spec
|
|
120
120
|
it do
|
121
121
|
InheritFromDecorator.new(band).to_hash.must_equal({"genre"=>"Punkrock", "label"=>{"name"=>"Fat Wreck", "city"=>"San Francisco", "employees"=>[{"name"=>"Mike"}], "location"=>{"city"=>"Sanfran"}}})
|
122
122
|
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
class ApplyTest < MiniTest::Spec
|
127
|
+
class AlbumDecorator < Representable::Decorator
|
128
|
+
property :title
|
129
|
+
|
130
|
+
property :hit do
|
131
|
+
property :title
|
132
|
+
end
|
133
|
+
|
134
|
+
collection :songs do
|
135
|
+
property :title
|
136
|
+
end
|
137
|
+
|
138
|
+
property :band do # yepp, people do crazy stuff like that.
|
139
|
+
property :label do
|
140
|
+
property :name
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# #apply
|
146
|
+
it do
|
147
|
+
properties = []
|
148
|
+
|
149
|
+
AlbumDecorator.apply do |dfn|
|
150
|
+
properties << dfn.name
|
151
|
+
dfn.merge! :cool => true
|
152
|
+
end.must_equal AlbumDecorator
|
153
|
+
|
154
|
+
properties.must_equal ["title", "hit", "title", "songs", "title", "band", "label", "name"]
|
155
|
+
# writeable
|
156
|
+
AlbumDecorator.representable_attrs.get(:band).representer_module.representable_attrs.get(:label).representer_module.representable_attrs.get(:name)[:cool].must_equal true
|
157
|
+
end
|
123
158
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
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-
|
11
|
+
date: 2014-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -168,10 +168,12 @@ files:
|
|
168
168
|
- TODO
|
169
169
|
- lib/representable.rb
|
170
170
|
- lib/representable/TODO.getting_serious
|
171
|
+
- lib/representable/apply.rb
|
171
172
|
- lib/representable/autoload.rb
|
172
173
|
- lib/representable/binding.rb
|
173
174
|
- lib/representable/coercion.rb
|
174
175
|
- lib/representable/config.rb
|
176
|
+
- lib/representable/debug.rb
|
175
177
|
- lib/representable/declarative.rb
|
176
178
|
- lib/representable/decorator.rb
|
177
179
|
- lib/representable/definition.rb
|