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 @callback_type = callback_type
end end
def matches?(subject) def matches?(controller)
@subject = subject @controller = controller
@controller_class = controller.class
callbacks.map(&:filter).include?(method_name) callbacks.map(&:filter).include?(method_name)
end end
def failure_message 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 end
alias failure_message_for_should failure_message alias failure_message_for_should failure_message
def failure_message_when_negated 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 end
alias failure_message_for_should_not failure_message_when_negated alias failure_message_for_should_not failure_message_when_negated
@ -90,10 +92,13 @@ module Shoulda # :nodoc:
private private
def callbacks def callbacks
subject._process_action_callbacks.select { |callback| callback.kind == kind } controller_class._process_action_callbacks.select do |callback|
callback.kind == kind
end
end end
attr_reader :method_name, :subject, :kind, :callback_type attr_reader :method_name, :controller, :controller_class, :kind,
:callback_type
end end
end end
end end

View File

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