/**
 * @module law The Law type and functions for working with a single law.
 */
import { Option as OP, Predicate as PR } from 'effect';
import fc from 'fast-check';
/**
 * A paper-thin wrapper over a fast-check property and its runtime
 * configuration adding:
 * 1. `Law ≡ property + assert + test` - Testing a law will run the
 *    _fast-check_ property inside an assertion inside
 *    [a vitest](https://vitest.dev/guide/features.html)
 *    `test(() => {...})` block. This means you can call
 *    [testLaw](https://middle-ages.github.io/effect-ts-laws-docs/functions/testLaw.html)
 *    and/or
 *    [testLaws](https://middle-ages.github.io/effect-ts-laws-docs/functions/testLaws.html)
 *    from inside a `describe(() => {...})` block, or even from the
 *    top level of your test file, but _not_ inside a
 *    `test(() => {...})` block.
 *       - The law can also be _checked_, instead of _tested_ using `checkLaw`.
 *         This exactly the same as `testLaw`, except in a pure function that
 *         returns the test results without using any `vitest` blocks.
 * 2. One or more Laws can be grouped under a single label into a `LawSet`.
 *    Useful for testing units that require multiple laws, for example
 *    typeclasses.  Besides its child _laws_, a `LawSet` can includes other
 *    `LawSets` as requirements to be run as a guard before testing its own
 *    laws.
 * 3. A law has a name, just like the `fc.Property` it is wrapping, but also
 *    a field for a note. It is shown only on failure or when the `fast-check`
 *    runtime parameter `verbose` is true.
 * A law can be converted into a `fast-check` property and tested.
 * @typeParam Ts - Tuple whose elements are the predicate arguments.
 * @category model
 */
export interface Law<Ts extends UnknownArgs> {
    /**
     * Law name to be used as test name. You can include a description of the
     * unit under test or anything else you wish to appear in the test name,
     * for example: `MyList.map:associative`.
     */
    name: string;
    /** A note shown only on failure or in verbose mode. */
    note: string;
    /**
     * Predicate to be tested. Its arguments will appear in a single tuple.
     */
    predicate: PR.Predicate<Ts>;
    /** Arbitrary for the arguments tuple of the predicate. */
    arbitrary: fc.Arbitrary<Ts>;
    /**
     * `fast-check` configuration
     * [parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
     * This configuration will override global fast-check configuration, but test
     * parameters may override this configuration.
     */
    parameters?: ParameterOverrides;
}
/**
 * Build a law from a name, a predicate, an optional note, an arbitrary for the
 * predicate arguments, and optional `fast-check` runtime parameters.
 * The runtime parameters are
 * [documented here](https://fast-check.dev/api-reference/interfaces/Parameters.html).
 * @example
 * import {Law, checkLaw, tinyPositive} from 'effect-ts-laws'
 * import {Option as OP} from 'effect'
 *
 * export const law: Law<[number, number]> = Law(
 *   'sum of positives ≥ both',           // • law name
 *   '∀a,b in N, sum=a+b: sum≥a ∧ sum≥b', // • law note
 *   tinyPositive,                        // • list of
 *   tinyPositive,                        //   arbitraries that
 * )(                                     //   are required for...
 *   (x, y) => x + y >= x && x + y >= y,  // • the law predicate
 *   {numRuns: 10_000},                   // • optional runtime config
 * )
 *
 * assert.equal(law.name, 'sum of positives ≥ both')
 * assert.deepStrictEqual(checkLaw(law), OP.none())
 * @typeParam Ts -  Argument type of predicate. For example, if the law
 * predicate signature is `Predicate<[a: number, b: string]>`, then `T`
 * would be `[a: number, b: string]`.
 * @param name - Law name, shown as test label.
 * @param note - String note to be shown on failure or in verbose mode.
 * @param arbitraries - A tuple of arbitraries, one per predicate argument.
 * @category constructors
 */
export declare const Law: <Ts extends UnknownArgs>(name: string, note: string, ...arbitraries: { [K in keyof Ts]: fc.Arbitrary<Ts[K]>; }) => (
/** Law predicate. Its argument type is encoded in `Ts`. */
predicate: (...args: Ts) => boolean, 
/** `fast-check` runtime parameters. */
parameters?: ParameterOverrides) => Law<Ts>;
/**
 * Return the given law but with its predicate negated.
 * @typeParam T - Argument type of law predicate. For example, if
 * the law predicate type is `Predicate<[number, number]>`, then
 * `T` would be `[number, string]`.
 * @param law - The law to be negated.
 * @returns A new `Law` object.
 * @category combinators
 */
export declare const negateLaw: <Ts extends UnknownArgs>({ predicate, ...law }: Law<Ts>) => Law<Ts>;
/**
 * Run the law and return either `None` on pass or `Some<string>` with the error
 * report on fail.
 *
 * See also {@link vitest.testLaw | testLaw}.
 * @category harness
 */
export declare const checkLaw: <Ts extends UnknownArgs>(law: Law<Ts>, parameters?: ParameterOverrides) => OP.Option<string>;
/**
 * Convert the law into a `fast-check` assertion.
 * @typeParam Ts - Tuple type of law predicate arguments.
 * @category harness
 * @param law - The law to be converted.
 * @param overrides - `fast-check` runtime parameters.
 * @returns A void function that will throw on predicate failure.
 */
export declare const asAssert: <Ts extends UnknownArgs>({ name, note, predicate, arbitrary, parameters }: Law<Ts>, overrides?: ParameterOverrides) => void;
/**
 * A base type for law predicate argument types.
 * @category model
 * @internal
 */
export type UnknownArgs = [unknown, ...unknown[]];
/**
 * When you need to work with laws but do not need to preserve the predicate
 * argument types.
 * @category model
 * @internal
 */
export type UnknownLaw = Law<any>;
/**
 * `fast-check` runtime
 * [parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
 * Fields with a type that depends on the property argument list
 * are omitted here and must be set on individual law tests.
 * @category fast-check
 */
export type ParameterOverrides = Omit<fc.Parameters, 'reporter' | 'asyncReporter' | 'examples'>;
//# sourceMappingURL=law.d.ts.map