## File: examples/README.md

# Examples based on `fast-check`

This directory gathers multiple examples of properties you might come with when using `fast-check`.

Try online with [CodeSandbox](https://codesandbox.io/s/github/dubzzz/fast-check/tree/main/examples?previewwindow=tests).

_Teach yourself property based through examples_

## Examples by category

Following examples show how you could think about properties given algorithms ranging from basic pure functions returning easy to assess outputs to complex state machines.

**Simple data structures**

101 for property based:

- `decompPrime` - Returns the list of prime factors corresponding to the input value
- `fibonacci` - Returns the item at a given position in the sequence of Fibonacci
- `indexOf` - Returns the position of the first occurrence of `pattern` in `text`
- `sort` - Returns a sorted copy of the input array

**Recursive structures**

Let's see how to generate recursive inputs using `letrec`, `memo` or even none of them:

- `isSearchTree` - Returns `true` if the tree is a binary search tree, `false` otherwise

**Misc**

Various algorithms to have more random examples:

- `knight` - Multi dimensional dichotomy given as a coding exercise
- `mazeGenerator` - Maze generator
- `roman` - Convert from and to roman notation for numbers

**State machines to user interfaces**

Property based testing applied to state machines or user interfaces:

- `MusicPlayer` - Simple music player with `play`, `pause`, `addTrack` and `next`

**Race conditions**

Property based testing used to detect race conditions in various kind of JavaScript snippets:

- `AutocompleteField` - An autocomplete field written in React providing suggestions as soon as possible
- `Counter` - Increment a counter stored in a DB using compare-and-swap
- `DebouncedAutocomplete` - An autocomplete field written in React providing suggestions in a debounced way (uses timers)
- `dependencyTree` - Fetch recursively dependencies for a npm package
- `TodoList` - Simple todolist React app
- `UserProfilePage` - A simple React component loading user profile on mount

## Rules of property based

1. Properties do not replace examples, they are just an extra layer of tests
2. Properties can be used at any level: unit, integration, end-to-end

## Tricks to find properties

1. Characteristics independent of the inputs

> Examples:
>
> `for any floating point number d, Math.floor(d) is an integer`
>
> `for any integer n, Math.abs(n) ≥ 0`

2. Characteristics derived from the inputs

> Examples:
>
> `for any a and b integers the average of a and b is between a and b`
>
> `for any array — data, sorted(data) and data contain the same elements`

3. Restricted set of inputs with useful characteristics

> Examples:
>
> `for any prime number p, its decomposition into prime factors is itself`
>
> `for any a, b and c strings the concatenation of a, b and c always contains b`

4. Characteristics on combination of functions

> Examples:
>
> `for any file f, unzip(zip(f)) is the original file`
>
> `for any a, b numbers lcm(a, b) * gcd(a, b) equals a * b`

5. Comparison with a simpler implementation

---

## File: packages/worker/README.md

# `@fast-check/worker`



Provide built-ins to run predicates directly within dedicated workers

[](https://npmx.dev/package/@fast-check/worker)
[](https://npmx.dev/package/@fast-check/worker)
[](https://github.com/dubzzz/fast-check/blob/main/packages/worker/LICENSE)

---

## Why?

`fast-check` alone is great but what if it led your code into an infinite and synchronous loop for such inputs? In such case, it would neither be able to shrink the issue, nor to report any for you as the single threaded philosophy at the root of JavaScript will prevent it from anything except waiting for the main thread to come back.

This package tends to provide a way to run easily your properties within dedicated workers automatically spawed by it.

## Example

Here are some of the changes you will have to do:

- hoist properties so that they get declared on the root scope
- replace `fc.property` by `property` coming from `propertyFor()`
- replace `fc.assert` by `assert` coming from `@fast-check/worker` for automatic cleaning of the workers as the test ends
- transpilation has not been addressed yet but it may probably work
- in theory, if you were only using `propertyFor` and `assert` without any external framework for `test`, `it` and others, the separation of the property from the assertion would be useless as the check for main thread is fully handled within `@fast-check/worker` itself so no hoisting needing in such case

```js
import { test } from '@jest/globals';
import fc from 'fast-check';
import { isMainThread } from 'node:worker_threads';
import { assert, propertyFor } from '@fast-check/worker';

const property = propertyFor(new URL(import.meta.url)); // or propertyFor(pathToFileURL(__filename)) in commonjs
const p1 = property(fc.nat(), fc.nat(), (start, end) => {
  // starting a possibly infinite loop
  for (let i = start; i !== end; ++i) {
    // doing stuff...
  }
});

if (isMainThread) {
  test('should assess p1', async () => {
    await assert(p1, { timeout: 1000 });
  });
}
```

Refer to the tests defined `test/main.spec.ts` for a living example of how you can use this package with a test runner such as Jest.

## Extra options

The builder of properties `propertyFor` accepts a second parameter to customize how the workers will behave. By default, workers will be shared across properties. In case you want a more isolation between your runs, you can use:

```js
const property = propertyFor(new URL(import.meta.url), { isolationLevel: 'predicate' });
// Other values:
// - "file": Re-use workers cross properties (default)
// - "property": Re-use workers for each run of the predicate. Not shared across properties!
// - "predicate": One worker per run of the predicate
```

By default, workers will receive the generated values from their parent thread. In some cases, such sending is made impossible as the generated values include non-serializable pieces. In such cases, you can opt-in to generate the values directly within the workers by using:

```js
const property = propertyFor(new URL(import.meta.url), { randomSource: 'worker' });
// Other values:
// - "main-thread": The main thread will be responsible to generate the random values and send them to the worker thread. It unfortunately cannot send any value that cannot be serialized between threads. (default)
// - "worker": The worker is responsible to generate its own values based on the instructions provided by the main thread. Switching to a worker mode allows to support non-serializable values, unfortunately it drops all shrinking. capabilities.
```

## Minimal requirements

- Node ≥14.18.0<sup>(1)</sup><sup>(2)</sup><sup>(3)</sup>
- TypeScript ≥4.1 (optional)

_(1): `worker_threads` alone would only require Node ≥10.5.0, but our usage of `require(node:*)` forces us to request at least Node ≥14.18.0_

_(2): this package targets ES2020 specification which is quite well supported (more than 94%) by any Node ≥14.5.0_

_(3): this package requires a version of node able to understand `package.json#exports`, supported by any Node ≥12.17.0_

---

## File: packages/vitest/README.md

# `@fast-check/vitest`



Bring the power of property based testing framework `fast-check` into Vitest.
`@fast-check/vitest` simplifies the integration of `fast-check` into Vitest.

[](https://npmx.dev/package/@fast-check/vitest)
[](https://npmx.dev/package/@fast-check/vitest)
[](https://github.com/dubzzz/fast-check/blob/main/packages/jest/LICENSE)

---

## Getting Started

Install `@fast-check/vitest`:

```bash
npm install --save-dev @fast-check/vitest
```

In order to work properly, `@fast-check/vitest` requires `vitest` to be installed.

## Examples

The library comes with two modes, both powered by fast-check:

- One-time random mode – A lightweight approach that introduces controlled randomness into your tests while keeping runs reproducible.
- Property-based testing mode – A full-fledged property-based testing approach leveraging the full capabilities of fast-check.

### One-time random mode

This mode extends Vitest's default `test` and `it` functions, allowing you to introduce controlled randomness into your tests while ensuring failures remain reproducible. This makes it easier to debug flaky tests and avoid irreproducible failures due to randomness.

Unlike property-based testing, this mode does not run tests multiple times or attempt shrinking when failures occur. Instead, it provides a determistic way to introduce randomness when needed.

```javascript
import { test, fc } from '@fast-check/vitest';
import { expect } from 'vitest';

// You can provide a fixed seed to force a replay by adding this line:
// >>  fc.configureGlobal({ seed })
// Eventually you can disable shrinking capabilities with:
// >>  fc.configureGlobal({ endOnFailure: false })
// >>  // or combine it with the one above if you need both

test('test relying on randomness', ({ g }) => {
  // Arrange
  const user = {
    firstName: g(fc.string),
    lastName: g(fc.string),
  };

  // Act
  const displayName = computeDisplayName(user);

  // Assert
  expect(displayName).toContain(user.firstName);
});

test('test not relying on randomness', () => {
  // your test
});
```

### Full property-based mode

For more extensive testing, `@fast-check/vitest` also provides full support for property-based testing. This mode enables exhaustive, randomized testing by generating a variety of inputs and detecting edge cases automatically.

```javascript
import { test, fc } from '@fast-check/vitest';

// for all a, b, c strings
// b is a substring of a + b + c
test.prop([fc.string(), fc.string(), fc.string()])('should detect the substring', (a, b, c) => {
  return (a + b + c).includes(b);
});

// same property but using named values
test.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('should detect the substring', ({ a, b, c }) => {
  return (a + b + c).includes(b);
});
```

Please note that the properties accepted by `@fast-check/vitest` as input can either be synchronous or asynchronous (even just `PromiseLike` instances).

### Seamless integration with Vitest's `beforeEach` / `afterEach`

Vitest's `beforeEach` and `afterEach` hooks are natively integrated into predicates. They are called respectively before and after each execution of the predicate. If a predicate runs _n_ times, `beforeEach` will be called _n_ times before it and `afterEach` _n_ times after it. The only caveat is that cleanup functions returned by `beforeEach` on the first predicate execution are deferred until the end of the test, as they are handled by vitest's own teardown mechanism. All other cleanups run between predicate executions as expected.

### Advanced

If you want to forward custom parameters to fast-check, `test.prop` accepts an optional `fc.Parameters` ([more](https://github.com/dubzzz/fast-check/blob/main/documentation/1-Guides/Runners.md#runners)).

`@fast-check/vitest` also comes with `.only`, `.skip`, `.todo` and `.concurrent` from vitest. It also accepts more complex ones such as `.concurrent.skip`.

```javascript
import { it, test, fc } from '@fast-check/vitest';

test.prop([fc.nat(), fc.nat()], { seed: 4242 })('should replay the test for the seed 4242', (a, b) => {
  return a + b === b + a;
});

test.skip.prop([fc.string()])('should be skipped', (text) => {
  return text.length === [...text].length;
});

describe('with it', () => {
  it.prop([fc.nat(), fc.nat()])('should run too', (a, b) => {
    return a + b === b + a;
  });
});
```

## Minimal requirements

| @fast-check/vitest | vitest                                                              | fast-check                       | Node                   |
| ------------------ | ------------------------------------------------------------------- | -------------------------------- | ---------------------- |
| **0.4**            | ^4.1.0                                                              | ^3.0.0 \|\| ^4.0.0               | ≥20.19.0<sup>(2)</sup> |
| **0.3**            | ^1 \|\| ^2 \|\| ^3 \|\| ^4                                          | ^3.0.0 \|\| ^4.0.0               | ≥20.19.0<sup>(2)</sup> |
| **0.2**            | ^1 \|\| ^2 \|\| ^3 \|\| ^4<sup>(1)</sup>                            | ^3.0.0 \|\| ^4.0.0               | ≥18<sup>(3)</sup>      |
| **0.1**            | >=0.28.1 <1.0.0 \|\| ^1 \|\| ^2<sup>(4)</sup> \|\| ^3<sup>(5)</sup> | ^3.0.0 \|\| ^4.0.0<sup>(6)</sup> | ≥14.16.0<sup>(3)</sup> |
| **0.0**            | >=0.28.1 <1.0.0 \|\| ^1                                             | ^3.0.0                           | ≥14.16.0<sup>(3)</sup> |


More details...

1. Official support for version 4.x of vitest starts at 0.2.3.
2. Requires support for `require(esm)`.
3. Same support as vitest.
4. Official support for version 2.x of vitest starts at 0.1.2.
5. Official support for version 3.x of vitest starts at 0.1.5.
6. Official support for version 4.x of fast-check starts at 0.1.6.

---

## File: packages/poisoning/README.md

# `@fast-check/poisoning`



Set of utilities to ease detection and revert of poisoning

[](https://npmx.dev/package/@fast-check/poisoning)
[](https://npmx.dev/package/@fast-check/poisoning)
[](https://github.com/dubzzz/fast-check/blob/main/packages/poisoning/LICENSE)

---

## Why?

In JavaScript, "prototype poisoning" is one of the most common source for CVEs or zero days. It allows attackers to change the behaviour of some defaults like `Array.prototype.map`, `Map`, `Set`... so that they behave differently and can be leveraged for evil stuffs. This package can be used in addition to `fast-check` in order to detect poisoning that may occur during your property based tests.

## Easy to use

The package comes with:

- `assertNoPoisoning`: assert that the defaults known when first importing the package in your code have not been changed
- `restoreGlobals`: restore the defaults so that any change that could have been detected by `assertNoPoisoning` will be resolved

## Minimal requirements

- Node ≥20.19.0

---

## File: packages/packaged/README.md

# `@fast-check/packaged`

Utility package removing any files that will not be part of the final bundle published to npm registry

[](https://npmx.dev/package/@fast-check/packaged)
[](https://npmx.dev/package/@fast-check/packaged)
[](https://github.com/dubzzz/fast-check/blob/main/packages/packaged/LICENSE)

---

## Why?

When publishing packages to npm registry, it is quite easy to forget about some files. It also happens many times that we want somehow to check the packaged bundle in some of our tests but totally forget that some files have not been added to the bundle and so that the final user will actually never be able to run this code.

This package mostly try to prevent this issue. It can easily be used in monorepos to emulate the bundled package when used against other packages of the monorepo to make sure others do not depend on internals or non published stuff.

## Easy to use

Run the following command at the root of your package to drop any file that will not make it in the final bundle published to npm.

```bash
# With npm
npx -p @fast-check/packaged packaged
# With pnpm
pnpm --package=@fast-check/packaged dlx packaged
# With yarn
yarn dlx -p @fast-check/packaged packaged
```

⚠️ You may want to try with `--dry-run` flag first to give it a try.

It also comes with some extra flags:

- `--dry-run`: do not drop any file or directory from the file system and only print what would have been removed
- `--keep <name>`: keep a root-level file or directory matching the exact name (not a glob pattern, can be specified multiple times, e.g. `--keep node_modules --keep src`)

## Simple API

```js
import { computePublishedFiles, removeNonPublishedFiles } from '@fast-check/packaged';

// Compute the list of all files that would be part of the bundle
// if we attempted to publish the packge defined at .
const publishedFilesRoot = await computePublishedFiles('.');

// Compute the list of all files that would be part of the bundle
// if we attempted to publish the packge defined at ./sub-directory
const publishedFilesSubDirectory = await computePublishedFiles('./sub-directory');

// Run the deletion of unwanted files
const { kept, removed } = await removeNonPublishedFiles('.', { dryRun: false, keep: [] });
// kept and removed are arrays of strings
// they may contain files or directories
```

## Minimal requirements

| @fast-check/packaged | node                   |
| -------------------- | ---------------------- |
| **0.6.x**            | ≥20.19.0<sup>(1)</sup> |


More details...

1. Requires support for `require(esm)`.

---

## File: packages/jest/README.md

# `@fast-check/jest`



Bring the power of property based testing framework `fast-check` into Jest.
`@fast-check/jest` simplifies the integration of `fast-check` into Jest testing framework.

[](https://npmx.dev/package/@fast-check/jest)
[](https://npmx.dev/package/@fast-check/jest)
[](https://github.com/dubzzz/fast-check/blob/main/packages/jest/LICENSE)

---

## Getting Started

Install `@fast-check/jest`:

```bash
npm install --save-dev @fast-check/jest
```

In order to work properly, `@fast-check/jest` requires `jest` to be installed.

We also highly recommend users to launch their tests using the `--show-seed` option provided by Jest. It ensures Jest will always print the seed by itself (requires Jest ≥29.2.0).

```sh
jest --show-seed
```

## Example

```javascript
import { test, fc } from '@fast-check/jest';

// for all a, b, c strings
// b is a substring of a + b + c
test.prop([fc.string(), fc.string(), fc.string()])('should detect the substring', (a, b, c) => {
  return (a + b + c).includes(b);
});

// Or the exact same test but based on named parameters
test.prop({ a: fc.string(), b: fc.string(), c: fc.string() })('should detect the substring', ({ a, b, c }) => {
  return (a + b + c).includes(b);
});
```

The `it` and `test` functions returned by `@fast-check/jest` are just enriched versions of the ones coming from `jest` itself. They both come with `.prop`.

Please note that the properties accepted by `@fast-check/jest` as input can either be synchronous or asynchronous (even just `PromiseLike` instances). In other words, the predicate passed as the last argument can be asynchronous.

**Remark:** `it` and `test` have been introduced in 1.4.0. You have to refer to [Deprecated API](#deprecated-api) if you are using a version of `@fast-check/jest` <1.4.0.

## Advanced

### Support for variations of `test` and `it`

If you want to forward custom parameters to `fast-check`, `test.prop` and its variants accept an optional `fc.Parameters` ([more](https://fast-check.dev/docs/core-blocks/runners/#assert)).

`@fast-check/jest` also comes with support for `.only`, `.skip`, `.todo` and `.concurrent` from `jest`. It also accepts more complex ones such as `.concurrent.failing` or `.concurrent.only.failing`.

```javascript
import { it, test, fc } from '@fast-check/jest';

// With custom `fc.Parameters`, here { seed: 4242 }
test.prop([fc.nat(), fc.nat()], { seed: 4242 })('should replay the test for the seed 4242', (a, b) => {
  return a + b === b + a;
});

// With .skip
test.skip.prop([fc.string()])('should be skipped', (text) => {
  return text.length === [...text].length;
});

// With it version
describe('with it', () => {
  it.prop([fc.nat(), fc.nat()])('should run too', (a, b) => {
    return a + b === b + a;
  });
});
```

### Experimental worker-based runner

**The following feature is experimental!** When used it makes runners able to kill long running synchonous code. Meaning that it will make fast-check able to kill infinite loops blocking the main thread. So far, the feature does not fully support transformations performed via transform steps defined with jest.

The CommonJS approach would be:

```js
const { init, fc } = require('@fast-check/jest/worker');
const { pathToFileURL } = require('node:url');

const { test, expect } = init(pathToFileURL(__filename));
// can also be passed options such as isolationLevel: init(pathToFileURL(__filename), {})

test.prop([fc.constant(null)])('should pass', (value) => {
  expect(value).toBe(null);
});
```

The ES Modules approach would be:

```js
import { init, fc } from '@fast-check/jest/worker';

const { test, expect } = await init(new URL(import.meta.url));
// can also be passed options such as isolationLevel: init(new URL(import.meta.url), {})

test.prop([fc.constant(null)])('should pass', (value) => {
  expect(value).toBe(null);
});
```

⚠️ Do not forget to add the `await` before `init` for the ES Module version!

#### Extra setup for `@fast-check/worker` 0.6.0 and later

Since `@fast-check/worker` is an ESM-only package, running it under Jest in CommonJS mode requires `babel-jest` to transpile it. Install the following dependencies:

```bash
npm install --save-dev babel-jest @babel/core @babel/preset-env
```

Then add a `babel.config.cjs` at the root of your project:

```js
module.exports = {
  presets: [['@babel/preset-env', { targets: { node: 'current' }, modules: 'commonjs' }]],
};
```

And update your Jest configuration to use `babel-jest` while excluding `@fast-check/worker` from the ignore patterns:

```js
module.exports = {
  transform: {
    '^.+\\.[t|j]sx?$': 'babel-jest',
  },
  transformIgnorePatterns: ['/node_modules/(?!(?:@fast-check/worker)/)'],
};
```

This ensures `@fast-check/worker` gets transpiled to CommonJS by Babel instead of being skipped. Without it, Jest will fail to load the ESM-only package.

For ES Modules mode, no extra setup is needed — just make sure to run Jest with `--experimental-vm-modules`:

```bash
node --experimental-vm-modules node_modules/jest/bin/jest.js
```

## Minimal requirements

| @fast-check/jest | jest                                    | fast-check | node                                                                                  |
| ---------------- | --------------------------------------- | ---------- | ------------------------------------------------------------------------------------- |
| ^2.0.0           | &gt;=26.5.0<sup>(1)</sup><sup>(2)</sup> | ^3.0.0     | &gt;=14.15.0<sup>(3)</sup> and &lt;18, &gt;=18.17.0 and &lt;19<sup>(4)</sup>, &gt;=20 |
| ^1.0.0           | &gt;=26.5.0<sup>(1)</sup><sup>(2)</sup> | ^3.0.0     | &gt;=14.15.0<sup>(3)</sup> and &lt;18, &gt;=18.17.0 and &lt;19<sup>(4)</sup>, &gt;=20 |

- (1) any version of `jest` should be greater or equal than 26.5.0 if you are using `commonjs`
- (2) in order to use `esm` build, you may need to enable experimental features of node, see [here](https://github.com/dubzzz/fast-check/blob/main/packages/test-jest-bundle-esm/package.json)
- (3) &gt;=14.15.0 is the minimal requirements for `jest`, &gt;=12.17.0 is the one for `@fast-check/jest`
- (4) timeout defined on jest might not be properly applied to fast-check for node 18 (until 18.17.0) and node 19, see [#4004](https://github.com/dubzzz/fast-check/pull/4004)

---

## File: packages/fast-check/README.md

<h1 align="center">
  
</h1>







## Getting started

Hands-on tutorial and definition of Property Based Testing: [🏁 see tutorial](https://fast-check.dev/docs/tutorials/quick-start/). Or directly try it online on our pre-configured [CodeSandbox](https://codesandbox.io/s/github/dubzzz/fast-check/tree/main/examples?previewwindow=tests).

Property based testing frameworks check the truthfulness of properties. A property is a statement like: _for all (x, y, ...) such that precondition(x, y, ...) holds predicate(x, y, ...) is true_.

Install the module with: `pnpm add -D fast-check` or `yarn add fast-check --dev` or `npm install fast-check --save-dev`

Example of integration in [mocha](http://mochajs.org/):

```js
import fc from 'fast-check';

// Code under test
const contains = (text, pattern) => text.indexOf(pattern) >= 0;

// Properties
describe('properties', () => {
  // string text always contains itself
  it('should always contain itself', () => {
    fc.assert(fc.property(fc.string(), (text) => contains(text, text)));
  });
  // string a + b + c always contains b, whatever the values of a, b and c
  it('should always contain its substrings', () => {
    fc.assert(
      fc.property(fc.string(), fc.string(), fc.string(), (a, b, c) => {
        // Alternatively: no return statement and direct usage of expect or assert
        return contains(a + b + c, b);
      }),
    );
  });
});
```

In case of failure, the test raises a red flag. Its output should help you to diagnose what went wrong in your implementation. Example with a failing implementation of contain:

```
1) should always contain its substrings
    Error: Property failed after 1 tests (seed: 1527422598337, path: 0:0): ["","",""]
    Shrunk 1 time(s)
    Got error: Property failed by returning false

    Hint: Enable verbose mode in order to have the list of all failing values encountered during the run
```

Integration with other test frameworks: [ava](https://github.com/dubzzz/fast-check-examples/blob/main/test-ava/example.spec.js), [jasmine](https://github.com/dubzzz/fast-check-examples/blob/main/test-jasmine/example.spec.js), [jest](https://github.com/dubzzz/fast-check-examples/blob/main/test-jest/example.spec.js), [mocha](https://github.com/dubzzz/fast-check-examples/blob/main/test/longest%20common%20substr/test.js) and [tape](https://github.com/dubzzz/fast-check-examples/blob/main/test-tape/example.spec.js).

More examples: [simple examples](https://github.com/dubzzz/fast-check/tree/main/examples), [fuzzing](https://github.com/dubzzz/fuzz-rest-api) and [against various algorithms](https://github.com/dubzzz/fast-check-examples).

Useful documentations:

- [🏁 Introduction to Property Based & Hands On](https://fast-check.dev/docs/tutorials/quick-start/)
- [🐣 Built-in arbitraries](https://fast-check.dev/docs/core-blocks/arbitraries/)
- [🔧 Custom arbitraries](https://fast-check.dev/docs/core-blocks/arbitraries/combiners/)
- [🏃‍♂️ Property based runners](https://fast-check.dev/docs/core-blocks/runners/)
- [💥 Tips](https://fast-check.dev/docs/configuration/)
- [🔌 API Reference](https://fast-check.dev/docs/api/)
- [⭐ Awesome fast-check](https://fast-check.dev/docs/ecosystem/)

## Why should I migrate to fast-check?

fast-check has initially been designed in an attempt to cope with limitations I encountered while using other property based testing frameworks designed for JavaScript:

- **Types:** strong and up-to-date types - _thanks to TypeScript_
- **Extendable:** easy `map` method to derive existing arbitraries while keeping shrink \[[more](https://fast-check.dev/docs/core-blocks/arbitraries/combiners/any/#map)\] - _some frameworks ask the user to provide both a->b and b->a mappings in order to keep a shrinker_
- **Extendable:** kind of flatMap-operation called `chain` \[[more](https://fast-check.dev/docs/core-blocks/arbitraries/combiners/any/#chain)\] - _able to bind the output of an arbitrary as input of another one while keeping the shrink working_
- **Extendable:** precondition checks with `fc.pre(...)` \[[more](https://fast-check.dev/docs/core-blocks/properties/#example)\] - _filtering invalid entries can be done directly inside the check function if needed_
- **Extendable:** easily switch from fake data in tests to property based with `fc.gen()` \[[more](https://fast-check.dev/docs/core-blocks/arbitraries/others/#gen)\] - _generate random values within your predicates_
- **Smart:** ability to shrink on `fc.oneof` \[[more](https://fast-check.dev/docs/core-blocks/arbitraries/combiners/any/#oneof)\] - _surprisingly some frameworks don't_
- **Smart:** biased by default - _by default it generates both small and large values, making it easier to dig into counterexamples without having to tweak a size parameter manually_
- **Debug:** verbose mode \[[more](https://fast-check.dev/docs/configuration/custom-reports/#verbosity)\]\[[tutorial](https://fast-check.dev/docs/tutorials/quick-start/read-test-reports/#how-to-increase-verbosity)\] - _easier troubleshooting with verbose mode enabled_
- **Debug:** replay directly on the minimal counterexample \[[tutorial](https://fast-check.dev/docs/tutorials/quick-start/read-test-reports/#how-to-re-run)\] - _no need to replay the whole sequence, you get directly the counterexample_
- **Debug:** custom examples in addition of generated ones \[[more](https://fast-check.dev/docs/configuration/user-definable-values/#run-against-custom-values)\] - _no need to duplicate the code to play the property on custom examples_
- **Debug:** logger per predicate run \[[more](https://fast-check.dev/docs/core-blocks/arbitraries/others/#context)\] - _simplify your troubleshoot with fc.context and its logging feature_
- **Unique:** model based approach \[[more](https://fast-check.dev/docs/advanced/model-based-testing/)\]\[[article](https://medium.com/criteo-labs/detecting-the-unexpected-in-web-ui-fuzzing-1f3822c8a3a5)\] - _use the power of property based testing to test UI, APIs or state machines_
- **Unique:** detect race conditions in your code \[[more](https://fast-check.dev/docs/advanced/race-conditions/)\]\[[tutorial](https://fast-check.dev/docs/tutorials/detect-race-conditions/)\] - _shuffle the way your promises and async calls resolve using the power of property based testing to detect races_
- **Unique:** simplify user definable corner cases \[[more](https://fast-check.dev/docs/configuration/user-definable-values/#shrink-custom-values)\] - _simplify bug resolution by asking fast-check if it can find an even simpler corner case_

For more details, refer to the documentation in the links above.

### Trusted

fast-check has been trusted for years by big projects like: [jest](https://github.com/jestjs/jest), [jasmine](https://github.com/jasmine/jasmine), [fp-ts](https://github.com/gcanti/fp-ts), [io-ts](https://github.com/gcanti/io-ts), [ramda](https://github.com/ramda/ramda), [js-yaml](https://github.com/nodeca/js-yaml), [query-string](https://github.com/sindresorhus/query-string)...

### Powerful

It also proved useful in finding bugs among major open source projects such as [jest](https://github.com/jestjs/jest), [query-string](https://github.com/sindresorhus/query-string)... and [many others](https://fast-check.dev/docs/introduction/track-record/).

## Compatibility

Here are the minimal requirements to use fast-check properly without any polyfills:

| fast-check | node                   | ECMAScript version | _TypeScript (optional)_ |
| ---------- | ---------------------- | ------------------ | ----------------------- |
| **4.x**    | ≥12.17.0<sup>(1)</sup> | ES2020             | ≥5.0                    |
| **3.x**    | ≥8<sup>(2)</sup>       | ES2017             | ≥4.1<sup>(3)</sup>      |
| **2.x**    | ≥8<sup>(2)</sup>       | ES2017             | ≥3.2<sup>(4)</sup>      |
| **1.x**    | ≥0.12<sup>(2)</sup>    | ES3                | ≥3.0<sup>(4)</sup>      |


More details...

1. Even if version 12.x should support most of the ES2020 features that will be leveraged by the version 4, we recommend relying at least on version 14.x of Node as it supports all the targeted specification. In addition, we highly encourage switching to still supported LTS versions of Node and not sticking to unsupported versions for too long.
2. Except for features that cannot be polyfilled - such as `bigint`-related ones - all the capabilities of fast-check should be usable given you use at least the minimal recommended version of node associated to your major of fast-check.
3. Require either lib or target ≥ ES2020 or `@types/node` to be installed.
4. Require either lib or target ≥ ES2015 or `@types/node` to be installed.



## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):






| [**Nicolas DUBIEN**](https://github.com/dubzzz)[💻](https://github.com/dubzzz/fast-check/commits?author=dubzzz) [📖](https://github.com/dubzzz/fast-check/commits?author=dubzzz) [⚠️](https://github.com/dubzzz/fast-check/commits?author=dubzzz) [🚇](#infra-dubzzz) [🎨](#design-dubzzz) [🚧](#maintenance-dubzzz) | [**Aaron Elligsen**](https://github.com/hath995)[💻](https://github.com/dubzzz/fast-check/commits?author=hath995) [📖](https://github.com/dubzzz/fast-check/commits?author=hath995) [⚠️](https://github.com/dubzzz/fast-check/commits?author=hath995) | [**Will Heslam**](https://github.com/willheslam)[📖](https://github.com/dubzzz/fast-check/commits?author=willheslam) | [**kazchimo**](https://github.com/kazchimo)[💻](https://github.com/dubzzz/fast-check/commits?author=kazchimo) [📖](https://github.com/dubzzz/fast-check/commits?author=kazchimo) | [**Brandon Chinn**](https://github.com/brandon-leapyear)[💻](https://github.com/dubzzz/fast-check/commits?author=brandon-leapyear) [📖](https://github.com/dubzzz/fast-check/commits?author=brandon-leapyear) | [**Irakli Safareli**](http://safareli.github.io/resume/)[📖](https://github.com/dubzzz/fast-check/commits?author=safareli) | [**Andrew Herron**](https://github.com/TheSpyder)[📖](https://github.com/dubzzz/fast-check/commits?author=TheSpyder) [🔌](#plugin-TheSpyder) |
| --- | --- | --- | --- | --- | --- | --- |
| [**Eric Crosson**](https://github.com/EricCrosson)[📖](https://github.com/dubzzz/fast-check/commits?author=EricCrosson) [💻](https://github.com/dubzzz/fast-check/commits?author=EricCrosson) | [**burrscurr**](https://github.com/burrscurr)[📖](https://github.com/dubzzz/fast-check/commits?author=burrscurr) | [**JC (Jonathan Chen)**](https://www.dijonkitchen.org/)[📖](https://github.com/dubzzz/fast-check/commits?author=dijonkitchen) | [**Larry Botha**](http://fixate.it/)[📖](https://github.com/dubzzz/fast-check/commits?author=larrybotha) [💻](https://github.com/dubzzz/fast-check/commits?author=larrybotha) [⚠️](https://github.com/dubzzz/fast-check/commits?author=larrybotha) | [**Roman Gusev**](https://epa.ms/RomanGusev)[📖](https://github.com/dubzzz/fast-check/commits?author=102) | [**Tim Wisniewski**](https://timwis.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=timwis) | [**Brais Piñeiro**](https://world.hey.com/brais)[💻](https://github.com/dubzzz/fast-check/commits?author=brapifra) [⚠️](https://github.com/dubzzz/fast-check/commits?author=brapifra) |
| [**Renaud-Pierre Bordes**](https://github.com/brds)[🎨](#design-brds) | [**Jemma Nelson**](https://github.com/fwip)[📖](https://github.com/dubzzz/fast-check/commits?author=fwip) | [**John Haugeland**](http://fullof.bs/)[📖](https://github.com/dubzzz/fast-check/commits?author=StoneCypher) | [**Trey Davis**](https://github.com/treydavis)[🎨](#design-treydavis) | [**Leon Si**](https://leonzalion.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=leonzalion) | [**Gorgi Kosev**](http://spion.github.io/)[🚇](#infra-spion) | [**mayconsacht**](https://github.com/mayconsacht)[💻](https://github.com/dubzzz/fast-check/commits?author=mayconsacht) |
| [**Simon Friis Vindum**](https://github.com/paldepind)[💻](https://github.com/dubzzz/fast-check/commits?author=paldepind) [⚠️](https://github.com/dubzzz/fast-check/commits?author=paldepind) | [**Richard Gibson**](https://twitter.com/gibson042)[📖](https://github.com/dubzzz/fast-check/commits?author=gibson042) | [**Alan Harper**](https://alanharper.com.au/)[📖](https://github.com/dubzzz/fast-check/commits?author=aussiegeek) | [**Makien Osman**](https://github.com/Osman-Sodefa)[💻](https://github.com/dubzzz/fast-check/commits?author=Osman-Sodefa) | [**David Sommerich**](https://github.com/sommd)[💻](https://github.com/dubzzz/fast-check/commits?author=sommd) [⚠️](https://github.com/dubzzz/fast-check/commits?author=sommd) | [**Diego Pedro**](https://github.com/diegopedro94)[💻](https://github.com/dubzzz/fast-check/commits?author=diegopedro94) [⚠️](https://github.com/dubzzz/fast-check/commits?author=diegopedro94) | [**Borui Gu**](https://github.com/BoruiGu)[📖](https://github.com/dubzzz/fast-check/commits?author=BoruiGu) |
| [**Brian Donovan**](https://github.com/eventualbuddha)[📖](https://github.com/dubzzz/fast-check/commits?author=eventualbuddha) | [**volrk**](https://github.com/volrk)[💻](https://github.com/dubzzz/fast-check/commits?author=volrk) [📖](https://github.com/dubzzz/fast-check/commits?author=volrk) [⚠️](https://github.com/dubzzz/fast-check/commits?author=volrk) | [**tinydylan**](https://github.com/tinydylan)[💻](https://github.com/dubzzz/fast-check/commits?author=tinydylan) [⚠️](https://github.com/dubzzz/fast-check/commits?author=tinydylan) | [**Caleb Jasik**](https://github.com/jasikpark)[📖](https://github.com/dubzzz/fast-check/commits?author=jasikpark) | [**Rulai Hu**](https://github.com/rulai-hu)[📖](https://github.com/dubzzz/fast-check/commits?author=rulai-hu) | [**Afonso Jorge Ramos**](https://github.com/afonsojramos)[📖](https://github.com/dubzzz/fast-check/commits?author=afonsojramos) | [**Tom Jenkinson**](https://tjenkinson.me/)[📖](https://github.com/dubzzz/fast-check/commits?author=tjenkinson) |
| [**phormio**](https://github.com/phormio)[📖](https://github.com/dubzzz/fast-check/commits?author=phormio) | [**Giovanni Gonzaga**](http://buildo.io/)[💻](https://github.com/dubzzz/fast-check/commits?author=giogonzo) [⚠️](https://github.com/dubzzz/fast-check/commits?author=giogonzo) | [**Tomas Carnecky**](https://caurea.org/)[💻](https://github.com/dubzzz/fast-check/commits?author=wereHamster) | [**Kirill Romanov**](https://github.com/Djaler)[💻](https://github.com/dubzzz/fast-check/commits?author=Djaler) [📖](https://github.com/dubzzz/fast-check/commits?author=Djaler) [⚠️](https://github.com/dubzzz/fast-check/commits?author=Djaler) | [**Giovanny González**](https://giovannyg.github.io/)[📖](https://github.com/dubzzz/fast-check/commits?author=giovannyg) | [**Mark Kulube**](https://github.com/markkulube)[🚇](#infra-markkulube) | [**Peter Hamilton**](http://www.undiscoveredfeatures.com/)[💻](https://github.com/dubzzz/fast-check/commits?author=hamiltop) |
| [**Chinedu Ozodi**](https://github.com/ChineduOzodi)[📖](https://github.com/dubzzz/fast-check/commits?author=ChineduOzodi) | [**Gunar Gessner**](https://github.com/gunar)[📖](https://github.com/dubzzz/fast-check/commits?author=gunar) | [**Christian Batchelor**](https://github.com/CSBatchelor)[⚠️](https://github.com/dubzzz/fast-check/commits?author=CSBatchelor) | [**Tomer Aberbach**](https://tomeraberba.ch/)[💻](https://github.com/dubzzz/fast-check/commits?author=TomerAberbach) [📖](https://github.com/dubzzz/fast-check/commits?author=TomerAberbach) [⚠️](https://github.com/dubzzz/fast-check/commits?author=TomerAberbach) | [**0xflotus**](https://github.com/0xflotus)[📖](https://github.com/dubzzz/fast-check/commits?author=0xflotus) | [**Ryan Leonard**](https://github.com/CodeLenny)[💻](https://github.com/dubzzz/fast-check/commits?author=CodeLenny) [📖](https://github.com/dubzzz/fast-check/commits?author=CodeLenny) [⚠️](https://github.com/dubzzz/fast-check/commits?author=CodeLenny) | [**Jason Dreyzehner**](https://blog.bitjson.com/)[💻](https://github.com/dubzzz/fast-check/commits?author=bitjson) [⚠️](https://github.com/dubzzz/fast-check/commits?author=bitjson) |
| [**Matin Zadeh Dolatabad**](https://matinzd.dev/)[💻](https://github.com/dubzzz/fast-check/commits?author=matinzd) | [**Juan Julián Merelo Guervós**](http://goo.gl/IlWG8U)[📖](https://github.com/dubzzz/fast-check/commits?author=JJ) | [**Simen Bekkhus**](https://github.com/SimenB)[📖](https://github.com/dubzzz/fast-check/commits?author=SimenB) | [**Tarjei Skjærset**](https://github.com/tskj)[📖](https://github.com/dubzzz/fast-check/commits?author=tskj) | [**Denis Gorbachev**](http://denisgorbachev.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=DenisGorbachev) | [**Trevor McCauley**](http://senocular.github.io/)[📖](https://github.com/dubzzz/fast-check/commits?author=senocular) | [**Grant Kiely**](http://grantkiely.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=gkiely) |
| [**Attila Večerek**](https://github.com/vecerek)[💻](https://github.com/dubzzz/fast-check/commits?author=vecerek) [📖](https://github.com/dubzzz/fast-check/commits?author=vecerek) [⚠️](https://github.com/dubzzz/fast-check/commits?author=vecerek) | [**Zach Bjornson**](http://www.zachbjornson.com/)[💻](https://github.com/dubzzz/fast-check/commits?author=zbjornson) [📖](https://github.com/dubzzz/fast-check/commits?author=zbjornson) | [**Bennett Perkins**](https://github.com/bennettp123)[📖](https://github.com/dubzzz/fast-check/commits?author=bennettp123) | [**Alexandre Oger**](https://github.com/nielk)[📖](https://github.com/dubzzz/fast-check/commits?author=nielk) [💻](https://github.com/dubzzz/fast-check/commits?author=nielk) | [**ej shafran**](https://github.com/ej-shafran)[📖](https://github.com/dubzzz/fast-check/commits?author=ej-shafran) | [**Niklas Gruhn**](https://github.com/gruhn)[💻](https://github.com/dubzzz/fast-check/commits?author=gruhn) [💬](#question-gruhn) | [**Patrick Roza**](https://patrickroza.com/)[💻](https://github.com/dubzzz/fast-check/commits?author=patroza) |
| [**Cindy Wu**](https://github.com/cindywu)[📖](https://github.com/dubzzz/fast-check/commits?author=cindywu) | [**Noah**](https://github.com/nmay231)[📖](https://github.com/dubzzz/fast-check/commits?author=nmay231) | [**James Vaughan**](https://github.com/jamesbvaughan)[📖](https://github.com/dubzzz/fast-check/commits?author=jamesbvaughan) [💻](https://github.com/dubzzz/fast-check/commits?author=jamesbvaughan) | [**Alex Errant**](https://github.com/AlexErrant)[💻](https://github.com/dubzzz/fast-check/commits?author=AlexErrant) | [**andrew jarrett**](https://ahrjarrett.com/)[💻](https://github.com/dubzzz/fast-check/commits?author=ahrjarrett) [📖](https://github.com/dubzzz/fast-check/commits?author=ahrjarrett) | [**Matthias Keckl**](https://github.com/matthyk)[📖](https://github.com/dubzzz/fast-check/commits?author=matthyk) | [**Dolan Murvihill**](https://github.com/dmurvihill)[💻](https://github.com/dubzzz/fast-check/commits?author=dmurvihill) |
| [**Emi**](https://github.com/emilianbold)[💻](https://github.com/dubzzz/fast-check/commits?author=emilianbold) | [**Russ Biggs**](https://www.russbiggs.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=russbiggs) | [**adamni21**](https://github.com/adamni21)[📖](https://github.com/dubzzz/fast-check/commits?author=adamni21) | [**Joseph Junker**](https://github.com/josephjunker)[📖](https://github.com/dubzzz/fast-check/commits?author=josephjunker) | [**Aleksey Shelementev**](https://github.com/rushelex)[💻](https://github.com/dubzzz/fast-check/commits?author=rushelex) | [**rugk**](https://github.com/rugk)[📖](https://github.com/dubzzz/fast-check/commits?author=rugk) | [**Makien Osman**](https://github.com/makeeno)[📖](https://github.com/dubzzz/fast-check/commits?author=makeeno) |
| [**Jonathan Neidel**](https://jneidel.com/)[📖](https://github.com/dubzzz/fast-check/commits?author=jneidel) |  |  |  |  |  |  |








This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! [Become one of them](CONTRIBUTING.md)

## Sponsors 💸

Many individuals and companies offer their financial support to the project, a huge thanks to all of them too 💓

[](https://github.com/sponsors/dubzzz)

You can also become one of them by contributing via [GitHub Sponsors](https://github.com/sponsors/dubzzz) or [OpenCollective](https://opencollective.com/fast-check/contribute).

---

## File: packages/ava/README.md

# `@fast-check/ava`



Bring the power of property based testing framework `fast-check` into AVA.
`@fast-check/ava` simplifies the integration of `fast-check` into AVA testing framework.

[](https://npmx.dev/package/@fast-check/ava)
[](https://npmx.dev/package/@fast-check/ava)
[](https://github.com/dubzzz/fast-check/blob/main/packages/ava/LICENSE)

---

## Getting Started

Install `@fast-check/ava`:

```bash
npm install --save-dev @fast-check/ava
```

In order to work properly, `@fast-check/ava` requires `ava` to be installed.

## Example

```typescript
import { testProp, fc } from '@fast-check/ava';

// for all a, b, c strings
// b is a substring of a + b + c
testProp('should detect the substring', [fc.string(), fc.string(), fc.string()], (t, a, b, c) => {
  t.true((a + b + c).includes(b));
});
```

The property is passed [AVA's `t` argument](https://github.com/avajs/ava/blob/main/docs/02-execution-context.md#execution-context-t-argument) as its first parameter, and the value of each arbitrary for the current test case for the rest of the parameters.

`@fast-check/ava` supports all of [AVA's assertions](https://github.com/avajs/ava/blob/main/docs/03-assertions.md#assertions) and like AVA, it supports synchronous and asynchronous functions, including promises, observables, and callbacks. See [AVA's documentation](https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#declaring-test) for more information.

⚠️ **WARNING:** When relying on `@fast-check/ava`, returning `true` or `false` in your predicates is not taken into account. The library wants assertions or plans to be defined as `ava` itself does. Nonetheless you can still use primitives such as `fc.pre` to cut runs at the middle if some invariants are unmeet: the started plan (if any) will just be ignored.

## Advanced

### `fast-check` Parameters

`testProp` accepts an optional `fc.Parameters` for forwarding custom parameters to `fast-check` ([more](https://fast-check.dev/docs/core-blocks/runners/#assert)).

```typescript
import { testProp, fc } from '@fast-check/ava';

testProp(
  'should detect the substring',
  [fc.string(), fc.string(), fc.string()],
  (t, a, b, c) => {
    t.true((a + b + c).includes(b));
  },
  { numRuns: 10 }, // Example of parameters
);
```

### AVA Modifiers

`@fast-check/ava` also comes with [`.only`], [`.serial`] [`.skip`], and [`.failing`] modifiers from AVA.

```typescript
import { testProp, fc } from '@fast-check/ava';

testProp(
  'should replay the test for the seed 4242',
  [fc.nat(), fc.nat()],
  (t, a, b) => {
    t.is(a + b, b + a);
  },
  { seed: 4242 },
);

testProp.skip('should be skipped', [fc.string()], (t, text) => {
  t.is([...text].length, text.length);
});
```

[`.only`]: https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#running-specific-tests
[`.serial`]: https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#running-tests-serially
[`.skip`]: https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#skipping-tests
[`.failing`]: https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#failing-tests

### AVA `before`/`after` Hooks

`@fast-check/ava` exposes AVA's `before`/`after` [hooks]:

```typescript
import { testProp, fc } from '@fast-check/ava';

testProp.before((t) => {
  connectToDatabase();
});

testProp();
// ... omitted for brevity

testProp.after((t) => {
  closeDatabaseConnection();
});
```

[hooks]: https://github.com/avajs/ava/blob/main/docs/01-writing-tests.md#before--after-hooks

### AVA Execution Context

`@fast-check/ava` mirror's AVA's procedure for customizing the test [execution context]:

```typescript
import { fc, testProp as anyTestProp, PropertyTestInterface } from '@fast-check/ava';

type TestContext = {
  state: string;
};

const testProp = anyTestProp as PropertyTestInterface<TestContext>;

testProp('should reach terminal state', [fc.string()], (t, received) => {
  // here t is typed as ExecutionContext<TestContext>
  console.log(t.context.state); // logs 'uninitialized'
  // ... omitted for brevity
});
```

[execution context]: https://github.com/avajs/ava/blob/main/docs/02-execution-context.md

## Minimal requirements

| @fast-check/ava | AVA                | fast-check | node                   |
| --------------- | ------------------ | ---------- | ---------------------- |
| **3.0**         | ^4 \|\| ^5 \|\| ^6 | ^3 \|\| ^4 | ≥20.19.0<sup>(1)</sup> |
| **2.0**         | ^4 \|\| ^5 \|\| ^6 | ^3 \|\| ^4 | ≥12.22.0<sup>(2)</sup> |
| **1.0**         | ^4 \|\| ^5 \|\| ^6 | ^3         | ≥12.22.0<sup>(2)</sup> |


More details...

1. Requires support for `require(esm)`.
2. As for ava 4.