Module: Spec::Rails::Matchers
- Included in:
- ActiveSupport::TestCase
- Defined in:
- lib/spec/rails/matchers.rb,
lib/spec/rails/matchers/route_to.rb,
lib/spec/rails/matchers/have_text.rb,
lib/spec/rails/matchers/ar_be_valid.rb,
lib/spec/rails/matchers/redirect_to.rb,
lib/spec/rails/matchers/include_text.rb,
lib/spec/rails/matchers/assert_select.rb,
lib/spec/rails/matchers/render_template.rb
Overview
Spec::Rails::Expectations::Matchers provides several expectation matchers intended to work with Rails components like models and responses. For example:
response.should redirect_to("some/url") #redirect_to(url) is the matcher.
In addition to those you see below, the arbitrary predicate feature of RSpec makes the following available as well:
response.should be_success #passes if response.success?
response.should be_redirect #passes if response.redirect?
Note that many of these matchers are part of a wrapper of assert_select
, so the documentation comes straight from that with some slight modifications. assert_select
is a Test::Unit extension originally contributed to the Rails community as a plugin by Assaf Arkin and eventually shipped as part of Rails.
For more info on assert_select
, see the relevant Rails documentation.
Defined Under Namespace
Classes: AssertSelect, BeRoutable, HaveText, IncludeText, PathDecomposer, RedirectTo, RenderTemplate, RouteTo
Constant Summary collapse
- USAGE =
ArgumentError.new( 'usage: { :method => "path" }.should route_to( :controller => "controller", :action => "action", [ args ] )' )
Instance Method Summary collapse
-
#be_routable ⇒ Object
(also: #be_routeable)
:call-seq: { “path” }.should_not be_routable # assumes GET { :get => “path” }.should_not be_routable { :put => “path” }.should_not be_routable.
-
#be_valid ⇒ Object
:call-seq: response.should be_valid response.should_not be_valid.
-
#have_rjs(*args, &block) ⇒ Object
:call-seq: response.should have_rjs(*args, &block).
-
#have_tag(*args, &block) ⇒ Object
:call-seq: response.should have_tag(*args, &block) string.should have_tag(*args, &block).
-
#have_text(text) ⇒ Object
:call-seq: response.should have_text(expected) response.should_not have_text(expected).
-
#include_text(text) ⇒ Object
:call-seq: response.should include_text(expected) response.should_not include_text(expected).
-
#redirect_to(opts) ⇒ Object
:call-seq: response.should redirect_to(url) response.should redirect_to(:action => action_name) response.should redirect_to(:controller => controller_name, :action => action_name) response.should_not redirect_to(url) response.should_not redirect_to(:action => action_name) response.should_not redirect_to(:controller => controller_name, :action => action_name).
-
#render_template(path) ⇒ Object
:call-seq: response.should render_template(template) response.should_not render_template(template).
-
#route_to(expected) ⇒ Object
:call-seq: “path”.should route_to(expected) # assumes GET { :get => “path” }.should route_to(expected) { :put => “path” }.should route_to(expected).
-
#send_email(*args, &block) ⇒ Object
:call-seq: response.should send_email(*args, &block).
-
#with_encoded(*args, &block) ⇒ Object
wrapper for assert_select_encoded.
-
#with_tag(*args, &block) ⇒ Object
wrapper for a nested assert_select.
-
#without_tag(*args, &block) ⇒ Object
wrapper for a nested assert_select with false.
Instance Method Details
#be_routable ⇒ Object Also known as: be_routeable
:call-seq:
{ "path" }.should_not be_routable # assumes GET
{ :get => "path" }.should_not be_routable
{ :put => "path" }.should_not be_routable
Uses ActionController::Routing::Routes to verify that the path-and-method cannot be routed to a controller. Since url_for() will always generate a path, even if that path is not routable, the negative test only needs to be performed on the route recognition.
Don’t use this matcher for testing expected routability - use .should route_to( :controller => “controller”, :action => “action” ) instead
Examples
{ :get => ‘/registrations/1/attendees/3/edit’ }.should_not be_routable { :get => ‘/attendees/3/edit’ }.should route_to( …<controller/action>… )
141 142 143 |
# File 'lib/spec/rails/matchers/route_to.rb', line 141 def be_routable BeRoutable.new(self) end |
#be_valid ⇒ Object
:call-seq:
response.should be_valid
response.should_not be_valid
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/spec/rails/matchers/ar_be_valid.rb', line 8 def be_valid ::Spec::Matchers::Matcher.new :be_valid do match do |actual| actual.valid? end do |actual| if actual.respond_to?(:errors) && ActiveRecord::Errors === actual.errors "Expected #{actual.inspect} to be valid, but it was not\nErrors: " + actual.errors..join(", ") else "Expected #{actual.inspect} to be valid" end end end end |
#have_rjs(*args, &block) ⇒ Object
:call-seq:
response.should have_rjs(*args, &block)
wrapper for assert_select_rjs
see documentation for assert_select_rjs at api.rubyonrails.org/
146 147 148 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 146 def have_rjs(*args, &block) AssertSelect.new(:assert_select_rjs, self, *args, &block) end |
#have_tag(*args, &block) ⇒ Object
:call-seq:
response.should have_tag(*args, &block)
string.should have_tag(*args, &block)
wrapper for assert_select with additional support for using css selectors to set expectation on Strings. Use this in helper specs, for example, to set expectations on the results of helper methods. Also allow specification of how the response is parsed using the options :xml and :strict options. By default, these options are set to false.
Examples
# in a controller spec
response.should have_tag("div", "some text")
# to force xml and/or strict parsing of the response
response.should have_tag("div", "some text", :xml => true)
response.should have_tag("div", "some text", :strict => true)
response.should have_tag("div", "some text", :xml => true, :strict => false)
# in a helper spec (person_address_tag is a method in the helper)
person_address_tag.should have_tag("input#person_address")
see documentation for assert_select at api.rubyonrails.org/
112 113 114 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 112 def have_tag(*args, &block) @__current_scope_for_assert_select = AssertSelect.new(:assert_select, self, *args, &block) end |
#have_text(text) ⇒ Object
:call-seq:
response.should have_text(expected)
response.should_not have_text(expected)
Accepts a String or a Regexp, matching a String using == and a Regexp using =~.
If response_or_text has a #body, then that is used as to match against else it uses response_or_text
Use this instead of response.should have_tag()
when you want to match the whole string or whole body
Examples
response.should have_text("This is the expected text")
51 52 53 |
# File 'lib/spec/rails/matchers/have_text.rb', line 51 def have_text(text) HaveText.new(text) end |
#include_text(text) ⇒ Object
:call-seq:
response.should include_text(expected)
response.should_not include_text(expected)
Accepts a String, matching using include?
Use this instead of response.should have_text()
when you either don’t know or don’t care where on the page this text appears.
Examples
response.should include_text("This text will be in the actual string")
48 49 50 |
# File 'lib/spec/rails/matchers/include_text.rb', line 48 def include_text(text) IncludeText.new(text) end |
#redirect_to(opts) ⇒ Object
:call-seq:
response.should redirect_to(url)
response.should redirect_to(:action => action_name)
response.should redirect_to(:controller => controller_name, :action => action_name)
response.should_not redirect_to(url)
response.should_not redirect_to(:action => action_name)
response.should_not redirect_to(:controller => controller_name, :action => action_name)
Passes if the response is a redirect to the url, action or controller/action. Useful in controller specs (integration or isolation mode).
Examples
response.should redirect_to("path/to/action")
response.should redirect_to("http://test.host/path/to/action")
response.should redirect_to(:action => 'list')
120 121 122 |
# File 'lib/spec/rails/matchers/redirect_to.rb', line 120 def redirect_to(opts) RedirectTo.new(request, opts) end |
#render_template(path) ⇒ Object
:call-seq:
response.should render_template(template)
response.should_not render_template(template)
For use in controller code examples (integration or isolation mode).
Passes if the specified template (view file) is rendered by the response. This file can be any view file, including a partial. However if it is a partial it must be rendered directly i.e. you can’t detect that a partial has been rendered as part of a view using render_template. For that you should use a message expectation (mock) instead:
controller.should_receive(:render).with(:partial => 'path/to/partial')
template
can include the controller path. It can also include an optional extension, which you only need to use when there is ambiguity.
Note that partials must be spelled with the preceding underscore.
Examples
response.should render_template('list')
response.should render_template('same_controller/list')
response.should render_template('other_controller/list')
# with extensions
response.should render_template('list.rjs')
response.should render_template('list.haml')
response.should render_template('same_controller/list.rjs')
response.should render_template('other_controller/list.rjs')
# partials
response.should render_template('_a_partial')
response.should render_template('same_controller/_a_partial')
response.should render_template('other_controller/_a_partial')
123 124 125 |
# File 'lib/spec/rails/matchers/render_template.rb', line 123 def render_template(path) RenderTemplate.new(path.to_s, @controller) end |
#route_to(expected) ⇒ Object
:call-seq:
"path".should route_to(expected) # assumes GET
{ :get => "path" }.should route_to(expected)
{ :put => "path" }.should route_to(expected)
Uses ActionController::Routing::Routes to verify that the path-and-method routes to a given set of options. Also verifies route-generation, so that the expected options do generate a pathname consisten with the indicated path/method.
For negative tests, only the route recognition failure can be tested; since route generation via path_to() will always generate a path as requested. Use .should_not be_routable() in this case.
Examples
{ :get => ‘/registrations/1/edit’ }.
should route_to(:controller => 'registrations', :action => 'edit', :id => '1')
{ :put => “/registrations/1” }.should
route_to(:controller => 'registrations', :action => 'update', :id => 1)
{ :post => “/registrations/” }.should
route_to(:controller => 'registrations', :action => 'create')
85 86 87 |
# File 'lib/spec/rails/matchers/route_to.rb', line 85 def route_to(expected) RouteTo.new(expected, self) end |
#send_email(*args, &block) ⇒ Object
:call-seq:
response.should send_email(*args, &block)
wrapper for assert_select_email
see documentation for assert_select_email at api.rubyonrails.org/
156 157 158 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 156 def send_email(*args, &block) AssertSelect.new(:assert_select_email, self, *args, &block) end |
#with_encoded(*args, &block) ⇒ Object
wrapper for assert_select_encoded
see documentation for assert_select_encoded at api.rubyonrails.org/
163 164 165 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 163 def with_encoded(*args, &block) should AssertSelect.new(:assert_select_encoded, self, *args, &block) end |
#with_tag(*args, &block) ⇒ Object
wrapper for a nested assert_select
response.should have_tag("div#form") do
with_tag("input#person_name[name=?]", "person[name]")
end
see documentation for assert_select at api.rubyonrails.org/
123 124 125 126 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 123 def with_tag(*args, &block) args = prepare_args(args, @__current_scope_for_assert_select) @__current_scope_for_assert_select.should have_tag(*args, &block) end |
#without_tag(*args, &block) ⇒ Object
wrapper for a nested assert_select with false
response.should have_tag("div#1") do
without_tag("span", "some text that shouldn't be there")
end
see documentation for assert_select at api.rubyonrails.org/
135 136 137 138 |
# File 'lib/spec/rails/matchers/assert_select.rb', line 135 def without_tag(*args, &block) args = prepare_args(args, @__current_scope_for_assert_select) @__current_scope_for_assert_select.should_not have_tag(*args, &block) end |