Files
computer-playbook/tests/utils/minitest_junit.rb
kevinveenbirkenbach 50a3edf3c2 feat(test): report the javascript, php and ruby suites in the CI summary
The step summary renders every junit report under build/test-reports,
so the three suites were absent from it for want of a report file. They
now write one under the same name the python runner derives from
INFINITO_TEST_TYPE.

minitest ships no junit reporter, and a gem for one file would be a
dependency the otherwise stdlib-only suite does not need, so it gets a
small plugin instead. The runners also provision their own toolchain
now that the host-side make prerequisites are gone.
2026-08-22 22:27:12 +02:00

70 lines
1.8 KiB
Ruby

# frozen_string_literal: true
# Minitest plugin writing a junit-xml report to INFINITO_JUNIT_REPORT.
require "minitest"
module Minitest
class InfinitoJUnitReporter < AbstractReporter
# @param path [String] file the junit report is written to
def initialize(path)
super()
@path = path
@results = []
end
def record(result)
@results << result
end
def report
require "fileutils"
FileUtils.mkdir_p(File.dirname(@path))
File.write(@path, document)
end
private
def document
body = @results.map { |result| testcase(result) }
['<?xml version="1.0" encoding="utf-8"?>', "<testsuites>", *body, "</testsuites>", ""].join("\n")
end
def testcase(result)
seconds = format("%.6f", result.time)
head = "<testcase name=#{escape(result.name)} " \
"classname=#{escape(result.klass)} time=\"#{seconds}\""
body = outcome(result)
body.empty? ? "#{head}/>" : "#{head}>#{body}</testcase>"
end
def outcome(result)
return "" if result.failures.empty?
failure = result.failures.first
message = escape("#{failure.class}: #{failure.message}")
return "<skipped message=#{message}/>" if result.skipped?
tag = failure.is_a?(UnexpectedError) ? "error" : "failure"
"<#{tag} message=#{message}/>"
end
def escape(value)
quoted = value.to_s
.gsub("&", "&amp;")
.gsub("<", "&lt;")
.gsub(">", "&gt;")
.gsub('"', "&quot;")
%("#{quoted}")
end
end
# @param _options [Hash] minitest runner options, unused
def self.plugin_infinito_junit_init(_options)
path = ENV.fetch("INFINITO_JUNIT_REPORT", nil)
reporter << InfinitoJUnitReporter.new(path) unless path.nil? || path.empty?
end
end
Minitest.extensions << "infinito_junit"