Skip to content

Commit

Permalink
Merge branch 'facebook:main' into docs-13222
Browse files Browse the repository at this point in the history
  • Loading branch information
brunocabral88 committed Sep 28, 2022
2 parents 09d0ef5 + fd9cd90 commit a1ab102
Show file tree
Hide file tree
Showing 164 changed files with 12,930 additions and 270 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/close-stale.yml
Expand Up @@ -3,6 +3,10 @@ on:
schedule:
- cron: '*/10 * * * *'

permissions:
issues: write # to close stale issues (actions/stale)
pull-requests: write # to close stale PRs (actions/stale)

jobs:
stale:
name: 'Close month old issues and PRs'
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/issues.yml
Expand Up @@ -4,6 +4,9 @@ on:
issues:
types: [labeled]

permissions:
issues: write # to close issues (peter-evans/close-issue)

jobs:
questions:
name: Questions
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/lock.yml
Expand Up @@ -4,8 +4,13 @@ on:
schedule:
- cron: '0 0 * * *'

permissions: {}
jobs:
lock:
permissions:
issues: write # to lock issues (dessant/lock-threads)
pull-requests: write # to lock PRs (dessant/lock-threads)

runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/nodejs.yml
Expand Up @@ -12,6 +12,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

jobs:
prepare-yarn-cache-ubuntu:
uses: ./.github/workflows/prepare-cache.yml
Expand Down
29 changes: 23 additions & 6 deletions CHANGELOG.md
Expand Up @@ -2,22 +2,39 @@

### Features

### Fixes

### Chore & Maintenance

### Performance

## 29.1.1

### Fixes

