# 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