lib/active_support/testing/assertions.rb in activesupport-6.1.7.10 vs lib/active_support/testing/assertions.rb in activesupport-7.0.0.alpha1

- old
+ new

@@ -97,11 +97,11 @@ exps = expressions.keys.map { |e| e.respond_to?(:call) ? e : lambda { eval(e, block.binding) } } before = exps.map(&:call) - retval = assert_nothing_raised(&block) + retval = _assert_nothing_raised_or_warn("assert_difference", &block) 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_value + diff, exp.call, error) @@ -174,11 +174,11 @@ # end def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } before = exp.call - retval = assert_nothing_raised(&block) + retval = _assert_nothing_raised_or_warn("assert_changes", &block) unless from == UNTRACKED error = "Expected change from #{from.inspect}" error = "#{message}.\n#{error}" if message assert from === before, error @@ -205,20 +205,34 @@ # # assert_no_changes 'Status.all_good?' do # post :create, params: { status: { ok: true } } # end # + # Provide the optional keyword argument :from to specify the expected + # initial value. + # + # assert_no_changes -> { Status.all_good? }, from: true do + # post :create, params: { status: { ok: true } } + # end + # # An error message can be specified. # # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do # post :create, params: { status: { ok: false } } # end - def assert_no_changes(expression, message = nil, &block) + def assert_no_changes(expression, message = nil, from: UNTRACKED, &block) exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } before = exp.call - retval = assert_nothing_raised(&block) + retval = _assert_nothing_raised_or_warn("assert_no_changes", &block) + + unless from == UNTRACKED + error = "Expected initial value of #{from.inspect}" + error = "#{message}.\n#{error}" if message + assert from === before, error + end + after = exp.call error = "#{expression.inspect} changed" error = "#{message}.\n#{error}" if message @@ -228,8 +242,24 @@ assert_equal before, after, error end retval end + + private + def _assert_nothing_raised_or_warn(assertion, &block) + assert_nothing_raised(&block) + rescue Minitest::UnexpectedError => e + if tagged_logger && tagged_logger.warn? + warning = <<~MSG + #{self.class} - #{name}: #{e.error.class} raised. + If you expected this exception, use `assert_raises` as near to the code that raises as possible. + Other block based assertions (e.g. `#{assertion}`) can be used, as long as `assert_raises` is inside their block. + MSG + tagged_logger.warn warning + end + + raise + end end end end