lib/pact/consumer_contract/query.rb in pact-support-1.17.0.pre.rc2 vs lib/pact/consumer_contract/query.rb in pact-support-1.17.0
- old
+ new
@@ -4,34 +4,44 @@
module Pact
class Query
DEFAULT_SEP = /[&;] */n
COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
+ class NestedQuery < Hash; end
+
def self.create query
if query.is_a? Hash
Pact::QueryHash.new(query)
else
Pact::QueryString.new(query)
end
end
+ def self.is_a_query_object?(object)
+ object.is_a?(Pact::QueryHash) || object.is_a?(Pact::QueryString)
+ end
+
+ def self.parsed_as_nested?(object)
+ object.is_a?(NestedQuery)
+ end
+
def self.parse_string query_string
- parsed_query = parse_query(query_string)
+ parsed_query = parse_string_as_non_nested_query(query_string)
# If Rails nested params...
- if parsed_query.keys.any?{ | key| key.include?("[") }
- parse_nested_query(query_string)
+ if parsed_query.keys.any?{ | key| key =~ /\[.*\]/ }
+ parse_string_as_nested_query(query_string)
else
parsed_query.each_with_object({}) do | (key, value), new_hash |
new_hash[key] = [*value]
end
end
end
# Ripped from Rack to avoid adding an unnecessary dependency, thank you Rack
# https://github.com/rack/rack/blob/649c72bab9e7b50d657b5b432d0c205c95c2be07/lib/rack/utils.rb
- def self.parse_query(qs, d = nil, &unescaper)
+ def self.parse_string_as_non_nested_query(qs, d = nil, &unescaper)
unescaper ||= method(:unescape)
params = {}
(qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
@@ -50,22 +60,22 @@
end
return params.to_h
end
- def self.parse_nested_query(qs, d = nil)
+ def self.parse_string_as_nested_query(qs, d = nil)
params = {}
unless qs.nil? || qs.empty?
(qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
k, v = p.split('=', 2).map! { |s| unescape(s) }
normalize_params(params, k, v)
end
end
- return params.to_h
+ return NestedQuery[params.to_h]
end
def self.normalize_params(params, name, v)
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
k = $1 || ''
@@ -97,17 +107,29 @@
params[k] << normalize_params({}, child_key, v)
end
else
params[k] ||= {}
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
- params[k] = normalize_params(params[k], after, v, depth - 1)
+ params[k] = normalize_params(params[k], after, v)
end
params
end
def self.params_hash_type?(obj)
obj.is_a?(Hash)
+ end
+
+ def self.params_hash_has_key?(hash, key)
+ return false if key =~ /\[\]/
+
+ key.split(/[\[\]]+/).inject(hash) do |h, part|
+ next h if part == ''
+ return false unless params_hash_type?(h) && h.key?(part)
+ h[part]
+ end
+
+ true
end
def self.unescape(s, encoding = Encoding::UTF_8)
URI.decode_www_form_component(s, encoding)
end