Last active
August 29, 2015 13:57
-
-
Save tiegz/9552611 to your computer and use it in GitHub Desktop.
Microgem for shoulda-matchers' assign_to helper (which was removed in 2+).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Gemfile.lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source "http://rubygems.org" | |
gemspec |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Gem::Specification.new do |s| | |
s.name = 'shoulda-matchers-assign-to' | |
s.version = '0.1.0' | |
s.platform = Gem::Platform::RUBY | |
s.author = 'Tieg Zaharia' | |
s.email = '[email protected]' | |
s.summary = 'Use assign_to with shoulda-matchers 2+' | |
s.description = 'assign_to was removed in shoulda-matchers v2. This adds it back.' | |
s.files = ['shoulda-matchers-assign-to.rb'] | |
s.test_file = 'shoulda-matchers-assign-to.rb' | |
s.require_path = '.' | |
s.add_development_dependency('shoulda-matchers', '~> 2.0') | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Extracted from shoulda-matchers 1.5.6 b/c it's gone in 2.0: | |
# http://robots.thoughtbot.com/shoulda-matchers-2-0 | |
module Shoulda # :nodoc: | |
module Matchers | |
module ActionController # :nodoc: | |
# Ensures that the controller assigned to the named instance variable. | |
# | |
# Options: | |
# * <tt>with_kind_of</tt> - The expected class of the instance variable | |
# being checked. | |
# * <tt>with</tt> - The value that should be assigned. | |
# | |
# Example: | |
# | |
# it { should assign_to(:user) } | |
# it { should_not assign_to(:user) } | |
# it { should assign_to(:user).with_kind_of(User) } | |
# it { should assign_to(:user).with(@user) } | |
def assign_to(variable) | |
AssignToMatcher.new(variable) | |
end | |
class AssignToMatcher # :nodoc: | |
attr_reader :failure_message_for_should, :failure_message_for_should_not | |
def initialize(variable) | |
@variable = variable.to_s | |
@options = {} | |
@options[:check_value] = false | |
end | |
def with_kind_of(expected_class) | |
@options[:expected_class] = expected_class | |
self | |
end | |
def with(expected_value = nil, &block) | |
@options[:check_value] = true | |
@options[:expected_value] = expected_value | |
@options[:expectation_block] = block | |
self | |
end | |
def matches?(controller) | |
@controller = controller | |
normalize_expected_value! | |
assigned_value? && | |
kind_of_expected_class? && | |
equal_to_expected_value? | |
end | |
def description | |
description = "assign @#{@variable}" | |
if @options.key?(:expected_class) | |
description << " with a kind of #{@options[:expected_class]}" | |
end | |
description | |
end | |
def in_context(context) | |
@context = context | |
self | |
end | |
private | |
def assigned_value? | |
if @controller.instance_variables.map(&:to_s).include?("@#{@variable}") | |
@failure_message_for_should_not = | |
"Didn't expect action to assign a value for @#{@variable}, " << | |
"but it was assigned to #{assigned_value.inspect}" | |
true | |
else | |
@failure_message_for_should = | |
"Expected action to assign a value for @#{@variable}" | |
false | |
end | |
end | |
def kind_of_expected_class? | |
if @options.key?(:expected_class) | |
if assigned_value.kind_of?(@options[:expected_class]) | |
@failure_message_for_should_not = | |
"Didn't expect action to assign a kind of #{@options[:expected_class]} " << | |
"for #{@variable}, but got one anyway" | |
true | |
else | |
@failure_message_for_should = | |
"Expected action to assign a kind of #{@options[:expected_class]} " << | |
"for #{@variable}, but got #{assigned_value.inspect} " << | |
"(#{assigned_value.class.name})" | |
false | |
end | |
else | |
true | |
end | |
end | |
def equal_to_expected_value? | |
if @options[:check_value] | |
if @options[:expected_value] == assigned_value | |
@failure_message_for_should_not = | |
"Didn't expect action to assign #{@options[:expected_value].inspect} " << | |
"for #{@variable}, but got it anyway" | |
true | |
else | |
@failure_message_for_should = | |
"Expected action to assign #{@options[:expected_value].inspect} " << | |
"for #{@variable}, but got #{assigned_value.inspect}" | |
false | |
end | |
else | |
true | |
end | |
end | |
def normalize_expected_value! | |
if @options[:expectation_block] | |
@options[:expected_value] = @context.instance_eval(&@options[:expectation_block]) | |
end | |
end | |
def assigned_value | |
@controller.instance_variable_get("@#{@variable}") | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe Shoulda::Matchers::ActionController::AssignToMatcher do | |
it 'includes the actual class in the failure message' do | |
define_class(:WrongClass) do | |
def to_s | |
'wrong class' | |
end | |
end | |
controller = build_response { @var = WrongClass.new } | |
matcher = assign_to(:var).with_kind_of(Fixnum) | |
matcher.matches?(controller) | |
matcher.failure_message_for_should.should =~ /but got wrong class \(WrongClass\)$/ | |
end | |
context 'a controller that assigns to an instance variable' do | |
it 'accepts assigning to that variable' do | |
controller.should assign_to(:var) | |
end | |
it 'accepts assigning to that variable with the correct class' do | |
controller.should assign_to(:var).with_kind_of(String) | |
end | |
it 'rejects assigning to that variable with another class' do | |
controller.should_not assign_to(:var).with_kind_of(Fixnum) | |
end | |
it 'accepts assigning the correct value to that variable' do | |
controller.should assign_to(:var).with('value') | |
end | |
it 'rejects assigning another value to that variable' do | |
controller.should_not assign_to(:var).with('other') | |
end | |
it 'rejects assigning to another variable' do | |
controller.should_not assign_to(:other) | |
end | |
it 'accepts assigning to the same value in the test context' do | |
expected = 'value' | |
controller.should assign_to(:var).in_context(self).with { expected } | |
end | |
it 'rejects assigning to the another value in the test context' do | |
expected = 'other' | |
controller.should_not assign_to(:var).in_context(self).with { expected } | |
end | |
def controller | |
build_response { @var = 'value' } | |
end | |
end | |
context 'a controller that assigns a nil value to an instance variable' do | |
it 'accepts assigning to that variable' do | |
controller = build_response do | |
@var = nil | |
end | |
controller.should assign_to(:var) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment