import { ResolvablePromise } from "../utils/utils";
import { Formatter, Messages, TestInfo } from "../formatters";
import { SpawnTestFileOptions } from "../spawnTestFile/spawnTestFile";
type AssertSnapshotObject<ARR, ACT> = {
    [name: string]: (act: Awaited<ACT>, arrange: Awaited<ARR>, after: After) => unknown;
};
export type After = <T>(data: T, cb: (data: T) => void) => T;
export type DescribeCallback = (test: TestFunction, after: After) => unknown;
export type TestInterface<ARR, ACT, ASS> = {
    ARRANGE?(after: After): ARR;
    ACT?(arrange: Awaited<ARR>, after: After): ACT;
    ASSERT?(act: Awaited<ACT>, arrange: Awaited<ARR>, after: After): ASS;
    ASSERTS?: AssertSnapshotObject<ARR, ACT>;
    SNAPSHOTS?: AssertSnapshotObject<ARR, ACT>;
} | {
    ARRANGE?(after: After): ARR;
    SNAPSHOT?(arrange: Awaited<ARR>, after: After): ACT;
    ASSERT?(act: Awaited<ACT>, arrange: Awaited<ARR>, after: After): ASS;
    ASSERTS?: AssertSnapshotObject<ARR, ACT>;
};
export type TestFunction = {
    <ARR, ACT, ASS>(description: string, testData: TestInterface<ARR, ACT, ASS>): Promise<void>;
    test: TestFunction;
    describe(description: string, cb: (test: TestFunction, after: After) => unknown): Promise<void>;
    after(cb: () => void): void;
};
export type RunTestFileOptions = {
    clearModuleCache: boolean;
};
export type SummaryResult = {
    count: number;
    ok: number;
    error: number;
};
export type Summary = {
    test: SummaryResult;
    assert: SummaryResult;
    describe: SummaryResult;
    total: SummaryResult;
    failed: {
        fileId: string;
        id: number;
        test: TestInfo;
        error: string;
    }[];
};
export type TestOptions = {
    snapshotsFolder?: string;
    confirmSnapshots?: boolean;
    reviewSnapshots?: boolean;
    regenerateSnapshots?: boolean;
    coverage?: boolean;
    coverageExclude?: RegExp[];
    coverageNoBranches?: boolean;
    coverageNoSourceMaps?: boolean;
    coverageTarget?: number;
    timeout?: number;
};
export type { Test };
type FullTestOptions = {
    description: string;
    descriptionPath: string[];
} & Required<TestOptions>;
type TestContext = {
    send: (msg: Messages) => void;
    readFile(path: string): Promise<Buffer>;
    writeFile(path: string, data: Buffer): Promise<void>;
};
declare class Test<ARR = any, ACT = any, ASS = any> {
    private _context;
    protected _options: FullTestOptions;
    readonly data?: (TestInterface<ARR, ACT, ASS> | DescribeCallback) | undefined;
    private _promise;
    private _pendingPromise;
    private _tests;
    private _pending;
    private _finished;
    private _ended;
    private _afters;
    protected _afterTest: (() => void)[];
    private _testErrors;
    readonly id: number;
    private _addAfter;
    constructor(_context: TestContext, _options: FullTestOptions, data?: (TestInterface<ARR, ACT, ASS> | DescribeCallback) | undefined);
    run(): Promise<void>;
    end(): Promise<void>;
    private _isDescribe;
    formatPath(): string;
    private _getAsserts;
    private _getSnapshots;
    describe(description: string, cb: DescribeCallback): ResolvablePromise;
    test<ARR, ASS, ACT>(description: string, testData: TestInterface<ARR, ASS, ACT>): ResolvablePromise;
    after(cb: () => void): void;
    private _add;
    private _runPending;
    private _awaitSubtests;
    private _runDescribe;
    private _checkSnapshot;
    private _runAssert;
    private _runSnapshot;
    private _runTest;
    private _runAfters;
    protected _runAfterTests(): Promise<void>;
}
declare class Root extends Test {
    formatter: Formatter | null;
    readonly summary: Summary;
    private _summaryMap;
    readonly notifyParentProcess: ((msg: {
        type: "testRunner";
        data: Messages;
    }) => void) | null;
    private _pendingSends;
    constructor(notifyParentProcess: ((msg: {
        type: "testRunner";
        data: Messages;
    }, sendHandle?: undefined, options?: undefined, callback?: (err: Error | null) => void) => boolean) | null, options?: TestOptions);
    awaitPendingSends(): Promise<void>;
    protected _runAfterTests(): Promise<void>;
    processMessage(fileId: string, msg: Messages): void;
    setFormatter(formatter: Formatter): void;
    runTestFile(file: string, options: RunTestFileOptions): any;
    spawnTestFile(file: string, options: SpawnTestFileOptions): Promise<void>;
}
export declare function isMessage(msg: unknown): msg is {
    data: Messages;
};
export declare function newRoot(options?: TestOptions): Root;
declare const _default: TestFunction;
export default _default;
