representable 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.textile +4 -0
- data/README.md +13 -12
- data/lib/representable.rb +12 -3
- data/lib/representable/bindings/hash_bindings.rb +5 -3
- data/lib/representable/version.rb +1 -1
- data/test/json_test.rb +12 -2
- data/test/representable_test.rb +9 -11
- data/test/test_helper.rb +11 -0
- metadata +2 -2
data/CHANGES.textile
CHANGED
data/README.md
CHANGED
@@ -55,6 +55,19 @@ It also adds support for parsing.
|
|
55
55
|
song = Song.new.extend(SongRepresenter).from_json(%{ {"title":"Roxanne"} })
|
56
56
|
#=> #<Song title="Roxanne", track=nil>
|
57
57
|
|
58
|
+
## Aliasing
|
59
|
+
|
60
|
+
If your property name doesn't match the name in the document, use the `:as` option.
|
61
|
+
|
62
|
+
module SongRepresenter
|
63
|
+
include Representable::JSON
|
64
|
+
|
65
|
+
property :title, as: :name
|
66
|
+
property :track
|
67
|
+
end
|
68
|
+
|
69
|
+
song.to_json #=> {"name":"Fallout","track":1}
|
70
|
+
|
58
71
|
|
59
72
|
## Wrapping
|
60
73
|
|
@@ -436,18 +449,6 @@ You can also define conditions on properties using `:if`, making them being cons
|
|
436
449
|
When rendering or parsing, the `track` property is considered only if track is valid. Note that the block is executed in instance context, giving you access to instance methods.
|
437
450
|
|
438
451
|
|
439
|
-
### Mapping
|
440
|
-
|
441
|
-
If your property name doesn't match the attribute name in the document, use the `:as` option.
|
442
|
-
|
443
|
-
module SongRepresenter
|
444
|
-
property :title
|
445
|
-
property :track, as: :track_number
|
446
|
-
end
|
447
|
-
|
448
|
-
song.to_json #=> {"title":"Superstars","track_number":1}
|
449
|
-
|
450
|
-
|
451
452
|
### False and Nil Values
|
452
453
|
|
453
454
|
Since representable-1.2 `false` values _are_ considered when parsing and rendering. That particularly means properties that used to be unset (i.e. `nil`) after parsing might be `false` now. Vice versa, `false` properties that weren't included in the rendered document will be visible now.
|
data/lib/representable.rb
CHANGED
@@ -121,7 +121,7 @@ private
|
|
121
121
|
module ClassInclusions
|
122
122
|
def included(base)
|
123
123
|
super
|
124
|
-
base.representable_attrs.
|
124
|
+
base.representable_attrs.inherit(representable_attrs)
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -145,7 +145,7 @@ private
|
|
145
145
|
|
146
146
|
module Declarations
|
147
147
|
def representable_attrs
|
148
|
-
@representable_attrs ||=
|
148
|
+
@representable_attrs ||= build_config
|
149
149
|
end
|
150
150
|
|
151
151
|
def representation_wrap=(name)
|
@@ -190,10 +190,15 @@ private
|
|
190
190
|
def definition_class
|
191
191
|
Definition
|
192
192
|
end
|
193
|
+
|
194
|
+
def build_config
|
195
|
+
Config.new
|
196
|
+
end
|
193
197
|
end
|
194
198
|
end
|
195
199
|
|
196
200
|
|
201
|
+
# NOTE: the API of Config is subject to change so don't rely too much on this private object.
|
197
202
|
class Config < Array
|
198
203
|
attr_accessor :wrap
|
199
204
|
|
@@ -207,7 +212,11 @@ private
|
|
207
212
|
def clone
|
208
213
|
self.class.new(collect { |d| d.clone })
|
209
214
|
end
|
210
|
-
|
215
|
+
|
216
|
+
def inherit(parent)
|
217
|
+
push(*parent.clone)
|
218
|
+
end
|
219
|
+
|
211
220
|
private
|
212
221
|
def infer_name_for(name)
|
213
222
|
name.to_s.split('::').last.
|
@@ -63,13 +63,15 @@ module Representable
|
|
63
63
|
class HashBinding < PropertyBinding
|
64
64
|
def serialize_for(value)
|
65
65
|
# requires value to respond to #each with two block parameters.
|
66
|
-
{}.tap do |
|
67
|
-
value.each { |key, obj|
|
66
|
+
{}.tap do |hsh|
|
67
|
+
value.each { |key, obj| hsh[key] = serialize(obj) }
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
def deserialize_from(fragment)
|
72
|
-
|
72
|
+
{}.tap do |hsh|
|
73
|
+
fragment.each { |key, item_fragment| hsh[key] = deserialize(item_fragment) }
|
74
|
+
end
|
73
75
|
end
|
74
76
|
end
|
75
77
|
end
|
data/test/json_test.rb
CHANGED
@@ -460,8 +460,18 @@ end
|
|
460
460
|
OpenStruct.new(:songs => {"7" => Song.new("Contemplation")}).extend(representer).to_hash.must_equal("songs"=>{"7"=>{"name"=>"Contemplation"}})
|
461
461
|
end
|
462
462
|
|
463
|
-
|
464
|
-
OpenStruct.new.extend(representer)
|
463
|
+
describe "parsing" do
|
464
|
+
subject { OpenStruct.new.extend(representer) }
|
465
|
+
let (:hash) { {"7"=>{"name"=>"Contemplation"}} }
|
466
|
+
|
467
|
+
it "parses incoming hash" do
|
468
|
+
subject.from_hash("songs"=>hash).songs.must_equal({"7"=>Song.new("Contemplation")})
|
469
|
+
end
|
470
|
+
|
471
|
+
it "doesn't modify the incoming hash" do
|
472
|
+
subject.from_hash("songs"=> incoming_hash = hash.dup)
|
473
|
+
hash.must_equal incoming_hash
|
474
|
+
end
|
465
475
|
end
|
466
476
|
end
|
467
477
|
end
|
data/test/representable_test.rb
CHANGED
@@ -571,31 +571,29 @@ class RepresentableTest < MiniTest::Spec
|
|
571
571
|
end
|
572
572
|
|
573
573
|
describe "Config" do
|
574
|
-
|
575
|
-
|
576
|
-
PunkRock = Class.new
|
577
|
-
end
|
574
|
+
subject { Representable::Config.new }
|
575
|
+
PunkRock = Class.new
|
578
576
|
|
579
577
|
describe "wrapping" do
|
580
578
|
it "returns false per default" do
|
581
|
-
assert_equal nil,
|
579
|
+
assert_equal nil, subject.wrap_for("Punk")
|
582
580
|
end
|
583
581
|
|
584
582
|
it "infers a printable class name if set to true" do
|
585
|
-
|
586
|
-
assert_equal "punk_rock",
|
583
|
+
subject.wrap = true
|
584
|
+
assert_equal "punk_rock", subject.wrap_for(PunkRock)
|
587
585
|
end
|
588
586
|
|
589
587
|
it "can be set explicitely" do
|
590
|
-
|
591
|
-
assert_equal "Descendents",
|
588
|
+
subject.wrap = "Descendents"
|
589
|
+
assert_equal "Descendents", subject.wrap_for(PunkRock)
|
592
590
|
end
|
593
591
|
end
|
594
592
|
|
595
593
|
describe "clone" do
|
596
594
|
it "clones all definitions" do
|
597
|
-
|
598
|
-
assert
|
595
|
+
subject << Object.new
|
596
|
+
assert subject.first != subject.clone.first
|
599
597
|
end
|
600
598
|
end
|
601
599
|
end
|
data/test/test_helper.rb
CHANGED
@@ -62,4 +62,15 @@ MiniTest::Spec.class_eval do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
module TestMethods
|
67
|
+
def representer_for(modules=[Representable::Hash], &block)
|
68
|
+
Module.new do
|
69
|
+
extend TestMethods
|
70
|
+
include *modules
|
71
|
+
module_exec(&block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
include TestMethods
|
65
76
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: representable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|