/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
package std.unittest
import std.fs.Path
import std.collection.*
import std.unittest.common.PrettyPrinter
sealed interface Reporter<TReport, TReturn> {}
// NOTE: our predefined reporters
public class CsvReporter <: Reporter<BenchReport, Unit> {
public CsvReporter(let directory: Path) {}
}
public class CsvRawReporter <: Reporter<BenchReport, Unit> {
public CsvRawReporter(let directory: Path) {}
}
public class XmlReporter <: Reporter<TestReport, Unit> {
public XmlReporter(let directory: Path) {}
}
public class XmlPerPackageReporter <: Reporter<TestReport, Unit> {
public XmlPerPackageReporter(let directory: Path) {}
}
public class ConsoleReporter <: Reporter<TestReport, Unit> & Reporter<BenchReport, Unit> {
public ConsoleReporter(let colored!: Bool = true) {}
}
public class TextReporter<PP> <: Reporter<TestReport, PP> & Reporter<BenchReport, PP>
where PP <: PrettyPrinter {
public TextReporter(let into!: PP) {}
}
// this hidden interface is needed because check for TextReporter<PP> is impossible without satisfying
// PP <: PrettyPrinter, which cannot be satisfied in generic context
interface TextReporterBase<PP> <: Reporter<TestReport, PP> & Reporter<BenchReport, PP> {
func printReport(report: Report): PP
}
extend <PP> TextReporter<PP> <: TextReporterBase<PP> where PP <: PrettyPrinter {
public func printReport(report: Report): PP {
let outputReporter = TestOutputReporter.fromDefaultConfiguration()
TextReports.printDefaultReport(into, report.groupResult, outputReporter, report.runConfiguration)
return into
}
}
extend ConsoleReporter <: TextReporterBase<Unit> {
public func printReport(report: Report): Unit {
let pp = TerminalPrettyPrinter(colored)
let outputReporter = TestOutputReporter.fromDefaultConfiguration()
TextReports.printDefaultReport(pp, report.groupResult, outputReporter, report.runConfiguration)
}
}
// NOTE: for our internal benchmarks
public class RawStatsReporter <: Reporter<BenchReport, HashMap<String, (Float64, Float64)>> {
public RawStatsReporter() {}
func benchResultsAsMap(result: TestGroupResult): HashMap<String, (Float64,Float64)> {
let caseNameToMeasurement = HashMap<String, (Float64,Float64)>()
result.visitAll<TestCaseResult> { cr =>
for ((key, value) in getEntries(cr)) {
caseNameToMeasurement[key] = value
}
}
caseNameToMeasurement
}
private static func getEntries(tcr: TestCaseResult): ArrayList<(String, (Float64, Float64))> {
let result = ArrayList<(String, (Float64, Float64))>()
tcr.visitPassedBenches{ step =>
let key = step.caseId.caseName + (step.arg.textDescription?.toString() ?? "")
result.add((key, ((step.result.mainResult, step.result.errorEst))))
}
result
}
}