Show the caller location of assertion methods

Not only defined in `Test::Unit` or `CoreAssertions`, also show the
caller location of assertion methods defined in the current class or
ancestors.
This commit is contained in:
Nobuyoshi Nakada 2024-05-08 17:24:36 +09:00
parent b4b39a6199
commit aabe718e64
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
2 changed files with 34 additions and 9 deletions

View File

@ -37,6 +37,26 @@ module Test
class PendedError < AssertionFailedError; end
class << self
##
# Extract the location where the last assertion method was
# called. Returns "<empty>" if _e_ does not have backtrace, or
# an empty string if no assertion method location was found.
def location e
last_before_assertion = nil
return '<empty>' unless e&.backtrace # SystemStackError can return nil.
e.backtrace.reverse_each do |s|
break if s =~ /:in \W(?:.*\#)?(?:assert|refute|flunk|pass|fail|raise|must|wont)/
last_before_assertion = s
end
return "" unless last_before_assertion
/:in / =~ last_before_assertion ? $` : last_before_assertion
end
end
module Order
class NoSort
def initialize(seed)
@ -1778,15 +1798,7 @@ module Test
end
def location e # :nodoc:
last_before_assertion = ""
return '<empty>' unless e&.backtrace # SystemStackError can return nil.
e.backtrace.reverse_each do |s|
break if s =~ /in .(?:Test::Unit::(?:Core)?Assertions#)?(assert|refute|flunk|pass|fail|raise|must|wont)/
last_before_assertion = s
end
last_before_assertion.sub(/:in .*$/, '')
Test::Unit.location e
end
##

View File

@ -50,4 +50,17 @@ class TestAssertion < Test::Unit::TestCase
assert_pattern_list(pattern_list, actual, message)
end
end
def test_caller_bactrace_location
begin
line = __LINE__; assert_fail_for_backtrace_location
rescue Test::Unit::AssertionFailedError => e
end
location = Test::Unit::Runner.new.location(e)
assert_equal "#{__FILE__}:#{line}", location
end
def assert_fail_for_backtrace_location
assert false
end
end