<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -15,6 +15,77 @@ module ThoughtBot # :nodoc:
           end
           fixtures *all_fixtures
         end
+        
+        # Macro that creates a test asserting a change between the return value
+        # of an expression that is run before and after the current setup block
+        # is run. This is similar to Active Support's &lt;tt&gt;assert_difference&lt;/tt&gt;
+        # assertion, but supports more than just numeric values.  See also
+        # should_not_change.
+        #
+        # Example:
+        #
+        #   context &quot;Creating a post&quot;
+        #     setup do
+        #       Post.create
+        #     end
+        #
+        #     should_change &quot;Post.count&quot;, :by =&gt; 1
+        #   end
+        #
+        # As shown in this example, the &lt;tt&gt;:by&lt;/tt&gt; option expects a numeric
+        # difference between the before and after values of the expression.  You
+        # may also specify &lt;tt&gt;:from&lt;/tt&gt; and &lt;tt&gt;:to&lt;/tt&gt; options:
+        #
+        #   should_change &quot;Post.count&quot;, :from =&gt; 0, :to =&gt; 1
+        #   should_change &quot;@post.title&quot;, :from =&gt; &quot;old&quot;, :to =&gt; &quot;new&quot;
+        #
+        # Combinations of &lt;tt&gt;:by&lt;/tt&gt;, &lt;tt&gt;:from&lt;/tt&gt;, and &lt;tt&gt;:to&lt;/tt&gt; are allowed:
+        #
+        #   should_change &quot;@post.title&quot;                # =&gt; assert the value changed in some way
+        #   should_change &quot;@post.title&quot; :from =&gt; &quot;old&quot; # =&gt; assert the value changed to anything other than &quot;old&quot;
+        #   should_change &quot;@post.title&quot; :to   =&gt; &quot;new&quot; # =&gt; assert the value changed from anything other than &quot;new&quot;
+        def should_change(expression, options = {}) 
+          by, from, to = get_options!([options], :by, :from, :to)
+          stmt = &quot;change '#{expression}'&quot;
+          stmt &lt;&lt; &quot; from '#{from}'&quot; if from
+          stmt &lt;&lt; &quot; to '#{to}'&quot; if to
+          stmt &lt;&lt; &quot; by #{by}&quot; if by
+
+          expression_eval = lambda { eval(expression) }
+          before = lambda do
+            @_before_should_change = expression_eval.bind(self).call
+            assert_equal from, @_before_should_change, &quot;'#{expression}' was not originally '#{from}'&quot; if from
+          end
+          should stmt, :before =&gt; before do
+            old_value = @_before_should_change
+            new_value = expression_eval.bind(self).call
+            assert_not_equal old_value, new_value, &quot;'#{expression}' did not change&quot; unless by == 0
+            assert_equal to, new_value, &quot;'#{expression}' was not changed to '#{to}'&quot; if to
+            assert_equal old_value + by, new_value if by
+          end
+        end
+        
+        # Macro that creates a test asserting no change between the return value
+        # of an expression that is run before and after the current setup block
+        # is run. This is the logical opposite of should_change.
+        #
+        # Example:
+        #
+        #   context &quot;Updating a post&quot;
+        #     setup do
+        #       @post.update_attributes(:title =&gt; &quot;new&quot;)
+        #     end
+        #
+        #     should_not_change &quot;Post.count&quot;
+        #   end
+        def should_not_change(expression)
+          expression_eval = lambda { eval(expression) }
+          before = lambda { @_before_should_not_change = expression_eval.bind(self).call }
+          should &quot;not change '#{expression}'&quot;, :before =&gt; before do
+            new_value = expression_eval.bind(self).call
+            assert_equal @_before_should_not_change, new_value, &quot;'#{expression}' changed&quot;
+          end
+        end
       end
       
       # Prints a message to stdout, tagged with the name of the calling method.</diff>
      <filename>lib/shoulda/general.rb</filename>
    </modified>
    <modified>
      <diff>@@ -77,4 +77,35 @@ class HelpersTest &lt; Test::Unit::TestCase # :nodoc:
       end
     end
   end
+  
+  context &quot;an array of numbers&quot; do
+    setup do
+      @a = [1, 2, 3]
+    end
+
+    context &quot;after adding another value&quot; do
+      setup do
+        @a.push(4)
+      end
+
+      should_change &quot;@a.length&quot;, :by =&gt; 1
+      should_change &quot;@a.length&quot;, :from =&gt; 3
+      should_change &quot;@a.length&quot;, :to =&gt; 4
+      should_change &quot;@a[0]&quot;, :by =&gt; 0
+      should_not_change &quot;@a[0]&quot;
+    end
+
+    context &quot;after replacing it with an array of strings&quot; do
+      setup do
+        @a = %w(a b c d e f)
+      end
+
+      should_change &quot;@a.length&quot;, :by =&gt; 3
+      should_change &quot;@a.length&quot;, :from =&gt; 3, :to =&gt; 6, :by =&gt; 3
+      should_change &quot;@a[0]&quot;
+      should_change &quot;@a[1]&quot;, :from =&gt; 2, :to =&gt; &quot;b&quot;
+      should_change &quot;@a[2]&quot;, :from =&gt; 3
+      should_change &quot;@a[3]&quot;, :to =&gt; &quot;d&quot;
+    end
+  end
 end</diff>
      <filename>test/other/helpers_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e6e2f6b906edc4ecd6d7f8a77046216e308d1cf0</id>
    </parent>
  </parents>
  <author>
    <name>Ryan McGeary</name>
    <email>ryanongit@mcgeary.org</email>
  </author>
  <url>http://github.com/rmm5t/shoulda/commit/5f786cbff6cdac99a5c60c36534df84854134c6d</url>
  <id>5f786cbff6cdac99a5c60c36534df84854134c6d</id>
  <committed-date>2008-07-09T06:53:50-07:00</committed-date>
  <authored-date>2008-07-09T06:53:50-07:00</authored-date>
  <message>Added new should_change and should_not_change macros; akin to Active Support's assert_difference.</message>
  <tree>2973919c01bea5be90a959c0798160124766d0e9</tree>
  <committer>
    <name>Ryan McGeary</name>
    <email>ryanongit@mcgeary.org</email>
  </committer>
</commit>
