representable 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +17 -0
- data/CHANGES.md +25 -0
- data/Gemfile +4 -12
- data/LICENSE +1 -1
- data/README.md +6 -6
- data/Rakefile +1 -6
- data/TODO +1 -3
- data/TODO-4.0.md +72 -0
- data/lib/representable.rb +19 -25
- data/lib/representable/binding.rb +32 -12
- data/lib/representable/cached.rb +1 -1
- data/lib/representable/coercion.rb +8 -6
- data/lib/representable/config.rb +13 -3
- data/lib/representable/debug.rb +23 -15
- data/lib/representable/declarative.rb +12 -7
- data/lib/representable/decorator.rb +1 -1
- data/lib/representable/definition.rb +7 -3
- data/lib/representable/deserializer.rb +5 -4
- data/lib/representable/for_collection.rb +1 -1
- data/lib/representable/hash.rb +9 -2
- data/lib/representable/hash/allow_symbols.rb +9 -11
- data/lib/representable/hash/binding.rb +1 -0
- data/lib/representable/hash/collection.rb +4 -2
- data/lib/representable/hash_methods.rb +3 -2
- data/lib/representable/insert.rb +1 -1
- data/lib/representable/json.rb +8 -7
- data/lib/representable/json/collection.rb +3 -0
- data/lib/representable/object.rb +1 -1
- data/lib/representable/object/binding.rb +5 -1
- data/lib/representable/option.rb +19 -0
- data/lib/representable/pipeline.rb +3 -2
- data/lib/representable/pipeline_factories.rb +4 -2
- data/lib/representable/populator.rb +1 -1
- data/lib/representable/represent.rb +1 -0
- data/lib/representable/serializer.rb +3 -2
- data/lib/representable/version.rb +1 -1
- data/lib/representable/virtus_coercion.rb +38 -0
- data/lib/representable/xml.rb +12 -10
- data/lib/representable/xml/binding.rb +19 -13
- data/lib/representable/xml/namespace.rb +122 -0
- data/lib/representable/yaml.rb +6 -2
- data/lib/representable/yaml/binding.rb +1 -0
- data/representable.gemspec +8 -9
- data/test/as_test.rb +7 -7
- data/test/binding_test.rb +14 -14
- data/test/cached_test.rb +59 -49
- data/test/class_test.rb +9 -9
- data/test/coercion_test.rb +33 -22
- data/test/config/inherit_test.rb +14 -14
- data/test/config_test.rb +20 -20
- data/test/decorator_scope_test.rb +4 -4
- data/test/decorator_test.rb +33 -20
- data/test/default_test.rb +8 -8
- data/test/defaults_options_test.rb +3 -3
- data/test/definition_test.rb +38 -40
- data/test/{example.rb → examples/example.rb} +0 -1
- data/test/examples/object.rb +1 -5
- data/test/exec_context_test.rb +8 -8
- data/test/features_test.rb +6 -6
- data/test/filter_test.rb +8 -8
- data/test/for_collection_test.rb +10 -10
- data/test/generic_test.rb +13 -13
- data/test/getter_setter_test.rb +5 -5
- data/test/hash_bindings_test.rb +1 -1
- data/test/hash_test.rb +45 -23
- data/test/heritage_test.rb +16 -13
- data/test/if_test.rb +9 -9
- data/test/include_exclude_test.rb +14 -14
- data/test/inherit_test.rb +18 -18
- data/test/inline_test.rb +24 -24
- data/test/instance_test.rb +31 -31
- data/test/is_representable_test.rb +10 -10
- data/test/json_test.rb +29 -7
- data/test/lonely_test.rb +31 -31
- data/test/nested_test.rb +13 -13
- data/test/object_test.rb +9 -9
- data/test/option_test.rb +36 -0
- data/test/parse_pipeline_test.rb +3 -5
- data/test/pipeline_test.rb +50 -50
- data/test/populator_test.rb +18 -18
- data/test/prepare_test.rb +4 -4
- data/test/private_options_test.rb +2 -2
- data/test/reader_writer_test.rb +2 -2
- data/test/render_nil_test.rb +2 -2
- data/test/represent_test.rb +14 -14
- data/test/representable_test.rb +34 -36
- data/test/schema_test.rb +8 -11
- data/test/serialize_deserialize_test.rb +2 -2
- data/test/skip_test.rb +14 -14
- data/test/stringify_hash_test.rb +3 -3
- data/test/test_helper.rb +26 -14
- data/test/uncategorized_test.rb +10 -10
- data/test/user_options_test.rb +4 -4
- data/test/virtus_coercion_test.rb +52 -0
- data/test/wrap_test.rb +19 -19
- data/test/xml_bindings_test.rb +0 -4
- data/test/xml_namespace_test.rb +186 -0
- data/test/xml_test.rb +103 -43
- data/test/yaml_test.rb +51 -26
- metadata +101 -39
- data/.travis.yml +0 -7
- data/lib/representable/TODO.getting_serious +0 -11
- data/lib/representable/autoload.rb +0 -10
- data/test/mongoid_test.rb +0 -31
@@ -4,11 +4,12 @@ module Representable
|
|
4
4
|
class Pipeline < Array
|
5
5
|
Stop = Class.new
|
6
6
|
|
7
|
-
# options is
|
7
|
+
# options is mutable.
|
8
8
|
def call(input, options)
|
9
9
|
inject(input) do |memo, block|
|
10
10
|
res = evaluate(block, memo, options)
|
11
|
-
return(Stop)if Stop == res
|
11
|
+
return(Stop) if Stop == res
|
12
|
+
|
12
13
|
res
|
13
14
|
end
|
14
15
|
end
|
@@ -2,7 +2,8 @@
|
|
2
2
|
module Representable
|
3
3
|
module Binding::Factories
|
4
4
|
def pipeline_for(name, input, options)
|
5
|
-
return yield unless proc = @definition[name]
|
5
|
+
return yield unless (proc = @definition[name])
|
6
|
+
|
6
7
|
# proc.(self, options)
|
7
8
|
instance_exec(input, options, &proc)
|
8
9
|
end
|
@@ -11,6 +12,7 @@ module Representable
|
|
11
12
|
def collect_for(item_functions)
|
12
13
|
return [Collect[*item_functions]] if array?
|
13
14
|
return [Collect::Hash[*item_functions]] if self[:hash]
|
15
|
+
|
14
16
|
item_functions
|
15
17
|
end
|
16
18
|
|
@@ -92,4 +94,4 @@ module Representable
|
|
92
94
|
funcs << (self[:setter] ? Setter : SetValue)
|
93
95
|
end
|
94
96
|
end
|
95
|
-
end
|
97
|
+
end
|
@@ -21,7 +21,7 @@ module Representable
|
|
21
21
|
def self.apply!(options)
|
22
22
|
return unless populator = options[:populator]
|
23
23
|
|
24
|
-
options[:parse_pipeline] = ->(
|
24
|
+
options[:parse_pipeline] = ->(_input, _opts) do
|
25
25
|
pipeline = Pipeline[*parse_functions] # TODO: AssignFragment
|
26
26
|
pipeline = Pipeline::Insert.(pipeline, SetValue, delete: true) # remove the setter function.
|
27
27
|
pipeline = Pipeline::Insert.(pipeline, populator, replace: CreateObject::Populator) # let the actual populator do the job.
|
@@ -3,7 +3,7 @@ module Representable
|
|
3
3
|
options[:binding].evaluate_option(:getter, input, options)
|
4
4
|
end
|
5
5
|
|
6
|
-
GetValue = ->(
|
6
|
+
GetValue = ->(_input, options) { options[:binding].send(:exec_context, options).public_send(options[:binding].getter) }
|
7
7
|
|
8
8
|
Writer = ->(input, options) do
|
9
9
|
options[:binding].evaluate_option(:writer, input, options)
|
@@ -37,6 +37,7 @@ module Representable
|
|
37
37
|
|
38
38
|
Serialize = ->(input, options) do
|
39
39
|
return if input.nil? # DISCUSS: how can we prevent that?
|
40
|
+
|
40
41
|
binding, options = options[:binding], options[:options] # FIXME: rename to :local_options.
|
41
42
|
|
42
43
|
options_for_nested = OptionsForNested.(options, binding)
|
@@ -51,4 +52,4 @@ module Representable
|
|
51
52
|
# Warning: don't rely on AssignAs/AssignName, i am not sure if i leave that as functions.
|
52
53
|
AssignAs = ->(input, options) { options[:as] = As.(input, options); input }
|
53
54
|
AssignName = ->(input, options) { options[:as] = options[:binding].name; input }
|
54
|
-
end
|
55
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
gem 'virtus'
|
2
|
+
require "virtus"
|
3
|
+
|
4
|
+
module Representable
|
5
|
+
module VirtusCoercion
|
6
|
+
class Coercer
|
7
|
+
def initialize(type)
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
# This gets called when the :render_filter or :parse_filter option is evaluated.
|
12
|
+
# Usually the Coercer instance is an element in a Pipeline to allow >1 filters per property.
|
13
|
+
def call(input, options)
|
14
|
+
Virtus::Attribute.build(@type).coerce(input)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.class_eval do
|
21
|
+
extend ClassMethods
|
22
|
+
register_feature VirtusCoercion
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def property(name, options={}, &block)
|
29
|
+
super.tap do |definition|
|
30
|
+
return definition unless type = options[:type]
|
31
|
+
|
32
|
+
definition.merge!(render_filter: coercer = Coercer.new(type))
|
33
|
+
definition.merge!(parse_filter: coercer)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/representable/xml.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
require 'representable/xml/collection'
|
1
|
+
gem 'nokogiri', '> 1.10.8'
|
2
|
+
require 'nokogiri'
|
4
3
|
|
5
|
-
|
6
|
-
require 'nokogiri'
|
7
|
-
rescue LoadError => _
|
8
|
-
abort "Missing dependency 'nokogiri' for Representable::XML. See dependencies section in README.md for details."
|
9
|
-
end
|
4
|
+
require 'representable'
|
10
5
|
|
11
6
|
module Representable
|
12
7
|
module XML
|
8
|
+
autoload :Binding, 'representable/xml/binding'
|
9
|
+
autoload :Collection, 'representable/xml/collection'
|
10
|
+
autoload :Namespace, 'representable/xml/namespace'
|
11
|
+
|
13
12
|
def self.included(base)
|
14
13
|
base.class_eval do
|
15
14
|
include Representable
|
@@ -46,16 +45,19 @@ module Representable
|
|
46
45
|
|
47
46
|
# Returns a Nokogiri::XML object representing this object.
|
48
47
|
def to_node(options={})
|
49
|
-
options[:doc]
|
48
|
+
options[:doc] = Nokogiri::XML::Document.new # DISCUSS: why do we need a fresh Document here?
|
50
49
|
root_tag = options[:wrap] || representation_wrap(options)
|
51
50
|
|
52
|
-
create_representation_with(
|
51
|
+
create_representation_with(Node(options[:doc], root_tag.to_s), options, Binding)
|
53
52
|
end
|
54
53
|
|
55
54
|
def to_xml(*args)
|
56
55
|
to_node(*args).to_s
|
57
56
|
end
|
58
57
|
|
58
|
+
alias_method :render, :to_xml
|
59
|
+
alias_method :parse, :from_xml
|
60
|
+
|
59
61
|
private
|
60
62
|
def remove_namespaces?
|
61
63
|
# TODO: make local Config easily extendable so you get Config#remove_ns? etc.
|
@@ -1,8 +1,14 @@
|
|
1
1
|
require 'representable/binding'
|
2
|
-
require 'representable/hash/binding.rb'
|
3
2
|
|
4
3
|
module Representable
|
5
4
|
module XML
|
5
|
+
module_function def Node(document, name, attributes={})
|
6
|
+
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.
|
7
|
+
|
8
|
+
attributes.each { |k, v| node[k] = v } # TODO: benchmark.
|
9
|
+
node
|
10
|
+
end
|
11
|
+
|
6
12
|
class Binding < Representable::Binding
|
7
13
|
def self.build_for(definition)
|
8
14
|
return Collection.new(definition) if definition.array?
|
@@ -10,6 +16,7 @@ module Representable
|
|
10
16
|
return AttributeHash.new(definition) if definition.hash? and definition[:use_attributes]
|
11
17
|
return Attribute.new(definition) if definition[:attribute]
|
12
18
|
return Content.new(definition) if definition[:content]
|
19
|
+
|
13
20
|
new(definition)
|
14
21
|
end
|
15
22
|
|
@@ -17,7 +24,7 @@ module Representable
|
|
17
24
|
wrap_node = parent
|
18
25
|
|
19
26
|
if wrap = self[:wrap]
|
20
|
-
parent << wrap_node =
|
27
|
+
parent << wrap_node = XML::Node(parent, wrap)
|
21
28
|
end
|
22
29
|
|
23
30
|
wrap_node << serialize_for(fragments, parent, as)
|
@@ -32,12 +39,15 @@ module Representable
|
|
32
39
|
|
33
40
|
# Creates wrapped node for the property.
|
34
41
|
def serialize_for(value, parent, as)
|
35
|
-
node =
|
36
|
-
serialize_node(node, value)
|
42
|
+
node = XML::Node(parent, as) # node doesn't have attr="" attributes!!!
|
43
|
+
serialize_node(node, value, as)
|
37
44
|
end
|
38
45
|
|
39
|
-
def serialize_node(node, value)
|
40
|
-
|
46
|
+
def serialize_node(node, value, as)
|
47
|
+
if typed?
|
48
|
+
value.name = as if as != self[:name]
|
49
|
+
return value
|
50
|
+
end
|
41
51
|
|
42
52
|
node.content = value
|
43
53
|
node
|
@@ -60,11 +70,7 @@ module Representable
|
|
60
70
|
def find_nodes(doc, as)
|
61
71
|
selector = as
|
62
72
|
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)
|
73
|
+
doc.xpath(selector) # nodes
|
68
74
|
end
|
69
75
|
|
70
76
|
def content_for(node) # TODO: move this into a ScalarDecorator.
|
@@ -100,8 +106,8 @@ module Representable
|
|
100
106
|
class Hash < Collection
|
101
107
|
def serialize_for(value, parent, as)
|
102
108
|
set_for(parent, value.collect do |k, v|
|
103
|
-
node =
|
104
|
-
serialize_node(node, v)
|
109
|
+
node = XML::Node(parent, k)
|
110
|
+
serialize_node(node, v, as)
|
105
111
|
end)
|
106
112
|
end
|
107
113
|
|
@@ -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/lib/representable/yaml.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
require 'representable
|
1
|
+
require 'psych'
|
2
|
+
require 'representable'
|
3
3
|
|
4
4
|
module Representable
|
5
5
|
module YAML
|
6
|
+
autoload :Binding, 'representable/yaml/binding'
|
6
7
|
include Hash
|
7
8
|
|
8
9
|
def self.included(base)
|
@@ -38,5 +39,8 @@ module Representable
|
|
38
39
|
doc.children << to_ast(*args)
|
39
40
|
stream.to_yaml
|
40
41
|
end
|
42
|
+
|
43
|
+
alias_method :render, :to_yaml
|
44
|
+
alias_method :parse, :from_yaml
|
41
45
|
end
|
42
46
|
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
|
|
@@ -19,17 +19,16 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
spec.license = "MIT"
|
21
21
|
|
22
|
-
spec.required_ruby_version = '>=
|
22
|
+
spec.required_ruby_version = '>= 2.4.0'
|
23
23
|
|
24
|
-
spec.add_dependency "uber",
|
25
|
-
spec.add_dependency "declarative",
|
24
|
+
spec.add_dependency "uber", "< 0.2.0"
|
25
|
+
spec.add_dependency "declarative", "< 0.1.0"
|
26
|
+
spec.add_dependency "trailblazer-option", "~> 0.1.0"
|
26
27
|
|
27
28
|
spec.add_development_dependency "rake"
|
28
|
-
spec.add_development_dependency "test_xml", "0.1.6"
|
29
|
+
spec.add_development_dependency "test_xml", ">= 0.1.6"
|
29
30
|
spec.add_development_dependency "minitest"
|
30
|
-
spec.add_development_dependency "mongoid"
|
31
31
|
spec.add_development_dependency "virtus"
|
32
|
-
spec.add_development_dependency "
|
33
|
-
|
34
|
-
spec.add_development_dependency "ruby-prof"
|
32
|
+
spec.add_development_dependency "dry-types"
|
33
|
+
spec.add_development_dependency "ruby-prof" if RUBY_ENGINE == "ruby" # mri
|
35
34
|
end
|
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
|
@@ -17,7 +17,7 @@ class AsTest < MiniTest::Spec
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it { render(song).must_equal_document output }
|
20
|
-
it { parse(song, input).name.must_equal "Wie Es Geht" }
|
20
|
+
it { _(parse(song, input).name).must_equal "Wie Es Geht" }
|
21
21
|
end
|
22
22
|
|
23
23
|
|
@@ -27,7 +27,7 @@ class AsTest < MiniTest::Spec
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it { render(song).must_equal_document({"Song" => "Revolution"}) }
|
30
|
-
it { parse(song, {"Song" => "Wie Es Geht"}).name.must_equal "Wie Es Geht" }
|
30
|
+
it { _(parse(song, {"Song" => "Wie Es Geht"}).name).must_equal "Wie Es Geht" }
|
31
31
|
end
|
32
32
|
|
33
33
|
|
@@ -37,7 +37,7 @@ class AsTest < MiniTest::Spec
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it { render(song, user_options:{volume: 1}).must_equal_document({"{:volume=>1}" => "Revolution"}) }
|
40
|
-
it { parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name.must_equal "Wie Es Geht" }
|
40
|
+
it { _(parse(song, {"{:volume=>1}" => "Wie Es Geht"}, user_options: {volume: 1}).name).must_equal "Wie Es Geht" }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -60,6 +60,6 @@ class AsXmlTest < MiniTest::Spec
|
|
60
60
|
|
61
61
|
it do
|
62
62
|
skip
|
63
|
-
representer.new(Album.new(Band.new("Offspring"))).to_xml.must_equal ""
|
63
|
+
_(representer.new(Album.new(Band.new("Offspring"))).to_xml).must_equal ""
|
64
64
|
end
|
65
|
-
end
|
65
|
+
end
|