/// <reference types="node" />
import { Maybe, Nullable, ValueOf } from "vest-utils";
import { TIsolate } from "vestjs-runtime";
declare enum Severity {
    WARNINGS = "warnings",
    ERRORS = "errors"
}
declare enum TestSeverity {
    Error = "error",
    Warning = "warning"
}
declare const TestStatus: {
    [x: string]: string;
    CANCELED: string;
    FAILED: string;
    OMITTED: string;
    PASSING: string;
    SKIPPED: string;
    UNTESTED: string;
    WARNING: string;
};
type TestStatus = ValueOf<typeof TestStatus>;
type TestFnPayload = {
    signal: AbortSignal;
};
type TestFn = (payload: TestFnPayload) => TestResult;
type AsyncTest = Promise<void>;
type TestResult = Maybe<AsyncTest | boolean> | void;
type WithFieldName<F extends TFieldName = TFieldName> = {
    fieldName: F;
};
type TIsolateTest<F extends TFieldName = TFieldName, G extends TGroupName = TGroupName> = TIsolate<CommonTestFields<F, G> & IsolateTestPayload>;
type IsolateTestPayload<F extends TFieldName = TFieldName, G extends TGroupName = TGroupName> = CommonTestFields<F, G> & {
    severity: TestSeverity;
    status: TestStatus;
    asyncTest?: AsyncTest;
};
type CommonTestFields<F extends TFieldName = TFieldName, G extends TGroupName = TGroupName> = {
    message?: Maybe<string>;
    groupName?: G;
    fieldName: F;
    testFn: TestFn;
};
declare class SummaryFailure<F extends TFieldName, G extends TGroupName> implements WithFieldName<F> {
    fieldName: F;
    message: string | undefined;
    groupName: G | undefined;
    constructor(fieldName: F, message: string | undefined, groupName: G | undefined);
    static fromTestObject<F extends TFieldName, G extends TGroupName>(testObject: TIsolateTest<F, G>): SummaryFailure<F & string, G & string>;
}
interface Done<F extends TFieldName, G extends TGroupName> {
    (...args: [
        cb: (res: SuiteResult<F, G>) => void
    ]): SuiteRunResult<F, G>;
    (...args: [
        fieldName: F,
        cb: (res: SuiteResult<F, G>) => void
    ]): SuiteRunResult<F, G>;
}
interface SuiteSelectors<F extends TFieldName, G extends TGroupName> {
    getWarning(): SummaryFailure<F, G> | undefined;
    getWarning(fieldName: F): string | undefined;
    getWarning(fieldName?: F): SummaryFailure<F, G> | string | undefined;
    getError(): SummaryFailure<F, G> | undefined;
    getError(fieldName: F): string | undefined;
    getError(fieldName?: F): SummaryFailure<F, G> | string | undefined;
    getMessage(fieldName: F): string | undefined;
    getErrors(): FailureMessages;
    getErrors(fieldName: F): string[];
    getErrors(fieldName?: F): string[] | FailureMessages;
    getWarnings(): FailureMessages;
    getWarnings(fieldName: F): string[];
    getWarnings(fieldName?: F): string[] | FailureMessages;
    getErrorsByGroup(groupName: G): FailureMessages;
    getErrorsByGroup(groupName: G, fieldName: F): string[];
    getErrorsByGroup(groupName: G, fieldName?: F): string[] | FailureMessages;
    getWarningsByGroup(groupName: G): FailureMessages;
    getWarningsByGroup(groupName: G, fieldName: F): string[];
    getWarningsByGroup(groupName: G, fieldName?: F): string[] | FailureMessages;
    hasErrors(fieldName?: F): boolean;
    hasWarnings(fieldName?: F): boolean;
    hasErrorsByGroup(groupName: G, fieldName?: F): boolean;
    hasWarningsByGroup(groupName: G, fieldName?: F): boolean;
    isTested(fieldName: F): boolean;
    isPending(fieldName?: F): boolean;
    isValid(fieldName?: F): boolean;
    isValidByGroup(groupName: G, fieldName?: F): boolean;
}
declare class SummaryBase {
    errorCount: number;
    warnCount: number;
    testCount: number;
    pendingCount: number;
}
declare class SuiteSummary<F extends TFieldName, G extends TGroupName> extends SummaryBase {
    [Severity.ERRORS]: SummaryFailure<F, G>[];
    [Severity.WARNINGS]: SummaryFailure<F, G>[];
    groups: Groups<G, F>;
    tests: Tests<F>;
    valid: Nullable<boolean>;
}
type GroupTestSummary = SingleTestSummary;
type Groups<G extends TGroupName, F extends TFieldName> = Record<G, Group<F>>;
type Group<F extends TFieldName> = Record<F, GroupTestSummary>;
type Tests<F extends TFieldName> = Record<F, SingleTestSummary>;
type SingleTestSummary = SummaryBase & {
    errors: string[];
    warnings: string[];
    valid: Nullable<boolean>;
    pendingCount: number;
};
type FailureMessages = Record<string, string[]>;
type SuiteResult<F extends TFieldName, G extends TGroupName> = SuiteSummary<F, G> & SuiteSelectors<F, G> & {
    suiteName: SuiteName;
};
type SuiteRunResult<F extends TFieldName, G extends TGroupName> = SuiteResult<F, G> & {
    done: Done<F, G>;
};
type SuiteName = Maybe<string>;
type TFieldName<T extends string = string> = T;
type TGroupName<G extends string = string> = G;
type ParsedVestObject<F extends TFieldName> = {
    valid(fieldName?: F): boolean;
    tested(fieldName?: F): boolean;
    invalid(fieldName?: F): boolean;
    untested(fieldName?: F): boolean;
    warning(fieldName?: F): boolean;
    pending(fieldName?: F): boolean;
};
/**
 * Creates a function that returns class names that match the validation result
 */
declare function classnames<F extends TFieldName, G extends TGroupName>(res: SuiteSummary<F, G>, classes?: SupportedClasses): (fieldName: F) => string;
type SupportedClasses = {
    [K in keyof ParsedVestObject<TFieldName>]?: string;
};
export { classnames as default };
//# sourceMappingURL=classnames.d.ts.map