representable 1.8.0 → 1.8.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: b00de985635f525b8a01171885aed414e6204034
4
- data.tar.gz: dc62dd3c718b5969a663da9587ef815ddb4eb6e8
3
+ metadata.gz: 4966e0bd638ff12a23976fed58fab076e5912e20
4
+ data.tar.gz: 4ca036c615f0e656d8268cdb1bf74918f1d9476a
5
5
  SHA512:
6
- metadata.gz: 9a7cc3fb19f4319e69cbf66e566ae70b9a8ede10bc5b9666756128ab7795eec2c35315f31603ff3ad3fa8b78ac170270389ba33e128b6848496d45fd1cec615f
7
- data.tar.gz: d2eb8e52c0485aebea0fe956fa98ef9d9c06f87a8d00a0d027dbea804b573982b364d1bcc06f3db65bbeb33e89e814a594300302675776be11024ce335569d69
6
+ metadata.gz: b2f875cda0fde3869bb592317de279ba4c92fb6e29b46685ed4908313bd43dab6a9614e9af6413368940ccad9e61dd7339fc0d325e1fdba9211906eb4ab40850
7
+ data.tar.gz: fb9e3c1d669e7219ee57451e5d5302ef41b770a6dea11f73c7699528de4a01ad3a0df6da4f8abb8cf9f691de1da94a9f92fa9014f74d4a3ec4f51366dbfead51
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 1.8.1
2
+
3
+ * Add `:serialize` and `:deserialize` options for overriding those steps.
4
+
1
5
  # 1.8.0
2
6
 
3
7
  ## Major Breakage
@@ -17,6 +21,7 @@
17
21
 
18
22
  * When unsure about the number of arguments passed into an option lambda, use `:pass_options`. This passes all general options in a dedicated `Options` object that responds to `binding`, `decorator`, `represented` and `user_options`. It's always the last argument for the block.
19
23
  * Added `parse_strategy: :find_or_instantiate`. More to come.
24
+ * Added `parse_strategy: lambda { |fragment, i, options| }` to implement your own deserialization.
20
25
  * Use `representable: false` to prevent calling `to_*/from_*` on a represented object even if the property is `typed?` (`:extend`, `:class` or `:instance` set).
21
26
  * Introduced `:use_decorator` option to force an inline representer to be implemented with a Decorator even in a module. This fixes a bug since we used the `:decorate` option in earlier versions, which was already used for something else.
22
27
  * Autoload `Representable::Hash*` and `Representable::Decorator`.
data/README.md CHANGED
@@ -125,10 +125,10 @@ end
125
125
  Surprisingly, `#collection` lets us define lists of objects to represent.
126
126
 
127
127
  ```ruby
128
- Song.new(title: "Fallout", composers: ["Steward Copeland", "Sting"]).
128
+ Song.new(title: "Fallout", composers: ["Stewart Copeland", "Sting"]).
129
129
  extend(SongRepresenter).to_json
130
130
 
131
- #=> {"title":"Fallout","composers":["Steward Copeland","Sting"]}
131
+ #=> {"title":"Fallout","composers":["Stewart Copeland","Sting"]}
132
132
  ```
133
133
 
134
134
  And again, this works both ways - in addition to the title it extracts the composers from the document, too.
@@ -162,7 +162,7 @@ When rendering, the `:extend` module is used to extend the attribute(s) with the
162
162
 
163
163
  ```ruby
164
164
  album.extend(AlbumRepresenter).to_json
165
- #=> {"name":"The Police","songs":[{"title":"Fallout","composers":["Steward Copeland","Sting"]},{"title":"Synchronicity","composers":[]}]}
165
+ #=> {"name":"The Police","songs":[{"title":"Fallout","composers":["Stewart Copeland","Sting"]},{"title":"Synchronicity","composers":[]}]}
166
166
  ```
167
167
 
168
168
  Parsing a documents needs both `:extend` and the `:class` option as the parser requires knowledge what kind of object to create from the nested composition.
