0
@@ -15,6 +15,77 @@ module ThoughtBot # :nodoc:
0
+ # Macro that creates a test asserting a change between the return value
0
+ # of an expression that is run before and after the current setup block
0
+ # is run. This is similar to Active Support's <tt>assert_difference</tt>
0
+ # assertion, but supports more than just numeric values. See also
0
+ # context "Creating a post"
0
+ # should_change "Post.count", :by => 1
0
+ # As shown in this example, the <tt>:by</tt> option expects a numeric
0
+ # difference between the before and after values of the expression. You
0
+ # may also specify <tt>:from</tt> and <tt>:to</tt> options:
0
+ # should_change "Post.count", :from => 0, :to => 1
0
+ # should_change "@post.title", :from => "old", :to => "new"
0
+ # Combinations of <tt>:by</tt>, <tt>:from</tt>, and <tt>:to</tt> are allowed:
0
+ # should_change "@post.title" # => assert the value changed in some way
0
+ # should_change "@post.title" :from => "old" # => assert the value changed to anything other than "old"
0
+ # should_change "@post.title" :to => "new" # => assert the value changed from anything other than "new"
0
+ def should_change(expression, options = {})
0
+ by, from, to = get_options!([options], :by, :from, :to)
0
+ stmt = "change '#{expression}'"
0
+ stmt << " from '#{from}'" if from
0
+ stmt << " to '#{to}'" if to
0
+ stmt << " by #{by}" if by
0
+ expression_eval = lambda { eval(expression) }
0
+ @_before_should_change = expression_eval.bind(self).call
0
+ assert_equal from, @_before_should_change, "'#{expression}' was not originally '#{from}'" if from
0
+ should stmt, :before => before do
0
+ old_value = @_before_should_change
0
+ new_value = expression_eval.bind(self).call
0
+ assert_not_equal old_value, new_value, "'#{expression}' did not change" unless by == 0
0
+ assert_equal to, new_value, "'#{expression}' was not changed to '#{to}'" if to
0
+ assert_equal old_value + by, new_value if by
0
+ # Macro that creates a test asserting no change between the return value
0
+ # of an expression that is run before and after the current setup block
0
+ # is run. This is the logical opposite of should_change.
0
+ # context "Updating a post"
0
+ # @post.update_attributes(:title => "new")
0
+ # should_not_change "Post.count"
0
+ def should_not_change(expression)
0
+ expression_eval = lambda { eval(expression) }
0
+ before = lambda { @_before_should_not_change = expression_eval.bind(self).call }
0
+ should "not change '#{expression}'", :before => before do
0
+ new_value = expression_eval.bind(self).call
0
+ assert_equal @_before_should_not_change, new_value, "'#{expression}' changed"
0
# Prints a message to stdout, tagged with the name of the calling method.