UNPKG

fast-check

Version:

Property based testing framework for JavaScript (like QuickCheck)

62 lines (61 loc) 1.98 kB
import { stream } from '../../stream/Stream.js'; import { cloneMethod } from '../symbols.js'; import { Arbitrary } from './definition/Arbitrary.js'; import { Shrinkable } from './definition/Shrinkable.js'; class DedupArbitrary extends Arbitrary { constructor(arb, numValues) { super(); this.arb = arb; this.numValues = numValues; } generate(mrng) { const items = []; if (this.numValues <= 0) { return this.wrapper(items); } for (let idx = 0; idx !== this.numValues - 1; ++idx) { items.push(this.arb.generate(mrng.clone())); } items.push(this.arb.generate(mrng)); return this.wrapper(items); } static makeItCloneable(vs, shrinkables) { vs[cloneMethod] = () => { const cloned = []; for (let idx = 0; idx !== shrinkables.length; ++idx) { cloned.push(shrinkables[idx].value); } this.makeItCloneable(cloned, shrinkables); return cloned; }; return vs; } wrapper(items) { let cloneable = false; const vs = []; for (let idx = 0; idx !== items.length; ++idx) { const s = items[idx]; cloneable = cloneable || s.hasToBeCloned; vs.push(s.value); } if (cloneable) { DedupArbitrary.makeItCloneable(vs, items); } return new Shrinkable(vs, () => stream(this.shrinkImpl(items)).map((v) => this.wrapper(v))); } *shrinkImpl(items) { if (items.length === 0) { return; } const its = items.map((s) => s.shrink()[Symbol.iterator]()); let cur = its.map((it) => it.next()); while (!cur[0].done) { yield cur.map((c) => c.value); cur = its.map((it) => it.next()); } } } function dedup(arb, numValues) { return new DedupArbitrary(arb, numValues); } export { dedup };