- `[jest-mock]` Revert ([#13145](https://github.com/facebook/jest/pull/13145))

## 29.1.0

### Features

- `[expect, @jest/expect]` support type inference for function parameters in `CalledWith` assertions ([#13268](https://github.com/facebook/jest/pull/13268))
- `[expect, @jest/expect]` Infer type of `*ReturnedWith` matchers argument ([#13278](https://github.com/facebook/jest/pull/13278))
- `[@jest/environment, jest-runtime]` Allow `jest.requireActual` and `jest.requireMock` to take a type argument ([#13253](https://github.com/facebook/jest/pull/13253))
- `[@jest/environment]` Allow `jest.mock` and `jest.doMock` to take a type argument ([#13254](https://github.com/facebook/jest/pull/13254))
- `[@jest/fake-timers]` Add `jest.now()` to return the current fake clock time ([#13244](https://github.com/facebook/jest/pull/13244), [13246](https://github.com/facebook/jest/pull/13246))
- `[@jest/mock]` Add `withImplementation` method for temporarily overriding a mock.
- `[@jest/fake-timers]` Add `jest.now()` to return the current fake clock time ([#13244](https://github.com/facebook/jest/pull/13244), [#13246](https://github.com/facebook/jest/pull/13246))
- `[@jest/mock]` Add `withImplementation` method for temporarily overriding a mock ([#13281](https://github.com/facebook/jest/pull/13281))
- `[expect]` Export `toThrow*` matchers ([#13328](https://github.com/facebook/jest/pull/13328))

### Fixes

- `[jest-circus, jest-jasmine2]` Fix error messages for Node's `assert.throes` ([#13322](https://github.com/facebook/jest/pull/13322))
- `[jest-haste-map]` Remove `__proto__` usage ([#13256](https://github.com/facebook/jest/pull/13256))
- `[jest-mock]` Improve `spyOn` typings to handle optional properties ([#13247](https://github.com/facebook/jest/pull/13247))
- `[jest-mock]` Fix mocking of getters and setters on classes ([#13145](https://github.com/facebook/jest/pull/13145))
- `[jest-snapshot]` Throw useful error when an array is passed as property matchers ([#13263](https://github.com/facebook/jest/pull/13263))

### Chore & Maintenance

### Performance
- `[jest-snapshot]` Prioritize parser used in the project ([#13323](https://github.com/facebook/jest/pull/13323))
- `[jest-transform]` Attempt to work around issues with atomic writes on Windows ([#11423](https://github.com/facebook/jest/pull/11423))

## 29.0.3

Expand Down
24 changes: 19 additions & 5 deletions docs/CLI.md
Expand Up @@ -180,8 +180,6 @@ Alias: `--collectCoverage`. Indicates that test coverage information should be c

Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`.

Note that using `v8` is considered experimental. This uses V8's builtin code coverage rather than one based on Babel. It is not as well tested, and it has also improved in the last few releases of Node. Using the latest versions of node (v14 at the time of this writing) will yield better results.

### `--debug`

Print debugging info about your Jest config.
Expand Down Expand Up @@ -311,7 +309,13 @@ Allows the test suite to pass when no files are found.

### `--projects <path1> ... <pathN>`

Run tests from one or more projects, found in the specified paths; also takes path globs. This option is the CLI equivalent of the [`projects`](configuration#projects-arraystring--projectconfig) configuration option. Note that if configuration files are found in the specified paths, _all_ projects specified within those configuration files will be run.
Run tests from one or more projects, found in the specified paths; also takes path globs. This option is the CLI equivalent of the [`projects`](configuration#projects-arraystring--projectconfig) configuration option.

:::note

If configuration files are found in the specified paths, _all_ projects specified within those configuration files will be run.

:::

### `--reporters`

Expand Down Expand Up @@ -387,7 +391,9 @@ A JSON string with options that will be passed to the `testEnvironment`. The rel

Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter.

Note that `column` is 0-indexed while `line` is not.
:::note

In the resulting object `column` is 0-indexed while `line` is not.

```json
{
Expand All @@ -396,6 +402,8 @@ Note that `column` is 0-indexed while `line` is not.
}
```

:::

### `--testMatch glob1 ... globN`

The glob patterns Jest uses to detect test files. Please refer to the [`testMatch` configuration](Configuration.md#testmatch-arraystring) for details.
Expand Down Expand Up @@ -456,7 +464,13 @@ Watch files for changes and rerun tests related to changed files. If you want to

Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option.

Use `--watchAll=false` to explicitly disable the watch mode. Note that in most CI environments, this is automatically handled for you.
Use `--watchAll=false` to explicitly disable the watch mode.

:::tip

In most CI environments, this is automatically handled for you.

:::

### `--watchman`

Expand Down
6 changes: 5 additions & 1 deletion docs/CodeTransformation.md
Expand Up @@ -140,7 +140,11 @@ Though not required, we _highly recommend_ implementing `getCacheKey` as well, s

Instead of having your custom transformer implement the `Transformer` interface directly, you can choose to export `createTransformer`, a factory function to dynamically create transformers. This is to allow having a transformer config in your jest config.

Note that [ECMAScript module](ECMAScriptModules.md) support is indicated by the passed in `supports*` options. Specifically `supportsDynamicImport: true` means the transformer can return `import()` expressions, which is supported by both ESM and CJS. If `supportsStaticESM: true` it means top level `import` statements are supported and the code will be interpreted as ESM and not CJS. See [Node's docs](https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs) for details on the differences.
:::note

[ECMAScript module](ECMAScriptModules.md) support is indicated by the passed in `supports*` options. Specifically `supportsDynamicImport: true` means the transformer can return `import()` expressions, which is supported by both ESM and CJS. If `supportsStaticESM: true` it means top level `import` statements are supported and the code will be interpreted as ESM and not CJS. See [Node's docs](https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs) for details on the differences.

:::

:::tip

Expand Down
12 changes: 9 additions & 3 deletions docs/Es6ClassMocks.md
Expand Up @@ -44,7 +44,11 @@ export default class SoundPlayerConsumer {

Calling `jest.mock('./sound-player')` returns a useful "automatic mock" you can use to spy on calls to the class constructor and all of its methods. It replaces the ES6 class with a mock constructor, and replaces all of its methods with [mock functions](MockFunctions.md) that always return `undefined`. Method calls are saved in `theAutomaticMock.mock.instances[index].methodName.mock.calls`.

Please note that if you use arrow functions in your classes, they will _not_ be part of the mock. The reason for that is that arrow functions are not present on the object's prototype, they are merely properties holding a reference to a function.
:::note

If you use arrow functions in your classes, they will _not_ be part of the mock. The reason for that is that arrow functions are not present on the object's prototype, they are merely properties holding a reference to a function.

:::

If you don't need to replace the implementation of the class, this is the easiest option to set up. For example:

Expand Down Expand Up @@ -240,9 +244,9 @@ jest.mock('./sound-player', () => {
});
```

**_Note: Arrow functions won't work_**
:::note

Note that the mock can't be an arrow function because calling `new` on an arrow function is not allowed in JavaScript. So this won't work:
The mock can't be an arrow function because calling `new` on an arrow function is not allowed in JavaScript. So this won't work:

```javascript
jest.mock('./sound-player', () => {
Expand All @@ -255,6 +259,8 @@ jest.mock('./sound-player', () => {

This will throw **_TypeError: \_soundPlayer2.default is not a constructor_**, unless the code is transpiled to ES5, e.g. by `@babel/preset-env`. (ES5 doesn't have arrow functions nor classes, so both will be transpiled to plain functions.)

:::

## Mocking a specific method of a class

Lets say that you want to mock or spy the method `playSoundFile` within the class `SoundPlayer`. A simple example:
Expand Down
47 changes: 44 additions & 3 deletions docs/ExpectAPI.md
Expand Up @@ -203,7 +203,40 @@ expect.extend({
});
```

:::
:::note

In TypeScript, when using `@types/jest` for example, you can declare the new `toBeWithinRange` matcher in the imported module like this:

```ts title="toBeWithinRange.ts"
expect.extend({
toBeWithinRange(received: number, floor: number, ceiling: number) {
// ...
},
});
declare global {
namespace jest {
interface Matchers<R> {
toBeWithinRange(a: number, b: number): R;
}
}
}
```

If you want to move the typings to a separate file (e.g. `types/jest/index.d.ts`), you may need to an export, e.g.:

```ts
interface CustomMatchers<R = unknown> {
toBeWithinRange(floor: number, ceiling: number): R;
}
declare global {
namespace jest {
interface Expect extends CustomMatchers {}
interface Matchers<R> extends CustomMatchers<R> {}
interface InverseAsymmetricMatchers extends CustomMatchers {}
}
}
export {};
```

#### Async Matchers

Expand Down Expand Up @@ -763,7 +796,9 @@ test('resolves to lemon', () => {
});
```

Note that, since you are still testing promises, the test is still asynchronous. Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by returning the unwrapped assertion.
:::note

Since you are still testing promises, the test is still asynchronous. Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by returning the unwrapped assertion.

Alternatively, you can use `async/await` in combination with `.resolves`:

Expand All @@ -774,6 +809,8 @@ test('resolves to lemon', async () => {
});
```

:::

### `.rejects`

Use `.rejects` to unwrap the reason of a rejected promise so any other matcher can be chained. If the promise is fulfilled the assertion fails.
Expand All @@ -789,7 +826,9 @@ test('rejects to octopus', () => {
});
```

Note that, since you are still testing promises, the test is still asynchronous. Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by returning the unwrapped assertion.
:::note

Since you are still testing promises, the test is still asynchronous. Hence, you will need to [tell Jest to wait](TestingAsyncCode.md#promises) by returning the unwrapped assertion.

Alternatively, you can use `async/await` in combination with `.rejects`.

Expand All @@ -799,6 +838,8 @@ test('rejects to octopus', async () => {
});
```

:::

### `.toBe(value)`

Use `.toBe` to compare primitive values or to check referential identity of object instances. It calls `Object.is` to compare values, which is even better for testing than `===` strict equality operator.
Expand Down
12 changes: 10 additions & 2 deletions docs/GettingStarted.md
Expand Up @@ -104,14 +104,18 @@ module.exports = api => {
};
```

> Note: `babel-jest` is automatically installed when installing Jest and will automatically transform files if a babel configuration exists in your project. To avoid this behavior, you can explicitly reset the `transform` configuration option:
:::note

`babel-jest` is automatically installed when installing Jest and will automatically transform files if a babel configuration exists in your project. To avoid this behavior, you can explicitly reset the `transform` configuration option:

```javascript title="jest.config.js"
module.exports = {
transform: {},
};
```

:::

</details>

### Using webpack
Expand Down Expand Up @@ -187,4 +191,8 @@ Or you may choose to install the [`@types/jest`](https://npmjs.com/package/@type
npm install --save-dev @types/jest
```

Note that `@types/jest` is a third party library maintained at [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest), hence the latest Jest features or versions may not be covered yet. Try to match versions of Jest and `@types/jest` as closely as possible. For example, if you are using Jest `27.4.0` then installing `27.4.x` of `@types/jest` is ideal.
:::info

`@types/jest` is a third party library maintained at [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest), hence the latest Jest features or versions may not be covered yet. Try to match versions of Jest and `@types/jest` as closely as possible. For example, if you are using Jest `27.4.0` then installing `27.4.x` of `@types/jest` is ideal.

:::
20 changes: 16 additions & 4 deletions docs/ManualMocks.md
Expand Up @@ -9,15 +9,23 @@ Manual mocks are used to stub out functionality with mock data. For example, ins

Manual mocks are defined by writing a module in a `__mocks__/` subdirectory immediately adjacent to the module. For example, to mock a module called `user` in the `models` directory, create a file called `user.js` and put it in the `models/__mocks__` directory. Note that the `__mocks__` folder is case-sensitive, so naming the directory `__MOCKS__` will break on some systems.

> When we require that module in our tests (meaning we want to use the manual mock instead of the real implementation), explicitly calling `jest.mock('./moduleName')` is **required**.
:::note

When we require that module in our tests (meaning we want to use the manual mock instead of the real implementation), explicitly calling `jest.mock('./moduleName')` is **required**.

:::

## Mocking Node modules

If the module you are mocking is a Node module (e.g.: `lodash`), the mock should be placed in the `__mocks__` directory adjacent to `node_modules` (unless you configured [`roots`](Configuration.md#roots-arraystring) to point to a folder other than the project root) and will be **automatically** mocked. There's no need to explicitly call `jest.mock('module_name')`.

Scoped modules (also known as [scoped packages](https://docs.npmjs.com/cli/v6/using-npm/scope)) can be mocked by creating a file in a directory structure that matches the name of the scoped module. For example, to mock a scoped module called `@scope/project-name`, create a file at `__mocks__/@scope/project-name.js`, creating the `@scope/` directory accordingly.

> Warning: If we want to mock Node's core modules (e.g.: `fs` or `path`), then explicitly calling e.g. `jest.mock('path')` is **required**, because core Node modules are not mocked by default.
:::caution

If we want to mock Node's build-in modules (e.g.: `fs` or `path`), then explicitly calling e.g. `jest.mock('path')` is **required**, because build-in modules are not mocked by default.

:::

## Examples

Expand All @@ -36,7 +44,11 @@ Scoped modules (also known as [scoped packages](https://docs.npmjs.com/cli/v6/us

When a manual mock exists for a given module, Jest's module system will use that module when explicitly calling `jest.mock('moduleName')`. However, when `automock` is set to `true`, the manual mock implementation will be used instead of the automatically created mock, even if `jest.mock('moduleName')` is not called. To opt out of this behavior you will need to explicitly call `jest.unmock('moduleName')` in tests that should use the actual module implementation.

> Note: In order to mock properly, Jest needs `jest.mock('moduleName')` to be in the same scope as the `require/import` statement.
:::info

In order to mock properly, Jest needs `jest.mock('moduleName')` to be in the same scope as the `require/import` statement.

:::

Here's a contrived example where we have a module that provides a summary of all the files in a given directory. In this case, we use the core (built in) `fs` module.

Expand Down Expand Up @@ -92,7 +104,7 @@ fs.readdirSync = readdirSync;
module.exports = fs;
```

Now we write our test. Note that we need to explicitly tell that we want to mock the `fs` module because it’s a core Node module:
Now we write our test. In this case `jest.mock('fs')` must be called explicitly, because `fs` is Node’s build-in module:

```javascript title="__tests__/FileSummarizer-test.js"
'use strict';
Expand Down
6 changes: 5 additions & 1 deletion docs/Puppeteer.md
Expand Up @@ -5,7 +5,11 @@ title: Using with puppeteer

With the [Global Setup/Teardown](Configuration.md#globalsetup-string) and [Async Test Environment](Configuration.md#testenvironment-string) APIs, Jest can work smoothly with [puppeteer](https://github.com/GoogleChrome/puppeteer).

> Generating code coverage for test files using Puppeteer is currently not possible if your test uses `page.$eval`, `page.$$eval` or `page.evaluate` as the passed function is executed outside of Jest's scope. Check out [issue #7962](https://github.com/facebook/jest/issues/7962#issuecomment-495272339) on GitHub for a workaround.
:::note

Generating code coverage for test files using Puppeteer is currently not possible if your test uses `page.$eval`, `page.$$eval` or `page.evaluate` as the passed function is executed outside of Jest's scope. Check out [issue #7962](https://github.com/facebook/jest/issues/7962#issuecomment-495272339) on GitHub for a workaround.

:::

## Use jest-puppeteer Preset

Expand Down

0 comments on commit a1ab102

Please sign in to comment.