mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
more refactorings
git-svn-id: https://svn.thoughtbot.com/plugins/shoulda/trunk@139 7bbfaf0e-4d1d-0410-9690-a8bb5f8ef2aa
This commit is contained in:
parent
6108062ffa
commit
9b6dac2b98
12 changed files with 256 additions and 42 deletions
6
Rakefile
6
Rakefile
|
@ -2,10 +2,14 @@ require 'rake'
|
||||||
require 'rake/testtask'
|
require 'rake/testtask'
|
||||||
require 'rake/rdoctask'
|
require 'rake/rdoctask'
|
||||||
|
|
||||||
|
require 'lib/tasks/list_tests.rb'
|
||||||
|
|
||||||
|
# Test::Unit::UI::VERBOSE
|
||||||
|
|
||||||
Rake::TestTask.new do |t|
|
Rake::TestTask.new do |t|
|
||||||
t.libs << 'lib'
|
t.libs << 'lib'
|
||||||
t.pattern = 'test/{unit,functional,other}/**/*_test.rb'
|
t.pattern = 'test/{unit,functional,other}/**/*_test.rb'
|
||||||
t.verbose = true
|
t.verbose = false
|
||||||
end
|
end
|
||||||
|
|
||||||
Rake::RDocTask.new { |rdoc|
|
Rake::RDocTask.new { |rdoc|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
$LOAD_PATH << File.join(File.dirname(__FILE__), 'controller_tests')
|
# $LOAD_PATH << File.join(File.dirname(__FILE__), 'controller_tests')
|
||||||
require 'private_helpers'
|
require 'shoulda/private_helpers'
|
||||||
require 'active_record_helpers'
|
require 'shoulda/active_record_helpers'
|
||||||
require 'controller_tests'
|
require 'shoulda/controller_tests/controller_tests.rb'
|
||||||
require 'context'
|
require 'shoulda/context'
|
||||||
require 'general'
|
require 'shoulda/general'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
config_file = "shoulda.conf"
|
config_file = "shoulda.conf"
|
||||||
|
@ -16,7 +16,7 @@ module Test # :nodoc:
|
||||||
module Unit # :nodoc:
|
module Unit # :nodoc:
|
||||||
class TestCase # :nodoc:
|
class TestCase # :nodoc:
|
||||||
|
|
||||||
include ThoughtBot::Shoulda::ControllerTests
|
include ThoughtBot::Shoulda::Controller
|
||||||
include ThoughtBot::Shoulda::General
|
include ThoughtBot::Shoulda::General
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
|
@ -2,13 +2,13 @@ module ThoughtBot # :nodoc:
|
||||||
module Shoulda # :nodoc:
|
module Shoulda # :nodoc:
|
||||||
# = Macro test helpers for your controllers
|
# = Macro test helpers for your controllers
|
||||||
#
|
#
|
||||||
module ControllerTests
|
module Controller
|
||||||
def self.included(other) # :nodoc:
|
def self.included(other) # :nodoc:
|
||||||
other.class_eval do
|
other.class_eval do
|
||||||
extend ThoughtBot::Shoulda::ControllerTests::ClassMethods
|
extend ThoughtBot::Shoulda::Controller::ClassMethods
|
||||||
include ThoughtBot::Shoulda::ControllerTests::InstanceMethods
|
include ThoughtBot::Shoulda::Controller::InstanceMethods
|
||||||
ThoughtBot::Shoulda::ControllerTests::ClassMethods::VALID_FORMATS.each do |format|
|
ThoughtBot::Shoulda::Controller::ClassMethods::VALID_FORMATS.each do |format|
|
||||||
include "ThoughtBot::Shoulda::ControllerTests::#{format.to_s.upcase}".constantize
|
include "ThoughtBot::Shoulda::Controller::#{format.to_s.upcase}".constantize
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -16,7 +16,7 @@ module ThoughtBot # :nodoc:
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
# Formats tested by #should_be_restful. Defaults to [:html, :xml]
|
# Formats tested by #should_be_restful. Defaults to [:html, :xml]
|
||||||
VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
|
VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
|
||||||
VALID_FORMATS.each {|f| require "formats/#{f}.rb"}
|
VALID_FORMATS.each {|f| require "shoulda/controller_tests/formats/#{f}.rb"}
|
||||||
|
|
||||||
# Actions tested by #should_be_restful
|
# Actions tested by #should_be_restful
|
||||||
VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
|
VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
|
||||||
|
@ -95,10 +95,10 @@ module ThoughtBot # :nodoc:
|
||||||
@parent ||= []
|
@parent ||= []
|
||||||
@parent = [@parent] unless @parent.is_a? Array
|
@parent = [@parent] unless @parent.is_a? Array
|
||||||
|
|
||||||
singular_args = @parent.map {|n| "record.#{n}"}
|
singular_args = @parent.map {|n| "@#{object}.#{n}"}
|
||||||
@destroy.redirect ||= "#{@object.pluralize}_url(#{singular_args.join(', ')})"
|
@destroy.redirect ||= "#{@object.pluralize}_url(#{singular_args.join(', ')})"
|
||||||
|
|
||||||
singular_args << 'record'
|
singular_args << "@#{object}"
|
||||||
@create.redirect ||= "#{@object}_url(#{singular_args.join(', ')})"
|
@create.redirect ||= "#{@object}_url(#{singular_args.join(', ')})"
|
||||||
@update.redirect ||= "#{@object}_url(#{singular_args.join(', ')})"
|
@update.redirect ||= "#{@object}_url(#{singular_args.join(', ')})"
|
||||||
@denied.redirect ||= "new_session_url"
|
@denied.redirect ||= "new_session_url"
|
||||||
|
@ -187,18 +187,35 @@ module ThoughtBot # :nodoc:
|
||||||
assert_template template.to_s
|
assert_template template.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def should_redirect_to(url)
|
||||||
|
should "redirect to #{url}" do
|
||||||
|
instantiate_variables_from_assigns do
|
||||||
|
assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
# Asserts that the controller's response was 'application/xml'
|
|
||||||
def assert_xml_response
|
|
||||||
assert_equal "application/xml; charset=utf-8", @response.headers['Content-Type'], "Body: #{@response.body.first(100)} ..."
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def instantiate_variables_from_assigns(*names, &blk)
|
||||||
|
old = {}
|
||||||
|
names = assigns.keys if names.empty?
|
||||||
|
names.each do |name|
|
||||||
|
old[name] = instance_variable_get("@#{name}")
|
||||||
|
instance_variable_set("@#{name}", assigns(name.to_sym))
|
||||||
|
end
|
||||||
|
blk.call
|
||||||
|
names.each do |name|
|
||||||
|
instance_variable_set("@#{name}", old[name])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_existing_record(res) # :nodoc:
|
def get_existing_record(res) # :nodoc:
|
||||||
returning(instance_variable_get "@#{res.object}") do |record|
|
returning(instance_variable_get("@#{res.object}")) do |record|
|
||||||
assert(record, "This test requires you to set @#{res.object} in your setup block")
|
assert(record, "This test requires you to set @#{res.object} in your setup block")
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,10 +1,10 @@
|
||||||
module ThoughtBot # :nodoc:
|
module ThoughtBot # :nodoc:
|
||||||
module Shoulda # :nodoc:
|
module Shoulda # :nodoc:
|
||||||
module ControllerTests # :nodoc:
|
module Controller # :nodoc:
|
||||||
module HTML # :nodoc: all
|
module HTML # :nodoc: all
|
||||||
def self.included(other)
|
def self.included(other)
|
||||||
other.class_eval do
|
other.class_eval do
|
||||||
extend ThoughtBot::Shoulda::ControllerTests::HTML::ClassMethods
|
extend ThoughtBot::Shoulda::Controller::HTML::ClassMethods
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,13 +115,8 @@ module ThoughtBot # :nodoc:
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
should_set_the_flash_to res.destroy.flash
|
should_set_the_flash_to res.destroy.flash
|
||||||
|
should_redirect_to res.destroy.redirect
|
||||||
|
|
||||||
should "redirect to #{res.destroy.redirect}" do
|
|
||||||
record = @record
|
|
||||||
assert_redirected_to eval(res.destroy.redirect, self.send(:binding), __FILE__, __LINE__),
|
|
||||||
"Flash: #{flash.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
should "destroy record" do
|
should "destroy record" do
|
||||||
assert_raises(::ActiveRecord::RecordNotFound) { @record.reload }
|
assert_raises(::ActiveRecord::RecordNotFound) { @record.reload }
|
||||||
end
|
end
|
||||||
|
@ -147,15 +142,11 @@ module ThoughtBot # :nodoc:
|
||||||
else
|
else
|
||||||
should_assign_to res.object
|
should_assign_to res.object
|
||||||
should_set_the_flash_to res.create.flash
|
should_set_the_flash_to res.create.flash
|
||||||
|
should_redirect_to res.create.redirect
|
||||||
|
|
||||||
should "not have errors on @#{res.object}" do
|
should "not have errors on @#{res.object}" do
|
||||||
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
||||||
end
|
end
|
||||||
|
|
||||||
should "redirect to #{res.create.redirect}" do
|
|
||||||
record = assigns(res.object)
|
|
||||||
assert_redirected_to eval(res.create.redirect, self.send(:binding), __FILE__, __LINE__)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -178,16 +169,14 @@ module ThoughtBot # :nodoc:
|
||||||
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
||||||
end
|
end
|
||||||
|
|
||||||
should "redirect to #{res.update.redirect}" do
|
should_redirect_to res.update.redirect
|
||||||
record = assigns(res.object)
|
|
||||||
assert_redirected_to eval(res.update.redirect, self.send(:binding), __FILE__, __LINE__)
|
|
||||||
end
|
|
||||||
|
|
||||||
should_set_the_flash_to(res.update.flash)
|
should_set_the_flash_to(res.update.flash)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def should_deny_html_request(res)
|
def should_deny_html_request(res)
|
||||||
should "be denied" do
|
should "be denied" do
|
||||||
assert_html_denied(res)
|
assert_html_denied(res)
|
166
lib/shoulda/controller_tests/formats/xml.rb
Normal file
166
lib/shoulda/controller_tests/formats/xml.rb
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
module ThoughtBot # :nodoc:
|
||||||
|
module Shoulda # :nodoc:
|
||||||
|
module Controller # :nodoc:
|
||||||
|
module XML # :nodoc:
|
||||||
|
def self.included(other)
|
||||||
|
other.class_eval do
|
||||||
|
extend ThoughtBot::Shoulda::Controller::XML::ClassMethods
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
# Macro that creates a test asserting that the controller responded with an XML content-type
|
||||||
|
def should_respond_with_xml
|
||||||
|
should "have ContentType set to 'application/xml'" do
|
||||||
|
assert_xml_response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def make_show_xml_tests(res)
|
||||||
|
context "on GET to :show as xml" do
|
||||||
|
setup do
|
||||||
|
request_xml
|
||||||
|
record = get_existing_record(res)
|
||||||
|
parent_params = make_parent_params(res, record)
|
||||||
|
get :show, parent_params.merge({ res.identifier => record.to_param })
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.denied.actions.include?(:show)
|
||||||
|
should_not_assign_to res.object
|
||||||
|
should_deny_xml_request(res)
|
||||||
|
else
|
||||||
|
should_assign_to res.object
|
||||||
|
should_respond_with :success
|
||||||
|
should_respond_with_xml
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_edit_xml_tests(res)
|
||||||
|
# XML doesn't need an :edit action
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_new_xml_tests(res)
|
||||||
|
# XML doesn't need a :new action
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_index_xml_tests(res)
|
||||||
|
context "on GET to :index as xml" do
|
||||||
|
setup do
|
||||||
|
request_xml
|
||||||
|
parent_params = make_parent_params(res)
|
||||||
|
get(:index, parent_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.denied.actions.include?(:index)
|
||||||
|
should_not_assign_to res.object.to_s.pluralize
|
||||||
|
should_deny_xml_request(res)
|
||||||
|
else
|
||||||
|
should_respond_with :success
|
||||||
|
should_respond_with_xml
|
||||||
|
should_assign_to res.object.to_s.pluralize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_destroy_xml_tests(res)
|
||||||
|
context "on DELETE to :destroy as xml" do
|
||||||
|
setup do
|
||||||
|
request_xml
|
||||||
|
@record = get_existing_record(res)
|
||||||
|
parent_params = make_parent_params(res, @record)
|
||||||
|
delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.denied.actions.include?(:destroy)
|
||||||
|
should_deny_xml_request(res)
|
||||||
|
|
||||||
|
should "not destroy record" do
|
||||||
|
assert @record.reload
|
||||||
|
end
|
||||||
|
else
|
||||||
|
should "destroy record" do
|
||||||
|
assert_raises(::ActiveRecord::RecordNotFound) { @record.reload }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_create_xml_tests(res)
|
||||||
|
context "on POST to :create as xml" do
|
||||||
|
setup do
|
||||||
|
request_xml
|
||||||
|
parent_params = make_parent_params(res)
|
||||||
|
@count = res.klass.count
|
||||||
|
post :create, parent_params.merge(res.object => res.create.params)
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.denied.actions.include?(:create)
|
||||||
|
should_deny_xml_request(res)
|
||||||
|
should_not_assign_to res.object
|
||||||
|
|
||||||
|
should "not create new record" do
|
||||||
|
assert_equal @count, res.klass.count
|
||||||
|
end
|
||||||
|
else
|
||||||
|
should_assign_to res.object
|
||||||
|
|
||||||
|
should "not have errors on @#{res.object}" do
|
||||||
|
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_update_xml_tests(res)
|
||||||
|
context "on PUT to :update as xml" do
|
||||||
|
setup do
|
||||||
|
request_xml
|
||||||
|
@record = get_existing_record(res)
|
||||||
|
parent_params = make_parent_params(res, @record)
|
||||||
|
put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.denied.actions.include?(:update)
|
||||||
|
should_not_assign_to res.object
|
||||||
|
should_deny_xml_request(res)
|
||||||
|
else
|
||||||
|
should_assign_to res.object
|
||||||
|
|
||||||
|
should "not have errors on @#{res.object}" do
|
||||||
|
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def should_deny_xml_request(res)
|
||||||
|
should "be denied" do
|
||||||
|
assert_xml_denied(res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_xml_denied(res)
|
||||||
|
flunk "what happens on a permission denied via xml?"
|
||||||
|
# assert_redirected_to eval(res.denied.redirect, self.send(:binding), __FILE__, __LINE__),
|
||||||
|
# "Flash: #{flash.inspect}"
|
||||||
|
# assert_contains(flash.values, res.denied.flash)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the next request's format to 'application/xml'
|
||||||
|
def request_xml
|
||||||
|
@request.accept = "application/xml"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Asserts that the controller's response was 'application/xml'
|
||||||
|
def assert_xml_response
|
||||||
|
assert_equal "application/xml; charset=utf-8", @response.headers['Content-Type'], "Body: #{@response.body.first(100)} ..."
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
38
lib/tasks/list_tests.rb
Normal file
38
lib/tasks/list_tests.rb
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
namespace :test do
|
||||||
|
desc "List the names of the test methods in a specification like format"
|
||||||
|
task :list do
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rubygems'
|
||||||
|
require 'active_support'
|
||||||
|
|
||||||
|
# bug in test unit. Set to true to stop from running.
|
||||||
|
Test::Unit.run = true
|
||||||
|
|
||||||
|
test_files = Dir.glob(File.join('test', '**', '*_test.rb'))
|
||||||
|
test_files.each do |file|
|
||||||
|
load file
|
||||||
|
klass = File.basename(file, '.rb').classify.constantize
|
||||||
|
# klass.run = false
|
||||||
|
|
||||||
|
puts
|
||||||
|
puts "#{klass.name.gsub(/Test$/, '')}"
|
||||||
|
test_methods = klass.instance_methods.grep(/^test/).sort
|
||||||
|
|
||||||
|
method_hash = test_methods.inject({}) do |h, name|
|
||||||
|
header = name.gsub(/^test: (.*)should.*$/, '\1')
|
||||||
|
test = name.gsub(/^test:.*should (.*)$/, '\1')
|
||||||
|
h[header] ||= []
|
||||||
|
h[header] << test
|
||||||
|
h
|
||||||
|
end
|
||||||
|
|
||||||
|
method_hash.keys.sort.each do |header|
|
||||||
|
puts " #{header.chomp} should"
|
||||||
|
method_hash[header].each do |test|
|
||||||
|
puts " - #{test}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,7 +20,7 @@ class UsersControllerTest < Test::Unit::TestCase
|
||||||
resource.object = :user
|
resource.object = :user
|
||||||
resource.parent = []
|
resource.parent = []
|
||||||
resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
|
resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
|
||||||
resource.formats = [:html]
|
resource.formats = [:html, :xml]
|
||||||
|
|
||||||
# resource.denied.actions = [:show]
|
# resource.denied.actions = [:show]
|
||||||
# resource.denied.redirect = 'users_url'
|
# resource.denied.redirect = 'users_url'
|
||||||
|
@ -28,8 +28,8 @@ class UsersControllerTest < Test::Unit::TestCase
|
||||||
resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
|
resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
|
||||||
resource.update.params = { :name => "sue" }
|
resource.update.params = { :name => "sue" }
|
||||||
|
|
||||||
resource.create.redirect = "user_url(record)"
|
resource.create.redirect = "user_url(@user)"
|
||||||
resource.update.redirect = "user_url(record)"
|
resource.update.redirect = "user_url(@user)"
|
||||||
resource.destroy.redirect = "users_url"
|
resource.destroy.redirect = "users_url"
|
||||||
|
|
||||||
resource.create.flash = /created/i
|
resource.create.flash = /created/i
|
||||||
|
|
Loading…
Reference in a new issue