From b935d6cd5bc03ba38e6e1edf674f84cbf8746ad1 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Thu, 27 Aug 2026 14:11:04 +0100 Subject: [PATCH] Use the simplecov 1.x spellings, and unstick the client base image The base image now carries simplecov 1.1.1 where it carried 0.21.2. Four spellings in the test harness are deprecated there, each announcing itself on stderr on every run: add_group -> group add_filter -> skip # :nocov: -> # simplecov:disable / # simplecov:enable and the formatter reopened SimpleCov::Formatter::JSONFormatter to redefine format, which in 1.1.1 makes ruby -w report the redefinition. It is now CoverageMetricsFormatter, named for the coverage_metrics.json it writes. It never needed to be that class: what it produces is per-group totals, not the per-file shape the shipped formatter writes, so it was only borrowing the name to make itself win. The client tests then failed where the server tests passed, because source/client/Dockerfile was pinned to cyberdojo/sinatra-base:759c4e9 on Docker Hub, while everything else moved to ghcr.io. The automated base-image PR only rewrites the Dockerfile at the repo root, so that pin had gone unbumped long enough to be serving ruby 3.3 and simplecov 0.21.2. Both Dockerfiles now name the same image, so both suites see the same gems, and the two coverage.rb copies can hold the same spellings. The group block parameter goes from the to path while passing, matching the other repos and saying what it is. Coverage is unchanged either side: server test 375 / code 253, client test 196 / code 80, nothing missed in any of them. --- source/client/Dockerfile | 2 +- source/server/differ.rb | 8 +- test/client/lib/coverage.rb | 10 +-- test/client/lib/simplecov_formatter_json.rb | 89 +++++++++++---------- test/server/lib/coverage.rb | 10 +-- test/server/lib/simplecov_formatter_json.rb | 89 +++++++++++---------- 6 files changed, 105 insertions(+), 103 deletions(-) diff --git a/source/client/Dockerfile b/source/client/Dockerfile index 868d4943..aa788e27 100644 --- a/source/client/Dockerfile +++ b/source/client/Dockerfile @@ -1,4 +1,4 @@ -FROM cyberdojo/sinatra-base:759c4e9@sha256:d5f87f343a9f88a598b810c0f02b81db0bb67319701a956aec3577cbd51c1c24 +FROM ghcr.io/cyber-dojo/sinatra-base:5ab6a10@sha256:c096154011cc1cef9cc69e8be948fb4329543f9670d4fb4fd3851a8aa016630d LABEL maintainer=jon@jaggersoft.com ARG COMMIT_SHA diff --git a/source/server/differ.rb b/source/server/differ.rb index 240d7191..b5f82246 100644 --- a/source/server/differ.rb +++ b/source/server/differ.rb @@ -14,17 +14,17 @@ def diff_summary(was_files:, now_files:) diff_plus(was_files, now_files, lines: false) end - # :nocov: + # simplecov:disable def diff_lines_files(was_files:, now_files:) diff_plus(was_files, now_files, lines: true) end - # :nocov: + # simplecov:enable - # :nocov: + # simplecov:disable def diff_summary_files(was_files:, now_files:) diff_plus(was_files, now_files, lines: false) end - # :nocov: + # simplecov:enable private diff --git a/test/client/lib/coverage.rb b/test/client/lib/coverage.rb index c5bbba57..e899276a 100644 --- a/test/client/lib/coverage.rb +++ b/test/client/lib/coverage.rb @@ -6,19 +6,19 @@ SimpleCov.start do enable_coverage :branch filters.clear - add_filter('test/lib/id58_test_base.rb') + skip('test/lib/id58_test_base.rb') coverage_dir(ENV.fetch('COVERAGE_ROOT', nil)) root(APP_DIR) test_tab = ENV.fetch('COVERAGE_TEST_TAB_NAME') code_tab = ENV.fetch('COVERAGE_CODE_TAB_NAME') - # add_group('debug') { |the| puts the.filename; false } - add_group(test_tab) { |the| the.filename.start_with?("#{APP_DIR}/test/") } - add_group(code_tab) { |the| the.filename.start_with?("#{APP_DIR}/source/") } + # group('debug') { |path| puts path.filename; false } + group(test_tab) { |path| path.filename.start_with?("#{APP_DIR}/test/") } + group(code_tab) { |path| path.filename.start_with?("#{APP_DIR}/source/") } end formatters = [ SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::JSONFormatter + CoverageMetricsFormatter ] SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(formatters) diff --git a/test/client/lib/simplecov_formatter_json.rb b/test/client/lib/simplecov_formatter_json.rb index 215dc51e..4507c71c 100644 --- a/test/client/lib/simplecov_formatter_json.rb +++ b/test/client/lib/simplecov_formatter_json.rb @@ -1,55 +1,56 @@ require 'simplecov' require 'json' -module SimpleCov - module Formatter - class JSONFormatter - # based on https://github.com/vicentllongo/simplecov-json - - def format(result) - data = { - timestamp: result.created_at.to_i, - command_name: result.command_name +# A SimpleCov formatter writing coverage_metrics.json, which check_metrics.rb +# reads. SimpleCov ships its own JSON formatter, shaped per file rather than +# per group, so this one carries its own name rather than reopening that class +# and redefining its format method. Redefining it makes ruby -w report the +# redefinition. +# +# based on https://github.com/vicentllongo/simplecov-json +class CoverageMetricsFormatter + def format(result) + data = { + timestamp: result.created_at.to_i, + command_name: result.command_name + } + result.groups.each do |name, file_list| + # name == 'code' or name == 'test' + data[name] = { + lines: { + total: file_list.lines_of_code, + covered: file_list.covered_lines, + missed: file_list.missed_lines + }, + branches: { + total: file_list.total_branches, + covered: file_list.covered_branches, + missed: file_list.missed_branches } - result.groups.each do |name, file_list| - # name == 'code' or name == 'test' - data[name] = { - lines: { - total: file_list.lines_of_code, - covered: file_list.covered_lines, - missed: file_list.missed_lines - }, - branches: { - total: file_list.total_branches, - covered: file_list.covered_branches, - missed: file_list.missed_branches - } - } - end - File.open(output_filepath, 'w+') do |file| - file.print(JSON.pretty_generate(data)) - end - puts output_message(result) - data.to_json - end + } + end + File.open(output_filepath, 'w+') do |file| + file.print(JSON.pretty_generate(data)) + end + puts output_message(result) + data.to_json + end - def output_filepath - File.join(output_path, output_filename) - end + def output_filepath + File.join(output_path, output_filename) + end - def output_filename - 'coverage_metrics.json' - end + def output_filename + 'coverage_metrics.json' + end - def output_message(result) - "Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." - end + def output_message(result) + "Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." + end - private + private - def output_path - SimpleCov.coverage_path - end - end + def output_path + SimpleCov.coverage_path end end diff --git a/test/server/lib/coverage.rb b/test/server/lib/coverage.rb index 68ab75e5..87d119ee 100644 --- a/test/server/lib/coverage.rb +++ b/test/server/lib/coverage.rb @@ -6,19 +6,19 @@ SimpleCov.start do enable_coverage :branch filters.clear - add_filter('test/lib/id58_test_base.rb') + skip('test/lib/id58_test_base.rb') coverage_dir(ENV.fetch('COVERAGE_ROOT')) root(APP_DIR) test_tab = ENV.fetch('COVERAGE_TEST_TAB_NAME') code_tab = ENV.fetch('COVERAGE_CODE_TAB_NAME') - # add_group('debug') { |the| puts the.filename; false } - add_group(test_tab) { |the| the.filename.start_with?("#{APP_DIR}/test/") } - add_group(code_tab) { |the| the.filename.start_with?("#{APP_DIR}/source/") } + # group('debug') { |path| puts path.filename; false } + group(test_tab) { |path| path.filename.start_with?("#{APP_DIR}/test/") } + group(code_tab) { |path| path.filename.start_with?("#{APP_DIR}/source/") } end formatters = [ SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::JSONFormatter + CoverageMetricsFormatter ] SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(formatters) diff --git a/test/server/lib/simplecov_formatter_json.rb b/test/server/lib/simplecov_formatter_json.rb index 215dc51e..4507c71c 100644 --- a/test/server/lib/simplecov_formatter_json.rb +++ b/test/server/lib/simplecov_formatter_json.rb @@ -1,55 +1,56 @@ require 'simplecov' require 'json' -module SimpleCov - module Formatter - class JSONFormatter - # based on https://github.com/vicentllongo/simplecov-json - - def format(result) - data = { - timestamp: result.created_at.to_i, - command_name: result.command_name +# A SimpleCov formatter writing coverage_metrics.json, which check_metrics.rb +# reads. SimpleCov ships its own JSON formatter, shaped per file rather than +# per group, so this one carries its own name rather than reopening that class +# and redefining its format method. Redefining it makes ruby -w report the +# redefinition. +# +# based on https://github.com/vicentllongo/simplecov-json +class CoverageMetricsFormatter + def format(result) + data = { + timestamp: result.created_at.to_i, + command_name: result.command_name + } + result.groups.each do |name, file_list| + # name == 'code' or name == 'test' + data[name] = { + lines: { + total: file_list.lines_of_code, + covered: file_list.covered_lines, + missed: file_list.missed_lines + }, + branches: { + total: file_list.total_branches, + covered: file_list.covered_branches, + missed: file_list.missed_branches } - result.groups.each do |name, file_list| - # name == 'code' or name == 'test' - data[name] = { - lines: { - total: file_list.lines_of_code, - covered: file_list.covered_lines, - missed: file_list.missed_lines - }, - branches: { - total: file_list.total_branches, - covered: file_list.covered_branches, - missed: file_list.missed_branches - } - } - end - File.open(output_filepath, 'w+') do |file| - file.print(JSON.pretty_generate(data)) - end - puts output_message(result) - data.to_json - end + } + end + File.open(output_filepath, 'w+') do |file| + file.print(JSON.pretty_generate(data)) + end + puts output_message(result) + data.to_json + end - def output_filepath - File.join(output_path, output_filename) - end + def output_filepath + File.join(output_path, output_filename) + end - def output_filename - 'coverage_metrics.json' - end + def output_filename + 'coverage_metrics.json' + end - def output_message(result) - "Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." - end + def output_message(result) + "Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." + end - private + private - def output_path - SimpleCov.coverage_path - end - end + def output_path + SimpleCov.coverage_path end end