# frozen_string_literal: true
require_relative '../../spec_helper'
module Aws
module Xml
describe Builder do
let(:shapes) { ApiHelper.sample_shapes }
let(:api) { ApiHelper.sample_api(shapes: shapes) }
let(:operation) {
operation = api.operation(:example_operation)
operation.input.location_name = 'xml'
operation
}
let(:rules) { operation.input }
def xml(params)
Builder.new(rules, indent: ' ').to_xml(params)
end
it 'serializes empty values as empty elements' do
expect(xml({})).to eq("\n")
end
it 'can serialize structures' do
params = Structure.new(*rules.shape.member_names).new
params.boolean = true
params.integer = 123
params.string = 'abc'
expect(xml(params)).to eq(<<-XML)
true
123
abc
XML
end
it 'orders xml elements by members order' do
params = {
string: 'a',
boolean: true,
integer: 1,
}
expect(xml(params)).to eq(<<-XML)
true
1
a
XML
end
it 'supports locationName traits on structure members' do
shapes['StructureShape']['members']['NumberList']['locationName'] = 'Ints'
expect(xml(number_list:[1,2,3])).to eq(<<-XML)
1
2
3
XML
end
it 'supports locationName traits on list members' do
shapes['IntegerList']['member']['locationName'] = 'int'
expect(xml(number_list:[1,2,3])).to eq(<<-XML)
1
2
3
XML
end
it 'supports locationName traits on map keys and values' do
shapes['StringMap']['key']['locationName'] = 'attrName'
shapes['StringMap']['value']['locationName'] = 'attrValue'
params = {
string_map: {
'color' => 'red',
'size' => 'large',
}
}
expect(xml(params)).to eq(<<-XML)
color
red
size
large
XML
end
it 'supports nested and complex structures' do
params = {
nested: {
nested: {
nested: { integer: 3 },
integer: 2
},
integer: 1
},
nested_list: [
{ string: "v1" },
{ string: "v2" },
{ nested: { string: "v3" }}
],
nested_map: {
"First" => { string: "v1" },
"Second" => { nested: { string: "v2" }},
},
number_list: [1,2,3,4,5],
string_map: {
"Size" => "large",
"Color" => "red",
},
blob: "data",
byte: "a",
boolean: true,
character: "b",
double: 123.456,
float: 654.321,
long: 321,
string: "Hello",
timestamp: Time.at(123456789),
}
expect(xml(params)).to eq(<<-XML)
3
2
1
v1
v2
v3
First
v1
Second
v2
1
2
3
4
5
Size
large
Color
red
ZGF0YQ==
a
true
b
123.456
654.321
321
Hello
#{Time.at(123456789).utc.iso8601}
XML
end
it 'supports flat lists' do
shapes['IntegerList']['flattened'] = true
expect(xml(string:'abc', number_list:[1,2,3])).to eq(<<-XML)
1
2
3
abc
XML
end
it 'supports flat list with locationName traits' do
shapes['IntegerList']['flattened'] = true
shapes['IntegerList']['member']['locationName'] = 'Number'
expect(xml(string:'abc', number_list:[1,2,3])).to eq(<<-XML)
1
2
3
abc
XML
end
it 'does not serialize nil values' do
expect(xml(string:'abc', integer:nil)).to eq(<<-XML)
abc
XML
end
it 'correctly serializes newlines' do
expect(xml(string:"\n")).to eq(<<-XML)
XML
end
it 'applies xml attribute members to the structure' do
shapes['StructureShape']['members']['String']['xmlAttribute'] = true
shapes['StructureShape']['members']['String']['locationName'] = 'encode'
params = {
nested: {
string: 'base64',
integer: 123
}
}
expect(xml(params)).to eq(<<-XML)
123
XML
end
describe 'namespaces' do
it 'applies xml namespace to the root node' do
operation.input.location_name = 'Xml'
operation.input['xmlNamespace'] = { 'uri' => 'http://foo.com' }
expect(xml(string:'abc')).to eq(<<-XML)
abc
XML
end
it 'applies xml namespaces to any shape' do
ns = { 'xmlNamespace' => {
'prefix' => 'xsi',
'uri' => 'http://xmlns.com/uri'
}}
shapes['StringShape'].update(ns)
shapes['StructureShape']['members']['Nested'].update(ns)
params = {
nested: {
string: 'abc'
}
}
expect(xml(params)).to eq(<<-XML)
abc
XML
end
end
end
end
end