aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/testing
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/testing')
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/dom.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb48
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb22
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/tag.rb21
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb12
-rw-r--r--actionpack/lib/action_dispatch/testing/performance_test.rb24
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb42
8 files changed, 137 insertions, 38 deletions
diff --git a/actionpack/lib/action_dispatch/testing/assertions/dom.rb b/actionpack/lib/action_dispatch/testing/assertions/dom.rb
index 9a917f704a..9c215de743 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/dom.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/dom.rb
@@ -1,3 +1,5 @@
+require 'action_controller/vendor/html-scanner'
+
module ActionDispatch
module Assertions
module DomAssertions
@@ -15,7 +17,7 @@ module ActionDispatch
assert_block(full_message) { expected_dom == actual_dom }
end
-
+
# The negated form of +assert_dom_equivalent+.
#
# ==== Examples
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 501a7c4dfb..5686bbdbde 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -28,7 +28,7 @@ module ActionDispatch
assert_block("") { true } # to count the assertion
elsif type.is_a?(Fixnum) && @response.response_code == type
assert_block("") { true } # to count the assertion
- elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type]
+ elsif type.is_a?(Symbol) && @response.response_code == Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
assert_block("") { true } # to count the assertion
else
assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index f0cca9a5f2..0c33539b4a 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -46,7 +46,6 @@ module ActionDispatch
request_method = nil
end
- ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
request = recognized_request_for(path, request_method)
expected_options = expected_options.clone
@@ -80,7 +79,6 @@ module ActionDispatch
def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
expected_path = "/#{expected_path}" unless expected_path[0] == ?/
# Load routes.rb if it hasn't been loaded.
- ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
generated_path, extra_keys = ActionController::Routing::Routes.generate_extras(options, defaults)
found_extras = options.reject {|k, v| ! extra_keys.include? k}
@@ -126,6 +124,46 @@ module ActionDispatch
assert_generates(path.is_a?(Hash) ? path[:path] : path, options, defaults, extras, message)
end
+ # A helper to make it easier to test different route configurations.
+ # This method temporarily replaces ActionController::Routing::Routes
+ # with a new RouteSet instance.
+ #
+ # The new instance is yielded to the passed block. Typically the block
+ # will create some routes using <tt>map.draw { map.connect ... }</tt>:
+ #
+ # with_routing do |set|
+ # set.draw do |map|
+ # map.connect ':controller/:action/:id'
+ # assert_equal(
+ # ['/content/10/show', {}],
+ # map.generate(:controller => 'content', :id => 10, :action => 'show')
+ # end
+ # end
+ # end
+ #
+ def with_routing
+ real_routes = ActionController::Routing::Routes
+ ActionController::Routing.module_eval { remove_const :Routes }
+
+ temporary_routes = ActionController::Routing::RouteSet.new
+ ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
+
+ yield temporary_routes
+ ensure
+ if ActionController::Routing.const_defined? :Routes
+ ActionController::Routing.module_eval { remove_const :Routes }
+ end
+ ActionController::Routing.const_set(:Routes, real_routes) if real_routes
+ end
+
+ def method_missing(selector, *args, &block)
+ if @controller && ActionController::Routing::Routes.named_routes.helpers.include?(selector)
+ @controller.send(selector, *args, &block)
+ else
+ super
+ end
+ end
+
private
# Recognizes the route for a given path.
def recognized_request_for(path, request_method = nil)
@@ -134,9 +172,11 @@ module ActionDispatch
# Assume given controller
request = ActionController::TestRequest.new
request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method
- request.path = path
+ request.path = path
+
+ params = ActionController::Routing::Routes.recognize_path(path, { :method => request.method })
+ request.path_parameters = params.with_indifferent_access
- ActionController::Routing::Routes.recognize(request)
request
end
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
index d22adfa749..c2dc591ff7 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
@@ -1,3 +1,5 @@
+require 'action_controller/vendor/html-scanner'
+
#--
# Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
# Under MIT and/or CC By license.
@@ -16,7 +18,7 @@ module ActionDispatch
#
# Use +css_select+ to select elements without making an assertions, either
# from the response HTML or elements selected by the enclosing assertion.
- #
+ #
# In addition to HTML responses, you can make the following assertions:
# * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations.
# * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
@@ -53,8 +55,8 @@ module ActionDispatch
# end
#
# # Selects all list items in unordered lists
- # items = css_select("ul>li")
- #
+ # items = css_select("ul>li")
+ #
# # Selects all form tags and then all inputs inside the form
# forms = css_select("form")
# forms.each do |form|
@@ -212,7 +214,7 @@ module ActionDispatch
# Otherwise just operate on the response document.
root = response_from_page_or_rjs
end
-
+
# First or second argument is the selector: string and we pass
# all remaining arguments. Array and we pass the argument. Also
# accepts selector itself.
@@ -225,7 +227,7 @@ module ActionDispatch
selector = arg
else raise ArgumentError, "Expecting a selector as the first argument"
end
-
+
# Next argument is used for equality tests.
equals = {}
case arg = args.shift
@@ -315,10 +317,10 @@ module ActionDispatch
# Returns all matches elements.
matches
end
-
+
def count_description(min, max) #:nodoc:
pluralize = lambda {|word, quantity| word << (quantity == 1 ? '' : 's')}
-
+
if min && max && (max != min)
"between #{min} and #{max} elements"
elsif min && !(min == 1 && max == 1)
@@ -327,7 +329,7 @@ module ActionDispatch
"at most #{max} #{pluralize['element', max]}"
end
end
-
+
# :call-seq:
# assert_select_rjs(id?) { |elements| ... }
# assert_select_rjs(statement, id?) { |elements| ... }
@@ -344,7 +346,7 @@ module ActionDispatch
# that update or insert an element with that identifier.
#
# Use the first argument to narrow down assertions to only statements
- # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>,
+ # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>,
# <tt>:show</tt>, <tt>:hide</tt>, <tt>:toggle</tt>, <tt>:remove</tta>,
# <tt>:insert_html</tt> and <tt>:redirect</tt>.
#
@@ -494,7 +496,7 @@ module ActionDispatch
# end
# end
# end
- #
+ #
#
# # Selects all paragraph tags from within the description of an RSS feed
# assert_select_feed :rss, 2.0 do
diff --git a/actionpack/lib/action_dispatch/testing/assertions/tag.rb b/actionpack/lib/action_dispatch/testing/assertions/tag.rb
index ef6867576e..5c735e61b2 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/tag.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/tag.rb
@@ -1,3 +1,5 @@
+require 'action_controller/vendor/html-scanner'
+
module ActionDispatch
module Assertions
# Pair of assertions to testing elements in the HTML output of the response.
@@ -76,10 +78,10 @@ module ActionDispatch
# # Assert that there is a "span" containing between 2 and 4 "em" tags
# # as immediate children
# assert_tag :tag => "span",
- # :children => { :count => 2..4, :only => { :tag => "em" } }
+ # :children => { :count => 2..4, :only => { :tag => "em" } }
#
# # Get funky: assert that there is a "div", with an "ul" ancestor
- # # and an "li" parent (with "class" = "enum"), and containing a
+ # # and an "li" parent (with "class" = "enum"), and containing a
# # "span" descendant that contains text matching /hello world/
# assert_tag :tag => "div",
# :ancestor => { :tag => "ul" },
@@ -98,7 +100,7 @@ module ActionDispatch
tag = find_tag(opts)
assert tag, "expected tag, but no tag found matching #{opts.inspect} in:\n#{@response.body.inspect}"
end
-
+
# Identical to +assert_tag+, but asserts that a matching tag does _not_
# exist. (See +assert_tag+ for a full discussion of the syntax.)
#
@@ -118,6 +120,19 @@ module ActionDispatch
tag = find_tag(opts)
assert !tag, "expected no tag, but found tag matching #{opts.inspect} in:\n#{@response.body.inspect}"
end
+
+ def find_tag(conditions)
+ html_document.find(conditions)
+ end
+
+ def find_all_tag(conditions)
+ html_document.find_all(conditions)
+ end
+
+ def html_document
+ xml = @response.content_type =~ /xml$/
+ @html_document ||= HTML::Document.new(@response.body, false, xml)
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 40d6f97b2a..2a5f5dcd5c 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -2,9 +2,7 @@ require 'stringio'
require 'uri'
require 'active_support/test_case'
require 'active_support/core_ext/object/metaclass'
-
-# TODO: Remove circular dependency on ActionController
-require 'action_controller/testing/process'
+require 'rack/test'
module ActionDispatch
module Integration #:nodoc:
@@ -128,9 +126,7 @@ module ActionDispatch
DEFAULT_HOST = "www.example.com"
include Test::Unit::Assertions
- include ActionDispatch::Assertions
- include ActionController::TestProcess
- include RequestHelpers
+ include TestProcess, RequestHelpers, Assertions
%w( status status_message headers body redirect? ).each do |method|
delegate method, :to => :response, :allow_nil => true
@@ -415,7 +411,7 @@ module ActionDispatch
# At its simplest, you simply extend IntegrationTest and write your tests
# using the get/post methods:
#
- # require "#{File.dirname(__FILE__)}/test_helper"
+ # require "test_helper"
#
# class ExampleTest < ActionController::IntegrationTest
# fixtures :people
@@ -439,7 +435,7 @@ module ActionDispatch
# powerful testing DSL that is specific for your application. You can even
# reference any named routes you happen to have defined!
#
- # require "#{File.dirname(__FILE__)}/test_helper"
+ # require "test_helper"
#
# class AdvancedTest < ActionController::IntegrationTest
# fixtures :people, :rooms
diff --git a/actionpack/lib/action_dispatch/testing/performance_test.rb b/actionpack/lib/action_dispatch/testing/performance_test.rb
index b1ed9d31f4..1b9a6c18b7 100644
--- a/actionpack/lib/action_dispatch/testing/performance_test.rb
+++ b/actionpack/lib/action_dispatch/testing/performance_test.rb
@@ -1,15 +1,17 @@
require 'active_support/testing/performance'
require 'active_support/testing/default'
-module ActionDispatch
- # An integration test that runs a code profiler on your test methods.
- # Profiling output for combinations of each test method, measurement, and
- # output format are written to your tmp/performance directory.
- #
- # By default, process_time is measured and both flat and graph_html output
- # formats are written, so you'll have two output files per test method.
- class PerformanceTest < ActionDispatch::IntegrationTest
- include ActiveSupport::Testing::Performance
- include ActiveSupport::Testing::Default
+if defined?(ActiveSupport::Testing::Performance)
+ module ActionDispatch
+ # An integration test that runs a code profiler on your test methods.
+ # Profiling output for combinations of each test method, measurement, and
+ # output format are written to your tmp/performance directory.
+ #
+ # By default, process_time is measured and both flat and graph_html output
+ # formats are written, so you'll have two output files per test method.
+ class PerformanceTest < ActionDispatch::IntegrationTest
+ include ActiveSupport::Testing::Performance
+ include ActiveSupport::Testing::Default
+ end
end
-end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
new file mode 100644
index 0000000000..eae703e1b6
--- /dev/null
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -0,0 +1,42 @@
+module ActionDispatch
+ module TestProcess
+ def assigns(key = nil)
+ assigns = {}
+ @controller.instance_variable_names.each do |ivar|
+ next if ActionController::Base.protected_instance_variables.include?(ivar)
+ assigns[ivar[1..-1]] = @controller.instance_variable_get(ivar)
+ end
+
+ key.nil? ? assigns : assigns[key.to_s]
+ end
+
+ def session
+ @request.session
+ end
+
+ def flash
+ @request.flash
+ end
+
+ def cookies
+ @request.cookies.merge(@response.cookies)
+ end
+
+ def redirect_to_url
+ @response.redirect_url
+ end
+
+ # Shortcut for <tt>ARack::Test::UploadedFile.new(ActionController::TestCase.fixture_path + path, type)</tt>:
+ #
+ # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')
+ #
+ # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
+ # This will not affect other platforms:
+ #
+ # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary)
+ def fixture_file_upload(path, mime_type = nil, binary = false)
+ fixture_path = ActionController::TestCase.send(:fixture_path) if ActionController::TestCase.respond_to?(:fixture_path)
+ Rack::Test::UploadedFile.new("#{fixture_path}#{path}", mime_type, binary)
+ end
+ end
+end