chef-gyoku 1.4.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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +62 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +154 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE +20 -0
- data/README.md +313 -0
- data/Rakefile +12 -0
- data/gyoku.gemspec +27 -0
- data/lib/gyoku/array.rb +96 -0
- data/lib/gyoku/hash.rb +105 -0
- data/lib/gyoku/prettifier.rb +29 -0
- data/lib/gyoku/version.rb +3 -0
- data/lib/gyoku/xml_key.rb +67 -0
- data/lib/gyoku/xml_value.rb +41 -0
- data/lib/gyoku.rb +14 -0
- data/spec/gyoku/array_spec.rb +121 -0
- data/spec/gyoku/hash_spec.rb +431 -0
- data/spec/gyoku/prettifier_spec.rb +39 -0
- data/spec/gyoku/xml_key_spec.rb +76 -0
- data/spec/gyoku/xml_value_spec.rb +61 -0
- data/spec/gyoku_spec.rb +82 -0
- data/spec/spec_helper.rb +15 -0
- metadata +132 -0
data/lib/gyoku/array.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
module Gyoku
|
2
|
+
module Array
|
3
|
+
module_function
|
4
|
+
|
5
|
+
NESTED_ELEMENT_NAME = "element"
|
6
|
+
|
7
|
+
# Builds XML and prettifies it if +pretty_print+ option is set to +true+
|
8
|
+
def to_xml(array, key, escape_xml = true, attributes = {}, options = {})
|
9
|
+
xml = build_xml(array, key, escape_xml, attributes, options)
|
10
|
+
|
11
|
+
if options[:pretty_print] && options[:unwrap]
|
12
|
+
Prettifier.prettify(xml, options)
|
13
|
+
else
|
14
|
+
xml
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Translates a given +array+ to XML. Accepts the XML +key+ to add the elements to,
|
19
|
+
# whether to +escape_xml+ and an optional Hash of +attributes+.
|
20
|
+
def self.build_xml(array, key, escape_xml = true, attributes = {}, options = {})
|
21
|
+
self_closing = options.delete(:self_closing)
|
22
|
+
unwrap = unwrap?(options.fetch(:unwrap, false), key)
|
23
|
+
|
24
|
+
iterate_with_xml array, key, attributes, options do |xml, item, attrs, index|
|
25
|
+
if self_closing
|
26
|
+
xml.tag!(key, attrs)
|
27
|
+
else
|
28
|
+
case item
|
29
|
+
when ::Hash
|
30
|
+
if unwrap
|
31
|
+
xml << Hash.to_xml(item, options)
|
32
|
+
else
|
33
|
+
xml.tag!(key, attrs) { xml << Hash.build_xml(item, options) }
|
34
|
+
end
|
35
|
+
when ::Array
|
36
|
+
xml.tag!(key, attrs) { xml << Array.build_xml(item, NESTED_ELEMENT_NAME) }
|
37
|
+
when NilClass
|
38
|
+
xml.tag!(key, "xsi:nil" => "true")
|
39
|
+
else
|
40
|
+
xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Iterates over a given +array+ with a Hash of +attributes+ and yields a builder +xml+
|
47
|
+
# instance, the current +item+, any XML +attributes+ and the current +index+.
|
48
|
+
def iterate_with_xml(array, key, attributes, options, &block)
|
49
|
+
xml = Builder::XmlMarkup.new
|
50
|
+
unwrap = unwrap?(options.fetch(:unwrap, false), key)
|
51
|
+
|
52
|
+
if unwrap
|
53
|
+
xml.tag!(key, attributes) { iterate_array(xml, array, attributes, &block) }
|
54
|
+
else
|
55
|
+
iterate_array(xml, array, attributes, &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
xml.target!
|
59
|
+
end
|
60
|
+
private_class_method :iterate_with_xml
|
61
|
+
|
62
|
+
# Iterates over a given +array+ with a Hash of +attributes+ and yields a builder +xml+
|
63
|
+
# instance, the current +item+, any XML +attributes+ and the current +index+.
|
64
|
+
def iterate_array(xml, array, attributes, &block)
|
65
|
+
array.each_with_index do |item, index|
|
66
|
+
attrs = if item.respond_to?(:keys)
|
67
|
+
item.each_with_object({}) do |v, st|
|
68
|
+
k = v[0].to_s
|
69
|
+
st[k[1..]] = v[1].to_s if Hash.explicit_attribute?(k)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
{}
|
73
|
+
end
|
74
|
+
yield xml, item, tag_attributes(attributes, index).merge(attrs), index
|
75
|
+
end
|
76
|
+
end
|
77
|
+
private_class_method :iterate_array
|
78
|
+
|
79
|
+
# Takes a Hash of +attributes+ and the +index+ for which to return attributes
|
80
|
+
# for duplicate tags.
|
81
|
+
def tag_attributes(attributes, index)
|
82
|
+
return {} if attributes.empty?
|
83
|
+
|
84
|
+
attributes.inject({}) do |hash, (key, value)|
|
85
|
+
value = value[index] if value.is_a? ::Array
|
86
|
+
value ? hash.merge(key => value) : hash
|
87
|
+
end
|
88
|
+
end
|
89
|
+
private_class_method :tag_attributes
|
90
|
+
|
91
|
+
def unwrap?(unwrap, key)
|
92
|
+
unwrap.is_a?(::Array) ? unwrap.include?(key.to_sym) : unwrap
|
93
|
+
end
|
94
|
+
private_class_method :unwrap?
|
95
|
+
end
|
96
|
+
end
|
data/lib/gyoku/hash.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require "builder"
|
2
|
+
require "gyoku/prettifier"
|
3
|
+
require "gyoku/array"
|
4
|
+
require "gyoku/xml_key"
|
5
|
+
require "gyoku/xml_value"
|
6
|
+
|
7
|
+
module Gyoku
|
8
|
+
module Hash
|
9
|
+
module_function
|
10
|
+
|
11
|
+
# Builds XML and prettifies it if +pretty_print+ option is set to +true+
|
12
|
+
def to_xml(hash, options = {})
|
13
|
+
xml = build_xml(hash, options)
|
14
|
+
|
15
|
+
if options[:pretty_print]
|
16
|
+
Prettifier.prettify(xml, options)
|
17
|
+
else
|
18
|
+
xml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Translates a given +hash+ with +options+ to XML.
|
23
|
+
def build_xml(hash, options = {})
|
24
|
+
iterate_with_xml hash do |xml, key, value, attributes|
|
25
|
+
self_closing = key.to_s[-1, 1] == "/"
|
26
|
+
escape_xml = key.to_s[-1, 1] != "!"
|
27
|
+
xml_key = XMLKey.create key, options
|
28
|
+
|
29
|
+
if :content! === key
|
30
|
+
xml << XMLValue.create(value, escape_xml, options)
|
31
|
+
elsif ::Array === value
|
32
|
+
xml << Array.build_xml(value, xml_key, escape_xml, attributes, options.merge(self_closing: self_closing))
|
33
|
+
elsif ::Hash === value
|
34
|
+
xml.tag!(xml_key, attributes) { xml << build_xml(value, options) }
|
35
|
+
elsif self_closing
|
36
|
+
xml.tag!(xml_key, attributes)
|
37
|
+
elsif NilClass === value
|
38
|
+
xml.tag!(xml_key, "xsi:nil" => "true")
|
39
|
+
else
|
40
|
+
xml.tag!(xml_key, attributes) { xml << XMLValue.create(value, escape_xml, options) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def explicit_attribute?(key)
|
46
|
+
key.to_s.start_with?("@")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Iterates over a given +hash+ and yields a builder +xml+ instance, the current
|
50
|
+
# Hash +key+ and any XML +attributes+.
|
51
|
+
#
|
52
|
+
# Keys beginning with "@" are treated as explicit attributes for their container.
|
53
|
+
# You can use both :attributes! and "@" keys to specify attributes.
|
54
|
+
# In the event of a conflict, the "@" key takes precedence.
|
55
|
+
def iterate_with_xml(hash)
|
56
|
+
xml = Builder::XmlMarkup.new
|
57
|
+
attributes = hash[:attributes!] || {}
|
58
|
+
hash_without_attributes = hash.except(:attributes!)
|
59
|
+
|
60
|
+
order(hash_without_attributes).each do |key|
|
61
|
+
node_attr = attributes[key] || {}
|
62
|
+
# node_attr must be kind of ActiveSupport::HashWithIndifferentAccess
|
63
|
+
node_attr = node_attr.map { |k, v| [k.to_s, v] }.to_h
|
64
|
+
node_value = hash[key].respond_to?(:keys) ? hash[key].clone : hash[key]
|
65
|
+
|
66
|
+
if node_value.respond_to?(:keys)
|
67
|
+
explicit_keys = node_value.keys.select { |k| explicit_attribute?(k) }
|
68
|
+
explicit_attr = {}
|
69
|
+
explicit_keys.each { |k| explicit_attr[k.to_s[1..]] = node_value[k] }
|
70
|
+
node_attr.merge!(explicit_attr)
|
71
|
+
explicit_keys.each { |k| node_value.delete(k) }
|
72
|
+
|
73
|
+
tmp_node_value = node_value.delete(:content!)
|
74
|
+
node_value = tmp_node_value unless tmp_node_value.nil?
|
75
|
+
node_value = "" if node_value.respond_to?(:empty?) && node_value.empty?
|
76
|
+
end
|
77
|
+
|
78
|
+
yield xml, key, node_value, node_attr
|
79
|
+
end
|
80
|
+
|
81
|
+
xml.target!
|
82
|
+
end
|
83
|
+
private_class_method :iterate_with_xml
|
84
|
+
|
85
|
+
# Deletes and returns an Array of keys stored under the :order! key of a given +hash+.
|
86
|
+
# Defaults to return the actual keys of the Hash if no :order! key could be found.
|
87
|
+
# Raises an ArgumentError in case the :order! Array does not match the Hash keys.
|
88
|
+
def order(hash)
|
89
|
+
order = hash[:order!] || hash.delete("order!")
|
90
|
+
hash_without_order = hash.except(:order!)
|
91
|
+
order = hash_without_order.keys unless order.is_a? ::Array
|
92
|
+
|
93
|
+
# Ignore Explicit Attributes
|
94
|
+
orderable = order.delete_if { |k| explicit_attribute?(k) }
|
95
|
+
hashable = hash_without_order.keys.select { |k| !explicit_attribute?(k) }
|
96
|
+
|
97
|
+
missing, spurious = hashable - orderable, orderable - hashable
|
98
|
+
raise ArgumentError, "Missing elements in :order! #{missing.inspect}" unless missing.empty?
|
99
|
+
raise ArgumentError, "Spurious elements in :order! #{spurious.inspect}" unless spurious.empty?
|
100
|
+
|
101
|
+
order
|
102
|
+
end
|
103
|
+
private_class_method :order
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "rexml/document"
|
2
|
+
|
3
|
+
module Gyoku
|
4
|
+
class Prettifier
|
5
|
+
DEFAULT_INDENT = 2
|
6
|
+
DEFAULT_COMPACT = true
|
7
|
+
|
8
|
+
attr_accessor :indent, :compact
|
9
|
+
|
10
|
+
def self.prettify(xml, options = {})
|
11
|
+
new(options).prettify(xml)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@indent = options[:indent] || DEFAULT_INDENT
|
16
|
+
@compact = options[:compact].nil? ? DEFAULT_COMPACT : options[:compact]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds intendations and newlines to +xml+ to make it more readable
|
20
|
+
def prettify(xml)
|
21
|
+
result = ""
|
22
|
+
formatter = REXML::Formatters::Pretty.new indent
|
23
|
+
formatter.compact = compact
|
24
|
+
doc = REXML::Document.new xml
|
25
|
+
formatter.write doc, result
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Gyoku
|
2
|
+
module XMLKey
|
3
|
+
class << self
|
4
|
+
CAMELCASE = lambda { |key| key.gsub(/\/(.?)/) { |m| "::#{m[-1].upcase}" }.gsub(/(?:^|_)(.)/) { |m| m[-1].upcase } }
|
5
|
+
LOWER_CAMELCASE = lambda { |key| key[0].chr.downcase + CAMELCASE.call(key)[1..] }
|
6
|
+
UPCASE = lambda { |key| key.upcase }
|
7
|
+
|
8
|
+
FORMULAS = {
|
9
|
+
lower_camelcase: lambda { |key| LOWER_CAMELCASE.call(key) },
|
10
|
+
camelcase: lambda { |key| CAMELCASE.call(key) },
|
11
|
+
upcase: lambda { |key| UPCASE.call(key) },
|
12
|
+
none: lambda { |key| key }
|
13
|
+
}
|
14
|
+
|
15
|
+
# Converts a given +object+ with +options+ to an XML key.
|
16
|
+
def create(key, options = {})
|
17
|
+
xml_key = chop_special_characters key.to_s
|
18
|
+
|
19
|
+
if unqualified = unqualify?(xml_key)
|
20
|
+
xml_key = xml_key.split(":").last
|
21
|
+
end
|
22
|
+
|
23
|
+
xml_key = key_converter(options, xml_key).call(xml_key) if Symbol === key
|
24
|
+
|
25
|
+
if !unqualified && qualify?(options) && !xml_key.include?(":")
|
26
|
+
xml_key = "#{options[:namespace]}:#{xml_key}"
|
27
|
+
end
|
28
|
+
|
29
|
+
xml_key
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Returns the formula for converting Symbol keys.
|
35
|
+
def key_converter(options, xml_key)
|
36
|
+
return options[:key_converter] if options[:key_converter].is_a? Proc
|
37
|
+
|
38
|
+
defined_key = options[:key_to_convert]
|
39
|
+
key_converter = if !defined_key.nil? && (defined_key == xml_key)
|
40
|
+
options[:key_converter]
|
41
|
+
elsif !defined_key.nil?
|
42
|
+
:lower_camelcase
|
43
|
+
elsif options[:except] == xml_key
|
44
|
+
:lower_camelcase
|
45
|
+
else
|
46
|
+
options[:key_converter] || :lower_camelcase
|
47
|
+
end
|
48
|
+
FORMULAS[key_converter]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Chops special characters from the end of a given +string+.
|
52
|
+
def chop_special_characters(string)
|
53
|
+
["!", "/"].include?(string[-1, 1]) ? string.chop : string
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns whether to remove the namespace from a given +key+.
|
57
|
+
def unqualify?(key)
|
58
|
+
key[0, 1] == ":"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns whether to namespace all keys (elementFormDefault).
|
62
|
+
def qualify?(options)
|
63
|
+
options[:element_form_default] == :qualified && options[:namespace]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "date"
|
3
|
+
|
4
|
+
module Gyoku
|
5
|
+
module XMLValue
|
6
|
+
class << self
|
7
|
+
# xs:date format
|
8
|
+
XS_DATE_FORMAT = "%Y-%m-%d"
|
9
|
+
|
10
|
+
# xs:time format
|
11
|
+
XS_TIME_FORMAT = "%H:%M:%S"
|
12
|
+
|
13
|
+
# xs:dateTime format
|
14
|
+
XS_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%Z"
|
15
|
+
|
16
|
+
# Converts a given +object+ to an XML value.
|
17
|
+
def create(object, escape_xml = true, options = {})
|
18
|
+
case object
|
19
|
+
when Time
|
20
|
+
object.strftime XS_TIME_FORMAT
|
21
|
+
when DateTime
|
22
|
+
object.strftime XS_DATETIME_FORMAT
|
23
|
+
when Date
|
24
|
+
object.strftime XS_DATE_FORMAT
|
25
|
+
when String
|
26
|
+
escape_xml ? CGI.escapeHTML(object) : object
|
27
|
+
when ::Hash
|
28
|
+
Gyoku::Hash.to_xml(object, options)
|
29
|
+
else
|
30
|
+
if object.respond_to?(:to_datetime)
|
31
|
+
create object.to_datetime
|
32
|
+
elsif object.respond_to?(:call)
|
33
|
+
create object.call
|
34
|
+
else
|
35
|
+
object.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/gyoku.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "gyoku/version"
|
2
|
+
require "gyoku/hash"
|
3
|
+
|
4
|
+
module Gyoku
|
5
|
+
# Converts a given Hash +key+ with +options+ into an XML tag.
|
6
|
+
def self.xml_tag(key, options = {})
|
7
|
+
XMLKey.create(key, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Translates a given +hash+ with +options+ to XML.
|
11
|
+
def self.xml(hash, options = {})
|
12
|
+
Hash.to_xml hash.dup, options
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Gyoku::Array do
|
4
|
+
describe ".to_xml" do
|
5
|
+
it "returns the XML for an Array of Hashes" do
|
6
|
+
array = [{name: "adam"}, {name: "eve"}]
|
7
|
+
result = "<user><name>adam</name></user><user><name>eve</name></user>"
|
8
|
+
|
9
|
+
expect(to_xml(array, "user")).to eq(result)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the XML for an Array of Hashes unwrapped" do
|
13
|
+
array = [{name: "adam"}, {name: "eve"}]
|
14
|
+
result = "<user><name>adam</name><name>eve</name></user>"
|
15
|
+
|
16
|
+
expect(to_xml(array, "user", true, {}, unwrap: true)).to eq(result)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns the XML for an Array of different Objects" do
|
20
|
+
array = [:symbol, "string", 123]
|
21
|
+
result = "<value>symbol</value><value>string</value><value>123</value>"
|
22
|
+
|
23
|
+
expect(to_xml(array, "value")).to eq(result)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "defaults to escape special characters" do
|
27
|
+
array = ["<tag />", "adam & eve"]
|
28
|
+
result = "<value><tag /></value><value>adam & eve</value>"
|
29
|
+
|
30
|
+
expect(to_xml(array, "value")).to eq(result)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "does not escape special characters when told to" do
|
34
|
+
array = ["<tag />", "adam & eve"]
|
35
|
+
result = "<value><tag /></value><value>adam & eve</value>"
|
36
|
+
|
37
|
+
expect(to_xml(array, "value", false)).to eq(result)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "adds attributes to a given tag" do
|
41
|
+
array = ["adam", "eve"]
|
42
|
+
result = '<value active="true">adam</value><value active="true">eve</value>'
|
43
|
+
|
44
|
+
expect(to_xml(array, "value", :escape_xml, active: true)).to eq(result)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "adds attributes to tags when :unwrap is true" do
|
48
|
+
array = [{item: "abc"}]
|
49
|
+
key = "items"
|
50
|
+
escape_xml = :escape_xml
|
51
|
+
attributes = {"amount" => "1"}
|
52
|
+
options = {unwrap: true}
|
53
|
+
result = "<items amount=\"1\"><item>abc</item></items>"
|
54
|
+
|
55
|
+
expect(to_xml(array, key, escape_xml, attributes, options)).to eq result
|
56
|
+
end
|
57
|
+
|
58
|
+
it "adds attributes to duplicate tags" do
|
59
|
+
array = ["adam", "eve"]
|
60
|
+
result = '<value id="1">adam</value><value id="2">eve</value>'
|
61
|
+
|
62
|
+
expect(to_xml(array, "value", :escape_xml, id: [1, 2])).to eq(result)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "skips attribute for element without attributes if there are fewer attributes than elements" do
|
66
|
+
array = ["adam", "eve", "serpent"]
|
67
|
+
result = '<value id="1">adam</value><value id="2">eve</value><value>serpent</value>'
|
68
|
+
|
69
|
+
expect(to_xml(array, "value", :escape_xml, id: [1, 2])).to eq(result)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "handles nested Arrays" do
|
73
|
+
array = [["one", "two"]]
|
74
|
+
result = "<value><element>one</element><element>two</element></value>"
|
75
|
+
|
76
|
+
expect(to_xml(array, "value")).to eq(result)
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when :pretty_print option is set to true" do
|
80
|
+
context "when :unwrap option is set to true" do
|
81
|
+
it "returns prettified xml" do
|
82
|
+
array = ["one", "two", {"three" => "four"}]
|
83
|
+
options = {pretty_print: true, unwrap: true}
|
84
|
+
result = "<test>\n <test>one</test>\n <test>two</test>\n <three>four</three>\n</test>"
|
85
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when :indent option is specified" do
|
89
|
+
it "returns prettified xml with specified indent" do
|
90
|
+
array = ["one", "two", {"three" => "four"}]
|
91
|
+
options = {pretty_print: true, indent: 3, unwrap: true}
|
92
|
+
result = "<test>\n <test>one</test>\n <test>two</test>\n <three>four</three>\n</test>"
|
93
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "when :compact option is specified" do
|
98
|
+
it "returns prettified xml with specified compact mode" do
|
99
|
+
array = ["one", {"two" => "three"}]
|
100
|
+
options = {pretty_print: true, compact: false, unwrap: true}
|
101
|
+
result = "<test>\n <test>\n one\n </test>\n <two>\n three \n </two>\n</test>"
|
102
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when :unwrap option is not set" do
|
108
|
+
it "returns non-prettified xml" do
|
109
|
+
array = ["one", "two", {"three" => "four"}]
|
110
|
+
options = {pretty_print: true}
|
111
|
+
result = "<test>one</test><test>two</test><test><three>four</three></test>"
|
112
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_xml(*args)
|
119
|
+
Gyoku::Array.to_xml(*args)
|
120
|
+
end
|
121
|
+
end
|