mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-19 08:40:12 +01:00
Next step in upgrading Tracks to Rails 2.2. Some highlights:
* Ran rake rails:update * Added old actionwebservice framework * Updated RSpec and RSpec-Rails * Removed asset_packager plugin (not compatible, Scott no longer maintaining), and replaced with bundle_fu. See the bundle_fu README for more info. * Hacks to UJS and ARTS plugins, which are no longer supported. Probably should move off both UJS and RJS. * Hack to flashobject_helper plugin (upgrade to Rails 2.2-compatible version if/when it comes out.) * Hack to skinny-spec plugin, for Rails 2.2 compatibility. Should check for official release. * Hacks to resource_feeder plugin, for Rails 2.2 compatibility. Should check for official release (not likely) or move off it. * Addressed some deprecation warnings. More to come. * My mobile mime type hackery is no longer necessary with new Rails features. Yay! * Updated environment.rb.tmpl with changes TODO: * Restore view specs marked pending * Fix failing integration tests. * Try selenium tests. * Investigate OpenID support. * Address deprecation warnings. * Consider moving parts of environment.rb to initializers * Address annoying config.gem warning about highline gem
This commit is contained in:
parent
6d11ebd1b0
commit
35ae5fc431
394 changed files with 15184 additions and 9936 deletions
|
|
@ -9,6 +9,7 @@ require "spec/rails/example/functional_example_group"
|
|||
require "spec/rails/example/controller_example_group"
|
||||
require "spec/rails/example/helper_example_group"
|
||||
require "spec/rails/example/view_example_group"
|
||||
require "spec/rails/example/cookies_proxy"
|
||||
|
||||
module Spec
|
||||
module Rails
|
||||
|
|
|
|||
|
|
@ -2,27 +2,24 @@ module Spec
|
|||
module Rails
|
||||
module Example
|
||||
class AssignsHashProxy #:nodoc:
|
||||
def initialize(object)
|
||||
@object = object
|
||||
def initialize(example_group, &block)
|
||||
@target = block.call
|
||||
@example_group = example_group
|
||||
end
|
||||
|
||||
def [](ivar)
|
||||
if assigns.include?(ivar.to_s)
|
||||
assigns[ivar.to_s]
|
||||
elsif assigns.include?(ivar)
|
||||
assigns[ivar]
|
||||
else
|
||||
nil
|
||||
end
|
||||
def [](key)
|
||||
return false if assigns[key] == false
|
||||
return false if assigns[key.to_s] == false
|
||||
assigns[key] || assigns[key.to_s] || @target.instance_variable_get("@#{key}")
|
||||
end
|
||||
|
||||
def []=(ivar, val)
|
||||
@object.instance_variable_set "@#{ivar}", val
|
||||
assigns[ivar.to_s] = val
|
||||
def []=(key, val)
|
||||
@target.instance_variable_set("@#{key}", val)
|
||||
end
|
||||
|
||||
def delete(name)
|
||||
assigns.delete(name.to_s)
|
||||
def delete(key)
|
||||
assigns.delete(key.to_s)
|
||||
@target.instance_variable_set("@#{key}", nil)
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
|
|
@ -35,7 +32,7 @@ module Spec
|
|||
|
||||
protected
|
||||
def assigns
|
||||
@object.assigns
|
||||
@example_group.orig_assigns
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ module Spec
|
|||
|
||||
attr_reader :response, :request, :controller
|
||||
|
||||
def initialize(defined_description, &implementation) #:nodoc:
|
||||
def initialize(defined_description, options={}, &implementation) #:nodoc:
|
||||
super
|
||||
controller_class_name = self.class.controller_class_name
|
||||
if controller_class_name
|
||||
|
|
@ -158,7 +158,9 @@ module Spec
|
|||
|
||||
protected
|
||||
def _assigns_hash_proxy
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new @controller
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new self do
|
||||
@response.template
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -183,61 +185,39 @@ module Spec
|
|||
unless integrate_views?
|
||||
if @template.respond_to?(:finder)
|
||||
(class << @template.finder; self; end).class_eval do
|
||||
define_method :file_exists? do
|
||||
true
|
||||
end
|
||||
define_method :file_exists? do; true; end
|
||||
end
|
||||
else
|
||||
(class << @template; self; end).class_eval do
|
||||
define_method :file_exists? do
|
||||
true
|
||||
end
|
||||
define_method :file_exists? do; true; end
|
||||
end
|
||||
end
|
||||
(class << @template; self; end).class_eval do
|
||||
define_method :render_file do |*args|
|
||||
@first_render ||= args[0]
|
||||
@first_render ||= args[0] unless args[0] =~ /^layouts/
|
||||
@_first_render ||= args[0] unless args[0] =~ /^layouts/
|
||||
end
|
||||
|
||||
define_method :_pick_template do |*args|
|
||||
@_first_render ||= args[0] unless args[0] =~ /^layouts/
|
||||
PickedTemplate.new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if matching_message_expectation_exists(options)
|
||||
expect_render_mock_proxy.render(options, &block)
|
||||
render_proxy.render(options, &block)
|
||||
@performed_render = true
|
||||
else
|
||||
unless matching_stub_exists(options)
|
||||
if matching_stub_exists(options)
|
||||
@performed_render = true
|
||||
else
|
||||
super(options, deprecated_status_or_extra_options, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def raise_with_disable_message(old_method, new_method)
|
||||
raise %Q|
|
||||
controller.#{old_method}(:render) has been disabled because it
|
||||
can often produce unexpected results. Instead, you should
|
||||
use the following (before the action):
|
||||
|
||||
controller.#{new_method}(*args)
|
||||
|
||||
See the rdoc for #{new_method} for more information.
|
||||
|
|
||||
end
|
||||
def should_receive(*args)
|
||||
if args[0] == :render
|
||||
raise_with_disable_message("should_receive", "expect_render")
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
def stub!(*args)
|
||||
if args[0] == :render
|
||||
raise_with_disable_message("stub!", "stub_render")
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def response(&block)
|
||||
# NOTE - we're setting @update for the assert_select_spec - kinda weird, huh?
|
||||
@update = block
|
||||
|
|
@ -255,17 +235,22 @@ module Spec
|
|||
end
|
||||
|
||||
def matching_message_expectation_exists(options)
|
||||
expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
|
||||
render_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
|
||||
end
|
||||
|
||||
def matching_stub_exists(options)
|
||||
expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
|
||||
render_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Spec::Example::ExampleGroupFactory.register(:controller, self)
|
||||
end
|
||||
|
||||
class PickedTemplate
|
||||
def render_template(*ignore_args); end
|
||||
def render_partial(*ignore_args); end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
25
vendor/plugins/rspec-rails/lib/spec/rails/example/cookies_proxy.rb
vendored
Normal file
25
vendor/plugins/rspec-rails/lib/spec/rails/example/cookies_proxy.rb
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
require 'action_controller/cookies'
|
||||
|
||||
module Spec
|
||||
module Rails
|
||||
module Example
|
||||
class CookiesProxy
|
||||
def initialize(example)
|
||||
@example = example
|
||||
end
|
||||
|
||||
def[]=(name, value)
|
||||
@example.request.cookies[name.to_s] = CGI::Cookie.new(name.to_s, value)
|
||||
end
|
||||
|
||||
def [](name)
|
||||
@example.response.cookies[name.to_s]
|
||||
end
|
||||
|
||||
def delete(name)
|
||||
@example.response.cookies.delete(name.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -27,6 +27,33 @@ module Spec
|
|||
def session
|
||||
response.session
|
||||
end
|
||||
|
||||
# Overrides the <tt>cookies()</tt> method in
|
||||
# ActionController::TestResponseBehaviour, returning a proxy that
|
||||
# accesses the requests cookies when setting a cookie and the
|
||||
# responses cookies when reading one. This allows you to set and read
|
||||
# cookies in examples using the same API with which you set and read
|
||||
# them in controllers.
|
||||
#
|
||||
# == Examples (Rails >= 1.2.6)
|
||||
#
|
||||
# cookies[:user_id] = '1234'
|
||||
# get :index
|
||||
# assigns[:user].id.should == '1234'
|
||||
#
|
||||
# post :login
|
||||
# cookies[:login].expires.should == 1.week.from_now
|
||||
#
|
||||
# == Examples (Rails >= 2.0.0 only)
|
||||
#
|
||||
# cookies[:user_id] = {:value => '1234', :expires => 1.minute.ago}
|
||||
# get :index
|
||||
# response.should be_redirect
|
||||
def cookies
|
||||
@cookies ||= Spec::Rails::Example::CookiesProxy.new(self)
|
||||
end
|
||||
|
||||
alias_method :orig_assigns, :assigns
|
||||
|
||||
# :call-seq:
|
||||
# assigns()
|
||||
|
|
@ -53,6 +80,7 @@ module Spec
|
|||
_assigns_hash_proxy[key]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -148,7 +148,9 @@ module Spec
|
|||
|
||||
protected
|
||||
def _assigns_hash_proxy
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new helper
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new self do
|
||||
helper
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,11 +11,15 @@ module Spec
|
|||
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)
|
||||
# However, Rails >= r8664 extracted these out to use ActiveSupport::Callbacks.
|
||||
# The latter case is handled at the TestCase level, in interop/testcase.rb
|
||||
unless ActiveSupport.const_defined?(:Callbacks) and self.include?(ActiveSupport::Callbacks)
|
||||
before(:each) do
|
||||
setup_fixtures if self.respond_to?(:setup_fixtures)
|
||||
end
|
||||
after(:each) do
|
||||
teardown_fixtures if self.respond_to?(:teardown_fixtures)
|
||||
end
|
||||
end
|
||||
|
||||
include Spec::Rails::Matchers
|
||||
|
|
|
|||
|
|
@ -3,61 +3,39 @@ require 'spec/mocks/framework'
|
|||
module Spec
|
||||
module Rails
|
||||
module Example
|
||||
# Provides specialized mock-like behaviour for controller and view examples,
|
||||
# allowing you to mock or stub calls to render with specific arguments while
|
||||
# ignoring all other calls.
|
||||
# Extends the #should_receive, #should_not_receive and #stub! methods in rspec's
|
||||
# mocking framework to handle #render calls to controller in controller examples
|
||||
# and template and view examples
|
||||
module RenderObserver
|
||||
|
||||
# Similar to mocking +render+ with the exception that calls to +render+ with
|
||||
# any other options are passed on to the receiver (i.e. controller in
|
||||
# controller examples, template in view examples).
|
||||
#
|
||||
# This is necessary because Rails uses the +render+ method on both
|
||||
# controllers and templates as a dispatcher to render different kinds of
|
||||
# things, sometimes resulting in many calls to the render method within one
|
||||
# request. This approach makes it impossible to use a normal mock object, which
|
||||
# is designed to observe all incoming messages with a given name.
|
||||
#
|
||||
# +expect_render+ is auto-verifying, so failures will be reported without
|
||||
# requiring you to explicitly request verification.
|
||||
#
|
||||
# Also, +expect_render+ uses parts of RSpec's mock expectation framework. Because
|
||||
# it wraps only a subset of the framework, using this will create no conflict with
|
||||
# other mock frameworks if you choose to use them. Additionally, the object returned
|
||||
# by expect_render is an RSpec mock object, which means that you can call any of the
|
||||
# chained methods available in RSpec's mocks.
|
||||
#
|
||||
# == Controller Examples
|
||||
#
|
||||
# controller.expect_render(:partial => 'thing', :object => thing)
|
||||
# controller.expect_render(:partial => 'thing', :collection => things).once
|
||||
#
|
||||
# controller.stub_render(:partial => 'thing', :object => thing)
|
||||
# controller.stub_render(:partial => 'thing', :collection => things).twice
|
||||
#
|
||||
# == View Examples
|
||||
#
|
||||
# template.expect_render(:partial => 'thing', :object => thing)
|
||||
# template.expect_render(:partial => 'thing', :collection => things)
|
||||
#
|
||||
# template.stub_render(:partial => 'thing', :object => thing)
|
||||
# template.stub_render(:partial => 'thing', :collection => things)
|
||||
# DEPRECATED
|
||||
#
|
||||
# Use should_receive(:render).with(opts) instead
|
||||
def expect_render(opts={})
|
||||
warn_deprecation("expect_render", "should_receive")
|
||||
register_verify_after_each
|
||||
expect_render_mock_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts)
|
||||
render_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts)
|
||||
end
|
||||
|
||||
# This is exactly like expect_render, with the exception that the call to render will not
|
||||
# be verified. Use this if you are trying to isolate your example from a complicated render
|
||||
# operation but don't care whether it is called or not.
|
||||
# DEPRECATED
|
||||
#
|
||||
# Use stub!(:render).with(opts) instead
|
||||
def stub_render(opts={})
|
||||
warn_deprecation("stub_render", "stub!")
|
||||
register_verify_after_each
|
||||
expect_render_mock_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts)
|
||||
render_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts)
|
||||
end
|
||||
|
||||
def warn_deprecation(deprecated_method, new_method)
|
||||
Kernel.warn <<-WARNING
|
||||
#{deprecated_method} is deprecated and will be removed from a future version of rspec-rails.
|
||||
|
||||
Please just use object.#{new_method} instead.
|
||||
WARNING
|
||||
end
|
||||
|
||||
def verify_rendered # :nodoc:
|
||||
expect_render_mock_proxy.rspec_verify
|
||||
render_proxy.rspec_verify
|
||||
end
|
||||
|
||||
def unregister_verify_after_each #:nodoc:
|
||||
|
|
@ -65,7 +43,32 @@ module Spec
|
|||
Spec::Example::ExampleGroup.remove_after(:each, &proc)
|
||||
end
|
||||
|
||||
protected
|
||||
def should_receive(*args)
|
||||
if args[0] == :render
|
||||
register_verify_after_each
|
||||
render_proxy.should_receive(:render, :expected_from => caller(1)[0])
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def should_not_receive(*args)
|
||||
if args[0] == :render
|
||||
register_verify_after_each
|
||||
render_proxy.should_not_receive(:render)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def stub!(*args)
|
||||
if args[0] == :render
|
||||
register_verify_after_each
|
||||
render_proxy.stub!(:render, :expected_from => caller(1)[0])
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def verify_rendered_proc #:nodoc:
|
||||
template = self
|
||||
|
|
@ -80,8 +83,8 @@ module Spec
|
|||
Spec::Example::ExampleGroup.after(:each, &proc)
|
||||
end
|
||||
|
||||
def expect_render_mock_proxy #:nodoc:
|
||||
@expect_render_mock_proxy ||= Spec::Mocks::Mock.new("expect_render_mock_proxy")
|
||||
def render_proxy #:nodoc:
|
||||
@render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ module Spec
|
|||
ensure_that_base_view_path_is_not_set_across_example_groups
|
||||
end
|
||||
|
||||
def initialize(defined_description, &implementation) #:nodoc:
|
||||
def initialize(defined_description, options={}, &implementation) #:nodoc:
|
||||
super
|
||||
@controller_class_name = "Spec::Rails::Example::ViewExampleGroupController"
|
||||
end
|
||||
|
|
@ -150,7 +150,9 @@ module Spec
|
|||
|
||||
protected
|
||||
def _assigns_hash_proxy
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new @controller
|
||||
@_assigns_hash_proxy ||= AssignsHashProxy.new self do
|
||||
@response.template
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -172,6 +174,9 @@ module Spec
|
|||
include helper_module
|
||||
end
|
||||
end
|
||||
|
||||
def forget_variables_added_to_assigns
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,15 +10,19 @@ module ActionView #:nodoc:
|
|||
end
|
||||
end
|
||||
end
|
||||
super(partial_path, local_assigns, deprecated_local_assigns)
|
||||
begin
|
||||
super(partial_path, local_assigns, deprecated_local_assigns)
|
||||
rescue ArgumentError # edge rails > 2.1 changed render_partial to accept only one arg
|
||||
super(partial_path)
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :orig_render, :render
|
||||
def render(options = {}, old_local_assigns = {}, &block)
|
||||
if expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
|
||||
expect_render_mock_proxy.render(options)
|
||||
if render_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
|
||||
render_proxy.render(options)
|
||||
else
|
||||
unless expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
|
||||
unless render_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
|
||||
orig_render(options, old_local_assigns, &block)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
14
vendor/plugins/rspec-rails/lib/spec/rails/interop/testcase.rb
vendored
Normal file
14
vendor/plugins/rspec-rails/lib/spec/rails/interop/testcase.rb
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
module Test
|
||||
module Unit
|
||||
class TestCase
|
||||
# Edge rails (r8664) introduces class-wide setup & teardown callbacks for Test::Unit::TestCase.
|
||||
# Make sure these still get run when running TestCases under rspec:
|
||||
prepend_before(:each) do
|
||||
run_callbacks :setup if respond_to?(:run_callbacks)
|
||||
end
|
||||
append_after(:each) do
|
||||
run_callbacks :teardown if respond_to?(:run_callbacks)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
dir = File.dirname(__FILE__)
|
||||
require 'spec/rails/matchers/assert_select'
|
||||
require 'spec/rails/matchers/change'
|
||||
require 'spec/rails/matchers/have_text'
|
||||
require 'spec/rails/matchers/include_text'
|
||||
require 'spec/rails/matchers/redirect_to'
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ module Spec # :nodoc:
|
|||
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'].blank? 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
|
||||
|
|
|
|||
11
vendor/plugins/rspec-rails/lib/spec/rails/matchers/change.rb
vendored
Normal file
11
vendor/plugins/rspec-rails/lib/spec/rails/matchers/change.rb
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
module Spec
|
||||
module Matchers
|
||||
class Change
|
||||
def evaluate_value_proc_with_ensured_evaluation_of_proxy
|
||||
value = evaluate_value_proc_without_ensured_evaluation_of_proxy
|
||||
ActiveRecord::Associations::AssociationProxy === value ? value.dup : value
|
||||
end
|
||||
alias_method_chain :evaluate_value_proc, :ensured_evaluation_of_proxy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -10,10 +10,18 @@ module Spec
|
|||
end
|
||||
|
||||
def matches?(response)
|
||||
@actual = response.rendered_file
|
||||
full_path(@actual) == full_path(@expected)
|
||||
|
||||
if response.respond_to?(:rendered_file)
|
||||
@actual = response.rendered_file
|
||||
else
|
||||
@actual = response.rendered_template.to_s
|
||||
end
|
||||
return false if @actual.blank?
|
||||
given_controller_path, given_file = path_and_file(@actual)
|
||||
expected_controller_path, expected_file = path_and_file(@expected)
|
||||
given_controller_path == expected_controller_path && given_file.match(expected_file)
|
||||
end
|
||||
|
||||
|
||||
def failure_message
|
||||
"expected #{@expected.inspect}, got #{@actual.inspect}"
|
||||
end
|
||||
|
|
@ -27,9 +35,21 @@ module Spec
|
|||
end
|
||||
|
||||
private
|
||||
def full_path(path)
|
||||
return nil if path.nil?
|
||||
path.include?('/') ? path : "#{@controller.class.to_s.underscore.gsub('_controller','')}/#{path}"
|
||||
def path_and_file(path)
|
||||
parts = path.split('/')
|
||||
file = parts.pop
|
||||
controller = parts.empty? ? current_controller_path : parts.join('/')
|
||||
return controller, file
|
||||
end
|
||||
|
||||
def controller_path_from(path)
|
||||
parts = path.split('/')
|
||||
parts.pop
|
||||
parts.join('/')
|
||||
end
|
||||
|
||||
def current_controller_path
|
||||
@controller.class.to_s.underscore.gsub(/_controller$/,'')
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,15 +9,21 @@ module Spec
|
|||
# methods stubbed out. Additional methods may be easily stubbed (via
|
||||
# add_stubs) if +stubs+ is passed.
|
||||
def mock_model(model_class, options_and_stubs = {})
|
||||
id = next_id
|
||||
options_and_stubs.reverse_merge!({
|
||||
id = options_and_stubs[:id] || next_id
|
||||
options_and_stubs = options_and_stubs.reverse_merge({
|
||||
:id => id,
|
||||
:to_param => id.to_s,
|
||||
:new_record? => false,
|
||||
:errors => stub("errors", :count => 0)
|
||||
})
|
||||
m = mock("#{model_class.name}_#{options_and_stubs[:id]}", options_and_stubs)
|
||||
m = mock("#{model_class.name}_#{id}", options_and_stubs)
|
||||
m.send(:__mock_proxy).instance_eval <<-CODE
|
||||
def @target.as_new_record
|
||||
self.stub!(:id).and_return nil
|
||||
self.stub!(:to_param).and_return nil
|
||||
self.stub!(:new_record?).and_return true
|
||||
self
|
||||
end
|
||||
def @target.is_a?(other)
|
||||
#{model_class}.ancestors.include?(other)
|
||||
end
|
||||
|
|
@ -52,24 +58,33 @@ module Spec
|
|||
# stub_model(Model)
|
||||
# stub_model(Model).as_new_record
|
||||
# stub_model(Model, hash_of_stubs)
|
||||
# stub_model(Model, instance_variable_name, hash_of_stubs)
|
||||
#
|
||||
# Creates an instance of +Model+ that is prohibited from accessing the
|
||||
# database. For each key in +hash_of_stubs+, if the model has a
|
||||
# matching attribute (determined by asking it, which it answers based
|
||||
# on schema.rb) are simply assigned the submitted values. If the model
|
||||
# does not have a matching attribute, the key/value pair is assigned
|
||||
# as a stub return value using RSpec's mocking/stubbing framework.
|
||||
# database*. For each key in +hash_of_stubs+, if the model has a
|
||||
# matching attribute (determined by asking it) are simply assigned the
|
||||
# submitted values. If the model does not have a matching attribute, the
|
||||
# key/value pair is assigned as a stub return value using RSpec's
|
||||
# mocking/stubbing framework.
|
||||
#
|
||||
# new_record? is overridden to return the result of id.nil? This means
|
||||
# that by default new_record? will return false. If you want the
|
||||
# object to behave as a new record, sending it +as_new_record+ will
|
||||
# <tt>new_record?</tt> is overridden to return the result of id.nil?
|
||||
# This means that by default new_record? will return false. If you want
|
||||
# the object to behave as a new record, sending it +as_new_record+ will
|
||||
# set the id to nil. You can also explicitly set :id => nil, in which
|
||||
# case new_record? will return true, but using +as_new_record+ makes
|
||||
# the example a bit more descriptive.
|
||||
# case new_record? will return true, but using +as_new_record+ makes the
|
||||
# example a bit more descriptive.
|
||||
#
|
||||
# While you can use stub_model in any example (model, view,
|
||||
# controller, helper), it is especially useful in view examples,
|
||||
# which are inherently more state-based than interaction-based.
|
||||
# While you can use stub_model in any example (model, view, controller,
|
||||
# helper), it is especially useful in view examples, which are
|
||||
# inherently more state-based than interaction-based.
|
||||
#
|
||||
# == Database Independence
|
||||
#
|
||||
# +stub_model+ does not make your examples entirely
|
||||
# database-independent. It does not stop the model class itself from
|
||||
# loading up its columns from the database. It just prevents data access
|
||||
# from the object itself. To completely decouple from the database, take
|
||||
# a look at libraries like unit_record or NullDB.
|
||||
#
|
||||
# == Examples
|
||||
#
|
||||
|
|
@ -77,9 +92,9 @@ module Spec
|
|||
# stub_model(Person).as_new_record
|
||||
# stub_model(Person, :id => 37)
|
||||
# stub_model(Person) do |person|
|
||||
# model.first_name = "David"
|
||||
# person.first_name = "David"
|
||||
# end
|
||||
def stub_model(model_class, stubs = {})
|
||||
def stub_model(model_class, stubs={})
|
||||
stubs = {:id => next_id}.merge(stubs)
|
||||
returning model_class.new do |model|
|
||||
model.id = stubs.delete(:id)
|
||||
|
|
@ -99,7 +114,7 @@ module Spec
|
|||
# - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc)
|
||||
#++
|
||||
# Stubs methods on +object+ (if +object+ is a symbol or string a new mock
|
||||
# with that name will be created). +stubs+ is a Hash of <tt>method=>value</tt>
|
||||
# with that name will be created). +stubs+ is a Hash of +method=>value+
|
||||
def add_stubs(object, stubs = {}) #:nodoc:
|
||||
m = [String, Symbol].index(object.class) ? mock(object.to_s) : object
|
||||
stubs.each {|k,v| m.stub!(k).and_return(v)}
|
||||
|
|
@ -114,4 +129,4 @@ module Spec
|
|||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,15 +40,23 @@ class ActiveRecordSafetyListener
|
|||
include Singleton
|
||||
def scenario_started(*args)
|
||||
if defined?(ActiveRecord::Base)
|
||||
ActiveRecord::Base.send :increment_open_transactions unless Rails::VERSION::STRING == "1.1.6"
|
||||
ActiveRecord::Base.connection.begin_db_transaction
|
||||
if ActiveRecord::Base.connection.respond_to?(:increment_open_transactions)
|
||||
ActiveRecord::Base.connection.increment_open_transactions
|
||||
else
|
||||
ActiveRecord::Base.send :increment_open_transactions
|
||||
end
|
||||
end
|
||||
ActiveRecord::Base.connection.begin_db_transaction
|
||||
end
|
||||
|
||||
def scenario_succeeded(*args)
|
||||
if defined?(ActiveRecord::Base)
|
||||
ActiveRecord::Base.connection.rollback_db_transaction
|
||||
ActiveRecord::Base.send :decrement_open_transactions unless Rails::VERSION::STRING == "1.1.6"
|
||||
if ActiveRecord::Base.connection.respond_to?(:decrement_open_transactions)
|
||||
ActiveRecord::Base.connection.decrement_open_transactions
|
||||
else
|
||||
ActiveRecord::Base.send :decrement_open_transactions
|
||||
end
|
||||
end
|
||||
end
|
||||
alias :scenario_pending :scenario_succeeded
|
||||
|
|
|
|||
|
|
@ -1,23 +1,15 @@
|
|||
module Spec
|
||||
module Rails
|
||||
module VERSION #:nodoc:
|
||||
BUILD_TIME_UTC = 20080615141040
|
||||
unless defined? MAJOR
|
||||
MAJOR = 1
|
||||
MINOR = 1
|
||||
TINY = 8
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
|
||||
SUMMARY = "rspec-rails #{STRING}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Verify that the plugin has the same revision as RSpec
|
||||
if Spec::Rails::VERSION::BUILD_TIME_UTC != Spec::VERSION::BUILD_TIME_UTC
|
||||
raise <<-EOF
|
||||
|
||||
############################################################################
|
||||
Your RSpec on Rails plugin is incompatible with your installed RSpec.
|
||||
|
||||
RSpec : #{Spec::VERSION::BUILD_TIME_UTC}
|
||||
RSpec on Rails : #{Spec::Rails::VERSION::BUILD_TIME_UTC}
|
||||
|
||||
Make sure your RSpec on Rails plugin is compatible with your RSpec gem.
|
||||
See http://rspec.rubyforge.org/documentation/rails/install.html for details.
|
||||
############################################################################
|
||||
EOF
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue