Permalink
Browse files

Back off rack 1.1-pre and bundle in the new testing goodies

  • Loading branch information...
1 parent 8974ab2 commit 5e5e34377ca22a4b5ea55975c119fb31d996ef80 @josh josh committed Aug 31, 2009
Showing with 300 additions and 5,422 deletions.
  1. +2 −1 actionpack/lib/action_controller/testing/integration.rb
  2. +1 −1 actionpack/lib/action_controller/testing/process.rb
  3. +0 −6 actionpack/lib/action_dispatch.rb
  4. +297 −2 actionpack/lib/action_dispatch/testing/test_request.rb
  5. +0 −90 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack.rb
  6. +0 −22 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/adapter/camping.rb
  7. +0 −37 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/abstract/handler.rb
  8. +0 −37 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/abstract/request.rb
  9. +0 −58 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/basic.rb
  10. +0 −124 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/md5.rb
  11. +0 −51 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/nonce.rb
  12. +0 −55 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/params.rb
  13. +0 −40 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/digest/request.rb
  14. +0 −480 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/auth/openid.rb
  15. +0 −63 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/builder.rb
  16. +0 −36 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/cascade.rb
  17. +0 −49 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/chunked.rb
  18. +0 −61 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/commonlogger.rb
  19. +0 −47 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/conditionalget.rb
  20. +0 −29 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb
  21. +0 −23 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_type.rb
  22. +0 −96 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/deflater.rb
  23. +0 −153 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/directory.rb
  24. +0 −88 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/file.rb
  25. +0 −69 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler.rb
  26. +0 −61 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/cgi.rb
  27. +0 −8 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/evented_mongrel.rb
  28. +0 −88 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/fastcgi.rb
  29. +0 −55 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/lsws.rb
  30. +0 −84 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/mongrel.rb
  31. +0 −59 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/scgi.rb
  32. +0 −8 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/swiftiplied_mongrel.rb
  33. +0 −18 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/thin.rb
  34. +0 −67 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb
  35. +0 −19 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb
  36. +0 −537 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lint.rb
  37. +0 −65 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lobster.rb
  38. +0 −16 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb
  39. +0 −27 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb
  40. +0 −204 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/mime.rb
  41. +0 −184 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/mock.rb
  42. +0 −57 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/recursive.rb
  43. +0 −106 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/reloader.rb
  44. +0 −254 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/request.rb
  45. +0 −183 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/response.rb
  46. +0 −98 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/rewindable_input.rb
  47. +0 −142 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/abstract/id.rb
  48. +0 −91 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/cookie.rb
  49. +0 −109 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/memcache.rb
  50. +0 −100 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/session/pool.rb
  51. +0 −349 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/showexceptions.rb
  52. +0 −106 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/showstatus.rb
  53. +0 −38 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/static.rb
  54. +0 −55 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb
  55. +0 −516 actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/utils.rb
