representable 2.1.0 → 2.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 783116ac1174ef6a0aa6eaf44c768bfe3786dec0
4
- data.tar.gz: bc85eaa1d218cd5c54161a607d80d6d3539937cf
3
+ metadata.gz: d4c1cc5843478c8c3c889dabd023eca71e622da8
4
+ data.tar.gz: c8b2850a2418de5d94dbc1024f5d84c93a979976
5
5
  SHA512:
6
- metadata.gz: 347783301a5545df8e009130eb741970d5635796368c3aae726f52e21f0357daefbfa367e7296b053aa14c8357ac1dcdff95b2cca828bfe2bf3f79fc34defe86
7
- data.tar.gz: ff5d1a1825af70bee387b09ee7f997718744e7a69b66f80fb379dbbd726e1640aec81888dd651cbfa6c78c218342bfc2a5305f1bf741972a677037e3d6176894
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
@@ -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
@@ -28,7 +28,7 @@ module Representable
28
28
  attr_reader :user_options, :represented # TODO: make private/remove.
29
29
 
30
30
  def as # DISCUSS: private?
31
- evaluate_option(:as)
31
+ @as ||= evaluate_option(:as)
32
32
  end
33
33
 
34
34
  # Retrieve value and write fragment to the doc.
@@ -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
@@ -33,6 +33,12 @@ module Representable
33
33
  self
34
34
  end
35
35
 
36
+ def delete!(name)
37
+ @runtime_options.delete(name)
38
+ @options.delete(name)
39
+ self
40
+ end
41
+
36
42
  def [](name)
37
43
  @runtime_options[name]
38
44
  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.send(@binding.deserialize_method, fragment, options)
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
- deserializer_class.new(@binding).call(fragment) # CollectionDeserializer/HashDeserializer/etc.
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 Deserializer::Collection.new(@binding).call(fragment)
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.send(@binding.serialize_method, user_options.merge!({:wrap => false}))
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)
@@ -1,3 +1,3 @@
1
1
  module Representable
2
- VERSION = "2.1.0"
2
+ VERSION = "2.1.1"
3
3
  end
@@ -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 "xxx- #inherit!" do
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) }
@@ -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\"}>" }
@@ -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.0
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-09-19 00:00:00.000000000 Z
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