File: //usr/share/rubygems-integration/all/gems/rack-test-0.7.0/lib/rack/test/utils.rb
module Rack
module Test
module Utils # :nodoc:
include Rack::Utils
extend Rack::Utils
def build_nested_query(value, prefix = nil)
case value
when Array
if value.empty?
"#{prefix}[]="
else
value.map do |v|
unless unescape(prefix) =~ /\[\]$/
prefix = "#{prefix}[]"
end
build_nested_query(v, "#{prefix}")
end.join("&")
end
when Hash
value.map do |k, v|
build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
end.join("&")
when NilClass
prefix.to_s
else
"#{prefix}=#{escape(value)}"
end
end
module_function :build_nested_query
def build_multipart(params, first = true, multipart = false)
if first
unless params.is_a?(Hash)
raise ArgumentError, "value must be a Hash"
end
query = lambda { |value|
case value
when Array
value.each(&query)
when Hash
value.values.each(&query)
when UploadedFile
multipart = true
end
}
params.values.each(&query)
return nil unless multipart
end
flattened_params = Hash.new
params.each do |key, value|
k = first ? key.to_s : "[#{key}]"
case value
when Array
value.map do |v|
if (v.is_a?(Hash))
nested_params = {}
build_multipart(v, false).each { |subkey, subvalue|
nested_params[subkey] = subvalue
}
flattened_params["#{k}[]"] ||= []
flattened_params["#{k}[]"] << nested_params
else
flattened_params["#{k}[]"] = value
end
end
when Hash
build_multipart(value, false).each { |subkey, subvalue|
flattened_params[k + subkey] = subvalue
}
else
flattened_params[k] = value
end
end
if first
build_parts(flattened_params)
else
flattened_params
end
end
module_function :build_multipart
private
def build_parts(parameters)
get_parts(parameters).join + "--#{MULTIPART_BOUNDARY}--\r"
end
module_function :build_parts
def get_parts(parameters)
parameters.map { |name, value|
if name =~ /\[\]\Z/ && value.is_a?(Array) && value.all? {|v| v.is_a?(Hash)}
value.map { |hash|
new_value = {}
hash.each { |k, v| new_value[name+k] = v }
get_parts(new_value).join
}.join
else
if value.respond_to?(:original_filename)
build_file_part(name, value)
elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
value.map do |v|
build_file_part(name, v)
end.join
else
primitive_part = build_primitive_part(name, value)
Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part
end
end
}
end
module_function :get_parts
def build_primitive_part(parameter_name, value)
unless value.is_a? Array
value = [value]
end
value.map do |v|
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{parameter_name}"\r
\r
#{v}\r
EOF
end.join
end
module_function :build_primitive_part
def build_file_part(parameter_name, uploaded_file)
::File.open(uploaded_file.path, "rb") do |physical_file|
physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding)
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r
Content-Type: #{uploaded_file.content_type}\r
Content-Length: #{::File.stat(uploaded_file.path).size}\r
\r
#{physical_file.read}\r
EOF
end
end
module_function :build_file_part
end
end
end