import { type PromiseOrValue, type PromiseReference } from '@dereekb/util'; /** * A done callback function used by test frameworks to signal that a test has completed. * * Most modern test frameworks have deprecated the "done" callback in favor of async/await. */ export type TestDoneCallback = ((...args: any[]) => any) & { /** * NOTE: Not available in all test frameworks, but here for legacy purposes. * * @param error */ fail?(error?: string | { message: string; }): any; }; /** * Passes the error to the TestDoneCallback. * * @param done - the test framework's done callback to signal completion or failure * @param e - the error to pass to the callback; defaults to a generic error */ export declare function failWithTestDoneCallback(done: TestDoneCallback, e?: unknown): void; /** * A test function that receives a done callback to signal completion. */ export type TestProvidesCallbackWithDone = (cb: TestDoneCallback) => void | undefined; /** * A test function that either uses a done callback or returns a promise to signal completion. */ export type TestProvidesCallback = TestProvidesCallbackWithDone | (() => Promise); /** * Reference wrapper around a {@link TestDoneCallback} that exposes the underlying promise, * allowing callers to await the done signal. */ export type TestDoneCallbackRef = Omit & { readonly _promise: PromiseReference; readonly done: TestDoneCallback; }; /** * Creates a new TestDoneCallbackRef. * * Used to create a promise reference that can be used to assert that a test function was called. * * @returns a new {@link TestDoneCallbackRef} with a done callback and underlying promise */ export declare function testDoneCallbackRef(): TestDoneCallbackRef; /** * Wraps a callback-based test (using done) for Vitest compatibility. * Converts the callback pattern to a Promise-based pattern. * * This also supports calling the input test with async, but still only returns when done is called. * * @example * * // Before (Jasmine/Jest style): * it('test name', (done) => { * // async test code * done(); * }); * * // After (Vitest compatible): * it('test name', callbackTest((done) => { * // async test code * done(); * })); * * @param testFn - the callback-based test function that receives a done callback * @returns a Promise-based wrapper function suitable for Vitest or other async test runners */ export declare function callbackTest(testFn: TestProvidesCallbackWithDone | ((cb: TestDoneCallback) => PromiseOrValue)): () => Promise; /** * A fixture instance that is generated new for each test run. */ export type TestFixtureInstance = I; /** * The test fixture is used as a singleton across tests used in a single context. * * This allows us to define tests while referencing the instance. */ export interface TestFixture { readonly instance: TestFixtureInstance; } /** * Cleanup function returned by {@link TestContextFixture.setInstance} to clear the current instance after a test completes. */ export type TestContextFixtureClearInstanceFunction = () => void; /** * TestFixture with additional functions that the TestContextFactory sees for managing the instance. * * The fixture is used as a reference point for the Instance that is changed between each test. */ export interface TestContextFixture extends TestFixture { /** * Sets the instance before the tests run, and returns a function to clean the instance later. * * If called again before the instance is finished being used, this should throw an exception. * * @param instance */ setInstance(instance: I): TestContextFixtureClearInstanceFunction; } /** * Abstract TestContextFixture instance. */ export declare abstract class AbstractTestContextFixture implements TestContextFixture { private _instance?; get instance(): I; setInstance(instance: I): TestContextFixtureClearInstanceFunction; } /** * Abstract TestContextFixture instance with a parent. */ export declare abstract class AbstractChildTestContextFixture> extends AbstractTestContextFixture { readonly parent: P; constructor(parent: P); } /** * Function that declares tests using the provided fixture. Called during test suite setup * to register test cases that will later run against fresh fixture instances. */ export type BuildTestsWithContextFunction = (fixture: F) => void; /** * Used for tests to execute a number of tests using the fixture. * * The fixture is automatically setup and torn down each test per the configuration with a clean fixture instance. */ export type TestContextFactory = (buildTests: BuildTestsWithContextFunction) => void; /** * Used to configure a TestContextFactory for building tests. */ export type TestContextBuilderFunction, C> = (config?: Partial) => TestContextFactory; export interface TestContextBuilderConfig, C> { /** * Builds a config given the optional, partial input config. This is used across all tests. */ buildConfig: (config?: Partial) => C; /** * Builds a new fixture to use across all encapsulated tests. */ buildFixture: (config: C) => F; /** * Arbitrary before each function, called before the instance is setup. */ beforeEach?: () => Promise; /** * Use for building an instance. * * When the promise resolves it should be ready to be used by the test being executed. */ setupInstance: (config: C) => Promise; /** * Use for cleaning up the instance before the next test. */ teardownInstance: (instance: I, config: C) => Promise; /** * Arbitrary after each function. */ afterEach?: () => Promise; } /** * Creates a TestContextBuilderFunction given the input builder. * * @param builder - configuration defining how to build configs, fixtures, and manage instance lifecycle * @returns a builder function that accepts optional partial config and produces a {@link TestContextFactory} */ export declare function testContextBuilder, C>(builder: TestContextBuilderConfig): TestContextBuilderFunction; /** * Configuration for {@link useTestContextFixture} that defines how to initialize and destroy * test instances, along with the fixture and test-building function. */ export interface UseContextFixture, I> { readonly fixture: C; readonly buildTests: BuildTestsWithContextFunction; initInstance(): PromiseOrValue; destroyInstance?(instance: I): PromiseOrValue; } /** * Registers beforeEach/afterEach hooks that manage instance lifecycle for a test context fixture. * * Before each test, a new instance is created and set on the fixture. After each test, the instance * is cleared and optionally destroyed. Test declarations happen synchronously between the hooks. * * @param config - fixture, test builder, and instance lifecycle functions */ export declare function useTestContextFixture, I>(config: UseContextFixture): void;