representable 2.2.0 → 2.2.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 +10 -1
- data/lib/representable.rb +4 -3
- data/lib/representable/config.rb +1 -1
- data/lib/representable/definition.rb +1 -1
- data/lib/representable/deserializer.rb +1 -1
- data/lib/representable/inheritable.rb +21 -0
- data/lib/representable/version.rb +1 -1
- data/representable.gemspec +0 -1
- data/test/definition_test.rb +11 -0
- data/test/inherit_test.rb +12 -2
- data/test/test_helper.rb +0 -1
- metadata +3 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23ffadf09dbcb9b8ec2540375586d5d967b4ba84
|
4
|
+
data.tar.gz: 462e4ac711a96341bdc049d30d9cd2b176cce7bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8166f8d2581b7b54c6b2fbc21f632e09423c3feffae3d253724548f17fcdae9a88a4fe44d83702a1eb2e721a06e667e69e737727e3f602eb773316f0b0c36265
|
7
|
+
data.tar.gz: ce020f9d71a1ab7509f8be5401292c7bb268b05a92ef43817d1edc0ece6220c61a65293da9a5cf6604034b2b137b63d852dd6336d28460df0e9dce00832c8998
|
data/CHANGES.md
CHANGED
@@ -1,10 +1,19 @@
|
|
1
|
+
# 2.2.1
|
2
|
+
|
3
|
+
## API change.
|
4
|
+
|
5
|
+
* Options in `Definition` are now Cloneable. That means they will deep-clone when they contain values that are `Cloneable`. This allows clean cloning of deeply nested configuration hashes, e.g. for `deserializer: {instance: ->{}}` in combination with inheritance across representers.
|
6
|
+
|
7
|
+
The former behavior was not to clone, which would allow sub-representers to bleed into the parent options, which is _wrong_. However, this fix shouldn't affect anyone but me.
|
8
|
+
|
9
|
+
|
1
10
|
# 2.2.0
|
2
11
|
|
3
12
|
## New Stuff
|
4
13
|
|
5
14
|
* Introduce `Representable::Cached` that will keep the mapper, which in turn will keep the bindings, which in turn will keep their representer, in case they're nested. You have to include this feature manually and you can expect a 50% and more speed-up for rendering and parsing. Not to speak about the reduced memory footprint.
|
6
15
|
|
7
|
-
|
16
|
+
```ruby
|
8
17
|
class SongDecorator < Representable::Decorator
|
9
18
|
include Representable::JSON
|
10
19
|
feature Representable::Cached
|
data/lib/representable.rb
CHANGED
@@ -88,9 +88,10 @@ private
|
|
88
88
|
base.inherit_module!(self)
|
89
89
|
end
|
90
90
|
|
91
|
-
def inherited(
|
92
|
-
|
93
|
-
|
91
|
+
def inherited(subclass) # DISCUSS: this could be in Decorator? but then we couldn't do B < A(include X) for non-decorators, right?
|
92
|
+
# FIXME: subclass.representable_attrs is ALWAYS empty at this point.
|
93
|
+
subclass.representable_attrs.inherit!(representable_attrs) # this should be inherit_class!
|
94
|
+
# DISCUSS: this could also just be: subclass.inheritable_attr :representable_attrs --> superclass.representable_attrs.clone
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
data/lib/representable/config.rb
CHANGED
@@ -21,7 +21,7 @@ module Representable
|
|
21
21
|
#
|
22
22
|
# Overwrite definition_class if you need a custom Definition object (helpful when using
|
23
23
|
# representable in other gems).
|
24
|
-
class Definitions < Inheritable::Hash
|
24
|
+
class Definitions < Inheritable::Hash # TODO: cloneable!
|
25
25
|
def initialize(definition_class)
|
26
26
|
@definition_class = definition_class
|
27
27
|
super()
|
@@ -11,7 +11,7 @@ module Representable
|
|
11
11
|
|
12
12
|
def initialize(sym, options={}, &block)
|
13
13
|
@options = {}
|
14
|
-
|
14
|
+
@options = Cloneable::Hash.new # allows deep cloning. we then had to set Pipeline cloneable.
|
15
15
|
@name = sym.to_s
|
16
16
|
options = options.clone
|
17
17
|
|
@@ -84,7 +84,7 @@ module Representable
|
|
84
84
|
|
85
85
|
fragment.each_with_index do |item_fragment, i|
|
86
86
|
# add more per-item options here!
|
87
|
-
next if @binding.evaluate_option(:skip_parse, item_fragment)
|
87
|
+
next if @binding.evaluate_option(:skip_parse, item_fragment) # TODO: pass in index!
|
88
88
|
|
89
89
|
collection << deserialize!(item_fragment, i) # FIXME: what if obj nil?
|
90
90
|
end
|
@@ -1,9 +1,28 @@
|
|
1
1
|
module Representable
|
2
2
|
# Objects marked cloneable will be cloned in #inherit!.
|
3
3
|
module Cloneable
|
4
|
+
# Implements recursive cloning for Hash.
|
5
|
+
# Values to clone have to include Cloneable.
|
6
|
+
class Hash < ::Hash
|
7
|
+
include Cloneable # This class is marked as Cloneable itself.
|
8
|
+
|
9
|
+
module Clone
|
10
|
+
def clone
|
11
|
+
self.class[ collect { |k,v| [k, clone_value(v)] } ]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def clone_value(value)
|
16
|
+
return value.clone if value.is_a?(Cloneable)
|
17
|
+
value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
include Clone
|
21
|
+
end
|
4
22
|
end
|
5
23
|
|
6
24
|
# Objects marked cloneable will be inherit!ed in #inherit! when available in parent and child.
|
25
|
+
# TODO: #inherit! will be removed in future versions of Representable in favor of #clone, only. manually merging objects sucks.
|
7
26
|
module Inheritable
|
8
27
|
include Cloneable # all Inheritable are also Cloneable since #clone is one step of our inheritance.
|
9
28
|
|
@@ -15,10 +34,12 @@ module Representable
|
|
15
34
|
end
|
16
35
|
end
|
17
36
|
|
37
|
+
# TODO: remove me.
|
18
38
|
class Hash < ::Hash
|
19
39
|
include Inheritable
|
20
40
|
|
21
41
|
module InstanceMethods
|
42
|
+
# FIXME: this method is currently run exactly once, for representable_attrs.inherit!(parent). it is only used for Config.
|
22
43
|
def inherit!(parent)
|
23
44
|
#merge!(parent.clone)
|
24
45
|
for key in (parent.keys + keys).uniq
|
data/representable.gemspec
CHANGED
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_development_dependency "rake"
|
28
28
|
s.add_development_dependency "test_xml", "0.1.6"
|
29
29
|
s.add_development_dependency "minitest", ">= 5.4.1"
|
30
|
-
s.add_development_dependency "mocha", ">= 0.13.0"
|
31
30
|
s.add_development_dependency "mongoid"
|
32
31
|
s.add_development_dependency "virtus"
|
33
32
|
s.add_development_dependency "json", '>= 1.7.7'
|
data/test/definition_test.rb
CHANGED
@@ -171,6 +171,17 @@ class DefinitionTest < MiniTest::Spec
|
|
171
171
|
assert_equal cloned[:volume], 8
|
172
172
|
end
|
173
173
|
|
174
|
+
# cloning of Cloneables in @options.
|
175
|
+
it do
|
176
|
+
definition = Representable::Definition.new(:title)
|
177
|
+
definition.merge!(deserializer: Representable::Inheritable::Hash.new)
|
178
|
+
|
179
|
+
clone = definition.clone
|
180
|
+
clone[:deserializer].merge!(b: 2)
|
181
|
+
|
182
|
+
definition[:deserializer].object_id.wont_equal clone[:deserializer].object_id
|
183
|
+
end
|
184
|
+
|
174
185
|
# pipeline gets cloned properly
|
175
186
|
describe "pipeline cloning" do
|
176
187
|
subject { Definition.new(:title, :render_filter => 1) }
|
data/test/inherit_test.rb
CHANGED
@@ -33,6 +33,7 @@ class InheritTest < MiniTest::Spec
|
|
33
33
|
end
|
34
34
|
|
35
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.
|
36
37
|
it { representer.prepare( Song.new(Struct.new(:string).new("Believe It"), 1)).to_hash.must_equal({"title"=>{"str"=>"Believe It"}, "no"=>1}) }
|
37
38
|
end
|
38
39
|
|
@@ -99,7 +100,11 @@ class InheritTest < MiniTest::Spec
|
|
99
100
|
describe ":inherit with decorator" do
|
100
101
|
representer!(:decorator => true) do
|
101
102
|
property :hit do
|
102
|
-
property :title
|
103
|
+
property :title, exec_context: :decorator
|
104
|
+
|
105
|
+
def title
|
106
|
+
"Cheap Transistor Radio"
|
107
|
+
end
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
@@ -112,8 +117,13 @@ class InheritTest < MiniTest::Spec
|
|
112
117
|
end
|
113
118
|
}
|
114
119
|
|
120
|
+
it { representer.new(OpenStruct.new(hit: OpenStruct.new(title: "I WILL BE OVERRIDDEN", :length => "2:59"))).to_hash.must_equal(
|
121
|
+
{"hit"=>{"title"=>"Cheap Transistor Radio"}}) }
|
122
|
+
|
123
|
+
# inheriting decorator inherits inline representer class (InlineRepresenter#title).
|
124
|
+
# inheriting decorator adds :length.
|
115
125
|
it { inheriting.new(OpenStruct.new(:hit => OpenStruct.new(:title => "Hole In Your Soul", :length => "2:59"))).to_hash.must_equal(
|
116
|
-
{"hit"=>{"title"=>"
|
126
|
+
{"hit"=>{"title"=>"Cheap Transistor Radio", "length"=>"2:59"}}) }
|
117
127
|
end
|
118
128
|
|
119
129
|
|
data/test/test_helper.rb
CHANGED
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.2.
|
4
|
+
version: 2.2.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: 2015-05-
|
11
|
+
date: 2015-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -94,20 +94,6 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 5.4.1
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: mocha
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.13.0
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.13.0
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: mongoid
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -293,53 +279,4 @@ signing_key:
|
|
293
279
|
specification_version: 4
|
294
280
|
summary: Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes
|
295
281
|
plain properties, collections, nesting, coercion and more.
|
296
|
-
test_files:
|
297
|
-
- test/as_test.rb
|
298
|
-
- test/benchmarking.rb
|
299
|
-
- test/binding_test.rb
|
300
|
-
- test/cached_test.rb
|
301
|
-
- test/class_test.rb
|
302
|
-
- test/coercion_test.rb
|
303
|
-
- test/config/inherit_test.rb
|
304
|
-
- test/config_test.rb
|
305
|
-
- test/decorator_scope_test.rb
|
306
|
-
- test/decorator_test.rb
|
307
|
-
- test/definition_test.rb
|
308
|
-
- test/example.rb
|
309
|
-
- test/examples/object.rb
|
310
|
-
- test/exec_context_test.rb
|
311
|
-
- test/features_test.rb
|
312
|
-
- test/filter_test.rb
|
313
|
-
- test/for_collection_test.rb
|
314
|
-
- test/generic_test.rb
|
315
|
-
- test/getter_setter_test.rb
|
316
|
-
- test/hash_bindings_test.rb
|
317
|
-
- test/hash_test.rb
|
318
|
-
- test/if_test.rb
|
319
|
-
- test/inherit_test.rb
|
320
|
-
- test/inheritable_test.rb
|
321
|
-
- test/inline_test.rb
|
322
|
-
- test/instance_test.rb
|
323
|
-
- test/is_representable_test.rb
|
324
|
-
- test/json_test.rb
|
325
|
-
- test/lonely_test.rb
|
326
|
-
- test/mongoid_test.rb
|
327
|
-
- test/nested_test.rb
|
328
|
-
- test/object_test.rb
|
329
|
-
- test/parse_strategy_test.rb
|
330
|
-
- test/pass_options_test.rb
|
331
|
-
- test/prepare_test.rb
|
332
|
-
- test/reader_writer_test.rb
|
333
|
-
- test/realistic_benchmark.rb
|
334
|
-
- test/represent_test.rb
|
335
|
-
- test/representable_test.rb
|
336
|
-
- test/schema_test.rb
|
337
|
-
- test/serialize_deserialize_test.rb
|
338
|
-
- test/skip_test.rb
|
339
|
-
- test/stringify_hash_test.rb
|
340
|
-
- test/test_helper.rb
|
341
|
-
- test/test_helper_test.rb
|
342
|
-
- test/wrap_test.rb
|
343
|
-
- test/xml_bindings_test.rb
|
344
|
-
- test/xml_test.rb
|
345
|
-
- test/yaml_test.rb
|
282
|
+
test_files: []
|