evaltest

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package evaltest integrates eval reports with Go's testing package. It presents a report through a *testing.T as subtests and provides report-level assertions (RequirePass, RequireVerified) for use in ordinary Go tests. All orchestration stays in github.com/looprig/eval: evaltest only runs the suite through eval.Run and presents or asserts on the resulting report — it never re-implements the runner.

The TB subset

testing.TB carries an unexported marker method, so no type outside the testing package can implement it. evaltest therefore accepts a minimal exported subset, TB, containing only the methods it uses. Both *testing.T and testing.TB satisfy TB, so callers pass a *testing.T exactly as the design intends; a test can also supply a fake recorder that implements TB to capture the presented output without failing a real test.

Subtest presentation vs. flat fallback

Subtests require Run(string, func(*testing.T)) bool, which is a *testing.T method and is not part of TB. Run type-asserts the passed value to that method set: when present (a real *testing.T) it emits a subtest per scenario and per evaluator; when absent (a fake recorder, or a *testing.B, whose Run signature differs) it falls back to flat, line-per-assessment rendering. Presentation is informational only — it renders the verdicts but does not itself fail the test on a failing verdict. Use RequirePass or RequireVerified to gate on the report.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RequirePass

func RequirePass(tb TB, report eval.Report)

RequirePass asserts that every evaluation in report reached a passing verdict and that the report actually verified something. It fails (via Errorf) when:

  • the report has no samples (nothing was verified — fail secure: an empty report is not a pass);
  • any sample failed at the target stage (its evaluators never ran);
  • any sample succeeded at the target stage but carries zero assessments (no evaluator ran, so nothing about that sample was verified);
  • any assessment has a status other than pass or skipped; or
  • the report contains no passing assessment at all (an all-skipped or otherwise pass-free report verified nothing and is not a pass).

StatusSkipped is permitted on an individual assessment: a deliberately skipped evaluator is an intentional non-run, not a failure. But at least one passing assessment must be present for the report as a whole to pass. Every other non-pass status — fail, unverified, error — fails the assertion.

func RequireVerified

func RequireVerified(tb TB, report eval.Report)

RequireVerified asserts that every evaluation in report reached a definite disposition — that nothing was left unverified or errored, and that every sample was actually covered by at least one evaluator. It fails (via Errorf) when:

  • the report has no samples;
  • any sample failed at the target stage;
  • any sample succeeded at the target stage but carries zero assessments (no evaluator ran, so the sample was not verified); or
  • any assessment has status unverified or error.

It ACCEPTS pass, fail, and skipped: a fail is a definite quality verdict and a skipped evaluator was intentionally not run (and, being an assessment, still counts as coverage), so neither is "unverified". Unlike RequirePass it does not require a passing assessment — it asserts coverage (everything ran and decided), not that the subject passed.

func Run

func Run(tb TB, suite eval.Suite, target eval.Target, evaluators ...eval.Evaluator) eval.Report

Run executes suite against target with evaluators via eval.Run under a default RunConfig (one trial, sequential), presents the result through tb, and returns the complete report. It never fails tb on a failing or errored verdict — presentation is informational; gate the report with RequirePass or RequireVerified. It calls tb.Helper so any failure it does signal is attributed to the caller.

When eval.Run returns a non-nil error — a preflight rejection (an ill-formed suite or config, a nil target or evaluator) or a context cancellation — Run surfaces it through tb.Errorf with a safe message and still returns whatever report exists (the zero report for a preflight failure, or the partial report for a cancellation). The eval package guarantees its error strings never echo untrusted content, so the surfaced message is safe.

func RunScenario

func RunScenario(tb TB, scenario eval.Scenario, target eval.Target, evaluators ...eval.Evaluator) eval.Report

RunScenario is the single-scenario convenience: it wraps scenario in a one-scenario suite (reusing the scenario's own Name and Revision for suite identity) and delegates to Run. An ill-formed scenario is rejected by eval.Run's preflight and surfaced through tb exactly as in Run.

Types

type TB

type TB interface {
	// Helper marks the calling function as a test helper so failures are
	// attributed to the caller's line.
	Helper()
	// Logf records informational, non-failing output.
	Logf(format string, args ...any)
	// Errorf records a failure and continues (it never calls runtime.Goexit), so
	// the caller can still return the complete report.
	Errorf(format string, args ...any)
}

TB is the minimal subset of testing.TB that evaltest uses. Both *testing.T and testing.TB satisfy it, so a caller passes a *testing.T unchanged; a test may supply a fake implementation to capture presented output. The variadic any is the standard printf logging boundary and is narrowed immediately by the format verbs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL