UNPKG

@tapjs/core

Version:
511 lines 14.1 kB
/** * The base class that is extended by all TAP-generating classes * * @module */ import { Domain } from 'async-hook-domain'; import { AsyncResource } from 'async_hooks'; import { Minipass } from 'minipass'; import { FinalResults, Parser, TapError } from 'tap-parser'; import { Deferred } from 'trivial-deferred'; import { Counts } from './counts.js'; import type { Extra, TestBase } from './index.js'; import { Lists } from './lists.js'; /** * Events emitted by the Base class */ export interface TapBaseEvents extends Minipass.Events<string> { /** * emitted when a timeout occurs */ timeout: [threw?: Extra]; /** * emitted when the test bails out */ bailout: [reason?: string]; /** * emitted when the test is complete */ complete: [results: FinalResults]; } /** * Wrapper for the async-hook-domain that catches errors thrown during * test operation. * * @see {@link https://npmjs.com/async-hook-domain} */ export declare class TapWrap extends AsyncResource { test: Base; onDestroy?: () => void; constructor(test: Base); emitDestroy(): this; } /** * A number indicating an amount of milliseconds */ export type MILLISECONDS = number; /** * Options that may be passed to any TAP-generating class */ export interface BaseOpts extends Extra { /** * Bail out on the first failure */ bail?: boolean; /** * Treat any unknown non-TAP data as an error * May be set at run-time by the TAP stream using `pragma +strict` */ strict?: boolean; /** * Do not emit the `TAP version 14` line. */ omitVersion?: boolean; /** * Do not elide empty lines and other unnecessary whitespace */ preserveWhitespace?: boolean; /** * Skip this test entirely, emitting a `# SKIP` directive */ skip?: boolean | string; /** * Mark this test as to be done later, emitting a `# TODO` directive */ todo?: boolean | string; /** * Amount of time in milliseconds before this test times out */ timeout?: MILLISECONDS; /** * track passes in the results lists, default false */ passes?: boolean; /** * treat todo tests as failures, default false */ failTodo?: boolean; /** * treat skip tests as failures, default false */ failSkip?: boolean; /** * treat only:true tests as failures, default false */ failOnly?: boolean; /** * The amount of time that this test took to complete. * * Typically, this is not set explicitly, but inferred from the actual * time spent. However in some cases, it may be reported by the * top-level `# time=...` comment in a TAP subprocess stream. */ time?: number; /** * The TAP data from a buffered test. * * @internal * * @group Internal Machinery */ tapChildBuffer?: string; /** * The stack where this test was initiated */ stack?: string; /** * Parent test of this test */ parent?: Base | TestBase; /** * The name of this test */ name?: string; /** * Numeric identifier attached to child tests. Most of the time, this is * set based on the `TAP_CHILD_ID` environment variable. */ childId?: number; /** * Any arbitrary data that is provided to this test object. Often, this * is set in a `t.before()` or `t.beforeEach()` method. Scalar values * are inherited by child tests. Object values are extended in child * tests using `Object.create()`. * * If not set in the options, this is initialized to a null-prototyped * object, so that usage like `t.context.foo = 'bar'` will work as expected. * * This is initialized and set on the Test object in the `runMain` method, * *not* at construction time. If set explicitly on the Test object in a * `before` hook, then any context specified on options or inherited from * the parent test will be ignored. */ context?: any; /** * Number of spaces that this test is indented. * * @internal * * @group Internal Machinery */ indent?: string; /** * True to output LOTS AND LOTS of noisy debugging information. * Set at the top level by the `TAP_DEBUG` environment variable. */ debug?: boolean; /** * Parser to use for this TAP stream. * * @internal * * @group Internal Machinery */ parser?: Parser; /** * True if this test should be buffered, and only processed once * complete. * * Defaults to true when `t.jobs` is set to a value greater than 1. * * If set false in that case, then the test will NOT be run in parallel, * so this provides a way to control the parallelism within a test suite. */ buffered?: boolean; /** * Setting silent:true in a subtest option makes it completely excluded * from test output, UNLESS it fails. * * This was used historically for a few things which are now implemented * with a more sophisticated promise management system, but can be handy in * some rare situations. */ silent?: boolean; } export declare class Base<Events extends TapBaseEvents = TapBaseEvents> extends Minipass<string, string, Events> { #private; /** * Set upon test completion when a child test is ready to be processed by its * parent. */ readyToProcess: boolean; /** * Options provided to this test */ options: BaseOpts; /** * number of spaces to indent the TAP stream */ indent: string; /** * TapWrap AsyncResource that limits the async-hook-domain * * @group Internal Machinery */ hook: TapWrap; /** * the async-hook-domain that catches throws and Promise rejections * * @group Internal Machinery */ hookDomain: Domain; /** * The timer that fires when the test times out * * @group Internal Machinery */ timer?: NodeJS.Timeout; /** * Set to true when the test times out, so its failure status can be * determined later. */ timedOut: boolean; /** * The tap parser attached to this TAP stream * * @group Internal Machinery */ parser: Parser; /** * Method that writes to stderr when `debug: true` is set in the options, * or no-ops otherwise */ debug: (...args: any[]) => void; /** * The count of all assertions that this stream emitted * * @group Test Reflection */ counts: Counts; /** * Lists of todo, skip, and failure test points. If `passes: true` is * set in the options, then passing test points will also be tracked. * * @group Test Reflection */ lists: Lists; /** * the name of this test * * @group Test Reflection */ name: string; /** * Set on completion. The results of the test run. * * @group Test Reflection */ results?: FinalResults; /** * Parent test of this TAP stream * * @group Internal Machinery */ parent?: Base | TestBase; /** * Nesting level, for serialization to node test runner * * Note that this is zero for parent-less tests, and *also* zero * for the first level of children. */ nestingLevel: number; /** * Bail out on the first failed test point */ bail: boolean; /** * Treat non-TAP data as an error. * May be set with `pragma +strict` in the TAP stream, or unset with * `pragma: -strict`. */ strict: boolean; /** * Do not emit the `TAP version 14` line at the start */ omitVersion: boolean; /** * Do not elide extraneous whitespace and empty lines. */ preserveWhitespace: boolean; /** * Unrecoverable TAP protocol errors in the stream * * @group Test Reflection */ errors: TapError[]; /** * Numeric identifier for this test */ childId: number; get context(): any; set context(c: any); /** * the TAP stream data for buffered tests * * @internal * * @group Internal Machinery */ output: string; /** * True if this test should be buffered and only processed on completion * * @internal * * @group Internal Machinery */ buffered: boolean; /** * True if this test emitted a bailout * * @group Test Reflection */ bailedOut: string | boolean; /** * high resolution bigint time when this test started * * @group Internal Machinery */ start: bigint; /** * Amount of time in milliseconds that this test took to complete. * * @group Test Reflection */ time: MILLISECONDS; /** * High resolution time in ns that this test took to complete. * * @group Test Reflection */ hrtime: bigint; /** * True if this test should be buffered and only emit data if it fails */ silent: boolean; /** * A `Deferred` promise wrapper that is resolved when this test completes. * * @group Internal Machinery */ deferred?: Deferred<FinalResults>; constructor(options?: BaseOpts); /** * Set the amount of time in milliseconds before this test is considered * a timeout. The time is counted from right now, so for example, repeatedly * calling `t.setTimeout(100)` can keep it going indefinitely, as long as * you call it more often than every 100ms. * * Calling `setTimeout(0)` will remove the timer and allow the test to run * indefinitely. * * @group Test Lifecycle Management */ setTimeout(n: MILLISECONDS): void; /** * Called when a timeout occurs. Only exposed because it has to be called * and/or extended by other classes, which all have their own sorts of * timeout behavior specific to the type of thing they represent. * * @internal * * @group Internal Machinery */ timeout(options?: { expired?: string; message?: string; }): void; /** * Run the `main` test function. Called by * {@link @tapjs/core!test-base.TestBase} when starting a subtest. * Initializes the TapWrap hook * * @internal * * @group Internal Machinery */ runMain(cb: () => void): void; /** * Returns true if this test has begun * * @group Test Reflection */ get started(): boolean; /** * True if the test has printed *some* output of any kind * * @group Test Reflection */ get printedOutput(): boolean; /** * Boolean indicating whether the underlying stream can be written to, * or if it has been ended. */ get streamWritable(): boolean; /** * The main test function. For this Base class, this is a no-op. Subclasses * implement this in their specific ways. * * @internal * * @group Internal Machinery */ main(cb: () => void): void; /** * Stream write method. * * For buffered tests, this collects the output in the * {@link @tapjs/core!base.Base#output} * field. Sets {@link @tapjs/core!base.Base#printedOutput} to `true` when * called. * * Note: you *probably* never need to call this. Instead, use the various * assertion methods and other parts of the API. * * @internal * * @group Internal Machinery */ write(c: string): boolean; /** * Method called when the parser encounters a bail out * * Extended by {@link @tapjs/core!test-base.TestBase} */ onbail(reason?: string): void; /** * Method called when the parser completes and emits its final results * * Extended by {@link @tapjs/core!worker.Worker} and * {@link @tapjs/core!tap.TAP} classes * * @internal * * @group Internal Machinery */ oncomplete(results: FinalResults): void; /** * extension point for plugins that want to be notified when the test * is about to end, whether explicitly or implicitly. * * If the function returns a Promise, it will be awaited before ending * the TAP stream. * * @internal * * @group Internal Machinery */ onbeforeend(): Promise<void> | void; /** * extension point for plugins that want to be notified when the test * is completely done, and terminating its parser. * * @internal * * @group Internal Machinery */ onEOF(): Promise<void> | void; /** * extension point for TestBase to know when a child tests is done being * processed and it's safe to move on to the next one. * * @internal * * @group Internal Machinery */ ondone(): void; /** * EventEmitter emit method, but closes the * {@link @tapjs/core!base.Base#hook} and * {@link @tapjs/core!base.Base#hookDomain} when emitting `'end'`. * * @internal * * @group Internal Machinery */ emit<Event extends keyof Events>(ev: Event, ...data: Events[Event]): boolean; /** * Mark the test as ended. In this base class, this is a no-op, but * in {@link @tapjs/core!test-base.TestBase}, it also triggers the other * end-of-test operations. */ end(): this; /** * Method called when an unrecoverable error is encountered in a test. * * Typically, in tests you would not call this, you'd just actually throw * an error. * * @internal * * @group Internal Machinery */ threw(er: any, extra?: Extra, proxy?: boolean, ended?: boolean): Extra | void | undefined; /** * returns true if the test has not as yet encountered any failures * * @group Test Reflection */ passing(): boolean; } //# sourceMappingURL=base.d.ts.map