class SpecReporter
implements Reporter

Human-readable reporter: tests nested under their QUnit module, with failures shown inline where they happen. The shape Node, Vitest and Mocha all default to — raw TAP is a poor local-dev experience.

Module headers are printed on change rather than buffered to the end, so output streams. Under concurrent groups the testEnd events interleave, so a module header can legitimately reappear — that reflects what actually ran, and beats withholding output until the run ends.

import type { ReporterContext } from './types.ts';

import type { TestDetails } from './types.ts';

// Defined, not invoked: streams the nested spec view to stdout.
function example(context: ReporterContext, details: TestDetails) {
  const reporter = new SpecReporter();
  reporter.onRunStart(context, { fileCount: 1, groupCount: 1 });
  reporter.onTestEnd(context, details); // "  ✔ adds (2ms)" under its module header
  reporter.onRunEnd(context, { durationMs: 350 });
}

Methods

onRunEnd(): void

Prints the outcome counts and, when any test failed, the failure recap.

import type { ReporterContext } from './types.ts';

// Defined, not invoked: reads context.counts and writes to stdout.
function example(reporter: SpecReporter, context: ReporterContext) {
  reporter.onRunEnd(context, { durationMs: 350 });
  // "  4 passing (350ms)" plus a numbered "Failures:" recap when anything failed
}

Resets per-run state and prints the run banner.

import type { ReporterContext } from './types.ts';

// Defined, not invoked: prints the banner to stdout.
function example(context: ReporterContext) {
  new SpecReporter().onRunStart(context, { fileCount: 3, groupCount: 2 });
  // "Running 3 test files across 2 worker(s)"
}
onTestEnd(
context: ReporterContext,
details: TestDetails
): void

Prints the module header when it changes, then this test's result line.

import type { ReporterContext } from './types.ts';

// Defined, not invoked: writes the header + result line to stdout.
function example(reporter: SpecReporter, context: ReporterContext) {
  reporter.onTestEnd(context, { status: 'passed', fullName: ['Math', 'adds'], runtime: 2 });
  // "Math" (only when the module changed) then "  ✔ adds (2ms)"
}

Usage

import { SpecReporter } from "lib/reporters/spec.ts";