mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
parent
f80480943e
commit
d3525f129e
6 changed files with 0 additions and 370 deletions
10
README.md
10
README.md
|
@ -66,16 +66,6 @@ describe PostsController, "#show" do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
## Independent Matchers
|
|
||||||
|
|
||||||
Matchers to test non-Rails-dependent code:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
describe Human do
|
|
||||||
it { should delegate_method(:work).to(:robot) }
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
In Rails 3 and Bundler, add the following to your Gemfile:
|
In Rails 3 and Bundler, add the following to your Gemfile:
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
require 'shoulda/matchers/independent/delegate_matcher'
|
|
||||||
|
|
||||||
module Shoulda
|
|
||||||
module Matchers
|
|
||||||
# = Matchers for non-Rails-dependent code.
|
|
||||||
module Independent
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,134 +0,0 @@
|
||||||
require 'bourne'
|
|
||||||
require 'active_support/deprecation'
|
|
||||||
|
|
||||||
module Shoulda # :nodoc:
|
|
||||||
module Matchers
|
|
||||||
module Independent # :nodoc:
|
|
||||||
|
|
||||||
# Ensure that a given method is delegated properly.
|
|
||||||
#
|
|
||||||
# Basic Syntax:
|
|
||||||
# it { should delegate_method(:deliver_mail).to(:mailman) }
|
|
||||||
#
|
|
||||||
# Options:
|
|
||||||
# * <tt>:as</tt> - tests that the object being delegated to is called with a certain method
|
|
||||||
# (defaults to same name as delegating method)
|
|
||||||
# * <tt>:with_arguments</tt> - tests that the method on the object being delegated to is
|
|
||||||
# called with certain arguments
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# it { should delegate_method(:deliver_mail).to(:mailman).as(:deliver_with_haste)
|
|
||||||
# it { should delegate_method(:deliver_mail).to(:mailman).
|
|
||||||
# with_arguments('221B Baker St.', :hastily => true) }
|
|
||||||
#
|
|
||||||
def delegate_method(delegating_method)
|
|
||||||
DelegateMatcher.new(delegating_method)
|
|
||||||
end
|
|
||||||
|
|
||||||
class DelegateMatcher
|
|
||||||
def initialize(delegating_method)
|
|
||||||
ActiveSupport::Deprecation.warn 'The delegate_method matcher is deprecated and will be removed in 2.0'
|
|
||||||
@delegating_method = delegating_method
|
|
||||||
end
|
|
||||||
|
|
||||||
def matches?(subject)
|
|
||||||
@subject = subject
|
|
||||||
ensure_target_method_is_present!
|
|
||||||
|
|
||||||
begin
|
|
||||||
extend Mocha::API
|
|
||||||
|
|
||||||
stubbed_object = stub(method_on_target)
|
|
||||||
subject.stubs(@target_method).returns(stubbed_object)
|
|
||||||
subject.send(@delegating_method)
|
|
||||||
|
|
||||||
matcher = Mocha::API::HaveReceived.new(method_on_target).with(*@delegated_arguments)
|
|
||||||
matcher.matches?(stubbed_object)
|
|
||||||
rescue NoMethodError, Mocha::ExpectationError
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def description
|
|
||||||
add_clarifications_to("delegate method ##{@delegating_method} to :#{@target_method}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def does_not_match?(subject)
|
|
||||||
raise InvalidDelegateMatcher
|
|
||||||
end
|
|
||||||
|
|
||||||
def to(target_method)
|
|
||||||
@target_method = target_method
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def as(method_on_target)
|
|
||||||
@method_on_target = method_on_target
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def with_arguments(*arguments)
|
|
||||||
@delegated_arguments = arguments
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def failure_message_for_should
|
|
||||||
base = "Expected #{delegating_method_name} to delegate to #{target_method_name}"
|
|
||||||
add_clarifications_to(base)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def add_clarifications_to(message)
|
|
||||||
if @delegated_arguments.present?
|
|
||||||
message << " with arguments: #{@delegated_arguments.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
if @method_on_target.present?
|
|
||||||
message << " as ##{@method_on_target}"
|
|
||||||
end
|
|
||||||
|
|
||||||
message
|
|
||||||
end
|
|
||||||
|
|
||||||
def delegating_method_name
|
|
||||||
method_name_with_class(@delegating_method)
|
|
||||||
end
|
|
||||||
|
|
||||||
def target_method_name
|
|
||||||
method_name_with_class(@target_method)
|
|
||||||
end
|
|
||||||
|
|
||||||
def method_name_with_class(method)
|
|
||||||
if Class === @subject
|
|
||||||
@subject.name + '.' + method.to_s
|
|
||||||
else
|
|
||||||
@subject.class.name + '#' + method.to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def method_on_target
|
|
||||||
@method_on_target || @delegating_method
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_target_method_is_present!
|
|
||||||
if @target_method.blank?
|
|
||||||
raise TargetNotDefinedError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class DelegateMatcher::TargetNotDefinedError < StandardError
|
|
||||||
def message
|
|
||||||
'Delegation needs a target. Use the #to method to define one, e.g. `post_office.should delegate(:deliver_mail).to(:mailman)`'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class DelegateMatcher::InvalidDelegateMatcher < StandardError
|
|
||||||
def message
|
|
||||||
'#delegate_to does not support #should_not syntax.'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,9 +2,6 @@
|
||||||
require 'rspec/core'
|
require 'rspec/core'
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
require 'shoulda/matchers/independent'
|
|
||||||
config.include Shoulda::Matchers::Independent
|
|
||||||
|
|
||||||
if defined?(::ActiveRecord)
|
if defined?(::ActiveRecord)
|
||||||
require 'shoulda/matchers/active_record'
|
require 'shoulda/matchers/active_record'
|
||||||
require 'shoulda/matchers/active_model'
|
require 'shoulda/matchers/active_model'
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
# :enddoc:
|
# :enddoc:
|
||||||
require 'test/unit/testcase'
|
require 'test/unit/testcase'
|
||||||
require 'shoulda/matchers/independent'
|
|
||||||
|
|
||||||
module Test
|
|
||||||
module Unit
|
|
||||||
class TestCase
|
|
||||||
include Shoulda::Matchers::Independent
|
|
||||||
extend Shoulda::Matchers::Independent
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if defined?(ActionController)
|
if defined?(ActionController)
|
||||||
require 'shoulda/matchers/action_controller'
|
require 'shoulda/matchers/action_controller'
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|
||||||
context '#description' do
|
|
||||||
context 'by default' do
|
|
||||||
it 'states that it should delegate method to the right object' do
|
|
||||||
matcher = delegate_method(:method_name).to(:target)
|
|
||||||
|
|
||||||
matcher.description.should == 'delegate method #method_name to :target'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with #as chain' do
|
|
||||||
it 'states that it should delegate method to the right object and method' do
|
|
||||||
matcher = delegate_method(:method_name).to(:target).as(:alternate)
|
|
||||||
|
|
||||||
matcher.description.should == 'delegate method #method_name to :target as #alternate'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with #with_argument chain' do
|
|
||||||
it 'states that it should delegate method to the right object with right argument' do
|
|
||||||
matcher = delegate_method(:method_name).to(:target).with_arguments(:foo, :bar => [1, 2])
|
|
||||||
|
|
||||||
matcher.description.should ==
|
|
||||||
'delegate method #method_name to :target with arguments: [:foo, {:bar=>[1, 2]}]'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'supports chaining on #to' do
|
|
||||||
matcher = delegate_method(:method)
|
|
||||||
|
|
||||||
matcher.to(:another_method).should == matcher
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'supports chaining on #with_arguments' do
|
|
||||||
matcher = delegate_method(:method)
|
|
||||||
|
|
||||||
matcher.with_arguments(1, 2, 3).should == matcher
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'supports chaining on #as' do
|
|
||||||
matcher = delegate_method(:method)
|
|
||||||
|
|
||||||
matcher.as(:some_other_method).should == matcher
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises an error if no delegation target is defined' do
|
|
||||||
expect { Object.new.should delegate_method(:name) }.
|
|
||||||
to raise_exception described_class::TargetNotDefinedError
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises an error if called with #should_not' do
|
|
||||||
expect { Object.new.should_not delegate_method(:name).to(:anyone) }.
|
|
||||||
to raise_exception described_class::InvalidDelegateMatcher
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'given a method that does not delegate' do
|
|
||||||
before do
|
|
||||||
define_class(:post_office) do
|
|
||||||
def deliver_mail
|
|
||||||
:delivered
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'rejects' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman)
|
|
||||||
|
|
||||||
matcher.matches?(post_office).should be_false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has a failure message that indicates which method should have been delegated' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman)
|
|
||||||
|
|
||||||
matcher.matches?(post_office)
|
|
||||||
|
|
||||||
message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman'
|
|
||||||
matcher.failure_message_for_should.should == message
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'uses the proper syntax for class methods in errors' do
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman)
|
|
||||||
|
|
||||||
matcher.matches?(PostOffice)
|
|
||||||
|
|
||||||
message = 'Expected PostOffice.deliver_mail to delegate to PostOffice.mailman'
|
|
||||||
matcher.failure_message_for_should.should == message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'given a method that delegates properly' do
|
|
||||||
it 'accepts' do
|
|
||||||
define_class(:mailman)
|
|
||||||
define_class(:post_office) do
|
|
||||||
def deliver_mail
|
|
||||||
mailman.deliver_mail
|
|
||||||
end
|
|
||||||
|
|
||||||
def mailman
|
|
||||||
Mailman.new
|
|
||||||
end
|
|
||||||
end.new.should delegate_method(:deliver_mail).to(:mailman)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'given a method that delegates properly with certain arguments' do
|
|
||||||
before do
|
|
||||||
define_class(:mailman)
|
|
||||||
define_class(:post_office) do
|
|
||||||
def deliver_mail
|
|
||||||
mailman.deliver_mail('221B Baker St.', :hastily => true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def mailman
|
|
||||||
Mailman.new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when given the correct arguments' do
|
|
||||||
it 'accepts' do
|
|
||||||
PostOffice.new.should delegate_method(:deliver_mail).
|
|
||||||
to(:mailman).with_arguments('221B Baker St.', :hastily => true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when not given the correct arguments' do
|
|
||||||
it 'rejects' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman).
|
|
||||||
with_arguments('123 Nowhere Ln.')
|
|
||||||
matcher.matches?(post_office).should be_false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has a failure message that indicates which arguments were expected' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman).with_arguments('123 Nowhere Ln.')
|
|
||||||
|
|
||||||
matcher.matches?(post_office)
|
|
||||||
|
|
||||||
message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman with arguments: ["123 Nowhere Ln."]'
|
|
||||||
matcher.failure_message_for_should.should == message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'given a method that delegates properly to a method of a different name' do
|
|
||||||
before do
|
|
||||||
define_class(:mailman)
|
|
||||||
define_class(:post_office) do
|
|
||||||
def deliver_mail
|
|
||||||
mailman.deliver_mail_and_avoid_dogs
|
|
||||||
end
|
|
||||||
|
|
||||||
def mailman
|
|
||||||
Mailman.new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when given the correct method name' do
|
|
||||||
it 'accepts' do
|
|
||||||
PostOffice.new.
|
|
||||||
should delegate_method(:deliver_mail).to(:mailman).as(:deliver_mail_and_avoid_dogs)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when given an incorrect method name' do
|
|
||||||
it 'rejects' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman).as(:watch_tv)
|
|
||||||
matcher.matches?(post_office).should be_false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has a failure message that indicates which method was expected' do
|
|
||||||
post_office = PostOffice.new
|
|
||||||
matcher = delegate_method(:deliver_mail).to(:mailman).as(:watch_tv)
|
|
||||||
|
|
||||||
matcher.matches?(post_office)
|
|
||||||
|
|
||||||
message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman as #watch_tv'
|
|
||||||
matcher.failure_message_for_should.should == message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Shoulda::Matchers::Independent::DelegateMatcher::TargetNotDefinedError do
|
|
||||||
it 'has a useful message' do
|
|
||||||
error = Shoulda::Matchers::Independent::DelegateMatcher::TargetNotDefinedError.new
|
|
||||||
error.message.should include 'Delegation needs a target'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Shoulda::Matchers::Independent::DelegateMatcher::InvalidDelegateMatcher do
|
|
||||||
it 'has a useful message' do
|
|
||||||
error = Shoulda::Matchers::Independent::DelegateMatcher::InvalidDelegateMatcher.new
|
|
||||||
error.message.should include 'does not support #should_not'
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Add table
Reference in a new issue