Browse files

Converted should_assign_to/should_not_assign_to to use a matcher

  • Loading branch information...
1 parent ceea356 commit 3ed10a4bade9f55c413099052e6d0d655bd27beb @jferris jferris committed Jan 31, 2009
View
6 controller_progress.txt
@@ -1,7 +1,5 @@
Unfinished:
-should_assign_to
should_filter_params
-should_not_assign_to
should_not_set_the_flash
should_render_with_layout
should_render_without_layout
@@ -12,9 +10,11 @@ should_route
should_set_the_flash_to
Finished:
-should_be_restful
+should_assign_to
+should_not_assign_to
Won't implement:
+should_be_restful
Already implemented in spec-rails:
should_redirect_to
View
3 lib/shoulda/controller.rb
@@ -7,8 +7,9 @@
module Test # :nodoc: all
module Unit
class TestCase
- extend Shoulda::Controller::Macros
+ include Shoulda::Controller::Matchers
include Shoulda::Controller::Helpers
+ extend Shoulda::Controller::Macros
Shoulda::Controller::VALID_FORMATS.each do |format|
include "Shoulda::Controller::#{format.to_s.upcase}".constantize
end
View
25 lib/shoulda/controller/macros.rb
@@ -25,6 +25,8 @@ module Controller # :nodoc:
# Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
# controller responds restfully to a variety of requested formats.
module Macros
+ include Matchers
+
# <b>DEPRECATED:</b> Please see
# http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
# information.
@@ -134,21 +136,21 @@ def should_filter_params(*keys)
def should_assign_to(*names)
opts = names.extract_options!
names.each do |name|
- test_name = "assign @#{name}"
- test_name << " as class #{opts[:class]}" if opts[:class]
+ matcher = assign_to(name).with_kind_of(opts[:class])
+ test_name = matcher.description
test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
should test_name do
- assigned_value = assigns(name.to_sym)
- assert_not_nil assigned_value, "The action isn't assigning to @#{name}"
- assert_kind_of opts[:class], assigned_value if opts[:class]
if opts[:equals]
instantiate_variables_from_assigns do
- expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
- assert_equal expected_value, assigned_value,
- "Instance variable @#{name} expected to be #{expected_value}" +
- " but was #{assigned_value}"
+ expected_value = eval(opts[:equals],
+ self.send(:binding),
+ __FILE__,
+ __LINE__)
+ matcher = matcher.with(expected_value)
end
end
+
+ assert_accepts matcher, @controller
end
end
end
@@ -161,8 +163,9 @@ def should_assign_to(*names)
# should_not_assign_to :user, :posts
def should_not_assign_to(*names)
names.each do |name|
- should "not assign to @#{name}" do
- assert !assigns(name.to_sym), "@#{name} was visible"
+ matcher = assign_to(name)
+ should "not #{matcher.description}" do
+ assert_rejects matcher, @controller
end
end
end
View
2 lib/shoulda/controller/matchers.rb
@@ -1,3 +1,5 @@
+require 'shoulda/controller/matchers/assign_to_matcher'
+
module Shoulda # :nodoc:
module Controller # :nodoc:
View
109 lib/shoulda/controller/matchers/assign_to_matcher.rb
@@ -0,0 +1,109 @@
+module Shoulda # :nodoc:
+ module Controller # :nodoc:
+ module Matchers
+
+ # 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:
+
+ def initialize(variable)
+ @variable = variable.to_s
+ end
+
+ def with_kind_of(expected_class)
+ @expected_class = expected_class
+ self
+ end
+
+ def with(expected_value)
+ @expected_value = expected_value
+ self
+ end
+
+ def matches?(controller)
+ @controller = controller
+ assigned_value? && kind_of_expected_class? && equal_to_expected_value?
+ end
+
+ attr_reader :failure_message, :negative_failure_message
+
+ def description
+ description = "assign @#{@variable}"
+ description << " with a kind of #{@expected_class}" if @expected_class
+ description
+ end
+
+ private
+
+ def assigned_value?
+ if assigned_value.nil?
+ @failure_message =
+ "Expected action to assign a value for @#{@variable}"
+ false
+ else
+ @negative_failure_message =
+ "Didn't expect action to assign a value for @#{@variable}, " <<
+ "but it was assigned to #{assigned_value.inspect}"
+ true
+ end
+ end
+
+ def kind_of_expected_class?
+ return true unless @expected_class
+ if assigned_value.kind_of?(@expected_class)
+ @negative_failure_message =
+ "Didn't expect action to assign a kind of #{@expected_class} " <<
+ "for #{@variable}, but got one anyway"
+ true
+ else
+ @failure_message =
+ "Expected action to assign a kind of #{@expected_class} " <<
+ "for #{@variable}, but got #{@variable.inspect} " <<
+ "(#{@variable.class.name})"
+ false
+ end
+ end
+
+ def equal_to_expected_value?
+ return true unless @expected_value
+ if @expected_value == assigned_value
+ @negative_failure_message =
+ "Didn't expect action to assign #{@expected_value.inspect} " <<
+ "for #{@variable}, but got it anyway"
+ true
+ else
+ @failure_message =
+ "Expected action to assign #{@expected_value.inspect} " <<
+ "for #{@variable}, but got #{assigned_value.inspect}"
+ false
+ end
+ end
+
+ def assigned_value
+ assigns[@variable]
+ end
+
+ def assigns
+ @controller.response.template.assigns
+ end
+
+ end
+
+ end
+ end
+end
View
35 test/matchers/controller/assign_to_matcher_test.rb
@@ -0,0 +1,35 @@
+require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
+
+class AssignToMatcherTest < Test::Unit::TestCase # :nodoc:
+
+ context "a controller that assigns to an instance variable" do
+ setup do
+ @controller = build_response { @var = 'value' }
+ end
+
+ should "accept assigning to that variable" do
+ assert_accepts assign_to(:var), @controller
+ end
+
+ should "accept assigning to that variable with the correct class" do
+ assert_accepts assign_to(:var).with_kind_of(String), @controller
+ end
+
+ should "reject assigning to that variable with another class" do
+ assert_rejects assign_to(:var).with_kind_of(Fixnum), @controller
+ end
+
+ should "accept assigning the correct value to that variable" do
+ assert_accepts assign_to(:var).with('value'), @controller
+ end
+
+ should "reject assigning another value to that variable" do
+ assert_rejects assign_to(:var).with('other'), @controller
+ end
+
+ should "reject assigning to another variable" do
+ assert_rejects assign_to(:other), @controller
+ end
+ end
+
+end

0 comments on commit 3ed10a4

Please sign in to comment.