lib/rspec/rails/matchers/have_rendered.rb
module RSpec
module Rails
module Matchers
# Matcher for template rendering.
module RenderTemplate
# @private
class RenderTemplateMatcher < RSpec::Rails::Matchers::BaseMatcher
def initialize(scope, expected, message = nil)
@expected = Symbol === expected ? expected.to_s : expected
@message = message
@scope = scope
@redirect_is = nil
end
# @api private
def matches?(*)
match_check = match_unless_raises ActiveSupport::TestCase::Assertion do
@scope.assert_template expected, @message
end
check_redirect unless match_check
match_check
end
# Uses normalize_argument_to_redirection to find and format
# the redirect location. normalize_argument_to_redirection is private
# in ActionDispatch::Assertions::ResponseAssertions so we call it
# here using #send. This will keep the error message format consistent
# @api private
def check_redirect
response = @scope.response
return unless response.respond_to?(:redirect?) && response.redirect?
@redirect_is = @scope.send(:normalize_argument_to_redirection, response.location)
end
# @api private
def failure_message
if @redirect_is
rescued_exception.message[/(.*?)( but|$)/, 1] +
" but was a redirect to <#{@redirect_is}>"
else
rescued_exception.message
end
end
# @api private
def failure_message_when_negated
"expected not to render #{expected.inspect}, but did"
end
end
# Delegates to `assert_template`.
#
# @example
# expect(response).to have_rendered("new")
def have_rendered(options, message = nil)
RenderTemplateMatcher.new(self, options, message)
end
alias_method :render_template, :have_rendered
end
end
end
end