Fix callback matchers to take controller instances

Controller matchers operate on instances of controllers, not controller
classes themselves.
This commit is contained in:
Elliot Winkler 2014-04-16 00:53:40 -06:00
parent a5623e7a6a
commit 025dfdc432
2 changed files with 33 additions and 25 deletions

View File

@ -68,18 +68,20 @@ module Shoulda # :nodoc:
@callback_type = callback_type
end
def matches?(subject)
@subject = subject
def matches?(controller)
@controller = controller
@controller_class = controller.class
callbacks.map(&:filter).include?(method_name)
end
def failure_message
"Expected that #{subject.name} would have :#{method_name} as a #{kind}_#{callback_type}"
"Expected that #{controller_class.name} would have :#{method_name} as a #{kind}_#{callback_type}"
end
alias failure_message_for_should failure_message
def failure_message_when_negated
"Expected that #{subject.name} would not have :#{method_name} as a #{kind}_#{callback_type}"
"Expected that #{controller_class.name} would not have :#{method_name} as a #{kind}_#{callback_type}"
end
alias failure_message_for_should_not failure_message_when_negated
@ -90,10 +92,13 @@ module Shoulda # :nodoc:
private
def callbacks
subject._process_action_callbacks.select { |callback| callback.kind == kind }
controller_class._process_action_callbacks.select do |callback|
callback.kind == kind
end
end
attr_reader :method_name, :subject, :kind, :callback_type
attr_reader :method_name, :controller, :controller_class, :kind,
:callback_type
end
end
end

View File

@ -2,52 +2,55 @@ require 'spec_helper'
describe Shoulda::Matchers::ActionController::CallbackMatcher do
shared_examples 'CallbackMatcher' do |kind, callback_type|
let(:matcher) { described_class.new(:authenticate_user!, kind, callback_type) }
let(:controller) { define_controller('HookController') }
let(:kind) { kind }
let(:callback_type) { callback_type }
let(:method_name) { :authenticate_user! }
let(:matcher) { described_class.new(method_name, kind, callback_type) }
let(:controller) { define_controller('HookController').new }
describe '#matches?' do
it "matches when a #{kind} hook is in place" do
add_callback(kind, callback_type, :authenticate_user!)
def match
__send__("use_#{kind}_#{callback_type}", method_name)
end
expect(matcher.matches?(controller)).to be_true
end
it "matches when a #{kind} hook is in place" do
add_callback(kind, callback_type, method_name)
it "does not match when a #{kind} hook is missing" do
expect(matcher.matches?(controller)).to be_false
end
expect(controller).to match
end
it "does not match when a #{kind} hook is missing" do
expect(controller).not_to match
end
describe 'description' do
it 'includes the filter kind and name' do
expect(matcher.description).to eq "have :authenticate_user! as a #{kind}_#{callback_type}"
expect(matcher.description).to eq "have #{method_name.inspect} as a #{kind}_#{callback_type}"
end
end
describe 'failure message' do
it 'includes the filter kind and name that was expected' do
message = "Expected that HookController would have :authenticate_user! as a #{kind}_#{callback_type}"
message = "Expected that HookController would have #{method_name.inspect} as a #{kind}_#{callback_type}"
expect {
expect(controller).to send("use_#{kind}_#{callback_type}", :authenticate_user!)
expect(controller).to send("use_#{kind}_#{callback_type}", method_name)
}.to fail_with_message(message)
end
end
describe 'failure message when negated' do
it 'includes the filter kind and name that was expected' do
add_callback(kind, callback_type, :authenticate_user!)
message = "Expected that HookController would not have :authenticate_user! as a #{kind}_#{callback_type}"
add_callback(kind, callback_type, method_name)
message = "Expected that HookController would not have #{method_name.inspect} as a #{kind}_#{callback_type}"
expect {
expect(controller).not_to send("use_#{kind}_#{callback_type}", :authenticate_user!)
}.to fail_with_message(message)
expect { expect(controller).not_to match }.to fail_with_message(message)
end
end
private
def add_callback(kind, callback_type, callback)
controller.send("#{kind}_#{callback_type}", callback)
controller.class.__send__("#{kind}_#{callback_type}", callback)
end
end