Authors property-based tests in JavaScript / TypeScript using fast-check - wires `fc.assert(fc.property(arbitrary, ...))`, picks arbitraries (`fc.integer`, `fc.string`, `fc.array`, `fc.tuple`, `fc.record`), uses `.map()` / `.chain()` / `.filter()` to build domain arbitraries, and integrates with Jest / Vitest / Mocha / Jasmine / AVA / Tape. Use when a JS/TS codebase needs PBT to catch edge cases - fast-check has been used to find bugs in major libraries (`query-string`, etc.) and is trusted by Jest, Jasmine, fp-ts, Ramda.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
How to build the generators passed to fc.property(<arbitraries...>, predicate).
Per fast-check-overview:
| Arbitrary | Generates |
|---|---|
fc.string() | Strings |
fc.integer() | Integers |
fc.float() / fc.double() | Floats |
fc.boolean() | Booleans |
fc.array(item) | Arrays of item |
fc.tuple(a, b, ...) | Fixed-length tuples |
fc.record({ key: ... }) | Objects with specified properties |
fc.option(item) | item or null |
fc.constantFrom(...) | One of fixed values |
fc.oneof(a, b, ...) | One of multiple arbitraries |
fc.uuid() / fc.ipV4() / fc.emailAddress() / fc.webUrl() | Format-specific |
fc.date() | Dates |
fc.uniqueArray(item) | Arrays without duplicates |
fc.dictionary(key, value) | Map / Record types |
Per fast-check-overview: "Extensible via map() and
chain() combinators."
// .map: transform a generated value
const evenInteger = fc.integer().map(n => n * 2);
// .chain: dependent generation (later value depends on earlier)
const stringWithKnownLength = fc.integer({ min: 1, max: 100 })
.chain(len => fc.string({ minLength: len, maxLength: len }));
// .filter: reject (use sparingly - slow when filter rejects most)
const positiveInteger = fc.integer().filter(n => n > 0);
// Better:
const positiveInteger = fc.integer({ min: 1 });.filter() discards rejections; .map() transforms. Prefer
.map() and constrained arbitraries over .filter() when
possible.
fc.recordconst user = fc.record({
id: fc.uuid(),
email: fc.emailAddress(),
age: fc.integer({ min: 18, max: 100 }),
tags: fc.uniqueArray(fc.constantFrom('admin', 'beta', 'churn-risk')),
createdAt: fc.date({ min: new Date('2020-01-01'), max: new Date() }),
});
it('serializes user to JSON and back', () => {
fc.assert(
fc.property(user, (u) => {
expect(JSON.parse(JSON.stringify(u))).toEqual({
...u,
createdAt: u.createdAt.toISOString(),
});
})
);
});fc.record produces objects with the specified shape; each field
is sampled per its arbitrary.