1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Start moving TestRequest and TestResponse into ActionDispatch

This commit is contained in:
Joshua Peek 2009-04-30 17:26:03 -05:00
parent 64e66cf161
commit 00d1a57e9f
14 changed files with 279 additions and 253 deletions

View file

@ -817,7 +817,8 @@ module ActionController #:nodoc:
end
def initialize_template_class(response)
@template = response.template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
@template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
response.template = @template if response.respond_to?(:template=)
@template.helpers.send :include, self.class.master_helper_module
response.redirected_to = nil
@performed_render = @performed_redirect = false

View file

@ -245,7 +245,7 @@ module ActionController
ActionController::Base.clear_last_instantiation!
opts = {
:method => method.to_s.upcase,
:method => method,
:params => parameters,
"SERVER_NAME" => host,
@ -276,17 +276,12 @@ module ActionController
mock_response = ::Rack::MockResponse.new(status, headers, body)
@request_count += 1
@request = Request.new(env)
@response = Response.from_response(mock_response)
@request = ActionDispatch::Request.new(env)
@response = ActionDispatch::TestResponse.from_response(mock_response)
@cookies.merge!(@response.cookies)
@html_document = nil
# Decorate the response with the standard behavior of the
# TestResponse so that things like assert_response can be
# used in integration tests.
@response.extend(TestResponseBehavior)
if @controller = ActionController::Base.last_instantiation
@controller.send(:set_test_assigns)
end

View file

@ -1,24 +1,19 @@
require 'rack/session/abstract/id'
module ActionController #:nodoc:
class TestRequest < ActionDispatch::Request #:nodoc:
class TestRequest < ActionDispatch::TestRequest #:nodoc:
attr_accessor :cookies
attr_accessor :query_parameters, :path
attr_accessor :host
def self.new(env = {})
super
end
attr_accessor :query_parameters
def initialize(env = {})
super(Rack::MockRequest.env_for("/").merge(env))
super
@query_parameters = {}
@query_parameters = {}
self.session = TestSession.new
self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => ActiveSupport::SecureRandom.hex(16))
initialize_default_values
initialize_containers
@request_uri = "/"
@cookies = {}
end
# Wraps raw_post in a StringIO.
@ -36,55 +31,8 @@ module ActionController #:nodoc:
end
end
def port=(number)
@env["SERVER_PORT"] = number.to_i
end
def action=(action_name)
@query_parameters.update({ "action" => action_name })
@parameters = nil
end
# Used to check AbstractRequest's request_uri functionality.
# Disables the use of @path and @request_uri so superclass can handle those.
def set_REQUEST_URI(value)
@env["REQUEST_URI"] = value
@request_uri = nil
@path = nil
end
def request_uri=(uri)
@request_uri = uri
@path = uri.split("?").first
end
def request_method=(method)
@request_method = method
end
def accept=(mime_types)
@env["HTTP_ACCEPT"] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
@accepts = nil
end
def if_modified_since=(last_modified)
@env["HTTP_IF_MODIFIED_SINCE"] = last_modified
end
def if_none_match=(etag)
@env["HTTP_IF_NONE_MATCH"] = etag
end
def remote_addr=(addr)
@env['REMOTE_ADDR'] = addr
end
def request_uri(*args)
@request_uri || super()
end
def path(*args)
@path || super()
query_parameters.update({ "action" => action_name })
end
def assign_parameters(controller_path, action, parameters)
@ -105,34 +53,15 @@ module ActionController #:nodoc:
end
end
raw_post # populate env['RAW_POST_DATA']
@parameters = nil # reset TestRequest#parameters to use the new path_parameters
end
def recycle!
@env["action_dispatch.request.request_parameters"] = {}
self.query_parameters = {}
self.path_parameters = {}
@headers, @request_method, @accepts, @content_type = nil, nil, nil, nil
end
def user_agent=(user_agent)
@env['HTTP_USER_AGENT'] = user_agent
@env.delete_if { |k, v| k =~ /^action_dispatch\.request/ }
self.query_parameters = {}
@headers = nil
end
private
def initialize_containers
@cookies = {}
end
def initialize_default_values
@host = "test.host"
@request_uri = "/"
@env['HTTP_USER_AGENT'] = "Rails Testing"
@env['REMOTE_ADDR'] = "0.0.0.0"
@env["SERVER_PORT"] = 80
@env['REQUEST_METHOD'] = "GET"
end
def url_encoded_request_parameters
params = self.request_parameters.dup
@ -145,84 +74,13 @@ module ActionController #:nodoc:
end
end
# A refactoring of TestResponse to allow the same behavior to be applied
# to the "real" CgiResponse class in integration tests.
module TestResponseBehavior #:nodoc:
def redirect_url_match?(pattern)
::ActiveSupport::Deprecation.warn("response.redirect_url_match? is deprecated. Use assert_match(/foo/, response.redirect_url) instead", caller)
return false if redirect_url.nil?
p = Regexp.new(pattern) if pattern.class == String
p = pattern if pattern.class == Regexp
return false if p.nil?
p.match(redirect_url) != nil
end
# Returns the template of the file which was used to
# render this response (or nil)
def rendered
ActiveSupport::Deprecation.warn("response.rendered has been deprecated. Use tempate.rendered instead", caller)
@template.instance_variable_get(:@_rendered)
end
# A shortcut to the flash. Returns an empty hash if no session flash exists.
def flash
request.session['flash'] || {}
end
# Do we have a flash?
def has_flash?
!flash.empty?
end
# Do we have a flash that has contents?
def has_flash_with_contents?
!flash.empty?
end
# Does the specified flash object exist?
def has_flash_object?(name=nil)
!flash[name].nil?
end
# Does the specified object exist in the session?
def has_session_object?(name=nil)
!session[name].nil?
end
# A shortcut to the template.assigns
def template_objects
ActiveSupport::Deprecation.warn("response.template_objects has been deprecated. Use tempate.assigns instead", caller)
@template.assigns || {}
end
# Does the specified template object exist?
def has_template_object?(name=nil)
ActiveSupport::Deprecation.warn("response.has_template_object? has been deprecated. Use tempate.assigns[name].nil? instead", caller)
!template_objects[name].nil?
end
# Returns binary content (downloadable file), converted to a String
def binary_content
raise "Response body is not a Proc: #{body_parts.inspect}" unless body_parts.kind_of?(Proc)
require 'stringio'
sio = StringIO.new
body_parts.call(self, sio)
sio.rewind
sio.read
end
end
# Integration test methods such as ActionController::Integration::Session#get
# and ActionController::Integration::Session#post return objects of class
# TestResponse, which represent the HTTP response results of the requested
# controller actions.
#
# See Response for more information on controller response objects.
class TestResponse < ActionDispatch::Response
include TestResponseBehavior
class TestResponse < ActionDispatch::TestResponse
def recycle!
body_parts.clear
headers.delete('ETag')
@ -293,7 +151,7 @@ module ActionController #:nodoc:
@response.recycle!
@html_document = nil
@request.env['REQUEST_METHOD'] = http_method
@request.request_method = http_method
@request.action = action.to_s
@ -331,7 +189,7 @@ module ActionController #:nodoc:
end
def flash
@response.flash
@request.flash
end
def cookies
@ -348,7 +206,7 @@ module ActionController #:nodoc:
options.update(:only_path => true, :action => action)
url = ActionController::UrlRewriter.new(@request, parameters)
@request.set_REQUEST_URI(url.rewrite(options))
@request.request_uri = url.rewrite(options)
end
end