@@ -267,7 +267,8 @@ def process(method, path, parameters = nil, rack_environment = nil)
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"HTTP_ACCEPT" => accept
}
- env = Rack::MockRequest.env_for(path, opts)
+
+ env = ActionDispatch::TestRequest.env_for(path, opts)
(rack_environment || {}).each do |key, value|
env[key] = value
@@ -84,7 +84,7 @@ def initialize(session = {})
#
# Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows):
# post :change_avatar, :avatar => ActionController::TestUploadedFile.new(ActionController::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary)
- TestUploadedFile = Rack::Utils::Multipart::UploadedFile
+ TestUploadedFile = ActionDispatch::TestRequest::Multipart::UploadedFile
module TestProcess
def self.included(base)
@@ -25,12 +25,6 @@
$:.unshift activesupport_path if File.directory?(activesupport_path)
require 'active_support'
-begin
- gem 'rack', '~> 1.1.pre'
-rescue Gem::LoadError, ArgumentError
- $:.unshift "#{File.dirname(__FILE__)}/action_dispatch/vendor/rack-1.1.pre"
-end
-
require 'rack'
module Rack
@@ -1,13 +1,308 @@
module ActionDispatch
class TestRequest < Request
- DEFAULT_ENV = Rack::MockRequest.env_for('/')
+ # Improve version of Multipart thats in rack/master
+ module Multipart #:nodoc:
+ class UploadedFile
+ # The filename, *not* including the path, of the "uploaded" file
+ attr_reader :original_filename
+
+ # The content type of the "uploaded" file
+ attr_accessor :content_type
+
+ def initialize(path, content_type = "text/plain", binary = false)
+ raise "#{path} file does not exist" unless ::File.exist?(path)
+ @content_type = content_type
+ @original_filename = ::File.basename(path)
+ @tempfile = Tempfile.new(@original_filename)
+ @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
+ @tempfile.binmode if binary
+ FileUtils.copy_file(path, @tempfile.path)
+ end
+
+ def path
+ @tempfile.path
+ end
+ alias_method :local_path, :path
+
+ def method_missing(method_name, *args, &block) #:nodoc:
+ @tempfile.__send__(method_name, *args, &block)
+ end
+ end
+
+ EOL = "\r\n"
+ MULTIPART_BOUNDARY = "AaB03x"
+
+ def self.parse_multipart(env)
+ unless env['CONTENT_TYPE'] =~
+ %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n
+ nil
+ else
+ boundary = "--#{$1}"
+
+ params = {}
+ buf = ""
+ content_length = env['CONTENT_LENGTH'].to_i
+ input = env['rack.input']
+ input.rewind
+
+ boundary_size = Utils.bytesize(boundary) + EOL.size
+ bufsize = 16384
+
+ content_length -= boundary_size
+
+ read_buffer = ''
+
+ status = input.read(boundary_size, read_buffer)
+ raise EOFError, "bad content body" unless status == boundary + EOL
+
+ rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n
+
+ loop {
+ head = nil
+ body = ''
+ filename = content_type = name = nil
+
+ until head && buf =~ rx
+ if !head && i = buf.index(EOL+EOL)
+ head = buf.slice!(0, i+2) # First \r\n
+ buf.slice!(0, 2) # Second \r\n
+
+ filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
+ content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
+ name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
+
+ if content_type || filename
+ body = Tempfile.new("RackMultipart")
+ body.binmode if body.respond_to?(:binmode)
+ end
+
+ next
+ end
+
+ # Save the read body part.
+ if head && (boundary_size+4 < buf.size)
+ body << buf.slice!(0, buf.size - (boundary_size+4))
+ end
+
+ c = input.read(bufsize < content_length ? bufsize : content_length, read_buffer)
+ raise EOFError, "bad content body" if c.nil? || c.empty?
+ buf << c
+ content_length -= c.size
+ end
+
+ # Save the rest.
+ if i = buf.index(rx)
+ body << buf.slice!(0, i)
+ buf.slice!(0, boundary_size+2)
+
+ content_length = -1 if $1 == "--"
+ end
+
+ if filename == ""
+ # filename is blank which means no file has been selected
+ data = nil
+ elsif filename
+ body.rewind
+
+ # Take the basename of the upload's original filename.
+ # This handles the full Windows paths given by Internet Explorer
+ # (and perhaps other broken user agents) without affecting
+ # those which give the lone filename.
+ filename =~ /^(?:.*[:\\\/])?(.*)/m
+ filename = $1
+
+ data = {:filename => filename, :type => content_type,
+ :name => name, :tempfile => body, :head => head}
+ elsif !filename && content_type
+ body.rewind
+
+ # Generic multipart cases, not coming from a form
+ data = {:type => content_type,
+ :name => name, :tempfile => body, :head => head}
+ else
+ data = body
+ end
+
+ Utils.normalize_params(params, name, data) unless data.nil?
+
+ break if buf.empty? || content_length == -1
+ }
+
+ input.rewind
+
+ params
+ end
+ end
+
+ def self.build_multipart(params, first = true)
+ if first
+ unless params.is_a?(Hash)
+ raise ArgumentError, "value must be a Hash"
+ end
+
+ multipart = false
+ 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 { |v|
+ build_multipart(v, false).each { |subkey, subvalue|
+ flattened_params["#{k}[]#{subkey}"] = subvalue
+ }
+ }
+ when Hash
+ build_multipart(value, false).each { |subkey, subvalue|
+ flattened_params[k + subkey] = subvalue
+ }
+ else
+ flattened_params[k] = value
+ end
+ end
+
+ if first
+ flattened_params.map { |name, file|
+ if file.respond_to?(:original_filename)
+ ::File.open(file.path, "rb") do |f|
+ f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
+<<-EOF
+--#{MULTIPART_BOUNDARY}\r
+Content-Disposition: form-data; name="#{name}"; filename="#{Rack::Utils.escape(file.original_filename)}"\r
+Content-Type: #{file.content_type}\r
+Content-Length: #{::File.stat(file.path).size}\r
+\r
+#{f.read}\r
+EOF
+ end
+ else
+<<-EOF
+--#{MULTIPART_BOUNDARY}\r
+Content-Disposition: form-data; name="#{name}"\r
+\r
+#{file}\r
+EOF
+ end
+ }.join + "--#{MULTIPART_BOUNDARY}--\r"
+ else
+ flattened_params
+ end
+ end
+ end
+
+ DEFAULT_ENV = {
+ "rack.version" => [1,0],
+ "rack.input" => StringIO.new,
+ "rack.errors" => StringIO.new,
+ "rack.multithread" => true,
+ "rack.multiprocess" => true,
+ "rack.run_once" => false,
+ }
+
+ # Improve version of env_for thats in rack/master
+ def self.env_for(uri="", opts={}) #:nodoc:
+ uri = URI(uri)
+ uri.path = "/#{uri.path}" unless uri.path[0] == ?/
+
+ env = DEFAULT_ENV.dup
+
+ env["REQUEST_METHOD"] = opts[:method] ? opts[:method].to_s.upcase : "GET"
+ env["SERVER_NAME"] = uri.host || "example.org"
+ env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
+ env["QUERY_STRING"] = uri.query.to_s
+ env["PATH_INFO"] = (!uri.path || uri.path.empty?) ? "/" : uri.path
+ env["rack.url_scheme"] = uri.scheme || "http"
+ env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
+
+ env["SCRIPT_NAME"] = opts[:script_name] || ""
+
+ if opts[:fatal]
+ env["rack.errors"] = FatalWarner.new
+ else
+ env["rack.errors"] = StringIO.new
+ end
+
+ if params = opts[:params]
+ if env["REQUEST_METHOD"] == "GET"
+ params = Rack::Utils.parse_nested_query(params) if params.is_a?(String)
+ params.update(Rack::Utils.parse_nested_query(env["QUERY_STRING"]))
+ env["QUERY_STRING"] = build_nested_query(params)
+ elsif !opts.has_key?(:input)
+ opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
+ if params.is_a?(Hash)
+ if data = Multipart.build_multipart(params)
+ opts[:input] = data
+ opts["CONTENT_LENGTH"] ||= data.length.to_s
+ opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Multipart::MULTIPART_BOUNDARY}"
+ else
+ opts[:input] = build_nested_query(params)
+ end
+ else
+ opts[:input] = params
+ end
+ end
+ end
+
+ empty_str = ""
+ empty_str.force_encoding("ASCII-8BIT") if empty_str.respond_to? :force_encoding
+ opts[:input] ||= empty_str
+ if String === opts[:input]
+ rack_input = StringIO.new(opts[:input])
+ else
+ rack_input = opts[:input]
+ end
+
+ rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
+ env['rack.input'] = rack_input
+
+ env["CONTENT_LENGTH"] ||= env["rack.input"].length.to_s
+
+ opts.each { |field, value|
+ env[field] = value if String === field
+ }
+
+ env
+ end
+
+ def self.build_nested_query(value, prefix = nil)
+ case value
+ when Array
+ value.map { |v|
+ build_nested_query(v, "#{prefix}[]")
+ }.join("&")
+ when Hash
+ value.map { |k, v|
+ build_nested_query(v, prefix ? "#{prefix}[#{Rack::Utils.escape(k)}]" : Rack::Utils.escape(k))
+ }.join("&")
+ when String
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
+ "#{prefix}=#{Rack::Utils.escape(value)}"
+ else
+ prefix
+ end
+ end
def self.new(env = {})
super
end
def initialize(env = {})
- super(DEFAULT_ENV.merge(env))
+ super(self.class.env_for('/').merge(env))
self.host = 'test.host'
self.remote_addr = '0.0.0.0'
Oops, something went wrong.

0 comments on commit 5e5e343

Please sign in to comment.