4 # Test numeric difference between the return value of an expression as a result of what is evaluated
5 # in the yielded block.
7 # assert_difference 'Article.count' do
8 # post :create, :article => {...}
11 # An arbitrary expression is passed in and evaluated.
13 # assert_difference 'assigns(:article).comments(:reload).size' do
14 # post :create, :comment => {...}
17 # An arbitrary positive or negative difference can be specified. The default is +1.
19 # assert_difference 'Article.count', -1 do
20 # post :delete, :id => ...
23 # An array of expressions can also be passed in and evaluated.
25 # assert_difference [ 'Article.count', 'Post.count' ], +2 do
26 # post :create, :article => {...}
29 # A error message can be specified.
31 # assert_difference 'Article.count', -1, "An Article should be destroyed" do
32 # post :delete, :id => ...
34 def assert_difference(expression
, difference
= 1, message
= nil, &block
)
35 b
= block
.send(:binding)
36 exps
= Array
.wrap(expression
)
37 before
= exps
.map
{ |e
| eval(e
, b
) }
41 exps
.each_with_index
do |e
, i
|
42 error
= "#{e.inspect} didn't change by #{difference}"
43 error
= "#{message}.\n#{error}" if message
44 assert_equal(before
[i
] + difference
, eval(e
, b
), error
)
48 # Assertion that the numeric result of evaluating an expression is not changed before and after
49 # invoking the passed in block.
51 # assert_no_difference 'Article.count' do
52 # post :create, :article => invalid_attributes
55 # A error message can be specified.
57 # assert_no_difference 'Article.count', "An Article should not be destroyed" do
58 # post :create, :article => invalid_attributes
60 def assert_no_difference(expression
, message
= nil, &block
)
61 assert_difference expression
, 0, message
, &block