representable 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGES.md +5 -0
- data/README.md +1 -1
- data/TODO +1 -3
- data/TODO-4.0.md +72 -0
- data/lib/representable/declarative.rb +3 -3
- data/lib/representable/deserializer.rb +1 -1
- data/lib/representable/serializer.rb +1 -1
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +6 -4
- data/lib/representable/xml/binding.rb +19 -12
- data/lib/representable/xml/namespace.rb +122 -0
- data/representable.gemspec +2 -2
- data/test/as_test.rb +2 -2
- data/test/binding_test.rb +7 -7
- data/test/cached_test.rb +13 -13
- data/test/class_test.rb +2 -2
- data/test/coercion_test.rb +1 -1
- data/test/config_test.rb +5 -5
- data/test/decorator_scope_test.rb +1 -1
- data/test/decorator_test.rb +8 -8
- data/test/default_test.rb +1 -1
- data/test/defaults_options_test.rb +3 -3
- data/test/definition_test.rb +9 -11
- data/test/examples/object.rb +1 -5
- data/test/exec_context_test.rb +2 -2
- data/test/features_test.rb +3 -3
- data/test/filter_test.rb +2 -2
- data/test/for_collection_test.rb +8 -8
- data/test/generic_test.rb +11 -11
- data/test/hash_bindings_test.rb +1 -1
- data/test/hash_test.rb +13 -13
- data/test/heritage_test.rb +16 -13
- data/test/if_test.rb +3 -3
- data/test/include_exclude_test.rb +2 -2
- data/test/inherit_test.rb +3 -3
- data/test/inline_test.rb +13 -13
- data/test/instance_test.rb +2 -2
- data/test/json_test.rb +4 -6
- data/test/lonely_test.rb +15 -15
- data/test/nested_test.rb +6 -6
- data/test/object_test.rb +4 -4
- data/test/parse_pipeline_test.rb +0 -2
- data/test/pipeline_test.rb +7 -7
- data/test/populator_test.rb +7 -7
- data/test/prepare_test.rb +2 -2
- data/test/represent_test.rb +10 -10
- data/test/representable_test.rb +7 -7
- data/test/schema_test.rb +3 -6
- data/test/skip_test.rb +6 -6
- data/test/test_helper.rb +16 -6
- data/test/wrap_test.rb +8 -8
- data/test/xml_namespace_test.rb +186 -0
- data/test/xml_test.rb +53 -34
- data/test/yaml_test.rb +11 -11
- metadata +9 -7
- data/lib/representable/TODO.getting_serious +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04ca3309b8af78dd1eaa8b4d47c457323180a881
|
4
|
+
data.tar.gz: c7d43dc372fc53576a6b64f22d3fc0bd1bff5a4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 528696ff8d8eae7b409566d9831a0117a90a361fdabe5a0345d0e5accac5cfbb2f3bfae5a34589000b5bdbf2632f7951356861215d210172c602b581694e68dc
|
7
|
+
data.tar.gz: 4d7409a62a9a25d31fc1c67d20e2b32b9cd0a1d8e9987b2cbe118bd4e069fe271dd82127f3e7656b92f01e8f1266524965def4089e439b4a1eac370e13a06bff
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 3.0.4
|
2
|
+
|
3
|
+
* Add proper XML namespace support.
|
4
|
+
* [internal] Replace `XML::Binding#node_for` with function `XML::Node`.
|
5
|
+
|
1
6
|
# 3.0.3
|
2
7
|
|
3
8
|
* Replace `Uber::Option` with the new [`Declarative::Option`](https://github.com/apotonick/declarative-option). This should result in a significant performance boost.
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Representable maps Ruby objects to documents and back.
|
|
5
5
|
[![Gitter Chat](https://badges.gitter.im/trailblazer/chat.svg)](https://gitter.im/trailblazer/chat)
|
6
6
|
[![TRB Newsletter](https://img.shields.io/badge/TRB-newsletter-lightgrey.svg)](http://trailblazer.to/newsletter/)
|
7
7
|
[![Build
|
8
|
-
Status](https://travis-ci.org/
|
8
|
+
Status](https://travis-ci.org/trailblazer/representable.svg)](https://travis-ci.org/trailblazer/representable)
|
9
9
|
[![Gem Version](https://badge.fury.io/rb/representable.svg)](http://badge.fury.io/rb/representable)
|
10
10
|
|
11
11
|
In other words: Take an object and decorate it with a representer module. This will allow you to render a JSON, XML or YAML document from that object. But that's only half of it! You can also use representers to parse a document and create or populate an object.
|
data/TODO
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
* Pass key/index as first block arg to :class and :extend
|
2
2
|
class: |key, hsh|
|
3
3
|
|
4
|
-
* Allow passing options to Binding#serialize.
|
5
|
-
serialize(.., options{:exclude => ..})
|
6
4
|
|
7
5
|
document `XML::AttributeHash` etc
|
8
6
|
|
@@ -37,4 +35,4 @@ module ReaderWriter
|
|
37
35
|
* DISCUSS: should inline representers be created at runtime, so we don't need ::representer_engine?
|
38
36
|
* deprecate `Decorator::Coercion`.
|
39
37
|
|
40
|
-
* cleanup XML so it matches the current #serialize standard.
|
38
|
+
* cleanup XML so it matches the current #serialize standard.
|
data/TODO-4.0.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Decorator
|
2
|
+
|
3
|
+
XML::Binding::Collection.to_xml(represented)
|
4
|
+
bindings.each bin.to_xml
|
5
|
+
|
6
|
+
|
7
|
+
# hat vorteil: [].each{ Collection.to_xml(item) }
|
8
|
+
|
9
|
+
* make all properties "Object-like", even arrays of strings etc. This saves us from having `extend ObjectBinding if typed?` and we could just call to_hash/from_hash on all attributes. performance issues here? otherwise: implement!
|
10
|
+
|
11
|
+
|
12
|
+
# how to?
|
13
|
+
|
14
|
+
class CH
|
15
|
+
wrap :character
|
16
|
+
prpoerty :a
|
17
|
+
|
18
|
+
|
19
|
+
class
|
20
|
+
proerty :author, dec: CH
|
21
|
+
|
22
|
+
# how to?
|
23
|
+
|
24
|
+
* override specific bindings and their logic? e.g. `Namespace#read`
|
25
|
+
* Extend nested representers, e.g. the namespace prefix, when it gets plugged into composition
|
26
|
+
* Easier polymorphic representer
|
27
|
+
|
28
|
+
# XML
|
29
|
+
|
30
|
+
* ditch annoying nokogiri in favor of https://github.com/YorickPeterse/oga
|
31
|
+
|
32
|
+
# Parsing
|
33
|
+
|
34
|
+
* Let bindings have any "xpath"
|
35
|
+
* Allow to parse "wildcard" sections where you have no idea about the property names (and attribute names, eg. with links)
|
36
|
+
|
37
|
+
# Options
|
38
|
+
|
39
|
+
* There should be an easier way to pass a set of options to all nested #to_node decorators.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
representable_attrs.keys.each do |property|
|
43
|
+
options[property.to_sym] = { show_definition: false, namespaces: options[:namespaces] }
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
* Allow passing options to Binding#serialize.
|
48
|
+
serialize(.., options{:exclude => ..})
|
49
|
+
|
50
|
+
|
51
|
+
# wrap, as
|
52
|
+
|
53
|
+
AsWithNamespace( Binding )
|
54
|
+
BUT NOT FOR AsWithNamespace( Binding::Attribute )
|
55
|
+
=> selectively wrap bindings at compile- and runtime
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
* Cleanup the manifest part in Decorator.
|
63
|
+
|
64
|
+
* all property objects should be extended/wrapped so we don't need the switch.
|
65
|
+
|
66
|
+
# Deprecations
|
67
|
+
|
68
|
+
* deprecate instance: { nil } which is superseded by parse_strategy: :sync
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
from_hash, property :band, class: vergessen
|
@@ -47,10 +47,10 @@ module Representable
|
|
47
47
|
NestedBuilder = ->(options) do
|
48
48
|
Module.new do
|
49
49
|
include Representable # FIXME: do we really need this?
|
50
|
-
feature
|
51
|
-
include
|
50
|
+
feature(*options[:_features])
|
51
|
+
include(*options[:_base]) # base when :inherit, or in decorator.
|
52
52
|
|
53
|
-
module_eval
|
53
|
+
module_eval(&options[:_block])
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -96,7 +96,7 @@ module Representable
|
|
96
96
|
If = ->(input, options) { options[:binding].evaluate_option(:if, nil, options) ? input : Pipeline::Stop }
|
97
97
|
|
98
98
|
StopOnExcluded = ->(input, options) do
|
99
|
-
return input unless
|
99
|
+
return input unless options[:options]
|
100
100
|
return input unless props = (options[:options][:exclude] || options[:options][:include])
|
101
101
|
|
102
102
|
res = props.include?(options[:binding].name.to_sym) # false with include: Stop. false with exclude: go!
|
@@ -51,4 +51,4 @@ module Representable
|
|
51
51
|
# Warning: don't rely on AssignAs/AssignName, i am not sure if i leave that as functions.
|
52
52
|
AssignAs = ->(input, options) { options[:as] = As.(input, options); input }
|
53
53
|
AssignName = ->(input, options) { options[:as] = options[:binding].name; input }
|
54
|
-
end
|
54
|
+
end
|
data/lib/representable/xml.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'representable'
|
2
|
-
require 'representable/xml/binding'
|
3
|
-
require 'representable/xml/collection'
|
4
2
|
|
5
3
|
begin
|
6
4
|
require 'nokogiri'
|
@@ -46,10 +44,10 @@ module Representable
|
|
46
44
|
|
47
45
|
# Returns a Nokogiri::XML object representing this object.
|
48
46
|
def to_node(options={})
|
49
|
-
options[:doc]
|
47
|
+
options[:doc] = Nokogiri::XML::Document.new # DISCUSS: why do we need a fresh Document here?
|
50
48
|
root_tag = options[:wrap] || representation_wrap(options)
|
51
49
|
|
52
|
-
create_representation_with(
|
50
|
+
create_representation_with(Node(options[:doc], root_tag.to_s), options, Binding)
|
53
51
|
end
|
54
52
|
|
55
53
|
def to_xml(*args)
|
@@ -73,3 +71,7 @@ module Representable
|
|
73
71
|
end
|
74
72
|
end
|
75
73
|
end
|
74
|
+
|
75
|
+
require "representable/xml/binding"
|
76
|
+
require "representable/xml/collection"
|
77
|
+
require "representable/xml/namespace"
|
@@ -3,6 +3,14 @@ require 'representable/hash/binding.rb'
|
|
3
3
|
|
4
4
|
module Representable
|
5
5
|
module XML
|
6
|
+
module_function
|
7
|
+
def Node(document, name, attributes={})
|
8
|
+
node = Nokogiri::XML::Node.new(name.to_s, document) # Java::OrgW3cDom::DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
|
9
|
+
|
10
|
+
attributes.each { |k, v| node[k] = v } # TODO: benchmark.
|
11
|
+
node
|
12
|
+
end
|
13
|
+
|
6
14
|
class Binding < Representable::Binding
|
7
15
|
def self.build_for(definition)
|
8
16
|
return Collection.new(definition) if definition.array?
|
@@ -17,7 +25,7 @@ module Representable
|
|
17
25
|
wrap_node = parent
|
18
26
|
|
19
27
|
if wrap = self[:wrap]
|
20
|
-
parent << wrap_node =
|
28
|
+
parent << wrap_node = XML::Node(parent, wrap)
|
21
29
|
end
|
22
30
|
|
23
31
|
wrap_node << serialize_for(fragments, parent, as)
|
@@ -32,12 +40,15 @@ module Representable
|
|
32
40
|
|
33
41
|
# Creates wrapped node for the property.
|
34
42
|
def serialize_for(value, parent, as)
|
35
|
-
node =
|
36
|
-
serialize_node(node, value)
|
43
|
+
node = XML::Node(parent, as) # node doesn't have attr="" attributes!!!
|
44
|
+
serialize_node(node, value, as)
|
37
45
|
end
|
38
46
|
|
39
|
-
def serialize_node(node, value)
|
40
|
-
|
47
|
+
def serialize_node(node, value, as)
|
48
|
+
if typed?
|
49
|
+
value.name = as if as != self[:name]
|
50
|
+
return value
|
51
|
+
end
|
41
52
|
|
42
53
|
node.content = value
|
43
54
|
node
|
@@ -60,11 +71,7 @@ module Representable
|
|
60
71
|
def find_nodes(doc, as)
|
61
72
|
selector = as
|
62
73
|
selector = "#{self[:wrap]}/#{as}" if self[:wrap]
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
def node_for(parent, name)
|
67
|
-
Nokogiri::XML::Node.new(name.to_s, parent.document)
|
74
|
+
doc.xpath(selector) # nodes
|
68
75
|
end
|
69
76
|
|
70
77
|
def content_for(node) # TODO: move this into a ScalarDecorator.
|
@@ -100,8 +107,8 @@ module Representable
|
|
100
107
|
class Hash < Collection
|
101
108
|
def serialize_for(value, parent, as)
|
102
109
|
set_for(parent, value.collect do |k, v|
|
103
|
-
node =
|
104
|
-
serialize_node(node, v)
|
110
|
+
node = XML::Node(parent, k)
|
111
|
+
serialize_node(node, v, as)
|
105
112
|
end)
|
106
113
|
end
|
107
114
|
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Representable::XML
|
2
|
+
# Experimental!
|
3
|
+
# Best explanation so far: http://books.xmlschemata.org/relaxng/relax-CHP-11-SECT-1.html
|
4
|
+
#
|
5
|
+
# Note: This module doesn't work with JRuby because Nokogiri uses a completely
|
6
|
+
# different implementation in Java which has other requirements that we couldn't fulfil.
|
7
|
+
# Please wait for Representable 4 where we replace Nokogiri with Oga.
|
8
|
+
module Namespace
|
9
|
+
def self.included(includer)
|
10
|
+
includer.extend(DSL)
|
11
|
+
end
|
12
|
+
|
13
|
+
module DSL
|
14
|
+
def namespace(namespace)
|
15
|
+
representable_attrs.options[:local_namespace] = namespace
|
16
|
+
representable_attrs.options[:namespace_mappings] ||= {}
|
17
|
+
representable_attrs.options[:namespace_mappings][namespace] = nil # this might get overwritten via #namespace_def later.
|
18
|
+
end
|
19
|
+
|
20
|
+
def namespace_def(mapping)
|
21
|
+
namespace_defs.merge!(mapping.invert)
|
22
|
+
end
|
23
|
+
|
24
|
+
# :private:
|
25
|
+
def namespace_defs
|
26
|
+
representable_attrs.options[:namespace_mappings] ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def property(name, options={})
|
30
|
+
uri = representable_attrs.options[:local_namespace] # per default, a property belongs to the local namespace.
|
31
|
+
options[:namespace] ||= uri # don't override if already set.
|
32
|
+
|
33
|
+
# a nested representer is automatically assigned "its" local namespace. It's like saying
|
34
|
+
# property :author, namespace: "http://ns/author" do ... end
|
35
|
+
|
36
|
+
super.tap do |dfn|
|
37
|
+
if dfn.typed? # FIXME: ouch, this should be doable with property's API to hook into the creation process.
|
38
|
+
dfn.merge!( namespace: dfn.representer_module.representable_attrs.options[:local_namespace] )
|
39
|
+
|
40
|
+
update_namespace_defs!(namespace_defs)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# :private:
|
46
|
+
# super ugly hack
|
47
|
+
# recursively injects the namespace_defs into all representers of this tree. will be done better in 4.0.
|
48
|
+
def update_namespace_defs!(namespace_defs)
|
49
|
+
representable_attrs.each do |dfn|
|
50
|
+
dfn.merge!(namespace_defs: namespace_defs) # this only helps with scalars
|
51
|
+
|
52
|
+
if dfn.typed?
|
53
|
+
representer = Class.new(dfn.representer_module) # don't pollute classes.
|
54
|
+
representer.update_namespace_defs!(namespace_defs)
|
55
|
+
dfn.merge!(extend: representer)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module AsWithNamespace
|
62
|
+
def write(doc, fragment, as)
|
63
|
+
super(doc, fragment, prefixed(self, as))
|
64
|
+
end
|
65
|
+
|
66
|
+
# FIXME: this is shit, the NestedOptions is executed too late here!
|
67
|
+
def read(node, as)
|
68
|
+
super(node, prefixed(self, as))
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def prefixed(dfn, as)
|
73
|
+
uri = dfn[:namespace] # this is generic behavior and per property
|
74
|
+
prefix = dfn[:namespace_defs][uri]
|
75
|
+
as = Namespace::Namespaced(prefix, as)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# FIXME: some "bug" in Representable's XML doesn't consider the container tag, so we could theoretically pick the
|
80
|
+
# wrong namespaced tag here :O
|
81
|
+
def from_node(node, options={})
|
82
|
+
super
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_node(options={})
|
86
|
+
local_uri = representable_attrs.options[:local_namespace] # every decorator MUST have a local namespace.
|
87
|
+
prefix = self.class.namespace_defs[local_uri]
|
88
|
+
|
89
|
+
root_tag = [prefix, representation_wrap(options)].compact.join(":")
|
90
|
+
|
91
|
+
options = { wrap: root_tag }.merge(options)
|
92
|
+
|
93
|
+
# TODO: there should be an easier way to pass a set of options to all nested #to_node decorators.
|
94
|
+
representable_attrs.keys.each do |property|
|
95
|
+
options[property.to_sym] = { show_definition: false, namespaces: options[:namespaces] }
|
96
|
+
end
|
97
|
+
|
98
|
+
super(options).tap do |node|
|
99
|
+
add_namespace_definitions!(node, self.class.namespace_defs) unless options[:show_definition] == false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# "Physically" add `xmlns` attributes to `node`.
|
104
|
+
def add_namespace_definitions!(node, namespaces)
|
105
|
+
namespaces.each do |uri, prefix|
|
106
|
+
prefix = prefix.nil? ? nil : prefix.to_s
|
107
|
+
node.add_namespace_definition(prefix, uri)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.Namespaced(prefix, name)
|
112
|
+
[ prefix, name ].compact.join(":")
|
113
|
+
end
|
114
|
+
|
115
|
+
# FIXME: this is a PoC, we need a better API to inject code.
|
116
|
+
def representable_map(options, format)
|
117
|
+
super.tap do |map|
|
118
|
+
map.each { |bin| bin.extend(AsWithNamespace) unless bin.is_a?(Binding::Attribute) }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/representable.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.platform = Gem::Platform::RUBY
|
10
10
|
spec.authors = ["Nick Sutterer"]
|
11
11
|
spec.email = ["apotonick@gmail.com"]
|
12
|
-
spec.homepage = "https://github.com/
|
12
|
+
spec.homepage = "https://github.com/trailblazer/representable/"
|
13
13
|
spec.summary = %q{Renders and parses JSON/XML/YAML documents from and to Ruby objects. Includes plain properties, collections, nesting, coercion and more.}
|
14
14
|
spec.description = spec.summary
|
15
15
|
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency "declarative-option", "< 0.2.0"
|
27
27
|
|
28
28
|
spec.add_development_dependency "rake"
|
29
|
-
spec.add_development_dependency "test_xml", "0.1.6"
|
29
|
+
spec.add_development_dependency "test_xml", ">= 0.1.6"
|
30
30
|
spec.add_development_dependency "minitest"
|
31
31
|
spec.add_development_dependency "virtus"
|
32
32
|
spec.add_development_dependency "multi_json"
|
data/test/as_test.rb
CHANGED
@@ -7,8 +7,8 @@ class AsTest < MiniTest::Spec
|
|
7
7
|
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
8
8
|
) do |format, mod, input, output|
|
9
9
|
|
10
|
-
let
|
11
|
-
let
|
10
|
+
let(:song) { representer.prepare(Song.new("Revolution")) }
|
11
|
+
let(:format) { format }
|
12
12
|
|
13
13
|
|
14
14
|
describe "as: with :symbol" do
|
data/test/binding_test.rb
CHANGED
@@ -2,10 +2,10 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class BindingTest < MiniTest::Spec
|
4
4
|
Binding = Representable::Binding
|
5
|
-
let
|
5
|
+
let(:render_nil_definition) { Representable::Definition.new(:song, :render_nil => true) }
|
6
6
|
|
7
7
|
describe "#skipable_empty_value?" do
|
8
|
-
let
|
8
|
+
let(:binding) { Binding.new(render_nil_definition) }
|
9
9
|
|
10
10
|
# don't skip when present.
|
11
11
|
it { binding.skipable_empty_value?("Disconnect, Disconnect").must_equal false }
|
@@ -22,8 +22,8 @@ class BindingTest < MiniTest::Spec
|
|
22
22
|
|
23
23
|
|
24
24
|
describe "#default_for" do
|
25
|
-
let
|
26
|
-
let
|
25
|
+
let(:definition) { Representable::Definition.new(:song, :default => "Insider") }
|
26
|
+
let(:binding) { Binding.new(definition) }
|
27
27
|
|
28
28
|
# return value when value present.
|
29
29
|
it { binding.default_for("Black And Blue").must_equal "Black And Blue" }
|
@@ -35,12 +35,12 @@ class BindingTest < MiniTest::Spec
|
|
35
35
|
it { binding.default_for(nil).must_equal "Insider" }
|
36
36
|
|
37
37
|
# return nil when value nil and render_nil: true.
|
38
|
-
it { Binding.new(render_nil_definition).default_for(nil).
|
38
|
+
it { Binding.new(render_nil_definition).default_for(nil).must_be_nil }
|
39
39
|
|
40
40
|
# return nil when value nil and render_nil: true, even when :default is set" do
|
41
|
-
it { Binding.new(Representable::Definition.new(:song, :render_nil => true, :default => "The Quest")).default_for(nil).
|
41
|
+
it { Binding.new(Representable::Definition.new(:song, :render_nil => true, :default => "The Quest")).default_for(nil).must_be_nil }
|
42
42
|
|
43
43
|
# return nil if no :default
|
44
|
-
it { Binding.new(Representable::Definition.new(:song)).default_for(nil).
|
44
|
+
it { Binding.new(Representable::Definition.new(:song)).default_for(nil).must_be_nil }
|
45
45
|
end
|
46
46
|
end
|