module ThoughtBot::Shoulda::Controller::Macros
def should_assign_to(*names)
should_assign_to :user, :class => User
should_assign_to :user, :posts
Example:
the instance variable being checked.
* :equals - A string which is evaluated and compared for equality with
* :class - The expected class of the instance variable being checked.
Options:
each of the named instance variable(s).
Macro that creates a test asserting that the controller assigned to
def should_assign_to(*names) opts = names.extract_options! names.each do |name| test_name = "assign @#{name}" test_name << " as class #{opts[:class]}" if opts[:class] test_name << " which is equal to #{opts[:equals]}" if opts[:equals] should test_name do assigned_value = assigns(name.to_sym) assert assigned_value, "The action isn't assigning to @#{name}" assert_kind_of opts[:class], assigned_value if opts[:class] if opts[:equals] instantiate_variables_from_assigns do expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__) assert_equal expected_value, assigned_value, "Instance variable @#{name} expected to be #{expected_value}" + " but was #{assigned_value}" end end end end end
def should_be_restful(&blk) # :yields: resource
is used to configure the tests for the details of your resources.
The +resource+ parameter passed into the block is a ResourceOptions object, and
"on GET to :show as xml should return
"on GET to :show as xml should respond with success."
"on GET to :show as xml should have ContentType set to 'application/xml'."
"on GET to :show as xml should assign @user."
"on GET to :show should respond with success."
"on GET to :show should render 'show' template."
"on GET to :show should not set the flash."
"on GET to :show should assign @user."
This generates about 40 tests, all of the format:
end
resource.update.params = { :title => "changed" }
resource.create.params = { :title => "first post", :body => 'blah blah blah'}
resource.parent = :user
should_be_restful do |resource|
+edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
The following definition will generate tests for the +index+, +show+, +new+,
Generates a full suite of tests for a restful controller.
information.
http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
DEPRECATED: Please see
def should_be_restful(&blk) # :yields: resource warn "[DEPRECATION] should_be_restful is deprecated. Please see http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more information." resource = ResourceOptions.new blk.call(resource) resource.normalize!(self) resource.formats.each do |format| resource.actions.each do |action| if self.respond_to? :"make_#{action}_#{format}_tests" self.send(:"make_#{action}_#{format}_tests", resource) else should "test #{action} #{format}" do flunk "Test for #{action} as #{format} not implemented" end end end end end
def should_filter_params(*keys)
Example:
is set for the specified keys
Macro that creates a test asserting that filter_parameter_logging
def should_filter_params(*keys) keys.each do |key| should "filter #{key}" do assert @controller.respond_to?(:filter_parameters), "The key #{key} is not filtered" filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s}) assert_equal '[FILTERED]', filtered[key.to_s], "The key #{key} is not filtered" end end end
def should_not_assign_to(*names)
Example:
any of the named instance variable(s).
Macro that creates a test asserting that the controller did not assign to
def should_not_assign_to(*names) names.each do |name| should "not assign to @#{name}" do assert !assigns(name.to_sym), "@#{name} was visible" end end end
def should_not_set_the_flash
Macro that creates a test asserting that the flash is empty. Same as
def should_not_set_the_flash should_set_the_flash_to nil end
def should_redirect_to(url)
should_redirect_to '"/"'
Example:
set by the controller are available to the evaled string.
The given string is evaled to produce the resulting redirect path. All of the instance variables
Macro that creates a test asserting that the controller returned a redirect to the given path.
def should_redirect_to(url) should "redirect to #{url.inspect}" do instantiate_variables_from_assigns do assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__) end end end
def should_render_a_form
def should_render_a_form should "display a form" do assert_select "form", true, "The template doesn't contain a <form> element" end end
def should_render_template(template)
Example:
Macro that creates a test asserting that the controller rendered the given template.
def should_render_template(template) should "render template #{template.inspect}" do assert_template template.to_s end end
def should_render_with_layout(expected_layout = 'application')
Example:
Macro that creates a test asserting that the controller rendered with the given layout.
def should_render_with_layout(expected_layout = 'application') if expected_layout should "render with #{expected_layout} layout" do response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last assert_equal expected_layout, response_layout, "Expected to render with layout #{expected_layout} but was rendered with #{response_layout}" end else should "render without layout" do assert_nil @response.layout, "Expected no layout, but was rendered using #{@response.layout}" end end end
def should_render_without_layout
Macro that creates a test asserting that the controller rendered without a layout.
def should_render_without_layout should_render_with_layout nil end
def should_respond_with(response)
Example:
Macro that creates a test asserting that the controller responded with a 'response' status code.
def should_respond_with(response) should "respond with #{response}" do assert_response response end end
def should_respond_with_content_type(content_type)
should_respond_with_content_type :rss
should_respond_with_content_type 'application/rss+xml'
Example:
Macro that creates a test asserting that the response content type was 'content_type'.
def should_respond_with_content_type(content_type) should "respond with content type of #{content_type}" do content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol if content_type.is_a? Regexp assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}" else assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}" end end end
def should_return_from_session(key, expected)
should_return_from_session :user_id, '@user.id'
Example:
set by the controller are available to the evaled string.
The given string is evaled to produce the resulting redirect path. All of the instance variables
Macro that creates a test asserting that a value returned from the session is correct.
def should_return_from_session(key, expected) should "return the correct value from the session for key #{key}" do instantiate_variables_from_assigns do expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__) assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}" end end end
def should_route(method, path, options)
:action => :show, :id => 1, :user_id => 1
should_route :get, "/users/1/posts/1",
should_route :delete, "/posts/1", :action => :destroy, :id => 1
should_route :put, "/posts/1", :action => :update, :id => 1
should_route :edit, "/posts/1", :action => :show, :id => 1
should_route :get, "/posts/1", :action => :show, :id => 1
should_route :post, "/posts", :action => :create
should_route :get, "/posts/new", :action => :new
should_route :get, "/posts", :controller => :posts, :action => :index
Examples:
+to_param+ is called on the +options+ given.
based on the current test.
If you don't specify a :controller, it will try to guess the controller
given +options+.
+method+ on the given +path+, and asserts that it routes to the
Macro that creates a routing test. It tries to use the given HTTP
def should_route(method, path, options) unless options[:controller] options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize end options[:controller] = options[:controller].to_s options[:action] = options[:action].to_s populated_path = path.dup options.each do |key, value| options[key] = value.to_param if value.respond_to? :to_param populated_path.gsub!(key.inspect, value.to_s) end should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}" should should_name do assert_routing({:method => method, :path => populated_path}, options) end end
def should_set_the_flash_to(val)
should_set_the_flash_to /created/i
should_set_the_flash_to "Thank you for placing this order."
Example:
val can be a String, a Regex, or nil (indicating that the flash should not be set)
Macro that creates a test asserting that the flash contains the given value.
:section: Test macros
def should_set_the_flash_to(val) if val should "have #{val.inspect} in the flash" do assert_contains flash.values, val, ", Flash: #{flash.inspect}" end else should "not set the flash" do assert_equal({}, flash, "Flash was set to:\n#{flash.inspect}") end end end