diff --git a/src/check/arbitrary/FrequencyArbitrary.ts b/src/check/arbitrary/FrequencyArbitrary.ts index c427f9b02b6..0f7567a7a32 100644 --- a/src/check/arbitrary/FrequencyArbitrary.ts +++ b/src/check/arbitrary/FrequencyArbitrary.ts @@ -13,21 +13,20 @@ class FrequencyArbitrary extends Arbitrary { readonly totalWeight: number; constructor(readonly warbs: WeightedArbitrary[]) { super(); - this.summedWarbs = warbs - .reduce( - (p: WeightedArbitrary[], c) => - p.concat({ - weight: p[p.length - 1].weight + c.weight, - arbitrary: c.arbitrary - }), - [{ weight: 0, arbitrary: warbs[0].arbitrary }] - ) - .slice(1); - this.totalWeight = this.summedWarbs[this.summedWarbs.length - 1].weight; + let currentWeight = 0; + this.summedWarbs = []; + for (let idx = 0; idx !== warbs.length; ++idx) { + currentWeight += warbs[idx].weight; + this.summedWarbs.push({ weight: currentWeight, arbitrary: warbs[idx].arbitrary }); + } + this.totalWeight = currentWeight; } generate(mrng: Random): Shrinkable { const selected = mrng.nextInt(0, this.totalWeight - 1); - return this.summedWarbs.find(warb => selected < warb.weight)!.arbitrary.generate(mrng); + for (let idx = 0; idx !== this.summedWarbs.length; ++idx) { + if (selected < this.summedWarbs[idx].weight) return this.summedWarbs[idx].arbitrary.generate(mrng); + } + throw new Error(`Unable to generate from fc.frequency`); } withBias(freq: number) { return new FrequencyArbitrary(this.warbs.map(v => ({ weight: v.weight, arbitrary: v.arbitrary.withBias(freq) }))); diff --git a/test/legacy/main.js b/test/legacy/main.js index 74fc0c40c0d..24082fdc506 100644 --- a/test/legacy/main.js +++ b/test/legacy/main.js @@ -69,3 +69,4 @@ testArbitrary(fc.json()); testArbitrary(fc.string()); testArbitrary(fc.fullUnicodeString()); testArbitrary(fc.lorem()); +testArbitrary(fc.frequency({ weight: 1, arbitrary: fc.nat() }, { weight: 2, arbitrary: fc.double() }));