diff options
-rw-r--r-- | activesupport/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activesupport/lib/active_support/testing/assertions.rb | 28 | ||||
-rw-r--r-- | activesupport/test/test_case_test.rb | 29 |
3 files changed, 57 insertions, 7 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index a21a817fbb..acff6367f2 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,10 @@ +* Support hash as first argument in `assert_difference`. This allows to specify multiple + numeric differences in the same assertion. + + assert_difference ->{ Article.count } => 1, ->{ Post.count } => 2 + + *Julien Meichelbeck* + * Add missing instrumentation for `read_multi` in `ActiveSupport::Cache::Store`. *Ignatius Reza Lesmana* diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb index 6f69c48674..a891ff616d 100644 --- a/activesupport/lib/active_support/testing/assertions.rb +++ b/activesupport/lib/active_support/testing/assertions.rb @@ -58,6 +58,12 @@ module ActiveSupport # post :create, params: { article: {...} } # end # + # A hash of expressions/numeric differences can also be passed in and evaluated. + # + # assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do + # post :create, params: { article: {...} } + # end + # # A lambda or a list of lambdas can be passed in and evaluated: # # assert_difference ->{ Article.count }, 2 do @@ -73,20 +79,28 @@ module ActiveSupport # assert_difference 'Article.count', -1, 'An Article should be destroyed' do # post :delete, params: { id: ... } # end - def assert_difference(expression, difference = 1, message = nil, &block) - expressions = Array(expression) - - exps = expressions.map { |e| + def assert_difference(expression, *args, &block) + expressions = + if expression.is_a?(Hash) + message = args[0] + expression + else + difference = args[0] || 1 + message = args[1] + Hash[Array(expression).map { |e| [e, difference] }] + end + + exps = expressions.keys.map { |e| e.respond_to?(:call) ? e : lambda { eval(e, block.binding) } } before = exps.map(&:call) retval = yield - expressions.zip(exps).each_with_index do |(code, e), i| - error = "#{code.inspect} didn't change by #{difference}" + expressions.zip(exps, before) do |(code, diff), exp, before_value| + error = "#{code.inspect} didn't change by #{diff}" error = "#{message}.\n#{error}" if message - assert_equal(before[i] + difference, e.call, error) + assert_equal(before_value + diff, exp.call, error) end retval diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index 79b75a001a..eced622137 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -115,6 +115,35 @@ class AssertDifferenceTest < ActiveSupport::TestCase end end + def test_hash_of_expressions + assert_difference "@object.num" => 1, "@object.num + 1" => 1 do + @object.increment + end + end + + def test_hash_of_expressions_with_message + error = assert_raises Minitest::Assertion do + assert_difference({ "@object.num" => 0 }, "Object Changed") do + @object.increment + end + end + assert_equal "Object Changed.\n\"@object.num\" didn't change by 0.\nExpected: 0\n Actual: 1", error.message + end + + def test_hash_of_lambda_expressions + assert_difference -> { @object.num } => 1, -> { @object.num + 1 } => 1 do + @object.increment + end + end + + def test_hash_of_expressions_identify_failure + assert_raises(Minitest::Assertion) do + assert_difference "@object.num" => 1, "1 + 1" => 1 do + @object.increment + end + end + end + def test_assert_changes_pass assert_changes "@object.num" do @object.increment |