Add from: option to ActiveSupport::TestCase#assert_no_changes

Permit asserting on the initial value that is expected not to change.
This commit is contained in:
George Claghorn 2021-05-23 16:22:43 -04:00
parent e888e3cf87
commit 21aea0db55
3 changed files with 60 additions and 3 deletions

@ -1,3 +1,15 @@
* The `from:` option is added to `ActiveSupport::TestCase#assert_no_changes`.
It permits asserting on the initial value that is expected not to change.
```ruby
assert_no_changes -> { Status.all_good? }, from: true do
post :create, params: { status: { ok: true } }
end
```
*George Claghorn*
* Deprecate `ActiveSupport::SafeBuffer`'s incorrect implicit conversion of objects into string.
Except for a few methods like `String#%`, objects must implement `#to_str`
@ -73,9 +85,9 @@
Ruby requires an initializer for non-numeric type as per examples below:
```ruby
%w[foo bar].sum('')
%w[foo bar].sum('')
# instead of %w[foo bar].sum
[[1, 2], [3, 4, 5]].sum([])
#instead of [[1, 2], [3, 4, 5]].sum
```

@ -207,16 +207,30 @@ def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &b
# 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)
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"

@ -286,6 +286,37 @@ def test_assert_no_changes_pass
end
end
def test_assert_no_changes_with_from_option
assert_no_changes "@object.num", from: 0 do
# ...
end
end
def test_assert_no_changes_with_from_option_with_wrong_value
assert_raises Minitest::Assertion do
assert_no_changes "@object.num", from: -1 do
# ...
end
end
end
def test_assert_no_changes_with_from_option_with_nil
error = assert_raises Minitest::Assertion do
assert_no_changes "@object.num", from: nil do
@object.increment
end
end
assert_equal "Expected initial value of nil", error.message
end
def test_assert_no_changes_with_from_and_case_operator
token = SecureRandom.hex
assert_no_changes -> { token }, from: /\w{32}/ do
# ...
end
end
def test_assert_no_changes_with_message
error = assert_raises Minitest::Assertion do
assert_no_changes "@object.num", "@object.num should not change" do