js/commands/test

js/commands/test.ts

fino:commands/test — reusable fino test command task.

Builds the fino test command as a Task from fino:task, so the same command definition backs the root Fino CLI and can be mounted by any other interface (a custom CLI, a tool surface) that speaks the Task protocol.

Positional arguments may be direct files, directories, or glob patterns. Directories expand to every .test.ts file beneath them, globs are resolved from the current working directory, and direct files are taken as given. Each matched module is dynamically imported — describe() and it() calls at module top level register tests as a side effect — and then execution is delegated to run() from fino:test/test, which emits TAP output.

Before importing anything the command calls allowInternalForTests(), lifting the loader's internal:* import restriction so test files can exercise internal modules directly.

import testCommand from 'fino:commands/test';

// Run every test under tests/net whose describe path mentions "socket".
await testCommand.parse(['--filter', 'socket', 'tests/net']);

Constants

const command

The test subcommand mounted by the root Fino CLI.

The command requires at least one positional path. Each argument is expanded (directories to their .test.ts files, globs from the current working directory, direct files as given); when the expanded set contains any .test.ts module, non-test helper files that also matched are dropped so directory and glob inputs only import real test modules. Every surviving file is imported for its registration side effects, then the run is handed to run() from fino:test/test.

Options map straight onto the runner: --filter keeps only describe() groups whose full path contains the given substring, --show-output controls when captured console output is printed (failures — the default — always, or never), and --durations appends duration=<time> metadata to every TAP result line.

Output is TAP text by default. When invoked with a json writer (for example fino test --json ...) the command instead emits a single JSON object describing the run: the raw inputs, the imported files, the effective options, and the runner's output.

Throws if no files are supplied, if expansion matches no files, or if --show-output is given an unrecognized value. Test failures do not throw here — they are reported through the runner's TAP output and exit code.

import test from 'fino:commands/test';

// Everything under tests/, with per-test durations.
await test.parse(['--durations', 'tests/']);

// Just the socket suites, showing console output even on success.
await test.parse(['--filter', 'socket', '--show-output', 'always', 'tests/net']);