Skip to content

Commit

Permalink
support :order! key with value :schema_order
Browse files Browse the repository at this point in the history
  • Loading branch information
pcai committed Oct 1, 2024
1 parent 2fd02fb commit 7351ccd
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
20 changes: 19 additions & 1 deletion lib/savon/qualified_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ def to_hash(hash, path)
return hash.map { |value| to_hash(value, path) } if hash.is_a?(Array)
return hash.to_s unless hash.is_a?(Hash)

hash.each_with_object({}) do |(key, value), newhash|
if hash[:order!] == :use_schema || @order_with_schema
@order_with_schema = true
ordered_keys = @used_namespaces.select { |t| t.first == path.first && t.length == 2 }.keys.collect { |k| k.last }
hash[:order!] = ordered_keys
end

result = hash.each_with_object({}) do |(key, value), newhash|
case key
when :order!
newhash[key] = add_namespaces_to_values(value, path)
Expand All @@ -32,6 +38,8 @@ def to_hash(hash, path)
end
newhash
end

ordered_keys(result)
end

private
Expand All @@ -48,5 +56,15 @@ def add_namespaces_to_values(values, path)
namespace.empty? ? value : "#{namespace}:#{translated_value}"
end
end

def ordered_keys(hash)
return hash unless @order_with_schema

if order_keys = hash.delete(:order!)
present_order_keys = order_keys & hash.keys
hash[:order!] = (present_order_keys + (hash.keys - present_order_keys)).select { |key| !key.to_s.end_with?('!') }
end
hash
end
end
end
29 changes: 29 additions & 0 deletions spec/savon/qualified_message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ module Savon
expect(xml).to eq good_xml
end

it "uses schema order when :order! is set to :use_schema" do
used_namespaces = {
%w(tns Foo) => 'ns'
}

hash = {
:foo => {
:order! => :use_schema,
:bar => 'zing',
:cash => 'pow'
}
}

good_result = {
"ns:Foo" => {
:order! => [:bar, :cash],
:bar => 'zing',
:cash => 'pow'
}
}

message = described_class.new(types, used_namespaces, key_converter)
resulting_hash = message.to_hash(hash, ['tns'])

expect(Gyoku.xml(resulting_hash, key_converter: key_converter)).to eq %(<ns:Foo><Bar>zing</Bar><Cash>pow</Cash></ns:Foo>)
expect(resulting_hash).to eq good_result

end

it "properly handles boolean false" do
used_namespaces = {
%w(tns Foo) => 'ns'
Expand Down

0 comments on commit 7351ccd

Please sign in to comment.