Skip to content

Commit cac6263

Browse files
committed
Lazily generate assertion failure messages
Some of them can be a bit costly to generate, particularly when inspecting very large objects or when accessing the AST of procs. Minitest supports passing the message as a callable, which allow us to defer all these computations.
1 parent 869c7bf commit cac6263

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

activesupport/lib/active_support/testing/assertions.rb

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module Assertions
1919
#
2020
# assert_not foo, 'foo should be false'
2121
def assert_not(object, message = nil)
22-
message ||= "Expected #{mu_pp(object)} to be nil or false"
22+
message ||= -> { "Expected #{mu_pp(object)} to be nil or false" }
2323
assert !object, message
2424
end
2525

@@ -118,10 +118,13 @@ def assert_difference(expression, *args, &block)
118118

119119
expressions.zip(exps, before) do |(code, diff), exp, before_value|
120120
actual = exp.call
121-
code_string = code.respond_to?(:call) ? _callable_to_source_string(code) : code
122-
error = "`#{code_string}` didn't change by #{diff}, but by #{actual - before_value}"
123-
error = "#{message}.\n#{error}" if message
124-
assert_equal(before_value + diff, actual, error)
121+
rich_message = -> do
122+
code_string = code.respond_to?(:call) ? _callable_to_source_string(code) : code
123+
error = "`#{code_string}` didn't change by #{diff}, but by #{actual - before_value}"
124+
error = "#{message}.\n#{error}" if message
125+
error
126+
end
127+
assert_equal(before_value + diff, actual, rich_message)
125128
end
126129

127130
retval
@@ -196,23 +199,32 @@ def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &b
196199
retval = _assert_nothing_raised_or_warn("assert_changes", &block)
197200

198201
unless from == UNTRACKED
199-
error = "Expected change from #{from.inspect}, got #{before.inspect}"
200-
error = "#{message}.\n#{error}" if message
201-
assert from === before, error
202+
rich_message = -> do
203+
error = "Expected change from #{from.inspect}, got #{before.inspect}"
204+
error = "#{message}.\n#{error}" if message
205+
error
206+
end
207+
assert from === before, rich_message
202208
end
203209

204210
after = exp.call
205211

206-
code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression
207-
error = "`#{code_string}` didn't change"
208-
error = "#{error}. It was already #{to.inspect}" if before == to
209-
error = "#{message}.\n#{error}" if message
210-
refute_equal before, after, error
212+
rich_message = -> do
213+
code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression
214+
error = "`#{code_string}` didn't change"
215+
error = "#{error}. It was already #{to.inspect}" if before == to
216+
error = "#{message}.\n#{error}" if message
217+
error
218+
end
219+
refute_equal before, after, rich_message
211220

212221
unless to == UNTRACKED
213-
error = "Expected change to #{to.inspect}, got #{after.inspect}\n"
214-
error = "#{message}.\n#{error}" if message
215-
assert to === after, error
222+
rich_message = -> do
223+
error = "Expected change to #{to.inspect}, got #{after.inspect}\n"
224+
error = "#{message}.\n#{error}" if message
225+
error
226+
end
227+
assert to === after, rich_message
216228
end
217229

218230
retval
@@ -244,21 +256,27 @@ def assert_no_changes(expression, message = nil, from: UNTRACKED, &block)
244256
retval = _assert_nothing_raised_or_warn("assert_no_changes", &block)
245257

246258
unless from == UNTRACKED
247-
error = "Expected initial value of #{from.inspect}, got #{before.inspect}"
248-
error = "#{message}.\n#{error}" if message
249-
assert from === before, error
259+
rich_message = -> do
260+
error = "Expected initial value of #{from.inspect}, got #{before.inspect}"
261+
error = "#{message}.\n#{error}" if message
262+
error
263+
end
264+
assert from === before, rich_message
250265
end
251266

252267
after = exp.call
253268

254-
code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression
255-
error = "`#{code_string}` changed"
256-
error = "#{message}.\n#{error}" if message
269+
rich_message = -> do
270+
code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression
271+
error = "`#{code_string}` changed"
272+
error = "#{message}.\n#{error}" if message
273+
error
274+
end
257275

258276
if before.nil?
259-
assert_nil after, error
277+
assert_nil after, rich_message
260278
else
261-
assert_equal before, after, error
279+
assert_equal before, after, rich_message
262280
end
263281

264282
retval

0 commit comments

Comments
 (0)