added rspec-rails for view method specs

This commit is contained in:
Adam Meehan 2008-07-07 15:16:30 +10:00
parent 494f3bdef4
commit 771f42f076
6 changed files with 418 additions and 0 deletions

View File

@ -0,0 +1,31 @@
====================================================================
== RSpec
Copyright (c) 2005-2007 The RSpec Development Team
====================================================================
== ARTS
Copyright (c) 2006 Kevin Clark, Jake Howerton
====================================================================
== ZenTest
Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
====================================================================
== AssertSelect
Copyright (c) 2006 Assaf Arkin
====================================================================
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,130 @@
# This is a wrapper of assert_select for rspec.
module Spec # :nodoc:
module Rails
module Matchers
class AssertSelect #:nodoc:
def initialize(assertion, spec_scope, *args, &block)
@assertion = assertion
@spec_scope = spec_scope
@args = args
@block = block
end
def matches?(response_or_text, &block)
if ActionController::TestResponse === response_or_text and
response_or_text.headers.key?('Content-Type') and
response_or_text.headers['Content-Type'].to_sym == :xml
@args.unshift(HTML::Document.new(response_or_text.body, false, true).root)
elsif String === response_or_text
@args.unshift(HTML::Document.new(response_or_text).root)
end
@block = block if block
begin
@spec_scope.send(@assertion, *@args, &@block)
rescue ::Test::Unit::AssertionFailedError => @error
end
@error.nil?
end
def failure_message; @error.message; end
def negative_failure_message; "should not #{description}, but did"; end
def description
{
:assert_select => "have tag#{format_args(*@args)}",
:assert_select_email => "send email#{format_args(*@args)}",
}[@assertion]
end
private
def format_args(*args)
return "" if args.empty?
return "(#{arg_list(*args)})"
end
def arg_list(*args)
args.collect do |arg|
arg.respond_to?(:description) ? arg.description : arg.inspect
end.join(", ")
end
end
# :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.
#
# == Examples
#
# # in a controller spec
# response.should have_tag("div", "some text")
#
# # 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 http://api.rubyonrails.org/
def have_tag(*args, &block)
AssertSelect.new(:assert_select, self, *args, &block)
end
# 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 http://api.rubyonrails.org/
def with_tag(*args, &block)
should have_tag(*args, &block)
end
# 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 http://api.rubyonrails.org/
def without_tag(*args, &block)
should_not have_tag(*args, &block)
end
# :call-seq:
# response.should have_rjs(*args, &block)
#
# wrapper for assert_select_rjs
#
# see documentation for assert_select_rjs at http://api.rubyonrails.org/
def have_rjs(*args, &block)
AssertSelect.new(:assert_select_rjs, self, *args, &block)
end
# :call-seq:
# response.should send_email(*args, &block)
#
# wrapper for assert_select_email
#
# see documentation for assert_select_email at http://api.rubyonrails.org/
def send_email(*args, &block)
AssertSelect.new(:assert_select_email, self, *args, &block)
end
# wrapper for assert_select_encoded
#
# see documentation for assert_select_encoded at http://api.rubyonrails.org/
def with_encoded(*args, &block)
should AssertSelect.new(:assert_select_encoded, self, *args, &block)
end
end
end
end

View File

@ -0,0 +1,59 @@
module Spec
module Rails
module Example
class FunctionalExampleGroup < RailsExampleGroup
include ActionController::TestProcess
include ActionController::Assertions
attr_reader :request, :response
before(:each) do
@controller_class = Object.path2class @controller_class_name
raise "Can't determine controller class for #{@controller_class_name}" if @controller_class.nil?
@controller = @controller_class.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@response.session = @request.session
end
def params
request.parameters
end
def flash
response.flash
end
def session
response.session
end
# :call-seq:
# assigns()
#
# Hash of instance variables to values that are made available to
# views. == Examples
#
# #in thing_controller.rb
# def new
# @thing = Thing.new
# end
#
# #in thing_controller_spec
# get 'new'
# assigns[:registration].should == Thing.new
#--
# NOTE - Even though docs only use assigns[:key] format, this supports
# assigns(:key) in order to avoid breaking old specs.
#++
def assigns(key = nil)
if key.nil?
_assigns_hash_proxy
else
_assigns_hash_proxy[key]
end
end
end
end
end
end

