bun/fast-check-no-unseeded-random
Disallow Math.random() and fc.sample() inside a fast-check property
fast-check draws every input of a property from one seed. When a property fails, it prints the seed so you can run the same inputs again, and it shrinks the inputs to the smallest ones that still fail.
A value from Math.random() or fc.sample() inside the function you pass to fc.property() or fc.asyncProperty() doesn't come from that seed. It's different on every run, so the failure can't be replayed or shrunk. Make the value a parameter of the property instead.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"bun/fast-check-no-unseeded-random" = "error" # or "warn"Examples#
example.ts1 problem
import fc from "fast-check";
import { pad } from "./text";
fc.assert(
fc.property(fc.string(), text => {
const width = Math.floor(Math.random()Math.random() ignores the seed of the run, so a failure cannot be replayed or shrunk. Make the value a parameter of the property. * 80);
return pad(text, width).length >= width;
}),
);example.ts1 problem
import { assert, integer, property, sample, string } from "fast-check";
import { pad } from "./text";
assert(
property(string(), text => {
const [width] = sample(integer({ min: 0, max: 80 }), 1)sample() ignores the seed of the run, so a failure cannot be replayed or shrunk. Make the value a parameter of the property.;
return pad(text, width).length >= width;
}),
);example.tsNo problems
import fc from "fast-check";
import { pad } from "./text";
fc.assert(
fc.property(fc.string(), fc.integer({ min: 0, max: 80 }), (text, width) => {
return pad(text, width).length >= width;
}),
);fc.sample() outside a property is fine:
example.tsNo problems
import fc from "fast-check";
console.log(fc.sample(fc.emailAddress(), 5));