/** * Provides methods for generating pseudo-random numbers using the Mersenne Twister 19937 algorithm. * Allows seeding for reproducible sequences and cloning the generator state. */ declare class Random { readonly initialSeed: string; /** * Predefined boundary values useful for testing edge cases involving safe integers. */ static readonly LONG_BOUNDS: number[]; /** * Predefined boundary values useful for testing edge cases involving 32-bit integers. */ static readonly INT_BOUNDS: number[]; /** * Creates a new Random instance. * @param initialSeed Optional seed value. If empty, an auto-generated seed is used. * @param useCount Optional number of times the generator has been used, to restore state. */ constructor(initialSeed?: string, useCount?: number); /** * Generates a random floating-point number within the specified range (inclusive). * Defaults to the range of `Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`. * @param min The minimum value (inclusive). * @param max The maximum value (inclusive). * @returns A random number. */ nextNumber(min?: number, max?: number): number; /** * Generates a random floating-point number between 0 (inclusive) and 1 (exclusive). * @returns A random probability value. */ nextProb(): number; /** * Generates a random "long" (safe integer) number. * With a certain probability (`boundProb`), it returns a boundary value from `LONG_BOUNDS`. * Otherwise, it returns a random 53-bit integer. * @param boundProb The probability (0 to 1) of returning a boundary value. Defaults to 0.2. * @returns A random safe integer, potentially a boundary value. */ nextLong(boundProb?: number): number; /** * Generates a random 32-bit integer. * With a certain probability (`boundProb`), it returns a boundary value from `INT_BOUNDS`. * Otherwise, it returns a random 32-bit integer. * @param boundProb The probability (0 to 1) of returning a boundary value. Defaults to 0.2. * @returns A random 32-bit integer, potentially a boundary value. */ nextInt(boundProb?: number): number; /** * Generates a random boolean value. * @param trueProb The probability (0 to 1) of returning `true`. Defaults to 0.5. * @returns A random boolean. */ nextBoolean(trueProb?: number): boolean; /** * Generates a random safe integer within the specified inclusive interval [min, max]. * Uses the underlying 53-bit integer generator. * @param min The minimum value (inclusive). * @param max The maximum value (inclusive). * @returns A random safe integer within the interval. */ interval(min: number, max: number): number; /** * Generates a random safe integer within the specified range [fromInclusive, toExclusive). * @param fromInclusive The minimum value (inclusive). * @param toExclusive The maximum value (exclusive). * @returns A random safe integer within the range. */ inRange(fromInclusive: number, toExclusive: number): number; /** * Generates a random 32-bit integer within the specified inclusive interval [min, max]. * Uses the underlying 32-bit integer generator. * @param min The minimum value (inclusive). * @param max The maximum value (inclusive). * @returns A random 32-bit integer within the interval. */ intInterval(min: number, max: number): number; /** * Generates a random 32-bit integer within the specified range [fromInclusive, toExclusive). * @param fromInclusive The minimum value (inclusive). * @param toExclusive The maximum value (exclusive). * @returns A random 32-bit integer within the range. */ intInRange(fromInclusive: number, toExclusive: number): number; /** * Creates a clone of the current Random instance, preserving the generator state. * @returns A new Random instance with the same seed and usage count. */ clone(): Random; } /** * An iterator for consuming a Stream. It keeps track of the remaining stream state. * Note: This iterator modifies the stream it references as it progresses. */ declare class Iterator { stream: Stream; constructor(stream: Stream); hasNext(): boolean; next(): T; } /** * Represents a potentially infinite lazy sequence of values of type T. * Operations on Streams are typically lazy, meaning they don't compute values * until they are explicitly requested (e.g., by an Iterator). */ declare class Stream { readonly head?: T | undefined; readonly tailGen: () => Stream; /** * Creates a new Stream instance. * @param head The first element of the stream, or undefined if the stream is empty. * @param tailGen A function that, when called, generates the rest of the stream (the tail). * This function enables the lazy evaluation of the stream. */ constructor(head?: T | undefined, tailGen?: () => Stream); isEmpty(): boolean; getHead(): T; getTail(): Stream; iterator(): Iterator; /** * Lazily transforms each element of the stream using the provided function. * @param transformer A function to apply to each element. * @returns A new Stream containing the transformed elements. */ transform(transformer: (_: T) => U): Stream; /** * Lazily filters the stream based on a predicate. * It iterates through the stream until it finds the first element satisfying the criteria. * @param criteria A function that returns true for elements to keep. * @returns A new Stream containing only the elements that satisfy the criteria. */ filter(criteria: (_: T) => boolean): Stream; /** * Lazily concatenates this stream with another stream. * The elements of the 'other' stream are only accessed after this stream is exhausted. * @param other The stream to append to the end of this stream. * @returns A new Stream representing the concatenation. */ concat(other: Stream): Stream; /** * Lazily takes the first n elements from the stream. * @param n The maximum number of elements to take. * @returns A new Stream containing at most n elements from the beginning of this stream. */ take(n: number): Stream; /** * Creates a shallow copy of the stream. The head is copied, and the tail generator function is reused. * Useful when multiple consumers might iterate over the same starting point independently. */ clone(): Stream; /** * Returns a string representation of the stream, evaluating up to n elements. * Useful for debugging and inspection. * @param n The maximum number of elements to include in the string representation. Defaults to 100. */ toString(n?: number): string; /** * Creates an empty Stream. */ static empty(): Stream; /** * Creates a Stream with a single element. */ static one(value: T): Stream; /** * Creates a Stream with two elements. */ static two(value1: T, value2: T): Stream; /** * Creates a Stream with three elements. */ static three(value1: T, value2: T, value3: T): Stream; } /** * Represents a value along with its potential shrinks. * In property-based testing, when a test fails, the Shrinkable is used * to find a simpler counterexample by recursively exploring the shrinks. * * @template T The type of the value being shrunk. */ declare class Shrinkable { readonly value: T; readonly shrinksGen: () => Stream>; constructor(value: T, shrinksGen?: () => Stream>); toString(): string; shrinks(): Stream>; with(shrinksGen: () => Stream>): Shrinkable; /** * Concatenates the given stream to the horizontal dead-ends of shrinkable tree. Does not alter this shrinkable. * Adds additional candidates to the tree with fixed stream. * @param then the stream to concatenate * @returns a new shrinkable with the concatenation of each stream in shrinkable tree and the given stream */ concatStatic(then: () => Stream>): Shrinkable; /** * Concatenates the stream generated with given stream generator to the horizontal dead-ends of shrinkable tree. Does not alter this shrinkable. * Adds additional candidates to the tree, represented as stream generated based on the parent shrinkable of the horizontal dead-end. * @param then the stream generator to generate stream for concatenation. the function takes parent shrinkable as input. * @returns a new shrinkable with the concatenation of each stream in shrinkable tree and the given stream */ concat(then: (_: Shrinkable) => Stream>): Shrinkable; /** * Inserts the given stream to the vertical dead-ends of shrinkable tree. Does not alter this shrinkable. * @param then the stream to insert at the vertical dead-ends * @returns a new shrinkable with the insertion of the given stream at the vertical dead-ends */ andThenStatic(then: () => Stream>): Shrinkable; /** * Inserts the stream generated with given stream generator to the vertical dead-ends of shrinkable tree. Does not alter this shrinkable. * Adds additional candidates to the tree, represented as stream generated based on the parent shrinkable of the vertical dead-end. * This effectively appends new shrinking strategy to the shrinkable * @param then the stream generator to generate stream for insertion. the function takes parent shrinkable as input. * @returns a new shrinkable with the insertion of the given stream at the vertical dead-ends */ andThen(then: (_: Shrinkable) => Stream>): Shrinkable; map(transformer: (_: T) => U): Shrinkable; flatMap(transformer: (_: T) => Shrinkable): Shrinkable; /** @throws If `criteria(value)` is false. */ filter(criteria: (_: T) => boolean): Shrinkable; take(n: number): Shrinkable; /** @throws If `n` is out of bounds. */ getNthChild(n: number): Shrinkable; /** @throws If any {@link getNthChild} step is out of range. */ retrieve(steps: number[]): Shrinkable; } /** * Defines the core interface for generating random values along with their shrinkable counterparts. * Shrinkable values are essential for property-based testing, allowing the system to find the smallest failing example. * @template T The type of value to generate. */ interface Generator { /** * Generates a random value wrapped in a Shrinkable container. * @param rand The random number generator instance. * @returns A Shrinkable containing the generated value and its potential smaller versions. */ generate(rand: Random): Shrinkable; /** * Transforms the generated values using a provided function. * @template U The type of the transformed value. * @param transformer A function to apply to the generated value. * @returns A new Generator producing transformed values. */ map(transformer: (arg: T) => U): Generator; /** * Chains the generation process by using the output of this generator to create a new generator. * This is useful for creating dependent random values. * @template U The type produced by the subsequent generator. * @param genFactory A function that takes the generated value and returns a new Generator. * @returns A new Generator producing values from the chained generator. */ flatMap(genFactory: (arg: T) => Generator): Generator; /** * Similar to flatMap, but preserves the original value, returning a tuple. * @template U The type produced by the subsequent generator. * @param genFactory A function that takes the generated value and returns a new Generator. * @returns A new Generator producing tuples of [originalValue, newValue]. */ chain(genFactory: (arg: T) => Generator): Generator<[T, U]>; /** * Chains generation assuming the current generator produces tuples, appending the new value. * Requires the current generator to produce an array/tuple. * @template Ts The tuple type produced by the current generator. * @template U The type produced by the subsequent generator. * @param genFactory A function that takes the generated tuple and returns a new Generator. * @returns A new Generator producing tuples with the new value appended. */ chainAsTuple(genFactory: (arg: Ts) => Generator): Generator<[...Ts, U]>; /** * Repeatedly applies a generator factory to the last generated value a specified number of times. * The final value is returned. * @param genFactory A function that takes the last value and returns the next generator. * @param minSize The minimum number of aggregation steps. * @param maxSize The maximum number of aggregation steps. * @returns A new Generator producing the aggregated value. */ aggregate(genFactory: (arg: T) => Generator, minSize: number, maxSize: number): Generator; /** * Similar to aggregate, but collects all intermediate values into an array. * @param genFactory A function that takes the last value and returns the next generator. * @param minSize The minimum number of accumulation steps. * @param maxSize The maximum number of accumulation steps. * @returns A new Generator producing an array of accumulated values. */ accumulate(genFactory: (arg: T) => Generator, minSize: number, maxSize: number): Generator>; /** * Filters the generated values based on a predicate. * It will keep generating values until one satisfies the predicate. * @param filterer A function that returns true if the value should be kept. * @returns A new Generator producing only values that satisfy the predicate. */ filter(filterer: (value: T) => boolean): Generator; } /** * A concrete implementation of the Generator interface. * @template T The type of value to generate. */ declare class Arbitrary implements Generator { readonly genFunction: GenFunction; /** * Creates an instance of Arbitrary. * @param genFunction The core function used to generate Shrinkable values. */ constructor(genFunction: GenFunction); generate(rand: Random): Shrinkable; map(transformer: (arg: T) => U): Generator; aggregate(genFactory: (arg: T) => Generator, minSize: number, maxSize: number): Generator; accumulate(genFactory: (arg: T) => Generator, minSize: number, maxSize: number): Generator>; flatMap(genFactory: (arg: T) => Generator): Generator; chain(genFactory: (arg: T) => Generator): Generator<[T, U]>; chainAsTuple(genFactory: (arg: Ts) => Generator): Generator<[...Ts, U]>; filter(filterer: (value: T) => boolean): Generator; } /** * Type alias for the core function within a Generator that produces a Shrinkable value. * @template ARG The type of value to generate. * @param rand The random number generator instance. * @returns A Shrinkable value. */ type GenFunction = (rand: Random) => Shrinkable; /** Helper type to extract the value type `T` from a `Generator`. */ type GenValueType = Gen extends Generator ? T : never; /** * Given a tuple of Generators, maps it to a tuple of the corresponding generated value types. * e.g., `[Generator, Generator]` becomes `[A, B]` */ type GenValueTypes[]> = { [K in keyof Gens]: GenValueType; }; /** * Creates a generator that produces tuples by combining the results of the provided element generators. * The resulting tuple's type is derived from the types generated by the input generators. * * @param elemGens - A rest parameter array of `Generator` instances. * @returns A `Generator` that produces tuples where each element corresponds to the value generated by the respective generator in `elemGens`. * * @example * ```ts * Gen.tuple(Gen.boolean(), Gen.interval(0, 9), Gen.asciiString(0, 4)) * ``` */ declare function TupleGen[]>(...elemGens: Gens): Generator>; /** * Creates a generator for instances of a class `Type`. * * It takes the class `Type` and a sequence of generators `gens` corresponding * to the constructor arguments of `Type`. It generates a tuple of values using * the provided generators and then uses these values to instantiate `Type`. * * @template T The type of the class instances to generate. * @template Gens An array of Generator types, corresponding to the constructor argument types. * @param Type The constructor function of the class to instantiate. * @param gens A sequence of generators for the constructor arguments. * @returns A Generator that produces instances of `Type`. * * @example * ```ts * class User { * constructor(public id: number, public name: string) {} * } * * const userGen = Gen.construct(User, Gen.interval(1, 100), Gen.asciiString(1, 20)) * ``` */ declare function construct[]>(Type: { new (...args: GenValueTypes): T; }, ...gens: Gens): Generator; /** * Represents a value with an associated weight, used for weighted random selection. */ declare class WeightedValue { readonly value: T; readonly weight: number; constructor(value: T, weight: number); } /** * Wraps a value with a weight for `elementOf` / `normalizeWeightedValues`. * * @param value The value to associate with a weight. * @param weight Relative weight; normalized with other weighted entries when building a distribution. * @returns A {@link WeightedValue} wrapper. * * @example * ```ts * Gen.elementOf(Gen.weightedValue('a', 0.7), 'b', 'c') * ``` */ declare function weightedValue(value: T, weight: number): WeightedValue; /** * Creates a generator that produces values randomly selected from the provided array, * respecting the weights if provided. Uses normalized weights to ensure fair selection. * @param values An array containing either plain values of type T or WeightedValue objects. * Weights should be between 0 and 1 (exclusive). If weights are provided, they don't need * to sum to 1 initially; they will be normalized. Unweighted values will share * the remaining probability mass equally. * @returns A `Generator` that produces values based on the weighted distribution. * * @example * ```ts * Gen.elementOf(1, 2, 3) * Gen.elementOf(Gen.weightedValue('x', 0.8), 'y') * ``` */ declare function elementOf(...values: Array>): Generator; /** * Wraps a Generator with an associated weight, used by `oneOf` to * determine the probability of selecting this generator. */ declare class Weighted implements Generator { readonly gen: Generator; readonly weight: number; constructor(gen: Generator, weight: number); generate(rand: Random): Shrinkable; map(transformer: (arg: T) => U): Generator; flatMap(gen2gen: (arg: T) => Generator): Generator; chain(gen2gen: (arg: T) => Generator): Generator<[T, U]>; chainAsTuple(genFactory: (arg: Ts) => Generator): Generator<[...Ts, U]>; aggregate(gen2gen: (arg: T) => Generator, minSize: number, maxSize: number): Generator; accumulate(gen2gen: (arg: T) => Generator, minSize: number, maxSize: number): Generator>; filter(filterer: (value: T) => boolean): Generator; } /** * Wraps a generator with a weight for `oneOf`. * * @param gen The generator to weight. * @param weight Relative weight; normalized with other weighted entries when building a distribution. * @returns A weighted generator wrapper accepted by {@link oneOf}. * * @example * ```ts * Gen.oneOf(Gen.weightedGen(Gen.interval(0, 5), 0.5), Gen.just(100)) * ``` */ declare function weightedGen(gen: Generator, weight: number): Weighted; /** * Creates a generator that randomly selects one of the provided generators * based on their assigned weights. If some generators are not explicitly * weighted (using `weightedGen`), the remaining probability mass (1.0 - sum of weights) * is distributed equally among them. * @param generators A list of generators, optionally wrapped with `weightedGen`. * @returns A `Generator` that samples one of the inputs according to weights. * * @example * ```ts * Gen.oneOf(Gen.just('a'), Gen.just('b')) * Gen.oneOf(Gen.weightedGen(Gen.float(), 0.2), Gen.interval(0, 10)) * ``` */ declare function oneOf(...generators: Generator[]): Generator; /** * Creates a generator that delays the evaluation of the provided function until the generator is sampled. * This is particularly useful for defining recursive generators or generators that depend on expensive computations. * @param func A function that returns the value to be generated. * @returns A Generator that produces the value returned by `func` upon generation. * * @example * ```ts * const g = Gen.lazy(() => JSON.parse('{"n":1}')) * ``` */ declare function lazy(func: () => T): Generator; /** * Creates a generator that always produces the same given value. * * @param value The constant value to be generated. * @returns A generator that yields the provided value. * * @example * ```ts * Gen.just({ k: 1 }) * ``` */ declare function just(value: T): Generator; /** * Chains the generation of a tuple with the generation of a subsequent value * that depends on the tuple's contents. * * This allows creating generators where the parameters of one generator depend * on the output of a previous one, specifically within the context of building up a tuple. * * @param tupleGen The generator for the initial tuple elements `Ts`. * @param genFactory A function that takes the generated tuple `Ts` and returns a generator for the final element `U`. * @returns A generator for the combined tuple `[...Ts, U]`. * * @example * ```ts * Gen.chainTuple(Gen.tuple(Gen.interval(0, 3), Gen.interval(0, 3)), ([x, y]) => Gen.just(x + y)) * ``` */ declare function chainTuple(tupleGen: Generator, genFactory: (arg: Ts) => Generator): Generator<[...Ts, U]>; /** * Creates a generator for boolean values. * * @param trueProb The probability of generating `true`. Must be between 0 and 1. Defaults to 0.5. * @returns A generator that produces shrinkable boolean values. */ declare function BooleanGen(trueProb?: number): Generator; /** * Generates integers within the specified inclusive range [min, max]. * * @param min The minimum value of the range (inclusive). Defaults to `Number.MIN_SAFE_INTEGER`. * @param max The maximum value of the range (inclusive). Defaults to `Number.MAX_SAFE_INTEGER`. * @returns A generator for integers within the specified range. * @throws If min is greater than max. */ declare function interval(min?: number, max?: number): Generator; /** * Generates integers within the specified range [fromInclusive, toExclusive). * * @param fromInclusive The minimum value of the range (inclusive). * @param toExclusive The maximum value of the range (exclusive). * @returns A generator for integers within the specified range. * @throws If fromInclusive is greater than or equal to toExclusive. */ declare function inRange(fromInclusive: number, toExclusive: number): Generator; /** * Generates a sequence of `count` integers starting from `start`. * Equivalent to `inRange(start, start + count)`. * @deprecated Use `Gen.interval` or `Gen.inRange` instead. * @param start The starting integer (inclusive). * @param count The number of integers to generate. * @returns A generator for the sequence of integers. */ declare function integers(start: number, count: number): Generator; /** * Generates arbitrary floating-point numbers between 0 (inclusive) and 1 (exclusive). * The generated values are shrinkable towards 0. * * @returns A Generator for floating-point numbers. */ declare function FloatingGen(): Generator; /** * Creates a generator for strings of a specified length range, using a given character code generator. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @param charGen - The generator used to produce character codes for the string. Defaults to `ASCIICharGen`. * @returns A generator that produces strings with shrinkable characters. * * @example * ```ts * Gen.string(0, 8) // default ASCII char codes * Gen.string(0, 4, Gen.unicode) // Unicode code units * ``` */ declare function StringGen(minSize: number, maxSize: number, charGen?: Generator): Generator; /** * Creates a generator for ASCII strings of a specified length range. * Equivalent to `StringGen(minSize, maxSize, ASCIICharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces ASCII strings. * * @example * ```ts * Gen.asciiString(1, 12) * ``` */ declare function ASCIIStringGen(minSize: number, maxSize: number): Generator; /** * Creates a generator for Unicode strings of a specified length range. * Uses `UnicodeCharGen` which avoids generating surrogate pair code points directly. * Equivalent to `StringGen(minSize, maxSize, UnicodeCharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces Unicode strings. * * @example * ```ts * Gen.unicodeString(0, 20) * ``` */ declare function UnicodeStringGen(minSize: number, maxSize: number): Generator; /** * Creates a generator for printable ASCII strings of a specified length range. * Equivalent to `StringGen(minSize, maxSize, PrintableASCIICharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces printable ASCII strings. * * @example * ```ts * Gen.printableAsciiString(3, 40) * ``` */ declare function PrintableASCIIStringGen(minSize: number, maxSize: number): Generator; /** * Generates an array of elements using the provided element generator. * The generated array adheres to the specified minimum and maximum size constraints. * It utilizes `shrinkableArray` to enable shrinking towards smaller arrays and simpler element values * during property-based testing failures. * * @template T The type of elements in the array. * @param elemGen The generator for individual elements. * @param minSize The minimum number of elements in the generated array. * @param maxSize The maximum number of elements in the generated array. * @returns {Generator>} A generator producing arrays of type T. * * @example * ```ts * Gen.array(Gen.interval(-5, 5), 0, 10) * ``` */ declare function ArrayGen(elemGen: Generator, minSize: number, maxSize: number): Generator>; /** * Generates an array containing unique elements, sorted in ascending order. * It achieves uniqueness by first generating a Set using `SetGen` and then converting the Set into an array. * Sorting ensures a canonical representation for the generated unique arrays. * * @template T The type of elements in the array. * @param elemGen The generator for individual elements. * @param minSize The minimum number of unique elements in the generated array. * @param maxSize The maximum number of unique elements in the generated array. * @returns {Generator>} A generator producing sorted arrays of unique elements of type T. * * @example * ```ts * Gen.uniqueArray(Gen.interval(0, 100), 1, 8) * ``` */ declare function UniqueArrayGen(elemGen: Generator, minSize: number, maxSize: number): Generator>; /** * Creates a Generator for producing Set instances. * * @param elemGen - The generator for the elements to be included in the set. * @param minSize - The minimum number of elements the generated set should contain. * @param maxSize - The maximum number of elements the generated set should contain. * @returns A Generator that produces Set instances with sizes between minSize and maxSize (inclusive). * * @example * ```ts * Gen.set(Gen.asciiString(1, 3), 0, 5) * ``` */ declare function SetGen(elemGen: Generator, minSize: number, maxSize: number): Generator>; interface Dictionary { [Key: string]: T; } /** * Generates a dictionary (object) with keys of type string and values of type T. * * @template T The type of elements in the dictionary values. * @param keyGen The generator for the dictionary keys (must generate strings). * @param elemGen The generator for the dictionary values. * @param minSize The minimum number of key-value pairs in the dictionary. * @param maxSize The maximum number of key-value pairs in the dictionary. * @returns A generator for dictionaries. * * @example * ```ts * Gen.dict(Gen.asciiString(1, 4), Gen.interval(0, 99), 0, 6) * ``` */ declare function DictionaryGen(keyGen: Generator, elemGen: Generator, minSize: number, maxSize: number): Generator>; /** * Represents a simple action that can be performed on an object. * It doesn't involve a model. * @template ObjectType The type of the object the action acts upon. */ declare class SimpleAction { readonly func: (obj: ObjectType) => void; readonly name: string; /** * @param func The function to execute when the action is called. * @param name An optional name for the action, used for reporting. */ constructor(func: (obj: ObjectType) => void, name?: string); call(obj: ObjectType): void; toString(): string; } /** * Represents an action that involves both a real object and a model. * Used for stateful property-based testing to compare system-under-test and model states. * @template ObjectType The type of the real object. * @template ModelType The type of the model object. */ declare class Action { readonly func: (obj: ObjectType, mdl: ModelType) => void; readonly name: string; /** * Creates an `Action` from a `SimpleAction`, ignoring the model. * @param simpleAction The simple action to convert. * @returns A new `Action` instance. */ static fromSimpleAction(simpleAction: SimpleAction): Action; /** * @param func The function to execute, taking both the object and the model. * @param name An optional name for the action. */ constructor(func: (obj: ObjectType, mdl: ModelType) => void, name?: string); call(obj: ObjectType, mdl: ModelType): void; toString(): string; } /** A generator for `SimpleAction` instances. */ type SimpleActionGen = Generator>; /** A generator for `Action` instances involving an object and a model. */ type ActionGen = Generator>; /** Represents an empty model, often used when no model is needed. */ type EmptyModel = {}; /** * Factory returning a generator for SimpleActions for a given object. * @template ObjectType The type of the object. */ type SimpleActionGenFactory = (obj: ObjectType) => Generator>; /** * Factory returning a generator for Actions for a given object and model. * @template ObjectType The type of the object. * @template ModelType The type of the model. */ type ActionGenFactory = (obj: ObjectType, model: ModelType) => Generator>; /** Union of SimpleActionGenFactory and SimpleActionGen. */ type SimpleActionGenOrFactory = SimpleActionGenFactory | SimpleActionGen; /** Union of ActionGenFactory and ActionGen. */ type ActionGenOrFactory = ActionGenFactory | ActionGen; /** * Creates a SimpleActionGenFactory combining multiple weighted SimpleActionGen or SimpleActionGenFactory instances. * * @template ObjectType The type of the object. * @param simpleActionGenFactories Array of SimpleActionGen, SimpleActionGenFactory, or weighted versions. * @returns A SimpleActionGenFactory selecting based on weights. * * @example * ```ts * const choose = Gen.simpleActionGenOf( * Gen.just(new SimpleAction((xs: number[]) => xs.push(1), 'push')), * Gen.weightedValue((xs: number[]) => Gen.just(new SimpleAction(() => xs.pop(), 'pop')), 0.3) * ) * ``` */ declare function simpleActionGenOf(...simpleActionGenFactories: Array | WeightedValue>>): SimpleActionGenFactory; /** * Creates an ActionGenFactory combining multiple weighted ActionGen or ActionGenFactory instances. * * @template ObjectType The type of the object. * @template ModelType The type of the model. * @param actionGenFactories Array of ActionGen, ActionGenFactory, or weighted versions. * @returns An ActionGenFactory selecting based on weights. * * @example * ```ts * const choose = Gen.actionOf( * Gen.just(new Action((_o: object, _m: object) => {}, 'a')), * Gen.just(new Action((_o: object, _m: object) => {}, 'b')) * ) * ``` */ declare function actionGenOf(...actionGenFactories: Array | WeightedValue>>): ActionGenFactory; type PropertyFunction = (...args: ARGS) => boolean; type PropertyFunctionVoid = (...args: ARGS) => void; /** * Represents a property-based test. * Encapsulates the test function, generators, execution logic, and configuration. */ declare class Property { readonly func: PropertyFunction | PropertyFunctionVoid; /** * Creates a new Property instance. * @param func The function to test. It should return boolean (true=pass) or void (throws on failure). */ constructor(func: PropertyFunction | PropertyFunctionVoid); /** * Runs the property test. * Executes the test function `numRuns` times with generated arguments. * On failure, attempts to shrink the arguments to a minimal failing case. * @param gens Generators for each argument of the test function. * @returns `true` if the property holds for all runs. * @throws An error describing the failure and the smallest failing arguments found. */ forAll[]>(...gens: GENS): boolean; /** * Runs the property function with a specific set of example arguments. * Does not involve generation or shrinking. * Useful for testing specific known cases or debugging. * @param args The example arguments to test. * @returns `true` if the function returns true/void, `false` if it returns false or throws. */ example(...args: ARGS): boolean; /** Sets the seed for the random number generator for reproducible runs. */ setSeed(seed: string): this; /** Sets the number of test runs to execute. */ setNumRuns(numRuns: number): this; /** Sets a setup function to be called before each test execution (including shrinks). */ setOnStartup(onStartup: () => void): this; /** Sets a cleanup function to be called after each *successful* test execution (including shrinks). */ setOnCleanup(onCleanup: () => void): this; /** Sets the default number of runs for all subsequently created Property instances. */ static setDefaultNumRuns(numRuns: number): void; } /** * Convenience function to create and run a Property test using default settings. * This is the main entry point for users. */ declare function forAll[]>(func: PropertyFunction | PropertyFunctionVoid, ...gens: GENS): boolean; /** * Stateful property test: random initial state, then a random-length sequence of actions whose * generators may depend on the current `(object, model)` pair. * * Each run: build a model from the initial object via `modelFactory`, then for each step call * `actionGenFactory(obj, model)` to sample the next `Action`, and run `action.call(obj, model)`. * Use this when you maintain a reference model in parallel with the real implementation (dual updates). * * Failures (thrown from an action or from optional `postCheck`) trigger shrinking: first the * random states used to generate actions, then the initial object via the `initialGen` shrink tree. * * Action generation can fail transiently; those steps are retried up to * `maxAllowedConsecutiveGenerationFailures` (not configurable from outside today). * * Prefer {@link simpleStatefulProperty} when you only need `SimpleAction`s and no real model * (`EmptyModel`). * * @template ObjectType The system under test. * @template ModelType The reference model state type. * @see {@link statefulProperty} — usual way to construct. */ declare class StatefulProperty { readonly initialGen: Generator; readonly modelFactory: (_: ObjectType) => ModelType; readonly actionGenFactory: ActionGenFactory; /** * @param initialGen Samples the starting `ObjectType` (shrunk on failure). * @param modelFactory Builds the model from the initial object (typically a pure spec of expected behavior). * @param actionGenFactory Given current `(obj, model)`, returns a generator of the next `Action` to apply. */ constructor(initialGen: Generator, modelFactory: (_: ObjectType) => ModelType, actionGenFactory: ActionGenFactory); /** Reproducible RNG for all runs; empty string uses a fresh seed each process. */ setSeed(seed: string): this; /** Number of full runs (each: new initial state + action sequence). Default 100. */ setNumRuns(numRuns: number): this; /** Minimum number of actions attempted per run (length is random in `[min, max]`). */ setMinActions(num: number): this; /** Maximum number of actions per run. */ setMaxActions(num: number): this; /** * Hook before each run and before replay during shrinking (same semantics as {@link Property#setOnStartup}). */ setOnStartup(onStartup: () => void): this; /** * Hook after a run completes without throwing through all actions and `postCheck` (also after replays that succeed). */ setOnCleanup(onCleanup: () => void): this; /** * Final assertion after the action sequence: e.g. compare `obj` with an independently recomputed result. * Runs only when no action threw. */ setPostCheck(postCheck: (obj: ObjectType, mdl: ModelType) => void): this; /** Same as {@link setPostCheck} but only receives `obj` (model ignored). */ setPostCheckWithoutModel(postCheck: (obj: ObjectType) => void): this; /** Log discarded actions and shrink internals to the console when `true`. */ setVerbosity(verbose: boolean): this; /** * Run the suite: `numRuns` iterations, each with a random action count in `[minActions, maxActions]`. * On first thrown error from an action, stops that iteration and shrinks toward a smaller failing case. * * @throws With a message that includes shrunk or original args when an action or `postCheck` fails. */ go(): void; /** * Same as {@link go}. Familiar name used by several stateful / model-based testing APIs. */ run(): void; } /** * Builds a {@link StatefulProperty} with an explicit model: use when actions update both a real object and a reference model. * * @template ObjectType The system under test. * @template ModelType The model type (often a pure functional spec). */ declare function statefulProperty(initialGen: Generator, modelFactory: (_: ObjectType) => ModelType, actionGenFactory: ActionGenFactory): StatefulProperty; /** * Same as {@link statefulProperty} but with `EmptyModel`: actions are {@link SimpleAction}s wrapped via * {@link Action.fromSimpleAction}, so you only write object-only logic. Use for invariants or SUT-only state machines. * * @template ObjectType The system under test. */ declare function simpleStatefulProperty(initialGen: Generator, simpleActionGenFactory: SimpleActionGenFactory): StatefulProperty; /** * Discards the current generated test case when `value` is false (like QuickCheck's `precondition` or * Hypothesis `assume`). Use inside a property body or with `Generator.filter` to skip invalid combinations * without counting them as failures. * * @param value - When `false`, the run is aborted by throwing `PreconditionError`. * @throws `PreconditionError` if `value` is false. */ declare function precond(value: boolean): void; /** * Built-in generators and combinators (`Gen.boolean`, `Gen.array`, …). * Each property aliases the implementation named in the first line; JSDoc matches that API (parameters and returns). */ declare const Gen: { /** * Same API as {@link BooleanGen}. * * Creates a generator for boolean values. * * @param trueProb The probability of generating `true`. Must be between 0 and 1. Defaults to 0.5. * @returns A generator that produces shrinkable boolean values. */ boolean: typeof BooleanGen; /** * Same API as {@link InRange}. * * Generates integers within the specified range [fromInclusive, toExclusive). * * @param fromInclusive The minimum value of the range (inclusive). * @param toExclusive The maximum value of the range (exclusive). * @returns A generator for integers within the specified range. * @throws If fromInclusive is greater than or equal to toExclusive. */ inRange: typeof inRange; /** * Same API as {@link Integers}. * * Generates a sequence of `count` integers starting from `start`. * Equivalent to `inRange(start, start + count)`. * * @deprecated Use `Gen.interval` or `Gen.inRange` instead. * @param start The starting integer (inclusive). * @param count The number of integers to generate. * @returns A generator for the sequence of integers. */ integers: typeof integers; /** * Same API as {@link Interval}. * * Generates integers within the specified inclusive range [min, max]. * * @param min The minimum value of the range (inclusive). Defaults to `Number.MIN_SAFE_INTEGER`. * @param max The maximum value of the range (inclusive). Defaults to `Number.MAX_SAFE_INTEGER`. * @returns A generator for integers within the specified range. * @throws If min is greater than max. */ interval: typeof interval; /** * Same API as {@link FloatingGen}. * * Generates arbitrary floating-point numbers between 0 (inclusive) and 1 (exclusive). * The generated values are shrinkable towards 0. * * @returns A Generator for floating-point numbers. */ float: typeof FloatingGen; /** * Same value as {@link ASCIICharGen}. * * Generates integers representing ASCII character codes (1–127). * @returns A `Generator` of code points. */ ascii: Generator; /** * Same value as {@link UnicodeCharGen}. * * Generates integers representing Unicode character codes. * Maps the interval to avoid generating surrogate pair code points directly (U+D800 to U+DFFF). * @returns A `Generator` of code points. */ unicode: Generator; /** * Same value as {@link PrintableASCIICharGen}. * * Generates integers representing printable ASCII character codes (32–127). * @returns A `Generator` of code points. */ printableAscii: Generator; /** * Same API as {@link StringGen}. * * Creates a generator for strings of a specified length range, using a given character code generator. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @param charGen - The generator used to produce character codes for the string. Defaults to `ASCIICharGen`. * @returns A generator that produces strings with shrinkable characters. * * @example * ```ts * Gen.string(0, 8) // default ASCII char codes * Gen.string(0, 4, Gen.unicode) // Unicode code units * ``` */ string: typeof StringGen; /** * Same API as {@link ASCIIStringGen}. * * Creates a generator for ASCII strings of a specified length range. * Equivalent to `StringGen(minSize, maxSize, ASCIICharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces ASCII strings. * * @example * ```ts * Gen.asciiString(1, 12) * ``` */ asciiString: typeof ASCIIStringGen; /** * Same API as {@link UnicodeStringGen}. * * Creates a generator for Unicode strings of a specified length range. * Uses `UnicodeCharGen` which avoids generating surrogate pair code points directly. * Equivalent to `StringGen(minSize, maxSize, UnicodeCharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces Unicode strings. * * @example * ```ts * Gen.unicodeString(0, 20) * ``` */ unicodeString: typeof UnicodeStringGen; /** * Same API as {@link PrintableASCIIStringGen}. * * Creates a generator for printable ASCII strings of a specified length range. * Equivalent to `StringGen(minSize, maxSize, PrintableASCIICharGen)`. * * @param minSize - The minimum length of the generated string (inclusive). * @param maxSize - The maximum length of the generated string (inclusive). * @returns A generator that produces printable ASCII strings. * * @example * ```ts * Gen.printableAsciiString(3, 40) * ``` */ printableAsciiString: typeof PrintableASCIIStringGen; /** * Same API as {@link ArrayGen}. * * Generates an array of elements using the provided element generator. * The generated array adheres to the specified minimum and maximum size constraints. * It utilizes `shrinkableArray` to enable shrinking towards smaller arrays and simpler element values * during property-based testing failures. * * @template T The type of elements in the array. * @param elemGen The generator for individual elements. * @param minSize The minimum number of elements in the generated array. * @param maxSize The maximum number of elements in the generated array. * @returns A generator producing arrays of type T. * * @example * ```ts * Gen.array(Gen.interval(-5, 5), 0, 10) * ``` */ array: typeof ArrayGen; /** * Same API as {@link UniqueArrayGen}. * * Generates an array containing unique elements, sorted in ascending order. * It achieves uniqueness by first generating a Set using `SetGen` and then converting the Set into an array. * Sorting ensures a canonical representation for the generated unique arrays. * * @template T The type of elements in the array. * @param elemGen The generator for individual elements. * @param minSize The minimum number of unique elements in the generated array. * @param maxSize The maximum number of unique elements in the generated array. * @returns A generator producing sorted arrays of unique elements of type T. * * @example * ```ts * Gen.uniqueArray(Gen.interval(0, 100), 1, 8) * ``` */ uniqueArray: typeof UniqueArrayGen; /** * Same API as {@link SetGen}. * * Creates a Generator for producing `Set` instances. * * @param elemGen - The generator for the elements to be included in the set. * @param minSize - The minimum number of elements the generated set should contain. * @param maxSize - The maximum number of elements the generated set should contain. * @returns A Generator that produces `Set` instances with sizes between minSize and maxSize (inclusive). * * @example * ```ts * Gen.set(Gen.asciiString(1, 3), 0, 5) * ``` */ set: typeof SetGen; /** * Same API as {@link TupleGen}. * * Creates a generator that produces tuples by combining the results of the provided element generators. * The resulting tuple's type is derived from the types generated by the input generators. * * @param elemGens - A rest parameter array of `Generator` instances. * @returns A `Generator` that produces tuples where each element corresponds to the value generated by the respective generator in `elemGens`. * * @example * ```ts * Gen.tuple(Gen.boolean(), Gen.interval(0, 9), Gen.asciiString(0, 4)) * ``` */ tuple: typeof TupleGen; /** * Same API as {@link DictionaryGen}. * * Generates a dictionary (object) with keys of type string and values of type T. * * @template T The type of elements in the dictionary values. * @param keyGen The generator for the dictionary keys (must generate strings). * @param elemGen The generator for the dictionary values. * @param minSize The minimum number of key-value pairs in the dictionary. * @param maxSize The maximum number of key-value pairs in the dictionary. * @returns A generator for dictionaries. * * @example * ```ts * Gen.dict(Gen.asciiString(1, 4), Gen.interval(0, 99), 0, 6) * ``` */ dict: typeof DictionaryGen; /** Same API as {@link DictionaryGen}. Alias of `dict`. */ dictionary: typeof DictionaryGen; /** * Same API as {@link SimpleActionGenOf}. * * Creates a SimpleActionGenFactory combining multiple weighted SimpleActionGen or SimpleActionGenFactory instances. * * @template ObjectType The type of the object. * @param simpleActionGenFactories Array of SimpleActionGen, SimpleActionGenFactory, or weighted versions. * @returns A SimpleActionGenFactory selecting based on weights. * * @example * ```ts * const choose = Gen.simpleActionGenOf( * Gen.just(new SimpleAction((xs: number[]) => xs.push(1), 'push')), * Gen.weightedValue((xs: number[]) => Gen.just(new SimpleAction(() => xs.pop(), 'pop')), 0.3) * ) * ``` */ simpleActionOf: typeof simpleActionGenOf; /** * Same API as {@link ActionGenOf}. * * Creates an ActionGenFactory combining multiple weighted ActionGen or ActionGenFactory instances. * * @template ObjectType The type of the object. * @template ModelType The type of the model. * @param actionGenFactories Array of ActionGen, ActionGenFactory, or weighted versions. * @returns An ActionGenFactory selecting based on weights. * * @example * ```ts * const choose = Gen.actionOf( * Gen.just(new Action((_o: object, _m: object) => {}, 'a')), * Gen.just(new Action((_o: object, _m: object) => {}, 'b')) * ) * ``` */ actionOf: typeof actionGenOf; /** * Same API as {@link Construct}. * * Creates a generator for instances of a class `Type`. * * It takes the class `Type` and a sequence of generators `gens` corresponding * to the constructor arguments of `Type`. It generates a tuple of values using * the provided generators and then uses these values to instantiate `Type`. * * @template T The type of the class instances to generate. * @template Gens An array of Generator types, corresponding to the constructor argument types. * @param Type The constructor function of the class to instantiate. * @param gens A sequence of generators for the constructor arguments. * @returns A Generator that produces instances of `Type`. * * @example * ```ts * class User { * constructor(public id: number, public name: string) {} * } * * const userGen = Gen.construct(User, Gen.interval(1, 100), Gen.asciiString(1, 20)) * ``` */ construct: typeof construct; /** * Same API as {@link ElementOf}. * * Creates a generator that produces values randomly selected from the provided array, * respecting the weights if provided. Uses normalized weights to ensure fair selection. * * @param values An array containing either plain values of type T or `WeightedValue` objects. * Weights should be between 0 and 1 (exclusive). If weights are provided, they don't need * to sum to 1 initially; they will be normalized. Unweighted values will share * the remaining probability mass equally. * @returns A `Generator` that produces values based on the weighted distribution. * * @example * ```ts * Gen.elementOf(1, 2, 3) * Gen.elementOf(Gen.weightedValue('x', 0.8), 'y') * ``` */ elementOf: typeof elementOf; /** * Same API as {@link WeightedValue} (the `weightedValue` helper from `combinator/elementof`). * * Wraps a value with a weight for `elementOf` / `normalizeWeightedValues`. * * @param value The value to associate with a weight. * @param weight Relative weight; normalized with other weighted entries when building a distribution. * @returns A `WeightedValue` class instance (same as calling the helper at module scope). * * @example * ```ts * Gen.elementOf(Gen.weightedValue('a', 0.7), 'b', 'c') * ``` */ weightedValue: typeof weightedValue; /** * Same API as {@link OneOf}. * * Creates a generator that randomly selects one of the provided generators * based on their assigned weights. If some generators are not explicitly * weighted (using `weightedGen`), the remaining probability mass (1.0 - sum of weights) * is distributed equally among them. * * @param generators A list of generators, optionally wrapped with `weightedGen`. * @returns A `Generator` that samples one of the inputs according to weights. * * @example * ```ts * Gen.oneOf(Gen.just('a'), Gen.just('b')) * Gen.oneOf(Gen.weightedGen(Gen.float(), 0.2), Gen.interval(0, 10)) * ``` */ oneOf: typeof oneOf; /** * Same API as {@link WeightedGen}. * * Wraps a generator with a weight for `oneOf`. * * @param gen The generator to weight. * @param weight Relative weight; normalized with other weighted entries when building a distribution. * @returns A weighted generator wrapper accepted by {@link OneOf}. * * @example * ```ts * Gen.oneOf(Gen.weightedGen(Gen.interval(0, 5), 0.5), Gen.just(100)) * ``` */ weightedGen: typeof weightedGen; /** * Same API as {@link Lazy}. * * Creates a generator that delays the evaluation of the provided function until the generator is sampled. * This is particularly useful for defining recursive generators or generators that depend on expensive computations. * * @param func A function that returns the value to be generated. * @returns A Generator that produces the value returned by `func` upon generation. * * @example * ```ts * const g = Gen.lazy(() => JSON.parse('{"n":1}')) * ``` */ lazy: typeof lazy; /** * Same API as {@link Just}. * * Creates a generator that always produces the same given value. * * @param value The constant value to be generated. * @returns A generator that yields the provided value. * * @example * ```ts * Gen.just({ k: 1 }) * ``` */ just: typeof just; /** * Same API as {@link ChainTuple}. * * Chains the generation of a tuple with the generation of a subsequent value * that depends on the tuple's contents. * * This allows creating generators where the parameters of one generator depend * on the output of a previous one, specifically within the context of building up a tuple. * * @param tupleGen The generator for the initial tuple elements `Ts`. * @param genFactory A function that takes the generated tuple `Ts` and returns a generator for the final element `U`. * @returns A generator for the combined tuple `[...Ts, U]`. * * @example * ```ts * Gen.chainTuple(Gen.tuple(Gen.interval(0, 3), Gen.interval(0, 3)), ([x, y]) => Gen.just(x + y)) * ``` */ chainTuple: typeof chainTuple; }; export { Action, type ActionGen, type ActionGenOrFactory, Arbitrary, Gen, type GenFunction, type Generator, Property, Random, Shrinkable, SimpleAction, type SimpleActionGen, type SimpleActionGenOrFactory, Stream, forAll, precond, simpleStatefulProperty, statefulProperty };