Skip to content

Commit

Permalink
Add :partial option to assert_template [#1550 state:resolved]
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information
mark authored and josh committed Dec 11, 2008
1 parent 5ede4ce commit 49306cc
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 23 deletions.
56 changes: 43 additions & 13 deletions actionpack/lib/action_controller/assertions/response_assertions.rb
Expand Up @@ -16,7 +16,7 @@ module ResponseAssertions
# ==== Examples
#
# # assert that the response was a redirection
# assert_response :redirect
# assert_response :redirect
#
# # assert that the response code was status code 401 (unauthorized)
# assert_response 401
Expand All @@ -41,7 +41,7 @@ def assert_response(type, message = nil)
end
end

# Assert that the redirection options passed in match those of the redirect called in the latest action.
# Assert that the redirection options passed in match those of the redirect called in the latest action.
# This match can be partial, such that assert_redirected_to(:controller => "weblog") will also
# match the redirection of redirect_to(:controller => "weblog", :action => "show") and so on.
#
Expand All @@ -60,12 +60,12 @@ def assert_redirected_to(options = {}, message=nil)
clean_backtrace do
assert_response(:redirect, message)
return true if options == @response.redirected_to

# Support partial arguments for hash redirections
if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
return true if options.all? {|(key, value)| @response.redirected_to[key] == value}
end

redirected_to_after_normalisation = normalize_argument_to_redirection(@response.redirected_to)
options_after_normalisation = normalize_argument_to_redirection(options)

Expand All @@ -75,29 +75,59 @@ def assert_redirected_to(options = {}, message=nil)
end
end

# Asserts that the request was rendered with the appropriate template file.
# Asserts that the request was rendered with the appropriate template file or partials
#
# ==== Examples
#
# # assert that the "new" view template was rendered
# assert_template "new"
#
def assert_template(expected = nil, message=nil)
# # assert that the "_customer" partial was rendered twice
# assert_template :partial => '_customer', :count => 2
#
# # assert that no partials were rendered
# assert_template :partial => false
#
def assert_template(options = {}, message = nil)
clean_backtrace do
rendered = @response.rendered_template.to_s
msg = build_message(message, "expecting <?> but rendering with <?>", expected, rendered)
assert_block(msg) do
if expected.nil?
@response.rendered_template.blank?
case options
when NilClass, String
rendered = @response.rendered[:template].to_s
msg = build_message(message,
"expecting <?> but rendering with <?>",
options, rendered)
assert_block(msg) do
if options.nil?
@response.rendered[:template].blank?
else
rendered.to_s.match(options)
end
end
when Hash
if expected_partial = options[:partial]
partials = @response.rendered[:partials]
if expected_count = options[:count]
found = partials.detect { |p, _| p.to_s.match(expected_partial) }
actual_count = found.nil? ? 0 : found.second
msg = build_message(message,
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
expected_partial, expected_count, actual_count)
assert(actual_count == expected_count.to_i, msg)
else
msg = build_message(message,
"expecting partial <?> but action rendered <?>",
options[:partial], partials.keys)
assert(partials.keys.any? { |p| p.to_s.match(expected_partial) }, msg)
end
else
rendered.to_s.match(expected)
assert @response.rendered[:partials].empty?,
"Expected no partials to be rendered"
end
end
end
end

private

# Proxy to to_param if the object will respond to it.
def parameterize(value)
value.respond_to?(:to_param) ? value.to_param : value
Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_controller/test_process.rb
Expand Up @@ -221,8 +221,8 @@ def redirect_url_match?( pattern )

# Returns the template of the file which was used to
# render this response (or nil)
def rendered_template
template.instance_variable_get(:@_first_render)
def rendered
template.instance_variable_get(:@_rendered)
end

# A shortcut to the flash. Returns an empty hash if no session flash exists.
Expand Down
5 changes: 0 additions & 5 deletions actionpack/lib/action_view/renderable.rb
Expand Up @@ -28,11 +28,6 @@ def render(view, local_assigns = {})
stack = view.instance_variable_get(:@_render_stack)
stack.push(self)

# This is only used for TestResponse to set rendered_template
unless is_a?(InlineTemplate) || view.instance_variable_get(:@_first_render)
view.instance_variable_set(:@_first_render, self)
end

view.send(:_evaluate_assigns_and_ivars)
view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)

Expand Down
20 changes: 20 additions & 0 deletions actionpack/lib/action_view/test_case.rb
@@ -1,4 +1,24 @@
module ActionView
class Base
alias_method :initialize_without_template_tracking, :initialize
def initialize(*args)
@_rendered = { :template => nil, :partials => Hash.new(0) }
initialize_without_template_tracking(*args)
end
end

module Renderable
alias_method :render_without_template_tracking, :render
def render(view, local_assigns = {})
if respond_to?(:path) && !is_a?(InlineTemplate)
rendered = view.instance_variable_get(:@_rendered)
rendered[:partials][self] += 1 if is_a?(RenderablePartial)
rendered[:template] ||= self
end
render_without_template_tracking(view, local_assigns)
end
end

class TestCase < ActiveSupport::TestCase
include ActionController::TestCase::Assertions

Expand Down
6 changes: 3 additions & 3 deletions actionpack/test/controller/action_pack_assertions_test.rb
Expand Up @@ -326,11 +326,11 @@ def test_flash_have_nots
# check if we were rendered by a file-based template?
def test_rendered_action
process :nothing
assert_nil @response.rendered_template
assert_nil @response.rendered[:template]

process :hello_world
assert @response.rendered_template
assert 'hello_world', @response.rendered_template.to_s
assert @response.rendered[:template]
assert 'hello_world', @response.rendered[:template].to_s
end

# check the redirection location
Expand Down
7 changes: 7 additions & 0 deletions actionpack/test/controller/render_test.rb
Expand Up @@ -1310,21 +1310,28 @@ def test_partial_collection_with_locals
def test_partial_collection_with_spacer
get :partial_collection_with_spacer
assert_equal "Hello: davidonly partialHello: mary", @response.body
assert_template :partial => 'test/_partial_only'
assert_template :partial => '_customer'
end

def test_partial_collection_shorthand_with_locals
get :partial_collection_shorthand_with_locals
assert_equal "Bonjour: davidBonjour: mary", @response.body
assert_template :partial => 'customers/_customer', :count => 2
assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0
end

def test_partial_collection_shorthand_with_different_types_of_records
get :partial_collection_shorthand_with_different_types_of_records
assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
assert_template :partial => 'good_customers/_good_customer', :count => 3
assert_template :partial => 'bad_customers/_bad_customer', :count => 3
end

def test_empty_partial_collection
get :empty_partial_collection
assert_equal " ", @response.body
assert_template :partial => false
end

def test_partial_with_hash_object
Expand Down

0 comments on commit 49306cc

Please sign in to comment.