@@ -453,6 +453,8 @@ Here's a list of all dynamic options and their argument signature.
453
453
  * `writer: lambda { |document, args| }` ([see Read And Write](#overriding-read-and-write))
454
454
  * `if: lambda { |args| }` ([see Conditions](#conditions))
455
455
  * `prepare: lambda { |object, args| }` ([see docs](#rendering-and-parsing-without-extend))
456
+ * `serialize: lambda { |object, args| }` ([see docs](#overriding-serialize-and-deserialize))
457
+ * `deserialize: lambda { |object, fragment, args| }` ([see docs](#overriding-serialize-and-deserialize))
456
458
  * `representation_wrap` is a dynamic option, too: `self.representation_wrap = lambda do { |args| }` ([see Wrapping](#wrapping))
457
459
 
458
460
 
@@ -491,11 +493,11 @@ end
491
493
  For XML we just include the `Representable::XML` module.
492
494
 
493
495
  ```xml
494
- Song.new(title: "Fallout", composers: ["Steward Copeland", "Sting"]).
496
+ Song.new(title: "Fallout", composers: ["Stewart Copeland", "Sting"]).
495
497
  extend(SongRepresenter).to_xml #=>
496
498
  <song>
497
499
  <title>Fallout</title>
498
- <composers>Steward Copeland</composers>
500
+ <composers>Stewart Copeland</composers>
499
501
  <composers>Sting</composers>
500
502
  </song>
501
503
  ```
@@ -823,7 +825,7 @@ song.extend(SongRepresenter).to_yaml
823
825
  #=>
824
826
  ---
825
827
  title: Fallout
826
- composers: [Steward Copeland, Sting]
828
+ composers: [Stewart Copeland, Sting]
827
829
  ```
828
830
 
829
831
  ## More on XML
@@ -992,6 +994,26 @@ If you want `nil` values to be included when rendering, use the `:render_nil` op
992
994
  property :track, render_nil: true
993
995
  ```
994
996
 
997
+
998
+ ### Overriding Serialize And Deserialize
999
+
1000
+ When serializing, the default mechanics after preparing the object are to call `object.to_hash`.
1001
+
1002
+ Override this step with `:serialize`.
1003
+
1004
+ ```ruby
1005
+ property :song, extend: SongRepresenter,
1006
+ serialize: lambda { |object, *args| Marshal.dump(object) }
1007
+ ```
1008
+
1009
+ Vice-versa, parsing allows the same.
1010
+
1011
+ ```ruby
1012
+ property :song, extend: SongRepresenter,
1013
+ deserialize: lambda { |object, fragment, *args| Marshal.load(fragment) }
1014
+ ```
1015
+
1016
+
995
1017
  ## Coercion
996
1018
 
997
1019
  If you fancy coercion when parsing a document you can use the Coercion module which uses [virtus](https://github.com/solnic/virtus) for type conversion.
@@ -135,6 +135,7 @@ module Representable
135
135
  end
136
136
 
137
137
  private
138
+ # DISCUSS: deprecate :class in favour of :instance and simplicity?
138
139
  def class_for(fragment, *args)
139
140
  item_class = class_from(fragment, *args) or return handle_deprecated_class(fragment)
140
141
  item_class.new
@@ -90,7 +90,7 @@ module Representable
90
90
  end
91
91
 
92
92
  def dynamic_options
93
- [:as, :getter, :setter, :class, :instance, :reader, :writer, :extend, :prepare, :if]
93
+ [:as, :getter, :setter, :class, :instance, :reader, :writer, :extend, :prepare, :if, :deserialize, :serialize]
94
94
  end
95
95
 
96
96
  def handle_extend!(options)
@@ -37,7 +37,9 @@ module Representable
37
37
  def deserialize(object, fragment, options) # TODO: merge with #serialize.
38
38
  return object unless @binding.representable?
39
39
 
40
- object.send(@binding.deserialize_method, fragment, options)
40
+ @binding.send(:evaluate_option, :deserialize, object, fragment) do
41
+ object.send(@binding.deserialize_method, fragment, options)
42
+ end
41
43
  end
42
44
 
43
45
  def prepare(object)
@@ -20,7 +20,9 @@ module Representable
20
20
  def serialize(object, user_options)
21
21
  return object unless @binding.representable?
22
22
 
23
- object.send(@binding.serialize_method, user_options.merge!({:wrap => false}))
23
+ @binding.send(:evaluate_option, :serialize, object) do
24
+ object.send(@binding.serialize_method, user_options.merge!({:wrap => false}))
25
+ end
24
26
  end
25
27
  end
26
28
  end
@@ -1,3 +1,3 @@
1
1
  module Representable
2
- VERSION = "1.8.0"
2
+ VERSION = "1.8.1"
3
3
  end
@@ -56,7 +56,7 @@ module SongRepresenter
56
56
  end
57
57
 
58
58
 
59
- song = Song.new(:title => "Fallout", :composers => ["Steward Copeland", "Sting"])
59
+ song = Song.new(:title => "Fallout", :composers => ["Stewart Copeland", "Sting"])
60
60
  puts song.extend(SongRepresenter).to_json
61
61
 
62
62
 
@@ -143,7 +143,7 @@ module SongRepresenter
143
143
  property :track
144
144
  collection :composers
145
145
  end
146
- song = Song.new(:title => "Fallout", :composers => ["Steward Copeland", "Sting"])
146
+ song = Song.new(:title => "Fallout", :composers => ["Stewart Copeland", "Sting"])
147
147
  puts song.extend(SongRepresenter).to_xml
148
148
 
149
149
  reset_representer(SongRepresenter)
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+
3
+ class SerializeDeserializeTest < BaseTest
4
+ subject { Struct.new(:song).new.extend(representer) }
5
+
6
+ describe "deserialize" do
7
+ representer! do
8
+ property :song,
9
+ :instance => lambda { |fragment, *| fragment.to_s.upcase },
10
+ :prepare => lambda { |fragment, *| fragment }, # TODO: allow false.
11
+ :deserialize => lambda { |object, fragment, args|
12
+ "#{object} #{fragment} #{args.inspect}"
13
+ }
14
+ end
15
+
16
+ it { subject.from_hash({"song" => Object}, {:volume => 9}).song.must_equal "OBJECT Object {:volume=>9}" }
17
+ end
18
+
19
+ describe "serialize" do
20
+ representer! do
21
+ property :song,
22
+ :representable => true,
23
+ :prepare => lambda { |fragment, *| fragment }, # TODO: allow false.
24
+ :serialize => lambda { |object, args|
25
+ "#{object} #{args.inspect}"
26
+ }
27
+ end
28
+
29
+ before { subject.song = "Arrested In Shanghai" }
30
+
31
+ it { subject.to_hash({:volume => 9}).must_equal({"song"=>"Arrested In Shanghai {:volume=>9}"}) }
32
+ end
33
+ end
metadata CHANGED
@@ -1,167 +1,167 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: representable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.8.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-04-14 00:00:00.000000000 Z
11
+ date: 2014-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: uber
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: test_xml
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.1.6
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.1.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ~>
88
88
  - !ruby/object:Gem::Version
89
89
  version: 5.0.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: 5.0.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: mocha
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: 0.13.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.13.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: mongoid
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - '>='
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - '>='
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: virtus
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ~>
130
130
  - !ruby/object:Gem::Version
131
131
  version: 0.5.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ~>
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.5.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: yajl-ruby
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ">="
143
+ - - '>='
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ">="
150
+ - - '>='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: json
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ~>
158
158
  - !ruby/object:Gem::Version
159
159
  version: 1.7.7
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ~>
165
165
  - !ruby/object:Gem::Version
166
166
  version: 1.7.7
167
167
  description: Renders and parses JSON/XML/YAML documents from and to Ruby objects.
@@ -172,8 +172,8 @@ executables: []
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
- - ".gitignore"
176
- - ".travis.yml"
175
+ - .gitignore
176
+ - .travis.yml
177
177
  - CHANGES.md
178
178
  - Gemfile
179
179
  - LICENSE
@@ -236,6 +236,7 @@ files:
236
236
  - test/prepare_test.rb
237
237
  - test/reader_writer_test.rb
238
238
  - test/representable_test.rb
239
+ - test/serialize_deserialize_test.rb
239
240
  - test/stringify_hash_test.rb
240
241
  - test/test_helper.rb
241
242
  - test/test_helper_test.rb
@@ -252,54 +253,19 @@ require_paths:
252
253
  - lib
253
254
  required_ruby_version: !ruby/object:Gem::Requirement
254
255
  requirements:
255
- - - ">="
256
+ - - '>='
256
257
  - !ruby/object:Gem::Version
257
258
  version: '0'
258
259
  required_rubygems_version: !ruby/object:Gem::Requirement
259
260
  requirements:
260
- - - ">="
261
+ - - '>='
261
262
  - !ruby/object:Gem::Version
262
263
  version: '0'
263
264
  requirements: []
264
265
  rubyforge_project:
265
- rubygems_version: 2.2.1
266
+ rubygems_version: 2.0.2
266
267
  signing_key:
267
268
  specification_version: 4
268
269
  summary: Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes
269
270
  plain properties, collections, nesting, coercion and more.
270
- test_files:
271
- - test/as_test.rb
272
- - test/class_test.rb
273
- - test/coercion_test.rb
274
- - test/config_test.rb
275
- - test/decorator_scope_test.rb
276
- - test/decorator_test.rb
277
- - test/definition_test.rb
278
- - test/example.rb
279
- - test/exec_context_test.rb
280
- - test/generic_test.rb
281
- - test/getter_setter_test.rb
282
- - test/hash_bindings_test.rb
283
- - test/hash_test.rb
284
- - test/if_test.rb
285
- - test/inherit_test.rb
286
- - test/inheritance_test.rb
287
- - test/inline_test.rb
288
- - test/instance_test.rb
289
- - test/is_representable_test.rb
290
- - test/json_test.rb
291
- - test/mongoid_test.rb
292
- - test/nested_test.rb
293
- - test/parse_strategy_test.rb
294
- - test/pass_options_test.rb
295
- - test/prepare_test.rb
296
- - test/reader_writer_test.rb
297
- - test/representable_test.rb
298
- - test/stringify_hash_test.rb
299
- - test/test_helper.rb
300
- - test/test_helper_test.rb
301
- - test/wrap_test.rb
302
- - test/xml_bindings_test.rb
303
- - test/xml_test.rb
304
- - test/yaml_test.rb
305
- has_rdoc:
271
+ test_files: []