View File

@ -0,0 +1,164 @@
module Spec
module Rails
module Example
# Helper Specs live in $RAILS_ROOT/spec/helpers/.
#
# Helper Specs use Spec::Rails::Example::HelperExampleGroup, which allows you to
# include your Helper directly in the context and write specs directly
# against its methods.
#
# HelperExampleGroup also includes the standard lot of ActionView::Helpers in case your
# helpers rely on any of those.
#
# == Example
#
# class ThingHelper
# def number_of_things
# Thing.count
# end
# end
#
# describe "ThingHelper example_group" do
# include ThingHelper
# it "should tell you the number of things" do
# Thing.should_receive(:count).and_return(37)
# number_of_things.should == 37
# end
# end
class HelperExampleGroup < FunctionalExampleGroup
class HelperObject < ActionView::Base
def protect_against_forgery?
false
end
def session=(session)
@session = session
end
def request=(request)
@request = request
end
def flash=(flash)
@flash = flash
end
def params=(params)
@params = params
end
def controller=(controller)
@controller = controller
end
private
attr_reader :session, :request, :flash, :params, :controller
end
class << self
# The helper name....
def helper_name(name=nil)
@helper_being_described = "#{name}_helper".camelize.constantize
send :include, @helper_being_described
end
def helper
@helper_object ||= returning HelperObject.new do |helper_object|
if @helper_being_described.nil?
if described_type.class == Module
helper_object.extend described_type
end
else
helper_object.extend @helper_being_described
end
end
end
end
# Returns an instance of ActionView::Base with the helper being spec'd
# included.
#
# == Example
#
# describe PersonHelper do
# it "should write a link to person with the name" do
# assigns[:person] = mock_model(Person, :full_name => "Full Name", :id => 37, :new_record? => false)
# helper.link_to_person.should == %{<a href="/people/37">Full Name</a>}
# end
# end
#
# module PersonHelper
# def link_to_person
# link_to person.full_name, url_for(person)
# end
# end
#
def helper
self.class.helper
end
# Reverse the load order so that custom helpers which are defined last
# are also loaded last.
ActionView::Base.included_modules.reverse.each do |mod|
include mod if mod.parents.include?(ActionView::Helpers)
end
before(:all) do
@controller_class_name = 'Spec::Rails::Example::HelperExampleGroupController'
end
before(:each) do
@controller.request = @request
@controller.url = ActionController::UrlRewriter.new @request, {} # url_for
@flash = ActionController::Flash::FlashHash.new
session['flash'] = @flash
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
helper.session = session
helper.request = @request
helper.flash = flash
helper.params = params
helper.controller = @controller
end
def flash
@flash
end
def eval_erb(text)
erb_args = [text]
if helper.respond_to?(:output_buffer)
erb_args += [nil, nil, '@output_buffer']
end
helper.instance_eval do
ERB.new(*erb_args).result(binding)
end
end
# TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
# When that is done, remove this method
def protect_against_forgery?
false
end
Spec::Example::ExampleGroupFactory.register(:helper, self)
protected
def _assigns_hash_proxy
@_assigns_hash_proxy ||= AssignsHashProxy.new helper
end
end
class HelperExampleGroupController < ApplicationController #:nodoc:
attr_accessor :request, :url
# Re-raise errors
def rescue_action(e); raise e; end
end
end
end
end

View File

@ -0,0 +1,5 @@
class Object # :nodoc:
def self.path2class(klassname)
klassname.split('::').inject(Object) { |k,n| k.const_get n }
end
end

View File

@ -0,0 +1,29 @@
require 'spec/interop/test'
if ActionView::Base.respond_to?(:cache_template_extension)
ActionView::Base.cache_template_extensions = false
end
module Spec
module Rails
module Example
class RailsExampleGroup < Test::Unit::TestCase
# Rails >= r8570 uses setup/teardown_fixtures explicitly
before(:each) do
setup_fixtures if self.respond_to?(:setup_fixtures)
end
after(:each) do
teardown_fixtures if self.respond_to?(:teardown_fixtures)
end
include Spec::Rails::Matchers
include Spec::Rails::Mocks
Spec::Example::ExampleGroupFactory.default(self)
end
end
end
end