Skip to content

Commit

Permalink
Merge pull request #21 from qbwc/single-element-array
Browse files Browse the repository at this point in the history
Use consistent types in xml_to_hash #17
  • Loading branch information
JasonBarnabe authored Aug 16, 2016
2 parents f93d594 + 6df91c1 commit f91b0ba
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
25 changes: 24 additions & 1 deletion lib/qbxml/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,23 @@ def self.xml_to_hash(node, hash = {}, opts = {})
name = node.name
schema = opts[:schema]
opts[:typecast_cache] ||= {}
opts[:is_repetitive_cache] ||= {}

# Insert node hash into parent hash correctly.
case hash[name]
when Array
hash[name] << node_hash
when Hash, String
# This parent has multiple nodes with the same name, but when we checked the first time,
# we found it is not defined as repetitive. I guess this means the schema is a liar.
hash[name] = [hash[name], node_hash]
else
hash[name] = node_hash
# We didn't see this node name under this parent yet.
if is_repetitive?(schema, node.path, opts[:is_repetitive_cache])
hash[name] = [node_hash]
else
hash[name] = node_hash
end
end

# Handle child elements
Expand Down Expand Up @@ -142,6 +150,21 @@ def self.typecast(schema, xpath, value, typecast_cache)
type_proc[value]
end

# Determines if the node is repetitive. Just because something is repetitive doesn't mean it always repeats.
# For example, a customer query could return 1 result or 100, but in both cases, we should be returning an
# Array.
def self.is_repetitive?(schema, xpath, is_repetitive_cache)
# Yes, we are parsing comments.
comment_path = xpath.gsub(/\[\d+\]/,'') + "/comment()"
return is_repetitive_cache[comment_path] || parse_repetitive_from_comment(schema, comment_path)
end

def self.parse_repetitive_from_comment(schema, comment_path)
comment = schema.xpath(comment_path).first
return false if comment.nil?
return comment.text.include?('may rep')
end

def self.deep_convert(hash, opts = {}, &block)
hash.inject(self.new) do |h, (k,v)|
k = k.to_s
Expand Down
21 changes: 20 additions & 1 deletion test/unit/xml_to_hash_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,28 @@ def test_array_of_strings
assert_equal h, qbxml.from_qbxml("<?qbxml version=\"7.0\"?>\n<QBXML>\n <QBXMLMsgsRq>\n <InvoiceQueryRq>\n <IncludeRetElement>TxnID</IncludeRetElement>\n <IncludeRetElement>RefNumber</IncludeRetElement>\n </InvoiceQueryRq>\n </QBXMLMsgsRq>\n</QBXML>\n")
end

def test_float_percentage
def test_array_with_one_element
qbxml = Qbxml.new
h = {
"qbxml" => {
"xml_attributes" => {},
"qbxml_msgs_rs" => {
"xml_attributes" => {},
'customer_query_rs' => {
"xml_attributes" => {},
'customer_ret' => [{
"xml_attributes"=> {},
'list_id' => 'abc'
}]
}
}
}
}
assert_equal h, qbxml.from_qbxml("<?qbxml version=\"7.0\"?>\n<QBXML>\n <QBXMLMsgsRs>\n <CustomerQueryRs>\n <CustomerRet><ListID>abc</ListID></CustomerRet>\n </CustomerQueryRs>\n </QBXMLMsgsRs>\n</QBXML>\n")
end

def test_float_percentage
qbxml = Qbxml.new
h = {
"qbxml" => {
"xml_attributes" => {},
Expand Down

0 comments on commit f91b0ba

Please sign in to comment.