From 18150e0d78abfacfdff71f3ffa0e3aaf70d196ad Mon Sep 17 00:00:00 2001 From: Robin Miller Date: Wed, 10 Sep 2025 15:57:37 -0600 Subject: [PATCH 1/2] Enable coverage for all files and add branch coverage tracking. --- test/json/test_helper.rb | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/test/json/test_helper.rb b/test/json/test_helper.rb index cf592deb..52938915 100644 --- a/test/json/test_helper.rb +++ b/test/json/test_helper.rb @@ -1,14 +1,6 @@ $LOAD_PATH.unshift(File.expand_path('../../../ext', __FILE__), File.expand_path('../../../lib', __FILE__)) -begin - require 'simplecov' -rescue LoadError - # Don't fail Ruby's test suite -else - SimpleCov.start -end - -require 'json' +require "coverage" require 'test/unit' if ENV["JSON_COMPACT"] @@ -35,3 +27,32 @@ require "core_assertions" Test::Unit::TestCase.include Test::Unit::CoreAssertions end + +Test::Unit.at_exit do + begin + require 'simplecov' + rescue LoadError + # Don't fail Ruby's test suite + else + # Force SimpleCov to include all files in its report, avoiding accidental require-order misses + SimpleCov.track_files 'lib/**/*.rb' + + SimpleCov.add_filter 'lib/json/truffle_ruby' unless RUBY_ENGINE == 'truffleruby' + + SimpleCov.enable_coverage :branch + SimpleCov.primary_coverage :branch + + # must be true for SimpleCov to generate a result at all + SimpleCov.running = true + coverage = SimpleCov.result + + SimpleCov.write_last_run(coverage) + coverage.format! + end +end + +# Start built-in Coverage directly because SimpleCov depends on JSON gem, wrecking the require order. +# SimpleCov is still used for the pretty formatting afterward. +# require is at end of file to avoid coverage monitoring any irrelevant code (eg. Test::Unit) +Coverage.start(lines: true, branches: true) +require 'json' From 11dde98afa685ea80d980352f6905b1adf9e0fdd Mon Sep 17 00:00:00 2001 From: Robin Miller Date: Wed, 10 Sep 2025 17:05:18 -0600 Subject: [PATCH 2/2] Use a require prepend in testing to prevent circular require breaking SimpleCov --- test/json/test_helper.rb | 55 +++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/test/json/test_helper.rb b/test/json/test_helper.rb index 52938915..5d230037 100644 --- a/test/json/test_helper.rb +++ b/test/json/test_helper.rb @@ -1,6 +1,5 @@ $LOAD_PATH.unshift(File.expand_path('../../../ext', __FILE__), File.expand_path('../../../lib', __FILE__)) -require "coverage" require 'test/unit' if ENV["JSON_COMPACT"] @@ -28,31 +27,45 @@ Test::Unit::TestCase.include Test::Unit::CoreAssertions end -Test::Unit.at_exit do - begin - require 'simplecov' - rescue LoadError - # Don't fail Ruby's test suite - else - # Force SimpleCov to include all files in its report, avoiding accidental require-order misses - SimpleCov.track_files 'lib/**/*.rb' +# The built-in Coverage module (and therefore SimpleCov) need to be activated prior to any require statements. +# But! SimpleCov requires 'json' before activating Coverage measurement, meaning it misses several files. +# +# The solution is to defer any JSON requires from SimpleCov, which works out because we require it ourselves before +# SimpleCov actually uses it for anything. +module JSONTestPatch + def require(name) + if name == 'json' + caller_path = caller_locations.first.path + + return false if caller_path.match? %r(/simplecov/) + end + + super(name) + end +end +Kernel.prepend JSONTestPatch - SimpleCov.add_filter 'lib/json/truffle_ruby' unless RUBY_ENGINE == 'truffleruby' +begin + require 'simplecov' +rescue LoadError + # Don't fail Ruby's test suite +else + # Override default at_exit or else it will fire when the Rake task process ends early + SimpleCov.external_at_exit = true + Test::Unit.at_exit do + SimpleCov.at_exit_behavior + end - SimpleCov.enable_coverage :branch - SimpleCov.primary_coverage :branch + SimpleCov.start do + # Force SimpleCov to include all files in its report, avoiding accidental require-order misses + track_files 'lib/**/*.rb' - # must be true for SimpleCov to generate a result at all - SimpleCov.running = true - coverage = SimpleCov.result + add_filter 'lib/json/truffle_ruby' unless RUBY_ENGINE == 'truffleruby' - SimpleCov.write_last_run(coverage) - coverage.format! + enable_coverage :branch + primary_coverage :branch end end -# Start built-in Coverage directly because SimpleCov depends on JSON gem, wrecking the require order. -# SimpleCov is still used for the pretty formatting afterward. -# require is at end of file to avoid coverage monitoring any irrelevant code (eg. Test::Unit) -Coverage.start(lines: true, branches: true) +# Require must be after SimpleCov is started for it to see the code require 'json'