From aabe718e6483eb572566878320a0d83f430d1cbc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 8 May 2024 17:24:36 +0900 Subject: [PATCH] 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. --- tool/lib/test/unit.rb | 30 +++++++++++++++++++--------- tool/test/testunit/test_assertion.rb | 13 ++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/tool/lib/test/unit.rb b/tool/lib/test/unit.rb index d758b5fb02..2b0856b822 100644 --- a/tool/lib/test/unit.rb +++ b/tool/lib/test/unit.rb @@ -37,6 +37,26 @@ module Test class PendedError < AssertionFailedError; end + class << self + ## + # Extract the location where the last assertion method was + # called. Returns "" 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 '' 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 '' 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 ## diff --git a/tool/test/testunit/test_assertion.rb b/tool/test/testunit/test_assertion.rb index 709b495572..1e19c102b8 100644 --- a/tool/test/testunit/test_assertion.rb +++ b/tool/test/testunit/test_assertion.rb @@ -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