representable 1.2.0 → 1.2.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.
- data/CHANGES.textile +5 -0
- data/README.rdoc +3 -3
- data/lib/representable.rb +6 -2
- data/lib/representable/binding.rb +4 -0
- data/lib/representable/bindings/json_bindings.rb +2 -1
- data/lib/representable/bindings/xml_bindings.rb +1 -1
- data/lib/representable/definition.rb +7 -3
- data/lib/representable/deprecations.rb +9 -7
- data/lib/representable/version.rb +1 -1
- data/test/definition_test.rb +24 -8
- data/test/json_bindings_test.rb +17 -0
- data/test/json_test.rb +3 -3
- data/test/representable_test.rb +22 -2
- data/test/test_helper.rb +11 -0
- data/test/xml_test.rb +1 -1
- metadata +2 -2
data/CHANGES.textile
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
h2. 1.2.1
|
2
|
+
|
3
|
+
* Deprecated @:represent_nil@ favor of @:render_nil@.
|
4
|
+
* API change: if a property is missing in an incoming document and there is no default set it is completely ignored and *not* set in the represented object.
|
5
|
+
|
1
6
|
h2. 1.2.0
|
2
7
|
|
3
8
|
* Deprecated @:except@ in favor of @:exclude@.
|
data/README.rdoc
CHANGED
@@ -251,11 +251,11 @@ When rendering or parsing, the +friends+ property is considered only if the cond
|
|
251
251
|
|
252
252
|
=== False and Nil Values
|
253
253
|
|
254
|
-
Since 1.2 +false+ values are considered when parsing and rendering. That particularly means properties that used to be unset (i.e.
|
254
|
+
Since 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+ values that weren't included in the rendered document will be visible now.
|
255
255
|
|
256
|
-
If you want +nil+ values to be included when rendering, use the +:
|
256
|
+
If you want +nil+ values to be included when rendering, use the +:render_nil+ option.
|
257
257
|
|
258
|
-
property :surename, :
|
258
|
+
property :surename, :render_nil => true
|
259
259
|
|
260
260
|
== DCI
|
261
261
|
|
data/lib/representable.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'representable/definition'
|
2
1
|
require 'representable/deprecations'
|
2
|
+
require 'representable/definition'
|
3
3
|
|
4
4
|
# Representable can be used in two ways.
|
5
5
|
#
|
@@ -96,7 +96,11 @@ private
|
|
96
96
|
# Parse value from doc and update the model property.
|
97
97
|
def uncompile_fragment(bin, doc)
|
98
98
|
value = read_fragment_for(bin, doc)
|
99
|
-
|
99
|
+
|
100
|
+
if value == Binding::FragmentNotFound
|
101
|
+
return unless bin.definition.has_default?
|
102
|
+
value = bin.definition.default
|
103
|
+
end
|
100
104
|
|
101
105
|
send(bin.definition.setter, value)
|
102
106
|
end
|
@@ -27,6 +27,8 @@ module Representable
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def read(hash)
|
30
|
+
return FragmentNotFound unless hash.has_key?(definition.from) # DISCUSS: put it all in #read for performance. not really sure if i like returning that special thing.
|
31
|
+
|
30
32
|
fragment = hash[definition.from]
|
31
33
|
deserialize_from(fragment)
|
32
34
|
end
|
@@ -54,7 +56,6 @@ module Representable
|
|
54
56
|
end
|
55
57
|
|
56
58
|
def deserialize_from(fragment)
|
57
|
-
fragment ||= {}
|
58
59
|
fragment.collect { |item_fragment| deserialize(item_fragment) }
|
59
60
|
end
|
60
61
|
end
|
@@ -7,6 +7,8 @@ module Representable
|
|
7
7
|
def initialize(sym, options={})
|
8
8
|
@name = sym.to_s
|
9
9
|
@options = options
|
10
|
+
|
11
|
+
options[:default] ||= [] if array? # FIXME: move to CollectionBinding!
|
10
12
|
end
|
11
13
|
|
12
14
|
def clone
|
@@ -42,6 +44,10 @@ module Representable
|
|
42
44
|
value
|
43
45
|
end
|
44
46
|
|
47
|
+
def has_default?
|
48
|
+
options.has_key?(:default)
|
49
|
+
end
|
50
|
+
|
45
51
|
def representer_module
|
46
52
|
options[:extend]
|
47
53
|
end
|
@@ -51,12 +57,10 @@ module Representable
|
|
51
57
|
end
|
52
58
|
|
53
59
|
def skipable_nil_value?(value)
|
54
|
-
value.nil? and not options[:
|
60
|
+
value.nil? and not options[:render_nil]
|
55
61
|
end
|
56
62
|
|
57
|
-
private
|
58
63
|
def default
|
59
|
-
options[:default] ||= [] if array? # FIXME: move to CollectionBinding!
|
60
64
|
options[:default]
|
61
65
|
end
|
62
66
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
module Representable
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Representable
|
2
|
+
module Deprecations
|
3
|
+
def skip_excluded_property?(binding, options) # TODO: remove with 1.3.
|
4
|
+
if options[:except]
|
5
|
+
options[:exclude] = options[:except]
|
6
|
+
warn "The :except option is deprecated and will be removed in 1.3. Please use :exclude."
|
7
|
+
end # i wanted a one-liner but failed :)
|
8
|
+
super
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
data/test/definition_test.rb
CHANGED
@@ -55,25 +55,41 @@ class DefinitionTest < MiniTest::Spec
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
describe "#has_default?" do
|
59
|
+
it "returns false if no :default set" do
|
60
|
+
assert_equal false, Representable::Definition.new(:song).has_default?
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns true if :default set" do
|
64
|
+
assert_equal true, Representable::Definition.new(:song, :default => nil).has_default?
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns true if :collection" do
|
68
|
+
assert_equal true, Representable::Definition.new(:songs, :collection => true).has_default?
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
58
74
|
describe "#skipable_nil_value?" do
|
59
75
|
# default if skipable_nil_value?
|
60
76
|
before do
|
61
|
-
@def = Representable::Definition.new(:song, :
|
77
|
+
@def = Representable::Definition.new(:song, :render_nil => true)
|
62
78
|
end
|
63
79
|
|
64
80
|
it "returns false when not nil" do
|
65
81
|
assert_equal false, @def.skipable_nil_value?("Disconnect, Disconnect")
|
66
82
|
end
|
67
83
|
|
68
|
-
it "returns false when nil and :
|
84
|
+
it "returns false when nil and :render_nil => true" do
|
69
85
|
assert_equal false, @def.skipable_nil_value?(nil)
|
70
86
|
end
|
71
87
|
|
72
|
-
it "returns true when nil and :
|
88
|
+
it "returns true when nil and :render_nil => false" do
|
73
89
|
assert_equal true, Representable::Definition.new(:song).skipable_nil_value?(nil)
|
74
90
|
end
|
75
91
|
|
76
|
-
it "returns false when not nil and :
|
92
|
+
it "returns false when not nil and :render_nil => false" do
|
77
93
|
assert_equal false, Representable::Definition.new(:song).skipable_nil_value?("Fatal Flu")
|
78
94
|
end
|
79
95
|
end
|
@@ -96,13 +112,13 @@ class DefinitionTest < MiniTest::Spec
|
|
96
112
|
assert_equal "Insider", @def.default_for(nil)
|
97
113
|
end
|
98
114
|
|
99
|
-
it "returns nil when value nil and :
|
100
|
-
@def = Representable::Definition.new(:song, :
|
115
|
+
it "returns nil when value nil and :render_nil true" do
|
116
|
+
@def = Representable::Definition.new(:song, :render_nil => true)
|
101
117
|
assert_equal nil, @def.default_for(nil)
|
102
118
|
end
|
103
119
|
|
104
|
-
it "returns nil when value nil and :
|
105
|
-
@def = Representable::Definition.new(:song, :
|
120
|
+
it "returns nil when value nil and :render_nil true even when :default is set" do
|
121
|
+
@def = Representable::Definition.new(:song, :render_nil => true, :default => "The Quest")
|
106
122
|
assert_equal nil, @def.default_for(nil)
|
107
123
|
end
|
108
124
|
|
data/test/json_bindings_test.rb
CHANGED
@@ -13,6 +13,23 @@ class JSONBindingTest < MiniTest::Spec
|
|
13
13
|
|
14
14
|
|
15
15
|
describe "PropertyBinding" do
|
16
|
+
describe "#read" do
|
17
|
+
before do
|
18
|
+
@property = Representable::JSON::PropertyBinding.new(Representable::Definition.new(:song))
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns fragment if present" do
|
22
|
+
assert_equal "Stick The Flag Up Your Goddamn Ass, You Sonofabitch", @property.read({"song" => "Stick The Flag Up Your Goddamn Ass, You Sonofabitch"})
|
23
|
+
assert_equal "", @property.read({"song" => ""})
|
24
|
+
assert_equal nil, @property.read({"song" => nil})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns FRAGMENT_NOT_FOUND if not in document" do
|
28
|
+
assert_equal Representable::Binding::FragmentNotFound, @property.read({})
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
16
33
|
describe "with plain text" do
|
17
34
|
before do
|
18
35
|
@property = Representable::JSON::PropertyBinding.new(Representable::Definition.new(:song))
|
data/test/json_test.rb
CHANGED
@@ -31,7 +31,7 @@ module JsonTest
|
|
31
31
|
|
32
32
|
it "yields new object and options to block" do
|
33
33
|
@Band.class_eval { attr_accessor :new_name }
|
34
|
-
@band = @Band.from_json({}, :new_name => "Diesel Boy") do |band, options|
|
34
|
+
@band = @Band.from_json("{}", :new_name => "Diesel Boy") do |band, options|
|
35
35
|
band.new_name= options[:new_name]
|
36
36
|
end
|
37
37
|
assert_equal "Diesel Boy", @band.new_name
|
@@ -378,8 +378,8 @@ end
|
|
378
378
|
assert_equal ["Cobra Skulls", "Diesel Boy"], cd.bands.map(&:name).sort
|
379
379
|
end
|
380
380
|
|
381
|
-
it "creates emtpy array
|
382
|
-
cd = Compilation.from_json({
|
381
|
+
it "creates emtpy array from default if configured" do
|
382
|
+
cd = Compilation.from_json({}.to_json)
|
383
383
|
assert_equal [], cd.bands
|
384
384
|
end
|
385
385
|
end
|
data/test/representable_test.rb
CHANGED
@@ -253,6 +253,26 @@ class RepresentableTest < MiniTest::Spec
|
|
253
253
|
@band.update_properties_from({"groupies"=>false}, {}, Representable::JSON)
|
254
254
|
assert_equal false, @band.groupies
|
255
255
|
end
|
256
|
+
|
257
|
+
it "ignores (no-default) properties not present in the incoming document" do
|
258
|
+
{ Representable::JSON => {},
|
259
|
+
Representable::XML => xml(%{<band/>})
|
260
|
+
}.each do |format, document|
|
261
|
+
nested_repr = Module.new do # this module is never applied.
|
262
|
+
include format
|
263
|
+
property :created_at
|
264
|
+
end
|
265
|
+
|
266
|
+
repr = Module.new do
|
267
|
+
include format
|
268
|
+
property :name, :class => Object, :extend => nested_repr
|
269
|
+
end
|
270
|
+
|
271
|
+
@band = Band.new.extend(repr)
|
272
|
+
@band.update_properties_from(document, {}, format)
|
273
|
+
assert_equal nil, @band.name, "Failed in #{format}"
|
274
|
+
end
|
275
|
+
end
|
256
276
|
end
|
257
277
|
|
258
278
|
describe "#create_representation_with" do
|
@@ -290,11 +310,11 @@ class RepresentableTest < MiniTest::Spec
|
|
290
310
|
assert_equal({"name"=>"No One's Choice","groupies"=>false}, @band.send(:create_representation_with, {}, {}, Representable::JSON))
|
291
311
|
end
|
292
312
|
|
293
|
-
it "includes nil attribute when :
|
313
|
+
it "includes nil attribute when :render_nil is true" do
|
294
314
|
mod = Module.new do
|
295
315
|
include Representable::JSON
|
296
316
|
property :name
|
297
|
-
property :groupies, :
|
317
|
+
property :groupies, :render_nil => true
|
298
318
|
end
|
299
319
|
|
300
320
|
@band.extend(mod) # FIXME: use clean object.
|
data/test/test_helper.rb
CHANGED
@@ -4,6 +4,7 @@ Bundler.setup
|
|
4
4
|
gem 'minitest'
|
5
5
|
require 'representable'
|
6
6
|
require 'representable/json'
|
7
|
+
require 'representable/xml'
|
7
8
|
require 'test/unit'
|
8
9
|
require 'minitest/spec'
|
9
10
|
require 'minitest/autorun'
|
@@ -28,3 +29,13 @@ class Song
|
|
28
29
|
name == other.name
|
29
30
|
end
|
30
31
|
end
|
32
|
+
|
33
|
+
module XmlHelper
|
34
|
+
def xml(document)
|
35
|
+
Nokogiri::XML(document).root
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
MiniTest::Spec.class_eval do
|
40
|
+
include XmlHelper
|
41
|
+
end
|
data/test/xml_test.rb
CHANGED
@@ -297,7 +297,7 @@ class CollectionTest < MiniTest::Spec
|
|
297
297
|
assert_equal ["Cobra Skulls", "Diesel Boy"], cd.bands.map(&:name).sort
|
298
298
|
end
|
299
299
|
|
300
|
-
it "collections can be empty" do
|
300
|
+
it "collections can be empty when default set" do
|
301
301
|
cd = Compilation.from_xml(%{
|
302
302
|
<compilation>
|
303
303
|
</compilation>
|
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.2.
|
4
|
+
version: 1.2.1
|
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: 2012-
|
12
|
+
date: 2012-06-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|