import { Arbitrary as JSCArbitrary, random as jscRandom } from "jsverify"; import { Arbitrary as FCArbitrary, Shrinkable as FCShrinkable, Random as FCRandom, Stream as FCStream } from "fast-check"; import { buildRngState } from "./build-rng-state"; /** @hidden */ class WrappedArbitrary extends FCArbitrary { private static readonly JSCSize = 50; constructor(readonly jscArbitrary: JSCArbitrary) { super(); } private shrink(v: T): FCStream> { if (!this.jscArbitrary.shrink) return FCStream.nil(); const wrapped = this; function* g(it: Iterable): IterableIterator> { for (const e of it) yield wrapped.toShrinkable(e); } // WARN: .shrink of jsverify has wrong typings return new FCStream(g((this.jscArbitrary.shrink(v) as any).toArray())); } private toShrinkable(v: T): FCShrinkable { return new FCShrinkable(v, () => this.shrink(v)); } generate(mrng: FCRandom): FCShrinkable { // compute a seed // seed jsverify generator (jscRandom as any).setStateString(buildRngState(mrng)); // generate the value and link it with its shrinker return this.toShrinkable( this.jscArbitrary.generator(WrappedArbitrary.JSCSize) ); } } export const jsc2fc = (jscArbitrary: JSCArbitrary): FCArbitrary => { return new WrappedArbitrary(jscArbitrary); };