import Macroable from '@poppinss/macroable';
import { type Group } from '../group/main.ts';
import { type Emitter } from '../emitter.ts';
import { type Refiner } from '../refiner.ts';
import type { DataSetNode, TestEndNode, TestOptions, TestExecutor, TestHooksHandler, TestHooksCleanupHandler } from '../types.ts';
/**
 * Test class exposes a self contained API to configure and run
 * tests along with its hooks.
 *
 * @example
 * const test = new Test('2 + 2 = 4', emitter, refiner)
 *
 * test.run(async ({ assert }) => {
 *   assert.equal(2 + 2 , 4)
 * })
 */
export declare class Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> extends Macroable {
    #private;
    title: string;
    parent?: Group<Context> | undefined;
    /**
     * Methods to call before the test callback is executed
     */
    static executingCallbacks: ((test: Test<any, any>) => void)[];
    /**
     * Methods to call after the test callback is executed
     */
    static executedCallbacks: ((test: Test<any, any>, hasError: boolean, errors: TestEndNode['errors']) => void)[];
    /**
     * Define a synchronous function to call before running
     * the test executor callback
     *
     * Do note: Async methods are not allowed
     */
    static executing(callback: (test: Test<any, any>) => void): void;
    /**
     * Define a synchronous function to call after running
     * the test executor callback
     *
     * Do note: Async methods are not allowed
     */
    static executed(callback: (test: Test<any, any>, hasError: boolean, errors: TestEndNode['errors']) => void): void;
    /**
     * Know if the test has been executed. Skipped and
     * todo tests are also considered executed.
     */
    get executed(): boolean;
    /**
     * Know if the test has failed.
     */
    get failed(): boolean;
    /**
     * Test options
     */
    options: TestOptions;
    /**
     * Reference to the test dataset
     */
    dataset?: any[];
    /**
     * Reference to the test context. Available at the time
     * of running the test
     */
    context: Context;
    /**
     * Find if the test is pinned
     */
    get isPinned(): boolean;
    constructor(title: string, context: Context | ((test: Test<Context, TestData>) => Context | Promise<Context>), emitter: Emitter, refiner: Refiner, parent?: Group<Context> | undefined);
    /**
     * Skip the test conditionally
     */
    skip(skip?: boolean | (() => Promise<boolean> | boolean), skipReason?: string): this;
    /**
     * Expect the test to fail. Helpful in creating test cases
     * to showcase bugs
     */
    fails(failReason?: string): this;
    /**
     * Define custom timeout for the test
     */
    timeout(timeout: number): this;
    /**
     * Disable test timeout. It is same as calling `test.timeout(0)`
     */
    disableTimeout(): this;
    /**
     * Reset the timeout from within the test callback.
     */
    resetTimeout(duration?: number): this;
    /**
     * Assign tags to the test. Later you can use the tags to run
     * specific tests
     */
    tags(tags: string[], strategy?: 'replace' | 'append' | 'prepend'): this;
    /**
     * Configure the number of times this test should be retried
     * when failing.
     */
    retry(retries: number): this;
    /**
     * Wait for the test executor to call done method
     */
    waitForDone(): this;
    /**
     * Pin current test. Pinning a test will only run the
     * pinned tests.
     */
    pin(): this;
    /**
     * Define the dataset for the test. The test executor will be invoked
     * for all the items inside the dataset array
     */
    with<Dataset extends DataSetNode>(dataset: Dataset): Test<Context, Dataset>;
    /**
     * Define the test executor function
     */
    run(executor: TestExecutor<Context, TestData>, debuggingError?: Error): this;
    /**
     * Register a test setup function
     */
    setup(handler: TestHooksHandler<Context>): this;
    /**
     * Register a test teardown function
     */
    teardown(handler: TestHooksHandler<Context>): this;
    /**
     * Register a cleanup hook from within the test
     */
    cleanup(handler: TestHooksCleanupHandler<Context>): this;
    /**
     * Execute test
     */
    exec(): Promise<void>;
}
