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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 887d742815c848ac3b63287c8858f2988a2de41d
4
- data.tar.gz: 78fbbf862aed5b2de60a9bc2ed7375b327a3e058
3
+ metadata.gz: 23ffadf09dbcb9b8ec2540375586d5d967b4ba84
4
+ data.tar.gz: 462e4ac711a96341bdc049d30d9cd2b176cce7bd
5
5
  SHA512:
6
- metadata.gz: a4e93c1474e69fb743ca1072fcee054f2e075e4eaf2902b9c885ee7c86b4156db93900889820a5375d61e97a3585c14b2e70931c91722791aec7cf21606226f6
7
- data.tar.gz: 93f25a5475e27863649981e0cb5bd553c81b5c02cfe1e16c4c630c368ec972938c4453aae7660ce0e1caf1e67e640a2ff590c5f58d17e7597e0b1abcbc0644a9
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
- ``ruby
16
+ ```ruby
8
17
  class SongDecorator < Representable::Decorator
9
18
  include Representable::JSON
10
19
  feature Representable::Cached
@@ -88,9 +88,10 @@ private
88
88
  base.inherit_module!(self)
89
89
  end
90
90
 
91
- def inherited(base) # DISCUSS: this could be in Decorator? but then we couldn't do B < A(include X) for non-decorators, right?
92
- super
93
- base.representable_attrs.inherit!(representable_attrs) # this should be inherit_class!
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
 
@@ -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
- # @options = Inheritable::Hash.new # allows deep cloning. we then had to set Pipeline cloneable.
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
@@ -1,3 +1,3 @@
1
1
  module Representable
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
@@ -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'
@@ -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) }
@@ -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"=>"Hole In Your Soul", "length"=>"2:59"}}) }
126
+ {"hit"=>{"title"=>"Cheap Transistor Radio", "length"=>"2:59"}}) }
117
127
  end
118
128
 
119
129
 
@@ -4,7 +4,6 @@ require 'representable/xml'
4
4
  require 'representable/yaml'
5
5
  require 'minitest/autorun'
6
6
  require 'test_xml/mini_test'
7
- require 'mocha/setup'
8
7
 
9
8
  class Album
10
9
  attr_accessor :songs, :best_song
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.0
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-18 00:00:00.000000000 Z
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: []