View file

@ -47,6 +47,8 @@ module ActionDispatch
autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
autoload :Assertions, 'action_dispatch/testing/assertions'
autoload :TestRequest, 'action_dispatch/testing/test_request'
autoload :TestResponse, 'action_dispatch/testing/test_response'
module Http
autoload :Headers, 'action_dispatch/http/headers'

View file

@ -83,7 +83,6 @@ module Rack
end
end
EOL = "\r\n"
MULTIPART_BOUNDARY = "AaB03x"
def self.parse_multipart(env)

View file

@ -31,7 +31,7 @@ module ActionDispatch
# <tt>:get</tt>. If the request \method is not listed in the HTTP_METHODS
# constant above, an UnknownHttpMethod exception is raised.
def request_method
@request_method ||= HTTP_METHOD_LOOKUP[super] || raise(ActionController::UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
HTTP_METHOD_LOOKUP[super] || raise(ActionController::UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
end
# Returns the HTTP request \method used for action processing as a
@ -85,7 +85,7 @@ module ActionDispatch
# For backward compatibility, the post \format is extracted from the
# X-Post-Data-Format HTTP header if present.
def content_type
@content_type ||= begin
@env["action_dispatch.request.content_type"] ||= begin
if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/
Mime::Type.lookup($1.strip.downcase)
else
@ -100,7 +100,7 @@ module ActionDispatch
# Returns the accepted MIME type for the request.
def accepts
@accepts ||= begin
@env["action_dispatch.request.accepts"] ||= begin
header = @env['HTTP_ACCEPT'].to_s.strip
fallback = xhr? ? Mime::JS : Mime::HTML
@ -160,7 +160,7 @@ module ActionDispatch
# GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of <tt>ActionController::Base.use_accept_header</tt>
def format(view_path = [])
@format ||=
@env["action_dispatch.request.format"] ||=
if parameters[:format]
Mime[parameters[:format]]
elsif ActionController::Base.use_accept_header && !(accepts == ONLY_ALL)
@ -171,12 +171,11 @@ module ActionDispatch
end
def formats
@formats =
if ActionController::Base.use_accept_header
Array(Mime[parameters[:format]] || accepts)
else
[format]
end
if ActionController::Base.use_accept_header
Array(Mime[parameters[:format]] || accepts)
else
[format]
end
end
# Sets the \format by string extension, which can be used to force custom formats
@ -192,7 +191,7 @@ module ActionDispatch
# end
def format=(extension)
parameters[:format] = extension.to_s
@format = Mime::Type.lookup_by_extension(parameters[:format])
@env["action_dispatch.request.format"] = Mime::Type.lookup_by_extension(parameters[:format])
end
# Returns a symbolized version of the <tt>:format</tt> parameter of the request.
@ -328,6 +327,10 @@ EOM
port == standard_port ? '' : ":#{port}"
end
def server_port
@env['SERVER_PORT'].to_i
end
# Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
# a different <tt>tld_length</tt>, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
def domain(tld_length = 1)
@ -396,18 +399,19 @@ EOM
# Returns both GET and POST \parameters in a single hash.
def parameters
@parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
@env["action_dispatch.request.parameters"] ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
end
alias_method :params, :parameters
def path_parameters=(parameters) #:nodoc:
@env.delete("action_dispatch.request.symbolized_path_parameters")
@env.delete("action_dispatch.request.parameters")
@env["action_dispatch.request.path_parameters"] = parameters
@symbolized_path_parameters = @parameters = nil
end
# The same as <tt>path_parameters</tt> with explicitly symbolized keys.
def symbolized_path_parameters
@symbolized_path_parameters ||= path_parameters.symbolize_keys
@env["action_dispatch.request.symbolized_path_parameters"] ||= path_parameters.symbolize_keys
end
# Returns a hash with the \parameters used to form the \path of the request.
@ -464,8 +468,8 @@ EOM
@env['rack.session.options'] = options
end
def server_port
@env['SERVER_PORT'].to_i
def flash
session['flash'] || {}
end
private

View file

@ -31,14 +31,6 @@ module ActionDispatch # :nodoc:
# end
# end
class Response < Rack::Response
def self.from_response(response)
new.tap do |resp|
resp.status = response.status
resp.headers = response.headers
resp.body = response.body
end
end
DEFAULT_HEADERS = { "Cache-Control" => "no-cache" }
attr_accessor :request
@ -47,27 +39,6 @@ module ActionDispatch # :nodoc:
attr_writer :header
alias_method :headers=, :header=
def template
ActiveSupport::Deprecation.warn("response.template has been deprecated. Use controller.template instead", caller)
@template
end
attr_writer :template
def session
ActiveSupport::Deprecation.warn("response.session has been deprecated. Use request.session instead", caller)
@request.session
end
def assigns
ActiveSupport::Deprecation.warn("response.assigns has been deprecated. Use controller.assigns instead", caller)
@template.controller.assigns
end
def layout
ActiveSupport::Deprecation.warn("response.layout has been deprecated. Use template.layout instead", caller)
@template.layout
end
delegate :default_charset, :to => 'ActionController::Base'
def initialize
@ -90,33 +61,6 @@ module ActionDispatch # :nodoc:
end
alias_method :status_message, :message
# Was the response successful?
def success?
(200..299).include?(response_code)
end
# Was the URL not found?
def missing?
response_code == 404
end
# Were we redirected?
def redirect?
(300..399).include?(response_code)
end
# Was there a server-side error?
def error?
(500..599).include?(response_code)
end
alias_method :server_error?, :error?
# Was there a client client?
def client_error?
(400..499).include?(response_code)
end
def body
str = ''
each { |part| str << part.to_s }

View file

@ -0,0 +1,56 @@
module ActionDispatch
class TestRequest < Request
def self.new(env = {})
super
end
def initialize(env = {})
super(Rack::MockRequest.env_for('/').merge(env))
self.host = 'test.host'
self.remote_addr = '0.0.0.0'
self.user_agent = 'Rails Testing'
end
def request_method=(method)
@env['REQUEST_METHOD'] = method.to_s.upcase
end
def host=(host)
@env['HTTP_HOST'] = host
end
def port=(number)
@env['SERVER_PORT'] = number.to_i
end
def request_uri=(uri)
@env['REQUEST_URI'] = uri
end
def path=(path)
@env['PATH_INFO'] = path
end
def if_modified_since=(last_modified)
@env['HTTP_IF_MODIFIED_SINCE'] = last_modified
end
def if_none_match=(etag)
@env['HTTP_IF_NONE_MATCH'] = etag
end
def remote_addr=(addr)
@env['REMOTE_ADDR'] = addr
end
def user_agent=(user_agent)
@env['HTTP_USER_AGENT'] = user_agent
end
def accept=(mime_types)
@env.delete("action_dispatch.request.accepts")
@env["HTTP_ACCEPT"] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
end
end
end

View file

@ -0,0 +1,131 @@
module ActionDispatch
class TestResponse < Response
def self.from_response(response)
new.tap do |resp|
resp.status = response.status
resp.headers = response.headers
resp.body = response.body
end
end
module DeprecatedHelpers
def template
ActiveSupport::Deprecation.warn("response.template has been deprecated. Use controller.template instead", caller)
@template
end
attr_writer :template
def session
ActiveSupport::Deprecation.warn("response.session has been deprecated. Use request.session instead", caller)
@request.session
end
def assigns
ActiveSupport::Deprecation.warn("response.assigns has been deprecated. Use controller.assigns instead", caller)
@template.controller.assigns
end
def layout
ActiveSupport::Deprecation.warn("response.layout has been deprecated. Use template.layout instead", caller)
@template.layout
end
def redirect_url_match?(pattern)
::ActiveSupport::Deprecation.warn("response.redirect_url_match? is deprecated. Use assert_match(/foo/, response.redirect_url) instead", caller)
return false if redirect_url.nil?
p = Regexp.new(pattern) if pattern.class == String
p = pattern if pattern.class == Regexp
return false if p.nil?
p.match(redirect_url) != nil
end
# Returns the template of the file which was used to
# render this response (or nil)
def rendered
ActiveSupport::Deprecation.warn("response.rendered has been deprecated. Use tempate.rendered instead", caller)
@template.instance_variable_get(:@_rendered)
end
# A shortcut to the flash. Returns an empty hash if no session flash exists.
def flash
ActiveSupport::Deprecation.warn("response.flash has been deprecated. Use request.flash instead", caller)
request.session['flash'] || {}
end
# Do we have a flash?
def has_flash?
ActiveSupport::Deprecation.warn("response.has_flash? has been deprecated. Use flash.any? instead", caller)
!flash.empty?
end
# Do we have a flash that has contents?
def has_flash_with_contents?
ActiveSupport::Deprecation.warn("response.has_flash_with_contents? has been deprecated. Use flash.any? instead", caller)
!flash.empty?
end
# Does the specified flash object exist?
def has_flash_object?(name=nil)
ActiveSupport::Deprecation.warn("response.has_flash_object? has been deprecated. Use flash[name] instead", caller)
!flash[name].nil?
end
# Does the specified object exist in the session?
def has_session_object?(name=nil)
ActiveSupport::Deprecation.warn("response.has_session_object? has been deprecated. Use session[name] instead", caller)
!session[name].nil?
end
# A shortcut to the template.assigns
def template_objects
ActiveSupport::Deprecation.warn("response.template_objects has been deprecated. Use tempate.assigns instead", caller)
@template.assigns || {}
end
# Does the specified template object exist?
def has_template_object?(name=nil)
ActiveSupport::Deprecation.warn("response.has_template_object? has been deprecated. Use tempate.assigns[name].nil? instead", caller)
!template_objects[name].nil?
end
end
include DeprecatedHelpers
# Was the response successful?
def success?
(200..299).include?(response_code)
end
# Was the URL not found?
def missing?
response_code == 404
end
# Were we redirected?
def redirect?
(300..399).include?(response_code)
end
# Was there a server-side error?
def error?
(500..599).include?(response_code)
end
alias_method :server_error?, :error?
# Was there a client client?
def client_error?
(400..499).include?(response_code)
end
# Returns binary content (downloadable file), converted to a String
def binary_content
raise "Response body is not a Proc: #{body_parts.inspect}" unless body_parts.kind_of?(Proc)
require 'stringio'
sio = StringIO.new
body_parts.call(self, sio)
sio.rewind
sio.read
end
end
end

View file

@ -305,24 +305,30 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
# check the empty flashing
def test_flash_me_naked
process :flash_me_naked
assert !@response.has_flash?
assert !@response.has_flash_with_contents?
assert_deprecated do
assert !@response.has_flash?
assert !@response.has_flash_with_contents?
end
end
# check if we have flash objects
def test_flash_haves
process :flash_me
assert @response.has_flash?
assert @response.has_flash_with_contents?
assert @response.has_flash_object?('hello')
assert_deprecated do
assert @response.has_flash?
assert @response.has_flash_with_contents?
assert @response.has_flash_object?('hello')
end
end
# ensure we don't have flash objects
def test_flash_have_nots
process :nothing
assert !@response.has_flash?
assert !@response.has_flash_with_contents?
assert_nil @response.flash['hello']
assert_deprecated do
assert !@response.has_flash?
assert !@response.has_flash_with_contents?
assert_nil @response.flash['hello']
end
end
# check if we were rendered by a file-based template?

View file

@ -345,7 +345,7 @@ class ActionCacheTest < ActionController::TestCase
cached_time = content_to_cache
reset!
@request.set_REQUEST_URI "/action_caching_test/expire.xml"
@request.request_uri = "/action_caching_test/expire.xml"
get :expire, :format => :xml
reset!

View file

@ -1923,7 +1923,7 @@ class RouteSetTest < Test::Unit::TestCase
end
end
request.path = "/people"
request.request_uri = "/people"
request.env["REQUEST_METHOD"] = "GET"
assert_nothing_raised { set.recognize(request) }
assert_equal("index", request.path_parameters[:action])
@ -1945,7 +1945,7 @@ class RouteSetTest < Test::Unit::TestCase
}
request.recycle!
request.path = "/people/5"
request.request_uri = "/people/5"
request.env["REQUEST_METHOD"] = "GET"
assert_nothing_raised { set.recognize(request) }
assert_equal("show", request.path_parameters[:action])
@ -2047,7 +2047,7 @@ class RouteSetTest < Test::Unit::TestCase
end
end
request.path = "/people/5"
request.request_uri = "/people/5"
request.env["REQUEST_METHOD"] = "GET"
assert_nothing_raised { set.recognize(request) }
assert_equal("show", request.path_parameters[:action])
@ -2059,7 +2059,7 @@ class RouteSetTest < Test::Unit::TestCase
assert_equal("update", request.path_parameters[:action])
request.recycle!
request.path = "/people/5.png"
request.request_uri = "/people/5.png"
request.env["REQUEST_METHOD"] = "GET"
assert_nothing_raised { set.recognize(request) }
assert_equal("show", request.path_parameters[:action])

View file

@ -201,7 +201,7 @@ XML
end
def test_process_with_request_uri_with_params_with_explicit_uri
@request.set_REQUEST_URI "/explicit/uri"
@request.request_uri = "/explicit/uri"
process :test_uri, :id => 7
assert_equal "/explicit/uri", @response.body
end
@ -212,7 +212,7 @@ XML
end
def test_process_with_query_string_with_explicit_uri
@request.set_REQUEST_URI "/explicit/uri?q=test?extra=question"
@request.request_uri = "/explicit/uri?q=test?extra=question"
process :test_query_string
assert_equal "q=test?extra=question", @response.body
end

View file

@ -0,0 +1,30 @@
require 'abstract_unit'
class TestRequestTest < ActiveSupport::TestCase
test "sane defaults" do
env = ActionDispatch::TestRequest.new.env
assert_equal "GET", env.delete("REQUEST_METHOD")
assert_equal "off", env.delete("HTTPS")
assert_equal "http", env.delete("rack.url_scheme")
assert_equal "example.org", env.delete("SERVER_NAME")
assert_equal "80", env.delete("SERVER_PORT")
assert_equal "/", env.delete("PATH_INFO")
assert_equal "", env.delete("SCRIPT_NAME")
assert_equal "", env.delete("QUERY_STRING")
assert_equal "0", env.delete("CONTENT_LENGTH")
assert_equal "test.host", env.delete("HTTP_HOST")
assert_equal "0.0.0.0", env.delete("REMOTE_ADDR")
assert_equal "Rails Testing", env.delete("HTTP_USER_AGENT")
assert_equal [0, 1], env.delete("rack.version")
assert_equal "", env.delete("rack.input").string
assert_kind_of StringIO, env.delete("rack.errors")
assert_equal true, env.delete("rack.multithread")
assert_equal true, env.delete("rack.multiprocess")
assert_equal false, env.delete("rack.run_once")
assert env.empty?, env.inspect
end
end