diff --git a/.circleci/config.yml b/.circleci/config.yml index 9c2ed2bf9a6b..a29f7e918b73 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: steps: - checkout - node/install: - lts: true + node-version: '14' install-npm: false - node/install-packages: *install - run: @@ -70,5 +70,5 @@ workflows: partial: true matrix: parameters: - node-version: ['10', '12', '15', '16'] + node-version: ['10', '12', '15', '16', '17'] - test-jest-jasmine diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index cfcbc9a1d0ab..a37e014a732d 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -69,7 +69,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [10.x, 12.x, 14.x, 15.x, 16.x] + node-version: [10.x, 12.x, 14.x, 15.x, 16.x, 17.x] os: [ubuntu-latest, macOS-latest, windows-latest] runs-on: ${{ matrix.os }} needs: prepare-yarn-cache diff --git a/CHANGELOG.md b/CHANGELOG.md index c37f53b3699e..3ca7f7a06dde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,33 @@ ### Performance +## 27.4.0 + +### Features + +- `[expect]` Enhancing the `toHaveProperty` matcher to support array selection ([#12092](https://github.com/facebook/jest/pull/12092)) +- `[jest-core]` Add support for `testResultsProcessor` written in ESM ([#12006](https://github.com/facebook/jest/pull/12006)) +- `[jest-diff, pretty-format]` Add `compareKeys` option for custom sorting of object keys ([#11992](https://github.com/facebook/jest/pull/11992)) +- `[jest-mock]` Add `ts-jest` mock util functions ([#12089](https://github.com/facebook/jest/pull/12089)) + +### Fixes + +- `[expect]` Allow again `expect.Matchers` generic with single value ([#11986](https://github.com/facebook/jest/pull/11986)) +- `[jest-circus, jest-jasmine2]` Avoid false concurrent test failures due to unhandled promise rejections ([#11987](https://github.com/facebook/jest/pull/11987)) +- `[jest-config]` Add missing `slash` dependency to `package.json` ([#12080](https://github.com/facebook/jest/pull/12080)) +- `[jest-core]` Incorrect detection of open ZLIB handles ([#12022](https://github.com/facebook/jest/pull/12022)) +- `[jest-diff]` Break dependency cycle ([#10818](https://github.com/facebook/jest/pull/10818)) +- `[jest-environment-jsdom]` Add `@types/jsdom` dependency ([#11999](https://github.com/facebook/jest/pull/11999)) +- `[jest-environment-jsdom]` Do not reset the global.document too early on teardown ([#11871](https://github.com/facebook/jest/pull/11871)) +- `[jest-transform]` Improve error and warning messages ([#11998](https://github.com/facebook/jest/pull/11998)) + +### Chore & Maintenance + +- `[docs]` CLI options alphabetized ([#11586](https://github.com/facebook/jest/pull/11586)) +- `[jest-runner]` Add info regarding timers to forcedExit message([#12083](https://github.com/facebook/jest/pull/12083)) +- `[*]` Replaced `substr` method with `substring` ([#12066](https://github.com/facebook/jest/pull/12066)) +- `[*]` Add `types` entry to all export maps ([#12073](https://github.com/facebook/jest/pull/12073)) + ## 27.3.1 ### Fixes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08bae3d7ba7c..a276b16e449f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ _Before_ submitting a pull request, please make sure the following is done… python --version ``` -1. Make sure you have a compatible version of `node` installed (As of April 14th 2021, `v14.x` is recommended). +1. Make sure you have a compatible version of `node` installed (As of October 29th 2021, `v16.x` is recommended). ```sh node -v diff --git a/README.md b/README.md index 0a30e3fdb221..c93a0ff72e72 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- npm version + npm version Jest is released under the MIT license. @@ -176,7 +176,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript diff --git a/docs/BypassingModuleMocks.md b/docs/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/docs/BypassingModuleMocks.md +++ b/docs/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/docs/CLI.md b/docs/CLI.md index e22c5df733e8..4d9af6aceb25 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -220,10 +224,6 @@ _Note: This option is only supported using the default `jest-circus` test runner Prints the test results in JSON. This mode will send all other test output and user messages to stderr. -### `--outputFile=` - -Write test results to a file when the `--json` option is also specified. The returned JSON structure is documented in [testResultsProcessor](Configuration.md#testresultsprocessor-string). - ### `--lastCommit` Run all tests affected by file changes in the last commit made. Behaves similarly to `--onlyChanged`. @@ -258,6 +258,10 @@ Activates notifications for test results. Good for when you don't want your cons Alias: `-o`. Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a git/hg repository at the moment and requires a static dependency graph (ie. no dynamic requires). +### `--outputFile=` + +Write test results to a file when the `--json` option is also specified. The returned JSON structure is documented in [testResultsProcessor](Configuration.md#testresultsprocessor-string). + ### `--passWithNoTests` Allows the test suite to pass when no files are found. @@ -272,6 +276,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -280,16 +292,16 @@ A list of paths to directories that Jest should use to search for files in. Alias: `-i`. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. -### `--selectProjects ... ` - -Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. - ### `--runTestsByPath` Run only the tests that were specified with their exact paths. _Note: The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files_ +### `--selectProjects ... ` + +Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. + ### `--setupFilesAfterEnv ... ` A list of paths to modules that run some code to configure or to set up the testing framework before each test. Beware that files imported by the setup scripts will not be mocked during testing. @@ -306,12 +318,6 @@ Prevent tests from printing messages through the console. A JSON string with options that will be passed to the `testEnvironment`. The relevant options depend on the environment. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -325,9 +331,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: -t. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like "GET /api/posts with auth", then you can use jest -t=auth. + +Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks. ### `--testPathIgnorePatterns=|[array]` @@ -335,6 +343,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/docs/CodeTransformation.md b/docs/CodeTransformation.md index a7a71094f728..8da5d7a72bc8 100644 --- a/docs/CodeTransformation.md +++ b/docs/CodeTransformation.md @@ -19,12 +19,12 @@ If you override the `transform` configuration option `babel-jest` will no longer ## Writing custom transformers -You can write you own transformer. The API of a transformer is as follows: +You can write your own transformer. The API of a transformer is as follows: ```ts interface SyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -59,7 +59,7 @@ interface SyncTransformer { interface AsyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -120,11 +120,11 @@ type TransformedSource = | {code: string; map?: RawSourceMap | string | null} | string; -// Config.ProjectConfig can be seen in in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) +// Config.ProjectConfig can be seen in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) // RawSourceMap comes from [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12) ``` -As can be seen, only `process` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. +As can be seen, only `process` or `processAsync` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. 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. @@ -138,8 +138,7 @@ While `babel-jest` by default will transpile TypeScript files, Babel will not ve Importing images is a way to include them in your browser bundle, but they are not valid JavaScript. One way of handling it in Jest is to replace the imported value with its filename. -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -149,9 +148,7 @@ module.exports = { }; ``` -```js -// jest.config.js - +```js title="jest.config.js" module.exports = { transform: { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': diff --git a/docs/Configuration.md b/docs/Configuration.md index 56131b06edfb..60ee6f4c889f 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" // Sync object /** @type {import('@jest/types').Config.InitialOptions} */ const config = { @@ -36,8 +35,7 @@ module.exports = async () => { Or through TypeScript (if `ts-node` is installed): -```ts -// jest.config.ts +```ts title="jest.config.ts" import type {Config} from '@jest/types'; // Sync object @@ -73,8 +71,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -99,8 +96,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -150,7 +146,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -404,9 +400,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -464,8 +458,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -473,8 +466,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -735,8 +727,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -773,7 +764,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -816,8 +807,7 @@ For example, if you want to respect Browserify's [`"browser"` field](https://git } ``` -```js -// resolver.js +```js title="resolver.js" const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; @@ -859,7 +849,7 @@ While Jest does not support [package `exports`](https://nodejs.org/api/packages. Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -915,15 +905,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1303,8 +1291,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/docs/Es6ClassMocks.md b/docs/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/docs/Es6ClassMocks.md +++ b/docs/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index eddf1bec562e..bef99cce8ab5 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -895,6 +895,16 @@ const houseForSale = { wallColor: 'white', 'nice.oven': true, }, + livingroom: { + amenities: [ + { + couch: [ + ['large', {dimensions: [20, 20]}], + ['small', {dimensions: [10, 10]}], + ], + }, + ], + }, 'ceiling.height': 2, }; @@ -922,6 +932,10 @@ test('this house has my desired features', () => { ['oven', 'stove', 'washer'], ); expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven'); + expect(houseForSale).toHaveProperty( + 'livingroom.amenities[0].couch[0][1].dimensions[0]', + 20, + ); expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']); expect(houseForSale).not.toHaveProperty(['kitchen', 'open']); diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index fa317619a57b..967ab4b06d3c 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 4f9c95cab35c..c4cd184b5661 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -102,8 +106,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -112,8 +115,7 @@ export default { }; ``` -```js -// __tests__/createMockFromModule.test.js +```js title="__tests__/createMockFromModule.test.js" const utils = jest.createMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -147,8 +149,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -178,8 +179,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.createMockFromModule('./example'); test('should run example code', () => { @@ -220,11 +220,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -451,7 +451,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -564,7 +564,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -578,7 +578,51 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +### `jest.mocked(item: T, deep = false)` + +The `mocked` test helper provides typings on your mocked modules and even their deep methods, based on the typing of its source. It makes use of the latest TypeScript feature, so you even have argument types completion in the IDE (as opposed to `jest.MockInstance`). + +_Note: while it needs to be a function so that input type is changed, the helper itself does nothing else than returning the given input value._ + +Example: + +```ts +// foo.ts +export const foo = { + a: { + b: { + c: { + hello: (name: string) => `Hello, ${name}`, + }, + }, + }, + name: () => 'foo', +}; +``` + +```ts +// foo.spec.ts +import {foo} from './foo'; +jest.mock('./foo'); + +// here the whole foo var is mocked deeply +const mockedFoo = jest.mocked(foo, true); + +test('deep', () => { + // there will be no TS error here, and you'll have completion in modern IDEs + mockedFoo.a.b.c.hello('me'); + // same here + expect(mockedFoo.a.b.c.hello.mock.calls).toHaveLength(1); +}); + +test('direct', () => { + foo.name(); + // here only foo.name is mocked (or its methods if it's an object) + expect(mocked(foo.name).mock.calls).toHaveLength(1); +}); +``` + +## Mock Timers ### `jest.useFakeTimers(implementation?: 'modern' | 'legacy')` diff --git a/docs/JestPlatform.md b/docs/JestPlatform.md index 2273524221cd..7e638e040b63 100644 --- a/docs/JestPlatform.md +++ b/docs/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `JestWorker` that take ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/docs/ManualMocks.md b/docs/ManualMocks.md index d481a5712e49..178226d727f9 100644 --- a/docs/ManualMocks.md +++ b/docs/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/docs/MockFunctionAPI.md b/docs/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/docs/MockFunctionAPI.md +++ b/docs/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/docs/MockFunctions.md b/docs/MockFunctions.md index d6dc73b999aa..2e686a92e837 100644 --- a/docs/MockFunctions.md +++ b/docs/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/docs/Puppeteer.md b/docs/Puppeteer.md index 53c16767b74e..16ab669a9ab2 100644 --- a/docs/Puppeteer.md +++ b/docs/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/docs/SetupAndTeardown.md b/docs/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/docs/SetupAndTeardown.md +++ b/docs/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/docs/TimerMocks.md b/docs/TimerMocks.md index e97e2af97709..b053c1dbdfc9 100644 --- a/docs/TimerMocks.md +++ b/docs/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -82,8 +80,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -103,8 +100,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -140,8 +136,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/docs/TutorialAsync.md b/docs/TutorialAsync.md index f9418ad6651b..9c283074cabd 100644 --- a/docs/TutorialAsync.md +++ b/docs/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/docs/TutorialReact.md b/docs/TutorialReact.md index 7cce1e08cf10..5fcfa52a098b 100644 --- a/docs/TutorialReact.md +++ b/docs/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/docs/TutorialReactNative.md b/docs/TutorialReactNative.md index d89564980791..ddb60b230c31 100644 --- a/docs/TutorialReactNative.md +++ b/docs/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/docs/WatchPlugins.md +++ b/docs/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/docs/Webpack.md b/docs/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/docs/Webpack.md +++ b/docs/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/e2e/__tests__/jasmineAsync.test.ts b/e2e/__tests__/jasmineAsync.test.ts index 3006a04b3810..8b6cfb93ec1c 100644 --- a/e2e/__tests__/jasmineAsync.test.ts +++ b/e2e/__tests__/jasmineAsync.test.ts @@ -168,4 +168,13 @@ describe('async jasmine', () => { expect(result.exitCode).toBe(0); }); + + it('works when another test fails while one is running', () => { + const {json} = runWithJson('jasmine-async', [ + 'concurrent-parallel-failure.test.js', + ]); + expect(json.numTotalTests).toBe(2); + expect(json.numPassedTests).toBe(1); + expect(json.numFailedTests).toBe(1); + }); }); diff --git a/e2e/__tests__/testResultsProcessor.test.ts b/e2e/__tests__/testResultsProcessor.test.ts index cd7d89e6f592..c3724b6fe92e 100644 --- a/e2e/__tests__/testResultsProcessor.test.ts +++ b/e2e/__tests__/testResultsProcessor.test.ts @@ -6,9 +6,10 @@ */ import * as path from 'path'; +import {onNodeVersions} from '@jest/test-utils'; import {json as runWithJson} from '../runJest'; -test('testNamePattern', () => { +test('testResultsProcessor', () => { const processorPath = path.resolve( __dirname, '../test-results-processor/processor.js', @@ -19,3 +20,18 @@ test('testNamePattern', () => { ]); expect(json.processed).toBe(true); }); + +// The versions where vm.Module exists and commonjs with "exports" is not broken +onNodeVersions('>=12.16.0', () => { + test('testResultsProcessor written in ESM', () => { + const processorPath = path.resolve( + __dirname, + '../test-results-processor/processor.mjs', + ); + const {json} = runWithJson('test-results-processor', [ + '--json', + `--testResultsProcessor=${processorPath}`, + ]); + expect(json.processed).toBe(true); + }); +}); diff --git a/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js b/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js new file mode 100644 index 000000000000..e4869be91465 --- /dev/null +++ b/e2e/jasmine-async/__tests__/concurrent-parallel-failure.test.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +it.concurrent('Good Test', async () => { + await new Promise(r => setTimeout(r, 100)); +}); + +it.concurrent('Bad Test', async () => { + expect('a').toBe('b'); +}); diff --git a/e2e/runJest.ts b/e2e/runJest.ts index 476ae851a115..3086fb7316f6 100644 --- a/e2e/runJest.ts +++ b/e2e/runJest.ts @@ -59,7 +59,7 @@ function spawnJest( dir: string, args: Array = [], options: RunJestOptions = {}, - spawnAsync: boolean = false, + spawnAsync = false, ): execa.ExecaSyncReturnValue | execa.ExecaChildProcess { const isRelative = !path.isAbsolute(dir); diff --git a/e2e/test-results-processor/processor.mjs b/e2e/test-results-processor/processor.mjs new file mode 100644 index 000000000000..be9679b3353d --- /dev/null +++ b/e2e/test-results-processor/processor.mjs @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export default function (results) { + results.processed = true; + return results; +} diff --git a/lerna.json b/lerna.json index fe4d1c5e92f8..094f954b840e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "27.3.1", + "version": "27.4.0", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index 23e6c9ab3716..fcba0589ef2b 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -1,7 +1,7 @@ { "name": "babel-jest", "description": "Jest plugin to use babel for transformation.", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -11,22 +11,25 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "devDependencies": { "@babel/core": "^7.1.0", - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/graceful-fs": "^4.1.3" }, "peerDependencies": { diff --git a/packages/babel-plugin-jest-hoist/package.json b/packages/babel-plugin-jest-hoist/package.json index 1b227eddb44f..3f0fbdcee042 100644 --- a/packages/babel-plugin-jest-hoist/package.json +++ b/packages/babel-plugin-jest-hoist/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-jest-hoist", - "version": "27.2.0", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -13,7 +13,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { diff --git a/packages/babel-preset-jest/package.json b/packages/babel-preset-jest/package.json index fadb5791e2a0..2377e9ba8aac 100644 --- a/packages/babel-preset-jest/package.json +++ b/packages/babel-preset-jest/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-jest", - "version": "27.2.0", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -13,7 +13,7 @@ "./package.json": "./package.json" }, "dependencies": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" }, "peerDependencies": { diff --git a/packages/diff-sequences/package.json b/packages/diff-sequences/package.json index 8f8743346883..0eb655364124 100644 --- a/packages/diff-sequences/package.json +++ b/packages/diff-sequences/package.json @@ -1,6 +1,6 @@ { "name": "diff-sequences", - "version": "27.0.6", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -21,7 +21,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "scripts": { diff --git a/packages/expect/package.json b/packages/expect/package.json index 606606abea91..0a5a10f6404f 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -1,6 +1,6 @@ { "name": "expect", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,21 +10,24 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json", "./build/utils": "./build/utils.js", "./build/matchers": "./build/matchers.js" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6" + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-regex-util": "^27.4.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "chalk": "^4.0.0", "fast-check": "^2.0.0", "immutable": "^4.0.0-rc.12" diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index a66503240bab..16f85cccd725 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -3334,6 +3334,15 @@ Expected value: 1 Received value: {"c": {"d": 1}} `; +exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {}}}}).toHaveProperty('.a.b.c') 1`] = ` +expect(received).toHaveProperty(path) + +Expected path: ".a.b.c" +Received path: [] + +Received value: {"a": {"b": {"c": {}}}} +`; + exports[`.toHaveProperty() {pass: false} expect({"a": {"b": {"c": {}}}}).toHaveProperty('a.b.c.d') 1`] = ` expect(received).toHaveProperty(path) @@ -3551,6 +3560,30 @@ Expected path: "memo" Expected value: not [] `; +exports[`.toHaveProperty() {pass: true} expect({"a": {"b": [[{"c": [{"d": 1}]}]]}}).toHaveProperty('a.b[0][0].c[0].d', 1) 1`] = ` +expect(received).not.toHaveProperty(path, value) + +Expected path: "a.b[0][0].c[0].d" + +Expected value: not 1 +`; + +exports[`.toHaveProperty() {pass: true} expect({"a": {"b": [{"c": [{"d": 1}]}]}}).toHaveProperty('a.b[0].c[0].d', 1) 1`] = ` +expect(received).not.toHaveProperty(path, value) + +Expected path: "a.b[0].c[0].d" + +Expected value: not 1 +`; + +exports[`.toHaveProperty() {pass: true} expect({"a": {"b": [{"c": {"d": [{"e": 1}, {"f": 2}]}}]}}).toHaveProperty('a.b[0].c.d[1].f', 2) 1`] = ` +expect(received).not.toHaveProperty(path, value) + +Expected path: "a.b[0].c.d[1].f" + +Expected value: not 2 +`; + exports[`.toHaveProperty() {pass: true} expect({"a": {"b": [1, 2, 3]}}).toHaveProperty('a,b,1') 1`] = ` expect(received).not.toHaveProperty(path) diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 6599df72b2b2..20b48ca6053a 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -1885,6 +1885,9 @@ describe('.toHaveProperty()', () => { [{a: {b: undefined}}, 'a.b', undefined], [{a: {}}, 'a.b', undefined], // delete for breaking change in future major [{a: {b: {c: 5}}}, 'a.b', {c: 5}], + [{a: {b: [{c: [{d: 1}]}]}}, 'a.b[0].c[0].d', 1], + [{a: {b: [{c: {d: [{e: 1}, {f: 2}]}}]}}, 'a.b[0].c.d[1].f', 2], + [{a: {b: [[{c: [{d: 1}]}]]}}, 'a.b[0][0].c[0].d', 1], [Object.assign(Object.create(null), {property: 1}), 'property', 1], [new Foo(), 'a', undefined], [new Foo(), 'b', 'b'], @@ -1955,6 +1958,7 @@ describe('.toHaveProperty()', () => { [ [{a: {b: {c: {}}}}, 'a.b.c.d'], + [{a: {b: {c: {}}}}, '.a.b.c'], [{a: 1}, 'a.b.c.d'], [{}, 'a'], [1, 'a.b.c'], diff --git a/packages/expect/src/asymmetricMatchers.ts b/packages/expect/src/asymmetricMatchers.ts index 02b19c363956..01f56a48df65 100644 --- a/packages/expect/src/asymmetricMatchers.ts +++ b/packages/expect/src/asymmetricMatchers.ts @@ -138,7 +138,7 @@ class Anything extends AsymmetricMatcher { } class ArrayContaining extends AsymmetricMatcher> { - constructor(sample: Array, inverse: boolean = false) { + constructor(sample: Array, inverse = false) { super(sample, inverse); } @@ -171,7 +171,7 @@ class ArrayContaining extends AsymmetricMatcher> { } class ObjectContaining extends AsymmetricMatcher> { - constructor(sample: Record, inverse: boolean = false) { + constructor(sample: Record, inverse = false) { super(sample, inverse); } @@ -209,7 +209,7 @@ class ObjectContaining extends AsymmetricMatcher> { } class StringContaining extends AsymmetricMatcher { - constructor(sample: string, inverse: boolean = false) { + constructor(sample: string, inverse = false) { if (!isA('String', sample)) { throw new Error('Expected is not a string'); } @@ -232,7 +232,7 @@ class StringContaining extends AsymmetricMatcher { } class StringMatching extends AsymmetricMatcher { - constructor(sample: string | RegExp, inverse: boolean = false) { + constructor(sample: string | RegExp, inverse = false) { if (!isA('String', sample) && !isA('RegExp', sample)) { throw new Error('Expected is not a String or a RegExp'); } diff --git a/packages/expect/src/index.ts b/packages/expect/src/index.ts index 648074fdba90..75ab9ba9d18d 100644 --- a/packages/expect/src/index.ts +++ b/packages/expect/src/index.ts @@ -431,7 +431,7 @@ const expectExport = expect as Expect; declare namespace expectExport { export type MatcherState = JestMatcherState; - export interface Matchers extends MatcherInterface {} + export interface Matchers extends MatcherInterface {} } export = expectExport; diff --git a/packages/expect/src/jestMatchersObject.ts b/packages/expect/src/jestMatchersObject.ts index cbfe6344a6db..544530bbe398 100644 --- a/packages/expect/src/jestMatchersObject.ts +++ b/packages/expect/src/jestMatchersObject.ts @@ -68,10 +68,7 @@ export const setMatchers = ( [unknown, ...Array], State > { - constructor( - inverse: boolean = false, - ...sample: [unknown, ...Array] - ) { + constructor(inverse = false, ...sample: [unknown, ...Array]) { super(sample, inverse); } diff --git a/packages/expect/src/matchers.ts b/packages/expect/src/matchers.ts index f7f019129d51..02e4c59813d0 100644 --- a/packages/expect/src/matchers.ts +++ b/packages/expect/src/matchers.ts @@ -44,6 +44,7 @@ import { getObjectSubset, getPath, iterableEquality, + pathAsArray, sparseArrayEquality, subsetEquality, typeEquality, @@ -126,7 +127,7 @@ const matchers: MatchersObject = { return {actual: received, expected, message, name: matcherName, pass}; }, - toBeCloseTo(received: number, expected: number, precision: number = 2) { + toBeCloseTo(received: number, expected: number, precision = 2) { const matcherName = 'toBeCloseTo'; const secondArgument = arguments.length === 3 ? 'precision' : undefined; const isNot = this.isNot; @@ -704,7 +705,7 @@ const matchers: MatchersObject = { const expectedPathLength = typeof expectedPath === 'string' - ? expectedPath.split('.').length + ? pathAsArray(expectedPath).length : expectedPath.length; if (expectedPathType === 'array' && expectedPathLength === 0) { diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index eab02cd36204..725289ebb3a4 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -45,7 +45,7 @@ export const getPath = ( propertyPath: string | Array, ): GetPath => { if (!Array.isArray(propertyPath)) { - propertyPath = (propertyPath as string).split('.'); + propertyPath = pathAsArray(propertyPath); } if (propertyPath.length) { @@ -372,6 +372,24 @@ export const partition = ( return result; }; +export const pathAsArray = (propertyPath: string): Array => { + // will match everything that's not a dot or a bracket, and "" for consecutive dots. + const pattern = RegExp('[^.[\\]]+|(?=(?:\\.)(?:\\.|$))', 'g'); + const properties: Array = []; + + // Because the regex won't match a dot in the beginning of the path, if present. + if (propertyPath[0] === '.') { + properties.push(''); + } + + propertyPath.replace(pattern, match => { + properties.push(match); + return match; + }); + + return properties; +}; + // Copied from https://github.com/graingert/angular.js/blob/a43574052e9775cbc1d7dd8a086752c979b0f020/src/Angular.js#L685-L693 export const isError = (value: unknown): value is Error => { switch (Object.prototype.toString.call(value)) { diff --git a/packages/jest-changed-files/package.json b/packages/jest-changed-files/package.json index a026b1c1f51e..5b35e00c3083 100644 --- a/packages/jest-changed-files/package.json +++ b/packages/jest-changed-files/package.json @@ -1,6 +1,6 @@ { "name": "jest-changed-files", - "version": "27.3.0", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,11 +10,14 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "execa": "^5.0.0", "throat": "^6.0.1" }, diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index 4d08abe5f428..8ad9b7683153 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -1,6 +1,6 @@ { "name": "jest-circus", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,27 +10,30 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json", "./runner": "./runner.js" }, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.3.1", + "expect": "^27.4.0", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.0", + "jest-matcher-utils": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-runtime": "^27.4.0", + "jest-snapshot": "^27.4.0", + "jest-util": "^27.4.0", + "pretty-format": "^27.4.0", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -38,7 +41,7 @@ "devDependencies": { "@babel/core": "^7.1.0", "@babel/register": "^7.0.0", - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/co": "^4.6.0", "@types/dedent": "^0.7.0", "@types/graceful-fs": "^4.1.3", diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index d7487477e31d..43bf59f1af4e 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -93,6 +93,9 @@ export const initialize = async ({ // that will result in this test to be skipped, so we'll be executing the promise function anyway, // even if it ends up being skipped. const promise = mutex(() => testFn()); + // Avoid triggering the uncaught promise rejection handler in case the test errors before + // being awaited on. + promise.catch(() => {}); globalsObject.test(testName, () => promise, timeout); }; diff --git a/packages/jest-circus/src/types.ts b/packages/jest-circus/src/types.ts index d381cfec56e1..98f36bf05af5 100644 --- a/packages/jest-circus/src/types.ts +++ b/packages/jest-circus/src/types.ts @@ -21,7 +21,7 @@ export const TEST_TIMEOUT_SYMBOL = Symbol.for( ) as unknown as 'TEST_TIMEOUT_SYMBOL'; declare global { - module NodeJS { + namespace NodeJS { interface Global { STATE_SYM_SYMBOL: Circus.State; RETRY_TIMES_SYMBOL: string; diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index d96fef5807d6..6d8203ebf682 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -1,30 +1,33 @@ { "name": "jest-cli", "description": "Delightful JavaScript Testing.", - "version": "27.3.1", + "version": "27.4.0", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json", "./bin/jest": "./bin/jest.js" }, "dependencies": { - "@jest/core": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/core": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/types": "^27.4.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-config": "^27.4.0", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", "prompts": "^2.0.1", "yargs": "^16.2.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/exit": "^0.1.30", "@types/graceful-fs": "^4.1.3", "@types/prompts": "^2.0.1", diff --git a/packages/jest-cli/src/cli/args.ts b/packages/jest-cli/src/cli/args.ts index 85f78feedfa6..eb5dabb2b170 100644 --- a/packages/jest-cli/src/cli/args.ts +++ b/packages/jest-cli/src/cli/args.ts @@ -148,8 +148,8 @@ export const options = { }, clearMocks: { description: - 'Automatically clear mock calls and instances between every ' + - 'test. Equivalent to calling jest.clearAllMocks() between each test.', + 'Automatically clear mock calls, instances and results before every test. ' + + 'Equivalent to calling jest.clearAllMocks() before each test.', type: 'boolean', }, collectCoverage: { @@ -440,8 +440,8 @@ export const options = { }, resetMocks: { description: - 'Automatically reset mock state between every test. ' + - 'Equivalent to calling jest.resetAllMocks() between each test.', + 'Automatically reset mock state before every test. ' + + 'Equivalent to calling jest.resetAllMocks() before each test.', type: 'boolean', }, resetModules: { @@ -456,8 +456,8 @@ export const options = { }, restoreMocks: { description: - 'Automatically restore mock state and implementation between every test. ' + - 'Equivalent to calling jest.restoreAllMocks() between each test.', + 'Automatically restore mock state and implementation before every test. ' + + 'Equivalent to calling jest.restoreAllMocks() before each test.', type: 'boolean', }, rootDir: { diff --git a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap index 7db61a7b69cf..05fb989e8bc1 100644 --- a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap @@ -108,7 +108,7 @@ Array [ }, Object { "initial": false, - "message": "Automatically clear mock calls and instances between every test?", + "message": "Automatically clear mock calls, instances and results before every test?", "name": "clearMocks", "type": "confirm", }, @@ -131,7 +131,7 @@ module.exports = { // The directory where Jest should store its cached dependency information // cacheDirectory: \\"/tmp/jest\\", - // Automatically clear mock calls and instances between every test + // Automatically clear mock calls, instances and results before every test // clearMocks: false, // Indicates whether the coverage information should be collected while executing the test @@ -219,7 +219,7 @@ module.exports = { // Use this configuration option to add custom reporters to Jest // reporters: undefined, - // Automatically reset mock state between every test + // Automatically reset mock state before every test // resetMocks: false, // Reset the module registry before running each individual test @@ -228,7 +228,7 @@ module.exports = { // A path to a custom resolver // resolver: undefined, - // Automatically restore mock state between every test + // Automatically restore mock state and implementation before every test // restoreMocks: false, // The root directory that Jest should scan for tests and modules within diff --git a/packages/jest-cli/src/init/generateConfigFile.ts b/packages/jest-cli/src/init/generateConfigFile.ts index 4e70ad309382..e629b085644c 100644 --- a/packages/jest-cli/src/init/generateConfigFile.ts +++ b/packages/jest-cli/src/init/generateConfigFile.ts @@ -11,7 +11,7 @@ import {defaults, descriptions} from 'jest-config'; const stringifyOption = ( option: keyof Config.InitialOptions, map: Partial, - linePrefix: string = '', + linePrefix = '', ): string => { const optionDescription = ` // ${descriptions[option]}`; const stringifiedObject = `${option}: ${JSON.stringify( diff --git a/packages/jest-cli/src/init/index.ts b/packages/jest-cli/src/init/index.ts index b063fcb66b91..700be87b8728 100644 --- a/packages/jest-cli/src/init/index.ts +++ b/packages/jest-cli/src/init/index.ts @@ -48,7 +48,7 @@ export default async ( } const questions = defaultQuestions.slice(0); - let hasJestProperty: boolean = false; + let hasJestProperty = false; let projectPackageJson: ProjectPackageJson; try { @@ -99,7 +99,7 @@ export default async ( ), ); - let promptAborted: boolean = false; + let promptAborted = false; // @ts-expect-error: Return type cannot be object - faulty typings const results: PromptsResults = await prompts(questions, { diff --git a/packages/jest-cli/src/init/questions.ts b/packages/jest-cli/src/init/questions.ts index 235411dc441a..fd4e9325ff7f 100644 --- a/packages/jest-cli/src/init/questions.ts +++ b/packages/jest-cli/src/init/questions.ts @@ -42,7 +42,8 @@ const defaultQuestions: Array = [ }, { initial: false, - message: 'Automatically clear mock calls and instances between every test?', + message: + 'Automatically clear mock calls, instances and results before every test?', name: 'clearMocks', type: 'confirm', }, diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index fed06d4f0b5f..f1bae672ee18 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -1,6 +1,6 @@ { "name": "jest-config", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "peerDependencies": { @@ -23,26 +26,27 @@ }, "dependencies": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.1", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.1", + "@jest/test-sequencer": "^27.4.0", + "@jest/types": "^27.4.0", + "babel-jest": "^27.4.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.3.1", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-jasmine2": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-circus": "^27.4.0", + "jest-environment-jsdom": "^27.4.0", + "jest-environment-node": "^27.4.0", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.0", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-runner": "^27.4.0", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.0", + "slash": "^3.0.0" }, "devDependencies": { "@types/babel__core": "^7.0.4", diff --git a/packages/jest-config/src/Descriptions.ts b/packages/jest-config/src/Descriptions.ts index 07d170eb9c44..686146c4ced3 100644 --- a/packages/jest-config/src/Descriptions.ts +++ b/packages/jest-config/src/Descriptions.ts @@ -12,7 +12,8 @@ const descriptions: {[key in keyof Config.InitialOptions]: string} = { bail: 'Stop running tests after `n` failures', cacheDirectory: 'The directory where Jest should store its cached dependency information', - clearMocks: 'Automatically clear mock calls and instances between every test', + clearMocks: + 'Automatically clear mock calls, instances and results before every test', collectCoverage: 'Indicates whether the coverage information should be collected while executing the test', collectCoverageFrom: @@ -53,10 +54,11 @@ const descriptions: {[key in keyof Config.InitialOptions]: string} = { preset: "A preset that is used as a base for Jest's configuration", projects: 'Run tests from one or more projects', reporters: 'Use this configuration option to add custom reporters to Jest', - resetMocks: 'Automatically reset mock state between every test', + resetMocks: 'Automatically reset mock state before every test', resetModules: 'Reset the module registry before running each individual test', resolver: 'A path to a custom resolver', - restoreMocks: 'Automatically restore mock state between every test', + restoreMocks: + 'Automatically restore mock state and implementation before every test', rootDir: 'The root directory that Jest should scan for tests and modules within', roots: diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index f9b4c8456218..e22cd5dfb754 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -43,7 +43,7 @@ export async function readConfig( // read individual configs for every project. skipArgvConfigOption?: boolean, parentConfigDirname?: Config.Path | null, - projectIndex: number = Infinity, + projectIndex = Infinity, skipMultipleConfigWarning = false, ): Promise { let rawOptions: Config.InitialOptions; diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index a8916f55fd3f..a50715620f29 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -551,7 +551,7 @@ export default async function normalize( initialOptions: Config.InitialOptions, argv: Config.Argv, configPath?: Config.Path | null, - projectIndex: number = Infinity, + projectIndex = Infinity, ): Promise<{ hasDeprecationWarnings: boolean; options: AllOptions; diff --git a/packages/jest-config/src/utils.ts b/packages/jest-config/src/utils.ts index 869e60897d7e..9958f6b6bcaf 100644 --- a/packages/jest-config/src/utils.ts +++ b/packages/jest-config/src/utils.ts @@ -65,7 +65,7 @@ export const replaceRootDirInPath = ( return path.resolve( rootDir, - path.normalize('./' + filePath.substr(''.length)), + path.normalize('./' + filePath.substring(''.length)), ); }; diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index e1a8ce5601c7..10818bcbf54b 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@jest/console", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,19 +10,22 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.3.1", - "jest-util": "^27.3.1", + "jest-message-util": "^27.4.0", + "jest-util": "^27.4.0", "slash": "^3.0.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/node": "*" }, "engines": { diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index 5399799e9ec9..ba69bc039f77 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -1,46 +1,49 @@ { "name": "@jest/core", "description": "Delightful JavaScript Testing.", - "version": "27.3.1", + "version": "27.4.0", "main": "./build/jest.js", "types": "./build/jest.d.ts", "exports": { - ".": "./build/jest.js", + ".": { + "types": "./build/jest.d.ts", + "default": "./build/jest.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/reporters": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/reporters": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-resolve-dependencies": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "jest-watcher": "^27.3.1", + "jest-changed-files": "^27.4.0", + "jest-config": "^27.4.0", + "jest-haste-map": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-resolve-dependencies": "^27.4.0", + "jest-runner": "^27.4.0", + "jest-runtime": "^27.4.0", + "jest-snapshot": "^27.4.0", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", + "jest-watcher": "^27.4.0", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "devDependencies": { - "@jest/test-sequencer": "^27.3.1", - "@jest/test-utils": "^27.3.1", + "@jest/test-sequencer": "^27.4.0", + "@jest/test-utils": "^27.4.0", "@types/exit": "^0.1.30", "@types/graceful-fs": "^4.1.2", "@types/micromatch": "^4.0.1", diff --git a/packages/jest-core/src/__tests__/collectHandles.test.js b/packages/jest-core/src/__tests__/collectHandles.test.js index e35201822189..b0628157af00 100644 --- a/packages/jest-core/src/__tests__/collectHandles.test.js +++ b/packages/jest-core/src/__tests__/collectHandles.test.js @@ -9,6 +9,7 @@ import {promises as dns} from 'dns'; import http from 'http'; import {PerformanceObserver} from 'perf_hooks'; +import zlib from 'zlib'; import collectHandles from '../collectHandles'; describe('collectHandles', () => { @@ -52,6 +53,20 @@ describe('collectHandles', () => { ); }); + it('should not collect the ZLIB open handle', async () => { + const handleCollector = collectHandles(); + + const decompressed = zlib.inflateRawSync( + Buffer.from('cb2a2d2e5128492d2ec9cc4b0700', 'hex'), + ); + + const openHandles = await handleCollector(); + + expect(openHandles).not.toContainEqual( + expect.objectContaining({message: 'ZLIB'}), + ); + }); + it('should collect handles opened in test functions with `done` callbacks', done => { const handleCollector = collectHandles(); const server = http.createServer((_, response) => response.end('ok')); diff --git a/packages/jest-core/src/collectHandles.ts b/packages/jest-core/src/collectHandles.ts index 6212625a8914..72fea6ee6b94 100644 --- a/packages/jest-core/src/collectHandles.ts +++ b/packages/jest-core/src/collectHandles.ts @@ -71,7 +71,8 @@ export default function collectHandles(): HandleCollectionResult { type === 'ELDHISTOGRAM' || type === 'PerformanceObserver' || type === 'RANDOMBYTESREQUEST' || - type === 'DNSCHANNEL' + type === 'DNSCHANNEL' || + type === 'ZLIB' ) { return; } diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index 636c28993385..b407687fa89d 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -13,6 +13,7 @@ import {CustomConsole} from '@jest/console'; import { AggregatedResult, Test, + TestResultsProcessor, formatTestResults, makeEmptyAggregatedTestResult, } from '@jest/test-result'; @@ -96,7 +97,10 @@ const processResults = async ( } if (testResultsProcessor) { - runResults = require(testResultsProcessor)(runResults); + const processor = await requireOrImportModule( + testResultsProcessor, + ); + runResults = processor(runResults); } if (isJSON) { if (outputFile) { diff --git a/packages/jest-create-cache-key-function/package.json b/packages/jest-create-cache-key-function/package.json index d80a2a942c23..655d095b8e24 100644 --- a/packages/jest-create-cache-key-function/package.json +++ b/packages/jest-create-cache-key-function/package.json @@ -1,17 +1,17 @@ { "name": "@jest/create-cache-key-function", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", "directory": "packages/jest-create-cache-key-function" }, "dependencies": { - "@jest/types": "^27.2.5" + "@jest/types": "^27.4.0" }, "devDependencies": { "@types/node": "*", - "jest-util": "^27.3.1" + "jest-util": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -20,7 +20,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "publishConfig": { diff --git a/packages/jest-diff/README.md b/packages/jest-diff/README.md index e01116fd68cb..d52f821789a3 100644 --- a/packages/jest-diff/README.md +++ b/packages/jest-diff/README.md @@ -394,6 +394,7 @@ For other applications, you can provide an options object as a third argument: | `commonColor` | `chalk.dim` | | `commonIndicator` | `' '` | | `commonLineTrailingSpaceColor` | `string => string` | +| `compareKeys` | `undefined` | | `contextLines` | `5` | | `emptyFirstOrLastLinePlaceholder` | `''` | | `expand` | `true` | @@ -612,3 +613,59 @@ If a content line is empty, then the corresponding comparison line is automatica | `aIndicator` | `'-·'` | `'-'` | | `bIndicator` | `'+·'` | `'+'` | | `commonIndicator` | `' ·'` | `''` | + +### Example of option for sorting object keys + +When two objects are compared their keys are printed in alphabetical order by default. If this was not the original order of the keys the diff becomes harder to read as the keys are not in their original position. + +Use `compareKeys` to pass a function which will be used when sorting the object keys. + +```js +const a = {c: 'c', b: 'b1', a: 'a'}; +const b = {c: 'c', b: 'b2', a: 'a'}; + +const options = { + // The keys will be in their original order + compareKeys: () => 0, +}; + +const difference = diff(a, b, options); +``` + +```diff +- Expected ++ Received + + Object { + "c": "c", +- "b": "b1", ++ "b": "b2", + "a": "a", + } +``` + +Depending on the implementation of `compareKeys` any sort order can be used. + +```js +const a = {c: 'c', b: 'b1', a: 'a'}; +const b = {c: 'c', b: 'b2', a: 'a'}; + +const options = { + // The keys will be in reverse order + compareKeys: (a, b) => (a > b ? -1 : 1), +}; + +const difference = diff(a, b, options); +``` + +```diff +- Expected ++ Received + + Object { + "a": "a", +- "b": "b1", ++ "b": "b2", + "c": "c", + } +``` diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 3ca49e7bf9d7..69a887bd899a 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -1,6 +1,6 @@ { "name": "jest-diff", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,17 +10,20 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "strip-ansi": "^6.0.0" }, "engines": { diff --git a/packages/jest-diff/src/__tests__/diff.test.ts b/packages/jest-diff/src/__tests__/diff.test.ts index 08be4d94e2c7..3d111e4720a6 100644 --- a/packages/jest-diff/src/__tests__/diff.test.ts +++ b/packages/jest-diff/src/__tests__/diff.test.ts @@ -1120,4 +1120,43 @@ describe('options', () => { expect(diffStringsUnified(aEmpty, bEmpty, options)).toBe(expected); }); }); + + describe('compare keys', () => { + const a = {a: {d: 1, e: 1, f: 1}, b: 1, c: 1}; + const b = {a: {d: 1, e: 2, f: 1}, b: 1, c: 1}; + + test('keeps the object keys in their original order', () => { + const compareKeys = () => 0; + const expected = [ + ' Object {', + ' "a": Object {', + ' "d": 1,', + '- "e": 1,', + '+ "e": 2,', + ' "f": 1,', + ' },', + ' "b": 1,', + ' "c": 1,', + ' }', + ].join('\n'); + expect(diff(a, b, {...optionsBe, compareKeys})).toBe(expected); + }); + + test('sorts the object keys in reverse order', () => { + const compareKeys = (a: string, b: string) => (a > b ? -1 : 1); + const expected = [ + ' Object {', + ' "c": 1,', + ' "b": 1,', + ' "a": Object {', + ' "f": 1,', + '- "e": 1,', + '+ "e": 2,', + ' "d": 1,', + ' },', + ' }', + ].join('\n'); + expect(diff(a, b, {...optionsBe, compareKeys})).toBe(expected); + }); + }); }); diff --git a/packages/jest-diff/src/diffLines.ts b/packages/jest-diff/src/diffLines.ts index 89e71f866b49..6997250adcdd 100644 --- a/packages/jest-diff/src/diffLines.ts +++ b/packages/jest-diff/src/diffLines.ts @@ -7,13 +7,97 @@ import diff from 'diff-sequences'; import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; +import { + joinAlignedDiffsExpand, + joinAlignedDiffsNoExpand, +} from './joinAlignedDiffs'; import {normalizeDiffOptions} from './normalizeDiffOptions'; -import {printDiffLines} from './printDiffs'; -import type {DiffOptions} from './types'; +import type {DiffOptions, DiffOptionsNormalized} from './types'; const isEmptyString = (lines: Array) => lines.length === 1 && lines[0].length === 0; +type ChangeCounts = { + a: number; + b: number; +}; + +const countChanges = (diffs: Array): ChangeCounts => { + let a = 0; + let b = 0; + + diffs.forEach(diff => { + switch (diff[0]) { + case DIFF_DELETE: + a += 1; + break; + + case DIFF_INSERT: + b += 1; + break; + } + }); + + return {a, b}; +}; + +const printAnnotation = ( + { + aAnnotation, + aColor, + aIndicator, + bAnnotation, + bColor, + bIndicator, + includeChangeCounts, + omitAnnotationLines, + }: DiffOptionsNormalized, + changeCounts: ChangeCounts, +): string => { + if (omitAnnotationLines) { + return ''; + } + + let aRest = ''; + let bRest = ''; + + if (includeChangeCounts) { + const aCount = String(changeCounts.a); + const bCount = String(changeCounts.b); + + // Padding right aligns the ends of the annotations. + const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; + const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff)); + const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); + + // Padding left aligns the ends of the counts. + const baCountLengthDiff = bCount.length - aCount.length; + const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff)); + const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff)); + + aRest = + aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount; + bRest = + bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount; + } + + return ( + aColor(aIndicator + ' ' + aAnnotation + aRest) + + '\n' + + bColor(bIndicator + ' ' + bAnnotation + bRest) + + '\n\n' + ); +}; + +export const printDiffLines = ( + diffs: Array, + options: DiffOptionsNormalized, +): string => + printAnnotation(options, countChanges(diffs)) + + (options.expand + ? joinAlignedDiffsExpand(diffs, options) + : joinAlignedDiffsNoExpand(diffs, options)); + // Compare two arrays of strings line-by-line. Format as comparison lines. export const diffLinesUnified = ( aLines: Array, diff --git a/packages/jest-diff/src/index.ts b/packages/jest-diff/src/index.ts index 719760f9003c..399b5cc5776c 100644 --- a/packages/jest-diff/src/index.ts +++ b/packages/jest-diff/src/index.ts @@ -11,6 +11,7 @@ import { format as prettyFormat, plugins as prettyFormatPlugins, } from 'pretty-format'; +import type {PrettyFormatOptions} from 'pretty-format'; import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; import {NO_DIFF_MESSAGE, SIMILAR_MESSAGE} from './constants'; import {diffLinesRaw, diffLinesUnified, diffLinesUnified2} from './diffLines'; @@ -49,13 +50,11 @@ const PLUGINS = [ const FORMAT_OPTIONS = { plugins: PLUGINS, }; -const FORMAT_OPTIONS_0 = {...FORMAT_OPTIONS, indent: 0}; const FALLBACK_FORMAT_OPTIONS = { callToJSON: false, maxDepth: 10, plugins: PLUGINS, }; -const FALLBACK_FORMAT_OPTIONS_0 = {...FALLBACK_FORMAT_OPTIONS, indent: 0}; // Generate a string that will highlight the difference between two values // with green and red. (similar to how github does code diffing) @@ -137,50 +136,20 @@ function compareObjects( ) { let difference; let hasThrown = false; - const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options); try { - const aCompare = prettyFormat(a, FORMAT_OPTIONS_0); - const bCompare = prettyFormat(b, FORMAT_OPTIONS_0); - - if (aCompare === bCompare) { - difference = noDiffMessage; - } else { - const aDisplay = prettyFormat(a, FORMAT_OPTIONS); - const bDisplay = prettyFormat(b, FORMAT_OPTIONS); - - difference = diffLinesUnified2( - aDisplay.split('\n'), - bDisplay.split('\n'), - aCompare.split('\n'), - bCompare.split('\n'), - options, - ); - } + const formatOptions = getFormatOptions(FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); } catch { hasThrown = true; } + const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options); // If the comparison yields no results, compare again but this time // without calling `toJSON`. It's also possible that toJSON might throw. if (difference === undefined || difference === noDiffMessage) { - const aCompare = prettyFormat(a, FALLBACK_FORMAT_OPTIONS_0); - const bCompare = prettyFormat(b, FALLBACK_FORMAT_OPTIONS_0); - - if (aCompare === bCompare) { - difference = noDiffMessage; - } else { - const aDisplay = prettyFormat(a, FALLBACK_FORMAT_OPTIONS); - const bDisplay = prettyFormat(b, FALLBACK_FORMAT_OPTIONS); - - difference = diffLinesUnified2( - aDisplay.split('\n'), - bDisplay.split('\n'), - aCompare.split('\n'), - bCompare.split('\n'), - options, - ); - } + const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options); + difference = getObjectsDifference(a, b, formatOptions, options); if (difference !== noDiffMessage && !hasThrown) { difference = @@ -190,3 +159,41 @@ function compareObjects( return difference; } + +function getFormatOptions( + formatOptions: PrettyFormatOptions, + options?: DiffOptions, +): PrettyFormatOptions { + const {compareKeys} = normalizeDiffOptions(options); + + return { + ...formatOptions, + compareKeys, + }; +} + +function getObjectsDifference( + a: Record, + b: Record, + formatOptions: PrettyFormatOptions, + options?: DiffOptions, +): string { + const formatOptionsZeroIndent = {...formatOptions, indent: 0}; + const aCompare = prettyFormat(a, formatOptionsZeroIndent); + const bCompare = prettyFormat(b, formatOptionsZeroIndent); + + if (aCompare === bCompare) { + return getCommonMessage(NO_DIFF_MESSAGE, options); + } else { + const aDisplay = prettyFormat(a, formatOptions); + const bDisplay = prettyFormat(b, formatOptions); + + return diffLinesUnified2( + aDisplay.split('\n'), + bDisplay.split('\n'), + aCompare.split('\n'), + bCompare.split('\n'), + options, + ); + } +} diff --git a/packages/jest-diff/src/joinAlignedDiffs.ts b/packages/jest-diff/src/joinAlignedDiffs.ts index 3b3a079eaa6a..4124853fcf93 100644 --- a/packages/jest-diff/src/joinAlignedDiffs.ts +++ b/packages/jest-diff/src/joinAlignedDiffs.ts @@ -6,13 +6,99 @@ */ import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; -import { - createPatchMark, - printCommonLine, - printDeleteLine, - printInsertLine, -} from './printDiffs'; -import type {DiffOptionsNormalized} from './types'; +import type {DiffOptionsColor, DiffOptionsNormalized} from './types'; + +const formatTrailingSpaces = ( + line: string, + trailingSpaceFormatter: DiffOptionsColor, +): string => line.replace(/\s+$/, match => trailingSpaceFormatter(match)); + +const printDiffLine = ( + line: string, + isFirstOrLast: boolean, + color: DiffOptionsColor, + indicator: string, + trailingSpaceFormatter: DiffOptionsColor, + emptyFirstOrLastLinePlaceholder: string, +): string => + line.length !== 0 + ? color( + indicator + ' ' + formatTrailingSpaces(line, trailingSpaceFormatter), + ) + : indicator !== ' ' + ? color(indicator) + : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 + ? color(indicator + ' ' + emptyFirstOrLastLinePlaceholder) + : ''; + +const printDeleteLine = ( + line: string, + isFirstOrLast: boolean, + { + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +const printInsertLine = ( + line: string, + isFirstOrLast: boolean, + { + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +const printCommonLine = ( + line: string, + isFirstOrLast: boolean, + { + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +// In GNU diff format, indexes are one-based instead of zero-based. +const createPatchMark = ( + aStart: number, + aEnd: number, + bStart: number, + bEnd: number, + {patchColor}: DiffOptionsNormalized, +): string => + patchColor( + `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`, + ); // jest --no-expand // diff --git a/packages/jest-diff/src/normalizeDiffOptions.ts b/packages/jest-diff/src/normalizeDiffOptions.ts index 0f4aedc8ceaf..5e7cb9336e1a 100644 --- a/packages/jest-diff/src/normalizeDiffOptions.ts +++ b/packages/jest-diff/src/normalizeDiffOptions.ts @@ -6,6 +6,7 @@ */ import chalk = require('chalk'); +import type {CompareKeys} from 'pretty-format'; import type {DiffOptions, DiffOptionsNormalized} from './types'; export const noColor = (string: string): string => string; @@ -24,6 +25,7 @@ const OPTIONS_DEFAULT: DiffOptionsNormalized = { commonColor: chalk.dim, commonIndicator: ' ', commonLineTrailingSpaceColor: noColor, + compareKeys: undefined, contextLines: DIFF_CONTEXT_DEFAULT, emptyFirstOrLastLinePlaceholder: '', expand: true, @@ -32,6 +34,11 @@ const OPTIONS_DEFAULT: DiffOptionsNormalized = { patchColor: chalk.yellow, }; +const getCompareKeys = (compareKeys?: CompareKeys): CompareKeys => + compareKeys && typeof compareKeys === 'function' + ? compareKeys + : OPTIONS_DEFAULT.compareKeys; + const getContextLines = (contextLines?: number): number => typeof contextLines === 'number' && Number.isSafeInteger(contextLines) && @@ -45,5 +52,6 @@ export const normalizeDiffOptions = ( ): DiffOptionsNormalized => ({ ...OPTIONS_DEFAULT, ...options, + compareKeys: getCompareKeys(options.compareKeys), contextLines: getContextLines(options.contextLines), }); diff --git a/packages/jest-diff/src/printDiffs.ts b/packages/jest-diff/src/printDiffs.ts index 05f8619e2b93..cde7b881fc27 100644 --- a/packages/jest-diff/src/printDiffs.ts +++ b/packages/jest-diff/src/printDiffs.ts @@ -5,111 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import { - DIFF_DELETE, - DIFF_EQUAL, - DIFF_INSERT, - Diff, - cleanupSemantic, -} from './cleanupSemantic'; -import {diffLinesUnified} from './diffLines'; +import {DIFF_EQUAL, Diff, cleanupSemantic} from './cleanupSemantic'; +import {diffLinesUnified, printDiffLines} from './diffLines'; import diffStrings from './diffStrings'; import getAlignedDiffs from './getAlignedDiffs'; -import { - joinAlignedDiffsExpand, - joinAlignedDiffsNoExpand, -} from './joinAlignedDiffs'; import {normalizeDiffOptions} from './normalizeDiffOptions'; -import type { - DiffOptions, - DiffOptionsColor, - DiffOptionsNormalized, -} from './types'; +import type {DiffOptions} from './types'; -const formatTrailingSpaces = ( - line: string, - trailingSpaceFormatter: DiffOptionsColor, -): string => line.replace(/\s+$/, match => trailingSpaceFormatter(match)); - -const printDiffLine = ( - line: string, - isFirstOrLast: boolean, - color: DiffOptionsColor, - indicator: string, - trailingSpaceFormatter: DiffOptionsColor, - emptyFirstOrLastLinePlaceholder: string, -): string => - line.length !== 0 - ? color( - indicator + ' ' + formatTrailingSpaces(line, trailingSpaceFormatter), - ) - : indicator !== ' ' - ? color(indicator) - : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 - ? color(indicator + ' ' + emptyFirstOrLastLinePlaceholder) - : ''; - -export const printDeleteLine = ( - line: string, - isFirstOrLast: boolean, - { - aColor, - aIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - aColor, - aIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const printInsertLine = ( - line: string, - isFirstOrLast: boolean, - { - bColor, - bIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - bColor, - bIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const printCommonLine = ( - line: string, - isFirstOrLast: boolean, - { - commonColor, - commonIndicator, - commonLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - commonColor, - commonIndicator, - commonLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const hasCommonDiff = ( - diffs: Array, - isMultiline: boolean, -): boolean => { +const hasCommonDiff = (diffs: Array, isMultiline: boolean): boolean => { if (isMultiline) { // Important: Ignore common newline that was appended to multiline strings! const iLast = diffs.length - 1; @@ -121,99 +24,6 @@ export const hasCommonDiff = ( return diffs.some(diff => diff[0] === DIFF_EQUAL); }; -export type ChangeCounts = { - a: number; - b: number; -}; - -export const countChanges = (diffs: Array): ChangeCounts => { - let a = 0; - let b = 0; - - diffs.forEach(diff => { - switch (diff[0]) { - case DIFF_DELETE: - a += 1; - break; - - case DIFF_INSERT: - b += 1; - break; - } - }); - - return {a, b}; -}; - -export const printAnnotation = ( - { - aAnnotation, - aColor, - aIndicator, - bAnnotation, - bColor, - bIndicator, - includeChangeCounts, - omitAnnotationLines, - }: DiffOptionsNormalized, - changeCounts: ChangeCounts, -): string => { - if (omitAnnotationLines) { - return ''; - } - - let aRest = ''; - let bRest = ''; - - if (includeChangeCounts) { - const aCount = String(changeCounts.a); - const bCount = String(changeCounts.b); - - // Padding right aligns the ends of the annotations. - const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; - const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff)); - const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); - - // Padding left aligns the ends of the counts. - const baCountLengthDiff = bCount.length - aCount.length; - const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff)); - const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff)); - - aRest = - aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount; - bRest = - bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount; - } - - return ( - aColor(aIndicator + ' ' + aAnnotation + aRest) + - '\n' + - bColor(bIndicator + ' ' + bAnnotation + bRest) + - '\n\n' - ); -}; - -export const printDiffLines = ( - diffs: Array, - options: DiffOptionsNormalized, -): string => - printAnnotation(options, countChanges(diffs)) + - (options.expand - ? joinAlignedDiffsExpand(diffs, options) - : joinAlignedDiffsNoExpand(diffs, options)); - -// In GNU diff format, indexes are one-based instead of zero-based. -export const createPatchMark = ( - aStart: number, - aEnd: number, - bStart: number, - bEnd: number, - {patchColor}: DiffOptionsNormalized, -): string => - patchColor( - `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`, - ); - // Compare two strings character-by-character. // Format as comparison lines in which changed substrings have inverse colors. export const diffStringsUnified = ( diff --git a/packages/jest-diff/src/types.ts b/packages/jest-diff/src/types.ts index 58d72f55c5c4..da33eb3131b5 100644 --- a/packages/jest-diff/src/types.ts +++ b/packages/jest-diff/src/types.ts @@ -4,6 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ +import type {CompareKeys} from 'pretty-format'; export type DiffOptionsColor = (arg: string) => string; // subset of Chalk type @@ -25,6 +26,7 @@ export type DiffOptions = { includeChangeCounts?: boolean; omitAnnotationLines?: boolean; patchColor?: DiffOptionsColor; + compareKeys?: CompareKeys; }; export type DiffOptionsNormalized = { @@ -39,6 +41,7 @@ export type DiffOptionsNormalized = { commonColor: DiffOptionsColor; commonIndicator: string; commonLineTrailingSpaceColor: DiffOptionsColor; + compareKeys: CompareKeys; contextLines: number; emptyFirstOrLastLinePlaceholder: string; expand: boolean; diff --git a/packages/jest-docblock/package.json b/packages/jest-docblock/package.json index 86048d40e695..2d41bd6b981a 100644 --- a/packages/jest-docblock/package.json +++ b/packages/jest-docblock/package.json @@ -1,6 +1,6 @@ { "name": "jest-docblock", - "version": "27.0.6", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index 70ac8382486e..0190dfa3c916 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -1,11 +1,14 @@ { "name": "jest-each", - "version": "27.3.1", + "version": "27.4.0", "description": "Parameterised tests for Jest", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "repository": { @@ -22,11 +25,11 @@ "author": "Matt Phillips (mattphillips)", "license": "MIT", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.0", + "pretty-format": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-environment-jsdom/package.json b/packages/jest-environment-jsdom/package.json index 4fd14807fd3c..04ec94468b0a 100644 --- a/packages/jest-environment-jsdom/package.json +++ b/packages/jest-environment-jsdom/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-jsdom", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,21 +10,24 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.0", + "@jest/fake-timers": "^27.4.0", + "@jest/types": "^27.4.0", + "@types/jsdom": "^16.2.4", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1", + "jest-mock": "^27.4.0", + "jest-util": "^27.4.0", "jsdom": "^16.6.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", - "@types/jsdom": "^16.2.4" + "@jest/test-utils": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts b/packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts index 6253fa99eb77..f10d330a7168 100644 --- a/packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts +++ b/packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts @@ -39,4 +39,28 @@ describe('JSDomEnvironment', () => { expect(env.dom.window.navigator.userAgent).toEqual('foo'); }); + + /** + * When used in conjunction with Custom Elements (part of the WebComponents standard) + * setting the global.document to null too early is problematic because: + * + * CustomElement's disconnectedCallback method is called when a custom element + * is removed from the DOM. The disconnectedCallback could need the document + * in order to remove some listener for example. + * + * global.close calls jsdom's Window.js.close which does this._document.body.innerHTML = "". + * The custom element will be removed from the DOM at this point, therefore disconnectedCallback + * will be called, so please make sure the global.document is still available at this point. + */ + it('should not set the global.document to null too early', () => { + const env = new JSDomEnvironment(makeProjectConfig()); + + const originalCloseFn = env.global.close.bind(env.global); + env.global.close = () => { + originalCloseFn(); + expect(env.global.document).not.toBeNull(); + }; + + return env.teardown(); + }); }); diff --git a/packages/jest-environment-jsdom/src/index.ts b/packages/jest-environment-jsdom/src/index.ts index 8db58a76a36e..1aab227fdb71 100644 --- a/packages/jest-environment-jsdom/src/index.ts +++ b/packages/jest-environment-jsdom/src/index.ts @@ -132,9 +132,14 @@ class JSDOMEnvironment implements JestEnvironment { if (this.errorEventListener) { this.global.removeEventListener('error', this.errorEventListener); } + this.global.close(); + // Dispose "document" to prevent "load" event from triggering. + + // Note that this.global.close() will trigger the CustomElement::disconnectedCallback + // Do not reset the document before CustomElement disconnectedCallback function has finished running, + // document should be accessible within disconnectedCallback. Object.defineProperty(this.global, 'document', {value: null}); - this.global.close(); } this.errorEventListener = null; // @ts-expect-error diff --git a/packages/jest-environment-node/package.json b/packages/jest-environment-node/package.json index fbc0a6f918c6..da8020177327 100644 --- a/packages/jest-environment-node/package.json +++ b/packages/jest-environment-node/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-node", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,19 +10,22 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.0", + "@jest/fake-timers": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-mock": "^27.4.0", + "jest-util": "^27.4.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1" + "@jest/test-utils": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-environment/package.json b/packages/jest-environment/package.json index f630437cd43c..28b8a670b6a7 100644 --- a/packages/jest-environment/package.json +++ b/packages/jest-environment/package.json @@ -1,6 +1,6 @@ { "name": "@jest/environment", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,14 +10,17 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", - "jest-mock": "^27.3.0" + "jest-mock": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-fake-timers/package.json b/packages/jest-fake-timers/package.json index 0b1bf4a01364..3263c873c170 100644 --- a/packages/jest-fake-timers/package.json +++ b/packages/jest-fake-timers/package.json @@ -1,6 +1,6 @@ { "name": "@jest/fake-timers", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,16 +10,19 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-message-util": "^27.4.0", + "jest-mock": "^27.4.0", + "jest-util": "^27.4.0" }, "devDependencies": { "@types/sinonjs__fake-timers": "^6.0.1", diff --git a/packages/jest-get-type/package.json b/packages/jest-get-type/package.json index 70ed94ff079d..c78e99d64e4e 100644 --- a/packages/jest-get-type/package.json +++ b/packages/jest-get-type/package.json @@ -1,7 +1,7 @@ { "name": "jest-get-type", "description": "A utility function to get the type of a value", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -14,7 +14,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "publishConfig": { diff --git a/packages/jest-globals/package.json b/packages/jest-globals/package.json index c74a0e69a14f..db2dcfe2e131 100644 --- a/packages/jest-globals/package.json +++ b/packages/jest-globals/package.json @@ -1,6 +1,6 @@ { "name": "@jest/globals", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -13,13 +13,16 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/environment": "^27.3.1", - "@jest/types": "^27.2.5", - "expect": "^27.3.1" + "@jest/environment": "^27.4.0", + "@jest/types": "^27.4.0", + "expect": "^27.4.0" }, "publishConfig": { "access": "public" diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index 0817340417e4..eea90785566f 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -1,6 +1,6 @@ { "name": "jest-haste-map", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,25 +10,28 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.0", + "jest-worker": "^27.4.0", "micromatch": "^4.0.4", "walker": "^1.0.7" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/fb-watchman": "^2.0.0", "@types/micromatch": "^4.0.1", "jest-snapshot-serializer-raw": "^1.1.0", diff --git a/packages/jest-haste-map/src/lib/fast_path.ts b/packages/jest-haste-map/src/lib/fast_path.ts index 39e3e1812387..ea1d0c11ef8d 100644 --- a/packages/jest-haste-map/src/lib/fast_path.ts +++ b/packages/jest-haste-map/src/lib/fast_path.ts @@ -10,7 +10,7 @@ import * as path from 'path'; // rootDir and filename must be absolute paths (resolved) export function relative(rootDir: string, filename: string): string { return filename.indexOf(rootDir + path.sep) === 0 - ? filename.substr(rootDir.length + 1) + ? filename.substring(rootDir.length + 1) : path.relative(rootDir, filename); } diff --git a/packages/jest-haste-map/src/worker.ts b/packages/jest-haste-map/src/worker.ts index 7422bb5643fc..4a53879e6ae4 100644 --- a/packages/jest-haste-map/src/worker.ts +++ b/packages/jest-haste-map/src/worker.ts @@ -63,7 +63,7 @@ export async function worker(data: WorkerMessage): Promise { } catch (err: any) { throw new Error(`Cannot parse ${filePath} as JSON: ${err.message}`); } - } else if (!blacklist.has(filePath.substr(filePath.lastIndexOf('.')))) { + } else if (!blacklist.has(filePath.substring(filePath.lastIndexOf('.')))) { // Process a random file that is returned as a MODULE. if (hasteImpl) { id = hasteImpl.getHasteName(filePath); diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index dd6d95cecd4a..e74da9bb2a97 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -1,6 +1,6 @@ { "name": "jest-jasmine2", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,27 +10,30 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.0", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.3.1", + "expect": "^27.4.0", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.0", + "jest-matcher-utils": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-runtime": "^27.4.0", + "jest-snapshot": "^27.4.0", + "jest-util": "^27.4.0", + "pretty-format": "^27.4.0", "throat": "^6.0.1" }, "devDependencies": { diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 6a31a66c32b7..84836e81dba4 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -215,6 +215,9 @@ function makeConcurrent( } catch (error: unknown) { promise = Promise.reject(error); } + // Avoid triggering the uncaught promise rejection handler in case the test errors before + // being awaited on. + promise.catch(() => {}); return spec; }; diff --git a/packages/jest-jasmine2/src/types.ts b/packages/jest-jasmine2/src/types.ts index bc131dedaf56..4d0ff244005e 100644 --- a/packages/jest-jasmine2/src/types.ts +++ b/packages/jest-jasmine2/src/types.ts @@ -93,7 +93,7 @@ export type Jasmine = { typeof globalThis; declare global { - module NodeJS { + namespace NodeJS { interface Global { expect: typeof expect; } diff --git a/packages/jest-leak-detector/package.json b/packages/jest-leak-detector/package.json index 89689845dc71..cb19c18fd614 100644 --- a/packages/jest-leak-detector/package.json +++ b/packages/jest-leak-detector/package.json @@ -1,6 +1,6 @@ { "name": "jest-leak-detector", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,12 +10,15 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.0" }, "devDependencies": { "@types/weak-napi": "^2.0.0", diff --git a/packages/jest-matcher-utils/README.md b/packages/jest-matcher-utils/README.md index a43ce68473bb..d3e9d13bf849 100644 --- a/packages/jest-matcher-utils/README.md +++ b/packages/jest-matcher-utils/README.md @@ -9,7 +9,7 @@ To add this package as a dependency of a project, run either of the following co - `npm install jest-matcher-utils` - `yarn add jest-matcher-utils` -## Exports ([src/index.ts](jest-matcher-utils/src/index.ts)) +## Exports ([src/index.ts](https://github.com/facebook/jest/blob/HEAD/packages/jest-matcher-utils/src/index.ts)) ### Functions diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index 466895ca8d04..df0b2b0ce474 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -1,7 +1,7 @@ { "name": "jest-matcher-utils", "description": "A set of utility functions for expect and related packages", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -14,17 +14,20 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-diff": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/node": "*" }, "publishConfig": { diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index 90a5ef6d1bbc..15092a808e93 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-message-util", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -13,17 +13,20 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, diff --git a/packages/jest-mock/package.json b/packages/jest-mock/package.json index 020e0881f6fd..bced57e6984d 100644 --- a/packages/jest-mock/package.json +++ b/packages/jest-mock/package.json @@ -1,6 +1,6 @@ { "name": "jest-mock", - "version": "27.3.0", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,14 +10,17 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/node": "*" }, "license": "MIT", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "publishConfig": { diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 854d79a1c7b7..bcee51078f13 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -9,7 +9,7 @@ /* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */ import vm, {Context} from 'vm'; -import {ModuleMocker, fn, spyOn} from '../'; +import {ModuleMocker, fn, mocked, spyOn} from '../'; describe('moduleMocker', () => { let moduleMocker: ModuleMocker; @@ -1452,6 +1452,13 @@ describe('moduleMocker', () => { }); }); +describe('mocked', () => { + it('should return unmodified input', () => { + const subject = {}; + expect(mocked(subject)).toBe(subject); + }); +}); + test('`fn` and `spyOn` do not throw', () => { expect(() => { fn(); diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 0d0cdce00a8c..8e25c3461f6b 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -32,6 +32,77 @@ export type MockFunctionMetadata< length?: number; }; +export type MockableFunction = (...args: Array) => any; +export type MethodKeysOf = { + [K in keyof T]: T[K] extends MockableFunction ? K : never; +}[keyof T]; +export type PropertyKeysOf = { + [K in keyof T]: T[K] extends MockableFunction ? never : K; +}[keyof T]; + +export type ArgumentsOf = T extends (...args: infer A) => any ? A : never; + +export type ConstructorArgumentsOf = T extends new (...args: infer A) => any + ? A + : never; +export type MaybeMockedConstructor = T extends new ( + ...args: Array +) => infer R + ? MockInstance> + : T; +export type MockedFunction = MockWithArgs & { + [K in keyof T]: T[K]; +}; +export type MockedFunctionDeep = MockWithArgs & + MockedObjectDeep; +export type MockedObject = MaybeMockedConstructor & { + [K in MethodKeysOf]: T[K] extends MockableFunction + ? MockedFunction + : T[K]; +} & {[K in PropertyKeysOf]: T[K]}; +export type MockedObjectDeep = MaybeMockedConstructor & { + [K in MethodKeysOf]: T[K] extends MockableFunction + ? MockedFunctionDeep + : T[K]; +} & {[K in PropertyKeysOf]: MaybeMockedDeep}; + +export type MaybeMockedDeep = T extends MockableFunction + ? MockedFunctionDeep + : T extends object + ? MockedObjectDeep + : T; + +export type MaybeMocked = T extends MockableFunction + ? MockedFunction + : T extends object + ? MockedObject + : T; + +export type ArgsType = T extends (...args: infer A) => any ? A : never; +export type Mocked = { + [P in keyof T]: T[P] extends (...args: Array) => any + ? MockInstance, ArgsType> + : T[P] extends Constructable + ? MockedClass + : T[P]; +} & T; +export type MockedClass = MockInstance< + InstanceType, + T extends new (...args: infer P) => any ? P : never +> & { + prototype: T extends {prototype: any} ? Mocked : never; +} & T; + +export interface Constructable { + new (...args: Array): any; +} + +export interface MockWithArgs + extends MockInstance, ArgumentsOf> { + new (...args: ConstructorArgumentsOf): T; + (...args: ArgumentsOf): ReturnType; +} + export interface Mock = Array> extends Function, MockInstance { @@ -1109,9 +1180,19 @@ export class ModuleMocker { private _typeOf(value: any): string { return value == null ? '' + value : typeof value; } + + // the typings test helper + mocked(item: T, deep?: false): MaybeMocked; + + mocked(item: T, deep: true): MaybeMockedDeep; + + mocked(item: T, _deep = false): MaybeMocked | MaybeMockedDeep { + return item as any; + } } const JestMock = new ModuleMocker(global as unknown as typeof globalThis); export const fn = JestMock.fn.bind(JestMock); export const spyOn = JestMock.spyOn.bind(JestMock); +export const mocked = JestMock.mocked.bind(JestMock); diff --git a/packages/jest-phabricator/package.json b/packages/jest-phabricator/package.json index 25e51faab1e2..03ba12239489 100644 --- a/packages/jest-phabricator/package.json +++ b/packages/jest-phabricator/package.json @@ -1,6 +1,6 @@ { "name": "jest-phabricator", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -8,11 +8,14 @@ }, "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/test-result": "^27.3.1" + "@jest/test-result": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-regex-util/package.json b/packages/jest-regex-util/package.json index 233654c75ab8..135003bc79fa 100644 --- a/packages/jest-regex-util/package.json +++ b/packages/jest-regex-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-regex-util", - "version": "27.0.6", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -16,7 +16,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "publishConfig": { diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index f1115961f3c7..d6742d6f55e2 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -1,6 +1,6 @@ { "name": "jest-repl", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,26 +10,29 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json", "./bin/jest-repl": "./bin/jest-repl.js", "./bin/jest-runtime-cli": "./bin/jest-runtime-cli.js" }, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/environment": "^27.4.0", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "chalk": "^4.0.0", - "jest-config": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-config": "^27.4.0", + "jest-runtime": "^27.4.0", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", "repl": "^0.1.3", "yargs": "^16.2.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/yargs": "^16.0.0", "execa": "^5.0.0" }, diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index 908ef2d96900..9224853cb9d3 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -1,19 +1,22 @@ { "name": "@jest/reporters", "description": "Jest's reporters", - "version": "27.3.1", + "version": "27.4.0", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -25,10 +28,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-haste-map": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-util": "^27.4.0", + "jest-worker": "^27.4.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -36,7 +39,7 @@ "v8-to-istanbul": "^8.1.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/exit": "^0.1.30", "@types/glob": "^7.1.1", "@types/graceful-fs": "^4.1.3", diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index 6b7b1f3070e8..81023948fc48 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve-dependencies", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,19 +10,22 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.1" + "@jest/types": "^27.4.0", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1" + "@jest/test-utils": "^27.4.0", + "jest-haste-map": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-runtime": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index f9e72e72e963..3b1cd77fbd24 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,17 +10,20 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", + "jest-haste-map": "^27.4.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index c252c232c0bb..3e2a52e1dcfa 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -1,6 +1,6 @@ { "name": "jest-runner", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,30 +10,33 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/environment": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-leak-detector": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.0", + "jest-environment-node": "^27.4.0", + "jest-haste-map": "^27.4.0", + "jest-leak-detector": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-runtime": "^27.4.0", + "jest-util": "^27.4.0", + "jest-worker": "^27.4.0", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -41,7 +44,7 @@ "@types/exit": "^0.1.30", "@types/graceful-fs": "^4.1.2", "@types/source-map-support": "^0.5.0", - "jest-jasmine2": "^27.3.1" + "jest-jasmine2": "^27.4.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index cd297c3696c5..5f6e17eeb615 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -273,7 +273,8 @@ export default class TestRunner { chalk.yellow( 'A worker process has failed to exit gracefully and has been force exited. ' + 'This is likely caused by tests leaking due to improper teardown. ' + - 'Try running with --detectOpenHandles to find leaks.', + 'Try running with --detectOpenHandles to find leaks. ' + + 'Active timers can also cause this, ensure that .unref() was called on them.', ), ); } diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 0c07f78d5cf8..7f86c9e9a5e8 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -1,6 +1,6 @@ { "name": "jest-runtime", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,17 +10,20 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/globals": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/environment": "^27.4.0", + "@jest/globals": "^27.4.0", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.0", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", @@ -29,26 +32,26 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-haste-map": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-mock": "^27.4.0", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-snapshot": "^27.4.0", + "jest-util": "^27.4.0", + "jest-validate": "^27.4.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.2.0" }, "devDependencies": { - "@jest/fake-timers": "^27.3.1", - "@jest/test-utils": "^27.3.1", + "@jest/fake-timers": "^27.4.0", + "@jest/test-utils": "^27.4.0", "@types/exit": "^0.1.30", "@types/glob": "^7.1.1", "@types/graceful-fs": "^4.1.2", "@types/node": "^14.0.27", - "jest-environment-node": "^27.3.1", + "jest-environment-node": "^27.4.0", "jest-snapshot-serializer-raw": "^1.1.0" }, "engines": { diff --git a/packages/jest-serializer/package.json b/packages/jest-serializer/package.json index 522821ab2279..c0d1911b410f 100644 --- a/packages/jest-serializer/package.json +++ b/packages/jest-serializer/package.json @@ -1,6 +1,6 @@ { "name": "jest-serializer", - "version": "27.0.6", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -20,7 +20,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "publishConfig": { diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index 3fb5b9aa1f72..ac56d4203c72 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -1,6 +1,6 @@ { "name": "jest-snapshot", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { @@ -20,29 +23,29 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.0", + "@jest/types": "^27.4.0", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.1", + "expect": "^27.4.0", "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", + "jest-diff": "^27.4.0", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.0", + "jest-matcher-utils": "^27.4.0", + "jest-message-util": "^27.4.0", + "jest-resolve": "^27.4.0", + "jest-util": "^27.4.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.0", "semver": "^7.3.2" }, "devDependencies": { "@babel/preset-flow": "^7.7.2", "@babel/preset-react": "^7.7.2", - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/graceful-fs": "^4.1.3", "@types/natural-compare": "^1.4.0", "@types/semver": "^7.1.0", diff --git a/packages/jest-snapshot/src/index.ts b/packages/jest-snapshot/src/index.ts index d9c7fed4dc38..58bae0a9d0b8 100644 --- a/packages/jest-snapshot/src/index.ts +++ b/packages/jest-snapshot/src/index.ts @@ -99,7 +99,7 @@ function stripAddedIndentation(inlineSnapshot: string) { return inlineSnapshot; } - lines[i] = lines[i].substr(indentation.length); + lines[i] = lines[i].substring(indentation.length); } } diff --git a/packages/jest-source-map/package.json b/packages/jest-source-map/package.json index 03844b9914e9..f86b7cb16cb4 100644 --- a/packages/jest-source-map/package.json +++ b/packages/jest-source-map/package.json @@ -1,6 +1,6 @@ { "name": "@jest/source-map", - "version": "27.0.6", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { diff --git a/packages/jest-test-result/package.json b/packages/jest-test-result/package.json index 3cc87d09bee3..86df893eae66 100644 --- a/packages/jest-test-result/package.json +++ b/packages/jest-test-result/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-result", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,12 +10,15 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/console": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.0", + "@jest/types": "^27.4.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, diff --git a/packages/jest-test-result/src/index.ts b/packages/jest-test-result/src/index.ts index 97c2def09908..26edbc397fa6 100644 --- a/packages/jest-test-result/src/index.ts +++ b/packages/jest-test-result/src/index.ts @@ -28,6 +28,7 @@ export type { TestEvents, TestFileEvent, TestResult, + TestResultsProcessor, TestCaseResult, V8CoverageResult, } from './types'; diff --git a/packages/jest-test-result/src/types.ts b/packages/jest-test-result/src/types.ts index 94c23cf72cd7..d911ac818fbf 100644 --- a/packages/jest-test-result/src/types.ts +++ b/packages/jest-test-result/src/types.ts @@ -78,6 +78,10 @@ export type AggregatedResult = AggregatedResultWithoutCoverage & { coverageMap?: CoverageMap | null; }; +export type TestResultsProcessor = ( + results: AggregatedResult, +) => AggregatedResult; + export type Suite = { title: string; suites: Array; diff --git a/packages/jest-test-sequencer/package.json b/packages/jest-test-sequencer/package.json index 9cd635b19a49..6f0638fb9c9d 100644 --- a/packages/jest-test-sequencer/package.json +++ b/packages/jest-test-sequencer/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-sequencer", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,14 +10,17 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/test-result": "^27.3.1", + "@jest/test-result": "^27.4.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-runtime": "^27.3.1" + "jest-haste-map": "^27.4.0", + "jest-runtime": "^27.4.0" }, "devDependencies": { "@types/graceful-fs": "^4.1.3" diff --git a/packages/jest-transform/package.json b/packages/jest-transform/package.json index 25622d2344c1..0baedb41eb49 100644 --- a/packages/jest-transform/package.json +++ b/packages/jest-transform/package.json @@ -1,6 +1,6 @@ { "name": "@jest/transform", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,20 +10,23 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.1", + "jest-haste-map": "^27.4.0", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.0", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -31,7 +34,7 @@ "write-file-atomic": "^3.0.0" }, "devDependencies": { - "@jest/test-utils": "^27.3.1", + "@jest/test-utils": "^27.4.0", "@types/babel__core": "^7.1.0", "@types/convert-source-map": "^1.5.1", "@types/fast-json-stable-stringify": "^2.0.0", diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 3591fa294fdf..7e17f65822e5 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -25,6 +25,12 @@ import { tryRealpath, } from 'jest-util'; import handlePotentialSyntaxError from './enhanceUnexpectedTokenMessage'; +import { + makeInvalidReturnValueError, + makeInvalidSourceMapWarning, + makeInvalidSyncTransformerError, + makeInvalidTransformerError, +} from './runtimeErrorsAndWarnings'; import shouldInstrument from './shouldInstrument'; import type { Options, @@ -258,7 +264,7 @@ class ScriptTransformer { ); if (!transformer) { - throw new TypeError('Jest: a transform must export something.'); + throw new Error(makeInvalidTransformerError(transformPath)); } if (typeof transformer.createTransformer === 'function') { transformer = transformer.createTransformer(transformerConfig); @@ -267,9 +273,7 @@ class ScriptTransformer { typeof transformer.process !== 'function' && typeof transformer.processAsync !== 'function' ) { - throw new TypeError( - 'Jest: a transform must export a `process` or `processAsync` function.', - ); + throw new Error(makeInvalidTransformerError(transformPath)); } const res = {transformer, transformerConfig}; this._transformCache.set(transformPath, res); @@ -373,11 +377,7 @@ class ScriptTransformer { } else if (processed != null && typeof processed.code === 'string') { transformed = processed; } else { - throw new TypeError( - "Jest: a transform's `process` function must return a string, " + - 'or an object with `code` key containing this string. ' + - "It's `processAsync` function must return a Promise resolving to it.", - ); + throw new Error(makeInvalidReturnValueError()); } } @@ -391,11 +391,8 @@ class ScriptTransformer { } } catch { const transformPath = this._getTransformPath(filename); - console.warn( - `jest-transform: The source map produced for the file ${filename} ` + - `by ${transformPath} was invalid. Proceeding without source ` + - 'mapping for that file.', - ); + invariant(transformPath); + console.warn(makeInvalidSourceMapWarning(filename, transformPath)); } } @@ -879,9 +876,9 @@ function readCodeCacheFile(cachePath: Config.Path): string | null { if (content == null) { return null; } - const code = content.substr(33); + const code = content.substring(33); const checksum = createHash('md5').update(code).digest('hex'); - if (checksum === content.substr(0, 32)) { + if (checksum === content.substring(0, 32)) { return code; } return null; @@ -997,7 +994,7 @@ function assertSyncTransformer( invariant(name); invariant( typeof transformer.process === 'function', - `Jest: synchronous transformer ${name} must export a "process" function.`, + makeInvalidSyncTransformerError(name), ); } diff --git a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts index 94ade78a4a2c..90691081727c 100644 --- a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts +++ b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts @@ -486,14 +486,14 @@ describe('ScriptTransformer', () => { await Promise.all([...promisesToReject, ...promisesToResolve]); }); - it('throws an error if neither `process` nor `processAsync is defined', async () => { + it('throws an error if neither `process` nor `processAsync` is defined', async () => { config = { ...config, transform: [['\\.js$', 'skipped-required-props-preprocessor', {}]], }; - await expect(() => createScriptTransformer(config)).rejects.toThrow( - 'Jest: a transform must export a `process` or `processAsync` function.', - ); + await expect(() => + createScriptTransformer(config), + ).rejects.toThrowErrorMatchingSnapshot(); }); it("(in sync mode) throws an error if `process` isn't defined", async () => { @@ -506,9 +506,7 @@ describe('ScriptTransformer', () => { const scriptTransformer = await createScriptTransformer(config); expect(() => scriptTransformer.transformSource('sample.js', '', {instrument: false}), - ).toThrow( - 'Jest: synchronous transformer skipped-required-props-preprocessor-only-async must export a "process" function.', - ); + ).toThrowErrorMatchingSnapshot(); }); it('(in async mode) handles only sync `process`', async () => { @@ -537,9 +535,9 @@ describe('ScriptTransformer', () => { ], ], }; - await expect(() => createScriptTransformer(config)).rejects.toThrow( - 'Jest: a transform must export a `process` or `processAsync` function.', - ); + await expect(() => + createScriptTransformer(config), + ).rejects.toThrowErrorMatchingSnapshot(); }); it("shouldn't throw error without process method. But with correct createTransformer method", async () => { diff --git a/packages/jest-transform/src/__tests__/__snapshots__/ScriptTransformer.test.ts.snap b/packages/jest-transform/src/__tests__/__snapshots__/ScriptTransformer.test.ts.snap index ffa97cef1c0b..b3bee10792be 100644 --- a/packages/jest-transform/src/__tests__/__snapshots__/ScriptTransformer.test.ts.snap +++ b/packages/jest-transform/src/__tests__/__snapshots__/ScriptTransformer.test.ts.snap @@ -1,5 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`ScriptTransformer (in sync mode) throws an error if \`process\` isn't defined 1`] = ` +"● Invalid synchronous transformer module: + \\"skipped-required-props-preprocessor-only-async\\" specified in the \\"transform\\" object of Jest configuration + must export a \`process\` function. + Code Transformation Documentation: + https://jestjs.io/docs/code-transformation +" +`; + exports[`ScriptTransformer in async mode, passes expected transform options to getCacheKey 1`] = ` [MockFunction] { "calls": Array [ @@ -126,7 +135,11 @@ const TRANSFORMED = { exports[`ScriptTransformer in async mode, uses the supplied preprocessor 2`] = `module.exports = "react";`; -exports[`ScriptTransformer in async mode, warns of unparseable inlined source maps from the preprocessor 1`] = `jest-transform: The source map produced for the file /fruits/banana.js by preprocessor-with-sourcemaps was invalid. Proceeding without source mapping for that file.`; +exports[`ScriptTransformer in async mode, warns of unparseable inlined source maps from the preprocessor 1`] = ` +● Invalid source map: + The source map for "/fruits/banana.js" returned by "preprocessor-with-sourcemaps" is invalid. + Proceeding without source mapping for that file. +`; exports[`ScriptTransformer passes expected transform options to getCacheKey 1`] = ` [MockFunction] { @@ -340,6 +353,24 @@ exports[`ScriptTransformer passes expected transform options to getCacheKeyAsync } `; +exports[`ScriptTransformer throws an error if createTransformer returns object without \`process\` method 1`] = ` +"● Invalid transformer module: + \\"skipped-required-create-transformer-props-preprocessor\\" specified in the \\"transform\\" object of Jest configuration + must export a \`process\` or \`processAsync\` or \`createTransformer\` function. + Code Transformation Documentation: + https://jestjs.io/docs/code-transformation +" +`; + +exports[`ScriptTransformer throws an error if neither \`process\` nor \`processAsync\` is defined 1`] = ` +"● Invalid transformer module: + \\"skipped-required-props-preprocessor\\" specified in the \\"transform\\" object of Jest configuration + must export a \`process\` or \`processAsync\` or \`createTransformer\` function. + Code Transformation Documentation: + https://jestjs.io/docs/code-transformation +" +`; + exports[`ScriptTransformer transforms a file async properly 1`] = ` /* istanbul ignore next */ function cov_25u22311x4() { @@ -688,6 +719,14 @@ const TRANSFORMED = { exports[`ScriptTransformer uses the supplied preprocessor 2`] = `module.exports = "react";`; -exports[`ScriptTransformer warns of unparseable inlined source maps from the async preprocessor 1`] = `jest-transform: The source map produced for the file /fruits/banana.js by async-preprocessor-with-sourcemaps was invalid. Proceeding without source mapping for that file.`; +exports[`ScriptTransformer warns of unparseable inlined source maps from the async preprocessor 1`] = ` +● Invalid source map: + The source map for "/fruits/banana.js" returned by "async-preprocessor-with-sourcemaps" is invalid. + Proceeding without source mapping for that file. +`; -exports[`ScriptTransformer warns of unparseable inlined source maps from the preprocessor 1`] = `jest-transform: The source map produced for the file /fruits/banana.js by preprocessor-with-sourcemaps was invalid. Proceeding without source mapping for that file.`; +exports[`ScriptTransformer warns of unparseable inlined source maps from the preprocessor 1`] = ` +● Invalid source map: + The source map for "/fruits/banana.js" returned by "preprocessor-with-sourcemaps" is invalid. + Proceeding without source mapping for that file. +`; diff --git a/packages/jest-transform/src/runtimeErrorsAndWarnings.ts b/packages/jest-transform/src/runtimeErrorsAndWarnings.ts new file mode 100644 index 000000000000..0da3e097c5c5 --- /dev/null +++ b/packages/jest-transform/src/runtimeErrorsAndWarnings.ts @@ -0,0 +1,67 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import chalk = require('chalk'); +import slash = require('slash'); + +const BULLET = '\u25cf '; +const DOCUMENTATION_NOTE = ` ${chalk.bold( + 'Code Transformation Documentation:', +)} + https://jestjs.io/docs/code-transformation +`; + +export const makeInvalidReturnValueError = (): string => + chalk.red( + [ + chalk.bold(BULLET + 'Invalid return value:'), + ` Code transformer's \`process\` function must return a string or an object`, + ' with `code` key containing a string. If `processAsync` function is implemented,', + ' it must return a Promise resolving to one of these values.', + '', + ].join('\n') + DOCUMENTATION_NOTE, + ); + +export const makeInvalidSourceMapWarning = ( + filename: string, + transformPath: string, +): string => + chalk.yellow( + [ + chalk.bold(BULLET + 'Invalid source map:'), + ` The source map for "${slash(filename)}" returned by "${slash( + transformPath, + )}" is invalid.`, + ' Proceeding without source mapping for that file.', + ].join('\n'), + ); + +export const makeInvalidSyncTransformerError = ( + transformPath: string, +): string => + chalk.red( + [ + chalk.bold(BULLET + 'Invalid synchronous transformer module:'), + ` "${slash( + transformPath, + )}" specified in the "transform" object of Jest configuration`, + ' must export a `process` function.', + '', + ].join('\n') + DOCUMENTATION_NOTE, + ); + +export const makeInvalidTransformerError = (transformPath: string): string => + chalk.red( + [ + chalk.bold(BULLET + 'Invalid transformer module:'), + ` "${slash( + transformPath, + )}" specified in the "transform" object of Jest configuration`, + ' must export a `process` or `processAsync` or `createTransformer` function.', + '', + ].join('\n') + DOCUMENTATION_NOTE, + ); diff --git a/packages/jest-transform/src/types.ts b/packages/jest-transform/src/types.ts index cc6f2e3995a4..0e0753c0eb1b 100644 --- a/packages/jest-transform/src/types.ts +++ b/packages/jest-transform/src/types.ts @@ -70,7 +70,7 @@ export interface TransformOptions export interface SyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -105,7 +105,7 @@ export interface SyncTransformer { export interface AsyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. diff --git a/packages/jest-types/package.json b/packages/jest-types/package.json index 5568a6ff62b7..a01733e905ca 100644 --- a/packages/jest-types/package.json +++ b/packages/jest-types/package.json @@ -1,6 +1,6 @@ { "name": "@jest/types", - "version": "27.2.5", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -13,7 +13,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { diff --git a/packages/jest-util/package.json b/packages/jest-util/package.json index 6d77e8e19335..e69abf3caff7 100644 --- a/packages/jest-util/package.json +++ b/packages/jest-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-util", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,11 +10,14 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", diff --git a/packages/jest-validate/package.json b/packages/jest-validate/package.json index 8275587c0de1..44a3b6d82034 100644 --- a/packages/jest-validate/package.json +++ b/packages/jest-validate/package.json @@ -1,6 +1,6 @@ { "name": "jest-validate", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,16 +10,19 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", + "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.0" }, "devDependencies": { "@types/yargs": "^16.0.0" diff --git a/packages/jest-watcher/package.json b/packages/jest-watcher/package.json index 6b51b676f971..7e3c3c7045cf 100644 --- a/packages/jest-watcher/package.json +++ b/packages/jest-watcher/package.json @@ -1,20 +1,23 @@ { "name": "jest-watcher", "description": "Delightful JavaScript Testing.", - "version": "27.3.1", + "version": "27.4.0", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/test-result": "^27.4.0", + "@jest/types": "^27.4.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.1", + "jest-util": "^27.4.0", "string-length": "^4.0.1" }, "repository": { diff --git a/packages/jest-worker/package.json b/packages/jest-worker/package.json index b74bdd6107f1..1ff7c4780fa6 100644 --- a/packages/jest-worker/package.json +++ b/packages/jest-worker/package.json @@ -1,6 +1,6 @@ { "name": "jest-worker", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,10 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { @@ -22,7 +25,7 @@ "@types/merge-stream": "^1.1.2", "@types/supports-color": "^8.1.0", "get-stream": "^6.0.0", - "jest-leak-detector": "^27.3.1", + "jest-leak-detector": "^27.4.0", "worker-farm": "^1.6.0" }, "engines": { diff --git a/packages/jest-worker/src/types.ts b/packages/jest-worker/src/types.ts index 3022faf3c93f..d1a44840cfe7 100644 --- a/packages/jest-worker/src/types.ts +++ b/packages/jest-worker/src/types.ts @@ -125,6 +125,7 @@ export type WorkerOptions = { setupArgs: Array; maxRetries: number; workerId: number; + workerData?: unknown; workerPath: string; }; diff --git a/packages/jest-worker/src/workers/NodeThreadsWorker.ts b/packages/jest-worker/src/workers/NodeThreadsWorker.ts index efd5d60af57c..da6c3741b6b0 100644 --- a/packages/jest-worker/src/workers/NodeThreadsWorker.ts +++ b/packages/jest-worker/src/workers/NodeThreadsWorker.ts @@ -7,10 +7,7 @@ import * as path from 'path'; import {PassThrough} from 'stream'; -import { - Worker, - WorkerOptions as WorkerThreadsWorkerOptions, -} from 'worker_threads'; +import {Worker} from 'worker_threads'; import mergeStream = require('merge-stream'); import { CHILD_MESSAGE_INITIALIZE, @@ -63,22 +60,19 @@ export default class ExperimentalWorker implements WorkerInterface { initialize(): void { this._worker = new Worker(path.resolve(__dirname, './threadChild.js'), { + env: { + ...process.env, + JEST_WORKER_ID: String(this._options.workerId + 1), // 0-indexed workerId, 1-indexed JEST_WORKER_ID + }, eval: false, + execArgv: process.execArgv, + // @ts-expect-error: added in newer versions resourceLimits: this._options.resourceLimits, stderr: true, stdout: true, - workerData: { - cwd: process.cwd(), - env: { - ...process.env, - JEST_WORKER_ID: String(this._options.workerId + 1), // 0-indexed workerId, 1-indexed JEST_WORKER_ID - } as NodeJS.ProcessEnv, - // Suppress --debug / --inspect flags while preserving others (like --harmony). - execArgv: process.execArgv.filter(v => !/^--(debug|inspect)/.test(v)), - silent: true, - ...this._options.forkOptions, - }, - } as WorkerThreadsWorkerOptions); + workerData: this._options.workerData, + ...this._options.forkOptions, + }); if (this._worker.stdout) { if (!this._stdout) { diff --git a/packages/jest-worker/src/workers/__tests__/NodeThreadsWorker.test.js b/packages/jest-worker/src/workers/__tests__/NodeThreadsWorker.test.js index 5bc2fe215aa1..9e1d6500b104 100644 --- a/packages/jest-worker/src/workers/__tests__/NodeThreadsWorker.test.js +++ b/packages/jest-worker/src/workers/__tests__/NodeThreadsWorker.test.js @@ -51,7 +51,7 @@ afterEach(() => { process.execArgv = originalExecArgv; }); -it('passes fork options down to child_process.fork, adding the defaults', () => { +it('passes fork options down to worker_threads.Worker, adding the defaults', () => { const thread = require.resolve('../threadChild'); process.execArgv = ['--inspect', '-p']; @@ -59,25 +59,28 @@ it('passes fork options down to child_process.fork, adding the defaults', () => // eslint-disable-next-line no-new new Worker({ forkOptions: { - cwd: '/tmp', execPath: 'hello', }, maxRetries: 3, + workerData: { + foo: 'bar', + }, workerId: process.env.JEST_WORKER_ID - 1, workerPath: '/tmp/foo/bar/baz.js', }); expect(workerThreads.mock.calls[0][0]).toBe(thread.replace(/\.ts$/, '.js')); expect(workerThreads.mock.calls[0][1]).toEqual({ + env: process.env, // Default option. eval: false, + execArgv: ['--inspect', '-p'], + execPath: 'hello', // Added option. + resourceLimits: undefined, stderr: true, stdout: true, workerData: { - cwd: '/tmp', // Overridden default option. - env: process.env, // Default option. - execArgv: ['-p'], // Filtered option. - execPath: 'hello', // Added option. - silent: true, // Default option. + // Added option. + foo: 'bar', }, }); }); @@ -91,9 +94,7 @@ it('passes workerId to the thread and assign it to env.JEST_WORKER_ID', () => { workerPath: '/tmp/foo', }); - expect(workerThreads.mock.calls[0][1].workerData.env.JEST_WORKER_ID).toEqual( - '3', - ); + expect(workerThreads.mock.calls[0][1].env.JEST_WORKER_ID).toEqual('3'); }); it('initializes the thread with the given workerPath', () => { diff --git a/packages/jest/package.json b/packages/jest/package.json index cdf5cc21e438..777cae7c84e5 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -1,18 +1,21 @@ { "name": "jest", "description": "Delightful JavaScript Testing.", - "version": "27.3.1", + "version": "27.4.0", "main": "./build/jest.js", "types": "./build/jest.d.ts", "exports": { - ".": "./build/jest.js", + ".": { + "types": "./build/jest.d.ts", + "default": "./build/jest.js" + }, "./package.json": "./package.json", "./bin/jest": "./bin/jest.js" }, "dependencies": { - "@jest/core": "^27.3.1", + "@jest/core": "^27.4.0", "import-local": "^3.0.2", - "jest-cli": "^27.3.1" + "jest-cli": "^27.4.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" diff --git a/packages/pretty-format/README.md b/packages/pretty-format/README.md index 315866f71929..c5cb0041dbfa 100755 --- a/packages/pretty-format/README.md +++ b/packages/pretty-format/README.md @@ -69,6 +69,7 @@ console.log(prettyFormat(onClick, options)); | key | type | default | description | | :-------------------- | :-------- | :--------- | :------------------------------------------------------ | | `callToJSON` | `boolean` | `true` | call `toJSON` method (if it exists) on objects | +| `compareKeys` | `function`| `undefined`| compare function used when sorting object keys | | `escapeRegex` | `boolean` | `false` | escape special characters in regular expressions | | `escapeString` | `boolean` | `true` | escape special characters in strings | | `highlight` | `boolean` | `false` | highlight syntax with colors in terminal (some plugins) | @@ -207,6 +208,7 @@ Write `serialize` to return a string, given the arguments: | key | type | description | | :------------------ | :-------- | :------------------------------------------------------ | | `callToJSON` | `boolean` | call `toJSON` method (if it exists) on objects | +| `compareKeys` | `function`| compare function used when sorting object keys | | `colors` | `Object` | escape codes for colors to highlight syntax | | `escapeRegex` | `boolean` | escape special characters in regular expressions | | `escapeString` | `boolean` | escape special characters in strings | diff --git a/packages/pretty-format/package.json b/packages/pretty-format/package.json index e1f225c347d2..aeed5c1abbe7 100644 --- a/packages/pretty-format/package.json +++ b/packages/pretty-format/package.json @@ -1,6 +1,6 @@ { "name": "pretty-format", - "version": "27.3.1", + "version": "27.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -11,12 +11,15 @@ "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "author": "James Kyle ", "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -26,7 +29,7 @@ "@types/react-is": "^17.0.0", "@types/react-test-renderer": "*", "immutable": "4.0.0-rc.9", - "jest-util": "^27.3.1", + "jest-util": "^27.4.0", "react": "*", "react-dom": "*", "react-test-renderer": "*" diff --git a/packages/pretty-format/src/__tests__/prettyFormat.test.ts b/packages/pretty-format/src/__tests__/prettyFormat.test.ts index fde20e6ac839..ab9d0b9da214 100644 --- a/packages/pretty-format/src/__tests__/prettyFormat.test.ts +++ b/packages/pretty-format/src/__tests__/prettyFormat.test.ts @@ -329,12 +329,28 @@ describe('prettyFormat()', () => { }); it('prints an object with sorted properties', () => { - /* eslint-disable sort-keys */ + // eslint-disable-next-line sort-keys const val = {b: 1, a: 2}; - /* eslint-enable sort-keys */ expect(prettyFormat(val)).toEqual('Object {\n "a": 2,\n "b": 1,\n}'); }); + it('prints an object with keys in their original order', () => { + // eslint-disable-next-line sort-keys + const val = {b: 1, a: 2}; + const compareKeys = () => 0; + expect(prettyFormat(val, {compareKeys})).toEqual( + 'Object {\n "b": 1,\n "a": 2,\n}', + ); + }); + + it('prints an object with keys sorted in reverse order', () => { + const val = {a: 1, b: 2}; + const compareKeys = (a: string, b: string) => (a > b ? -1 : 1); + expect(prettyFormat(val, {compareKeys})).toEqual( + 'Object {\n "b": 2,\n "a": 1,\n}', + ); + }); + it('prints regular expressions from constructors', () => { const val = new RegExp('regexp'); expect(prettyFormat(val)).toEqual('/regexp/'); diff --git a/packages/pretty-format/src/collections.ts b/packages/pretty-format/src/collections.ts index 6884059fe307..97fae10163ba 100644 --- a/packages/pretty-format/src/collections.ts +++ b/packages/pretty-format/src/collections.ts @@ -6,10 +6,13 @@ * */ -import type {Config, Printer, Refs} from './types'; +import type {CompareKeys, Config, Printer, Refs} from './types'; -const getKeysOfEnumerableProperties = (object: Record) => { - const keys: Array = Object.keys(object).sort(); +const getKeysOfEnumerableProperties = ( + object: Record, + compareKeys: CompareKeys, +) => { + const keys: Array = Object.keys(object).sort(compareKeys); if (Object.getOwnPropertySymbols) { Object.getOwnPropertySymbols(object).forEach(symbol => { @@ -175,7 +178,7 @@ export function printObjectProperties( printer: Printer, ): string { let result = ''; - const keys = getKeysOfEnumerableProperties(val); + const keys = getKeysOfEnumerableProperties(val, config.compareKeys); if (keys.length) { result += config.spacingOuter; diff --git a/packages/pretty-format/src/index.ts b/packages/pretty-format/src/index.ts index 80cd8af4850a..4969eced6499 100644 --- a/packages/pretty-format/src/index.ts +++ b/packages/pretty-format/src/index.ts @@ -35,6 +35,7 @@ import type { export type { Colors, + CompareKeys, Config, Options, OptionsReceived, @@ -42,6 +43,7 @@ export type { NewPlugin, Plugin, Plugins, + PrettyFormatOptions, Printer, Refs, Theme, @@ -396,6 +398,7 @@ const DEFAULT_THEME_KEYS = Object.keys(DEFAULT_THEME) as Array< export const DEFAULT_OPTIONS: Options = { callToJSON: true, + compareKeys: undefined, escapeRegex: false, escapeString: true, highlight: false, @@ -485,6 +488,10 @@ const getConfig = (options?: OptionsReceived): Config => ({ options && options.highlight ? getColorsHighlight(options) : getColorsEmpty(), + compareKeys: + options && typeof options.compareKeys === 'function' + ? options.compareKeys + : DEFAULT_OPTIONS.compareKeys, escapeRegex: getEscapeRegex(options), escapeString: getEscapeString(options), indent: diff --git a/packages/pretty-format/src/types.ts b/packages/pretty-format/src/types.ts index cb7413069436..4723bef1b380 100644 --- a/packages/pretty-format/src/types.ts +++ b/packages/pretty-format/src/types.ts @@ -32,8 +32,11 @@ type ThemeReceived = { value?: string; }; +export type CompareKeys = ((a: string, b: string) => number) | undefined; + export type Options = { callToJSON: boolean; + compareKeys: CompareKeys; escapeRegex: boolean; escapeString: boolean; highlight: boolean; @@ -48,6 +51,7 @@ export type Options = { export interface PrettyFormatOptions { callToJSON?: boolean; + compareKeys?: CompareKeys; escapeRegex?: boolean; escapeString?: boolean; highlight?: boolean; @@ -64,6 +68,7 @@ export type OptionsReceived = PrettyFormatOptions; export type Config = { callToJSON: boolean; + compareKeys: CompareKeys; colors: Colors; escapeRegex: boolean; escapeString: boolean; diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index b6757aed4ab6..d073ad42c1d8 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,22 +1,25 @@ { "name": "@jest/test-utils", - "version": "27.3.1", + "version": "27.4.0", "private": true, "license": "MIT", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { - ".": "./build/index.js", + ".": { + "types": "./build/index.d.ts", + "default": "./build/index.js" + }, "./package.json": "./package.json" }, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.0", "@types/jest": "*", "@types/node": "*", "@types/semver": "^7.1.0", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.0", "semver": "^7.3.2" }, "engines": { diff --git a/scripts/buildUtils.js b/scripts/buildUtils.js index 29f286e11f1e..d2ba6ba08fc6 100644 --- a/scripts/buildUtils.js +++ b/scripts/buildUtils.js @@ -44,7 +44,14 @@ module.exports.getPackages = function getPackages() { assert.deepStrictEqual( pkg.exports, { - '.': pkg.main, + '.': + pkg.types == null + ? pkg.main + : { + types: pkg.types, + // eslint-disable-next-line sort-keys + default: pkg.main, + }, './package.json': './package.json', ...Object.values(pkg.bin || {}).reduce( (mem, curr) => diff --git a/scripts/verifyPnP.js b/scripts/verifyPnP.js index 89131fb7e60c..607b7da38d3b 100644 --- a/scripts/verifyPnP.js +++ b/scripts/verifyPnP.js @@ -36,6 +36,9 @@ try { jest: `*`, }, name: 'test-pnp', + resolutions: { + typescript: '~4.4', + }, }, null, 2, diff --git a/test-types/expect.test.ts b/test-types/expect.test.ts new file mode 100644 index 000000000000..1ff227af29e2 --- /dev/null +++ b/test-types/expect.test.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type * as expect from 'expect'; + +export type M = expect.Matchers; +export type N = expect.Matchers; +// @ts-expect-error +export type E = expect.Matchers<>; diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 0512ae0879b6..73555ee58d96 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -80,7 +80,7 @@ module.exports = { { tagName: 'meta', name: 'theme-color', - content: JestThemeColor, + content: '#FFF', }, { tagName: 'meta', diff --git a/website/src/css/docusaurusTheme.css b/website/src/css/docusaurusTheme.css index 0d7b8843d878..420a79605df1 100644 --- a/website/src/css/docusaurusTheme.css +++ b/website/src/css/docusaurusTheme.css @@ -70,3 +70,14 @@ html[data-theme='dark'] .footer--dark { .footer--dark .text--center { color: var(--grey); } + +.docusaurus-highlight-code-line { + background-color: rgba(0, 0, 0, 0.1); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +html[data-theme='dark'] .docusaurus-highlight-code-line { + background-color: rgba(0, 0, 0, 0.3); +} diff --git a/website/versioned_docs/version-25.x/BypassingModuleMocks.md b/website/versioned_docs/version-25.x/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/website/versioned_docs/version-25.x/BypassingModuleMocks.md +++ b/website/versioned_docs/version-25.x/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/website/versioned_docs/version-25.x/CLI.md b/website/versioned_docs/version-25.x/CLI.md index 156a6f42681c..a6f3443d2017 100644 --- a/website/versioned_docs/version-25.x/CLI.md +++ b/website/versioned_docs/version-25.x/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -260,6 +264,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -286,12 +298,6 @@ Print your Jest config and then exits. Prevent tests from printing messages through the console. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -305,9 +311,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ ### `--testPathIgnorePatterns=|[array]` @@ -315,6 +323,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/website/versioned_docs/version-25.x/Configuration.md b/website/versioned_docs/version-25.x/Configuration.md index 55ab8e845024..f00bcb705ddd 100644 --- a/website/versioned_docs/version-25.x/Configuration.md +++ b/website/versioned_docs/version-25.x/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" /** @type {import('@jest/types').Config.InitialOptions} */ const config = { verbose: true, @@ -45,8 +44,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -71,8 +69,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -128,7 +125,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -369,9 +366,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -429,8 +424,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -438,8 +432,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -672,8 +665,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -710,7 +702,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -744,7 +736,7 @@ Note: the defaultResolver passed as an option is the Jest default resolver which Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -800,15 +792,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1147,8 +1137,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/website/versioned_docs/version-25.x/Es6ClassMocks.md b/website/versioned_docs/version-25.x/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/website/versioned_docs/version-25.x/Es6ClassMocks.md +++ b/website/versioned_docs/version-25.x/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/website/versioned_docs/version-25.x/GettingStarted.md b/website/versioned_docs/version-25.x/GettingStarted.md index fa317619a57b..423b1e4c42b6 100644 --- a/website/versioned_docs/version-25.x/GettingStarted.md +++ b/website/versioned_docs/version-25.x/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```js title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/website/versioned_docs/version-25.x/JestObjectAPI.md b/website/versioned_docs/version-25.x/JestObjectAPI.md index c13fa986bd6b..7726215cd7d8 100644 --- a/website/versioned_docs/version-25.x/JestObjectAPI.md +++ b/website/versioned_docs/version-25.x/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -98,8 +102,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -108,8 +111,7 @@ export default { }; ``` -```js -// __tests__/genMockFromModule.test.js +```js title="__tests__/genMockFromModule.test.js" const utils = jest.genMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -143,8 +145,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -174,8 +175,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.genMockFromModule('./example'); test('should run example code', () => { @@ -216,11 +216,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -447,7 +447,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -560,7 +560,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -574,7 +574,7 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +## Mock Timers ### `jest.useFakeTimers()` diff --git a/website/versioned_docs/version-25.x/JestPlatform.md b/website/versioned_docs/version-25.x/JestPlatform.md index 568b39317aa5..1cc478cbacc7 100644 --- a/website/versioned_docs/version-25.x/JestPlatform.md +++ b/website/versioned_docs/version-25.x/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `Worker` that takes th ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/website/versioned_docs/version-25.x/ManualMocks.md b/website/versioned_docs/version-25.x/ManualMocks.md index 2f58f0606375..9387ca82fc5a 100644 --- a/website/versioned_docs/version-25.x/ManualMocks.md +++ b/website/versioned_docs/version-25.x/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/website/versioned_docs/version-25.x/MockFunctionAPI.md b/website/versioned_docs/version-25.x/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/website/versioned_docs/version-25.x/MockFunctionAPI.md +++ b/website/versioned_docs/version-25.x/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/website/versioned_docs/version-25.x/MockFunctions.md b/website/versioned_docs/version-25.x/MockFunctions.md index 873dfff9462a..d583d55bdca8 100644 --- a/website/versioned_docs/version-25.x/MockFunctions.md +++ b/website/versioned_docs/version-25.x/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/website/versioned_docs/version-25.x/Puppeteer.md b/website/versioned_docs/version-25.x/Puppeteer.md index c0b92dfd97dd..65c78ff9faab 100644 --- a/website/versioned_docs/version-25.x/Puppeteer.md +++ b/website/versioned_docs/version-25.x/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/website/versioned_docs/version-25.x/SetupAndTeardown.md b/website/versioned_docs/version-25.x/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/website/versioned_docs/version-25.x/SetupAndTeardown.md +++ b/website/versioned_docs/version-25.x/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/website/versioned_docs/version-25.x/TimerMocks.md b/website/versioned_docs/version-25.x/TimerMocks.md index ff8a16ef988a..8086ccd10b8b 100644 --- a/website/versioned_docs/version-25.x/TimerMocks.md +++ b/website/versioned_docs/version-25.x/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -64,8 +62,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -85,8 +82,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -124,8 +120,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/website/versioned_docs/version-25.x/TutorialAsync.md b/website/versioned_docs/version-25.x/TutorialAsync.md index dd8a2da77977..0534aec12667 100644 --- a/website/versioned_docs/version-25.x/TutorialAsync.md +++ b/website/versioned_docs/version-25.x/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/website/versioned_docs/version-25.x/TutorialReact.md b/website/versioned_docs/version-25.x/TutorialReact.md index d6be521ae589..39d0eaa01018 100644 --- a/website/versioned_docs/version-25.x/TutorialReact.md +++ b/website/versioned_docs/version-25.x/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/website/versioned_docs/version-25.x/TutorialReactNative.md b/website/versioned_docs/version-25.x/TutorialReactNative.md index beabd0d09e2d..18b740a54290 100644 --- a/website/versioned_docs/version-25.x/TutorialReactNative.md +++ b/website/versioned_docs/version-25.x/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/website/versioned_docs/version-25.x/WatchPlugins.md b/website/versioned_docs/version-25.x/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/website/versioned_docs/version-25.x/WatchPlugins.md +++ b/website/versioned_docs/version-25.x/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/website/versioned_docs/version-25.x/Webpack.md b/website/versioned_docs/version-25.x/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/website/versioned_docs/version-25.x/Webpack.md +++ b/website/versioned_docs/version-25.x/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/website/versioned_docs/version-26.x/BypassingModuleMocks.md b/website/versioned_docs/version-26.x/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/website/versioned_docs/version-26.x/BypassingModuleMocks.md +++ b/website/versioned_docs/version-26.x/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/website/versioned_docs/version-26.x/CLI.md b/website/versioned_docs/version-26.x/CLI.md index 2d4c5fcf389c..ea113388ed19 100644 --- a/website/versioned_docs/version-26.x/CLI.md +++ b/website/versioned_docs/version-26.x/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -272,6 +276,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -280,16 +292,16 @@ A list of paths to directories that Jest should use to search for files in. Alias: `-i`. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. -### `--selectProjects ... ` - -Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. - ### `--runTestsByPath` Run only the tests that were specified with their exact paths. _Note: The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files_ +### `--selectProjects ... ` + +Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. + ### `--setupFilesAfterEnv ... ` A list of paths to modules that run some code to configure or to set up the testing framework before each test. Beware that files imported by the setup scripts will not be mocked during testing. @@ -302,12 +314,6 @@ Print your Jest config and then exits. Prevent tests from printing messages through the console. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -321,9 +327,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ ### `--testPathIgnorePatterns=|[array]` @@ -331,6 +339,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/website/versioned_docs/version-26.x/Configuration.md b/website/versioned_docs/version-26.x/Configuration.md index fdf5b8aaf8c9..0d8af958caa5 100644 --- a/website/versioned_docs/version-26.x/Configuration.md +++ b/website/versioned_docs/version-26.x/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" // Sync object /** @type {import('@jest/types').Config.InitialOptions} */ const config = { @@ -36,8 +35,7 @@ module.exports = async () => { Or through TypeScript (if `ts-node` is installed): -```ts -// jest.config.ts +```ts title="jest.config.ts" import type {Config} from '@jest/types'; // Sync object @@ -73,8 +71,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -99,8 +96,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -150,7 +146,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -387,9 +383,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -447,8 +441,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -456,8 +449,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -708,8 +700,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -746,7 +737,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -787,8 +778,7 @@ For example, if you want to respect Browserify's [`"browser"` field](https://git } ``` -```js -// resolver.js +```js title="resolver.js" const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; @@ -828,7 +818,7 @@ module.exports = (request, options) => { Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -884,15 +874,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1235,8 +1223,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/website/versioned_docs/version-26.x/Es6ClassMocks.md b/website/versioned_docs/version-26.x/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/website/versioned_docs/version-26.x/Es6ClassMocks.md +++ b/website/versioned_docs/version-26.x/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/website/versioned_docs/version-26.x/GettingStarted.md b/website/versioned_docs/version-26.x/GettingStarted.md index fa317619a57b..423b1e4c42b6 100644 --- a/website/versioned_docs/version-26.x/GettingStarted.md +++ b/website/versioned_docs/version-26.x/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```js title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/website/versioned_docs/version-26.x/JestObjectAPI.md b/website/versioned_docs/version-26.x/JestObjectAPI.md index e7d8808d33c8..c5adb411182a 100644 --- a/website/versioned_docs/version-26.x/JestObjectAPI.md +++ b/website/versioned_docs/version-26.x/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -102,8 +106,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -112,8 +115,7 @@ export default { }; ``` -```js -// __tests__/createMockFromModule.test.js +```js title="__tests__/createMockFromModule.test.js" const utils = jest.createMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -147,8 +149,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -178,8 +179,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.createMockFromModule('./example'); test('should run example code', () => { @@ -220,11 +220,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -451,7 +451,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -564,7 +564,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -578,7 +578,7 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +## Mock Timers ### `jest.useFakeTimers(implementation?: 'modern' | 'legacy')` diff --git a/website/versioned_docs/version-26.x/JestPlatform.md b/website/versioned_docs/version-26.x/JestPlatform.md index 3066711bc5e0..429b1172c8bb 100644 --- a/website/versioned_docs/version-26.x/JestPlatform.md +++ b/website/versioned_docs/version-26.x/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `JestWorker` that take ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/website/versioned_docs/version-26.x/ManualMocks.md b/website/versioned_docs/version-26.x/ManualMocks.md index d481a5712e49..178226d727f9 100644 --- a/website/versioned_docs/version-26.x/ManualMocks.md +++ b/website/versioned_docs/version-26.x/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/website/versioned_docs/version-26.x/MockFunctionAPI.md b/website/versioned_docs/version-26.x/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/website/versioned_docs/version-26.x/MockFunctionAPI.md +++ b/website/versioned_docs/version-26.x/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/website/versioned_docs/version-26.x/MockFunctions.md b/website/versioned_docs/version-26.x/MockFunctions.md index 873dfff9462a..d583d55bdca8 100644 --- a/website/versioned_docs/version-26.x/MockFunctions.md +++ b/website/versioned_docs/version-26.x/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/website/versioned_docs/version-26.x/Puppeteer.md b/website/versioned_docs/version-26.x/Puppeteer.md index c0b92dfd97dd..65c78ff9faab 100644 --- a/website/versioned_docs/version-26.x/Puppeteer.md +++ b/website/versioned_docs/version-26.x/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/website/versioned_docs/version-26.x/SetupAndTeardown.md b/website/versioned_docs/version-26.x/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/website/versioned_docs/version-26.x/SetupAndTeardown.md +++ b/website/versioned_docs/version-26.x/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/website/versioned_docs/version-26.x/TimerMocks.md b/website/versioned_docs/version-26.x/TimerMocks.md index ff8a16ef988a..8086ccd10b8b 100644 --- a/website/versioned_docs/version-26.x/TimerMocks.md +++ b/website/versioned_docs/version-26.x/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -64,8 +62,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -85,8 +82,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -124,8 +120,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/website/versioned_docs/version-26.x/TutorialAsync.md b/website/versioned_docs/version-26.x/TutorialAsync.md index dd8a2da77977..0534aec12667 100644 --- a/website/versioned_docs/version-26.x/TutorialAsync.md +++ b/website/versioned_docs/version-26.x/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/website/versioned_docs/version-26.x/TutorialReact.md b/website/versioned_docs/version-26.x/TutorialReact.md index d6be521ae589..39d0eaa01018 100644 --- a/website/versioned_docs/version-26.x/TutorialReact.md +++ b/website/versioned_docs/version-26.x/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/website/versioned_docs/version-26.x/TutorialReactNative.md b/website/versioned_docs/version-26.x/TutorialReactNative.md index beabd0d09e2d..18b740a54290 100644 --- a/website/versioned_docs/version-26.x/TutorialReactNative.md +++ b/website/versioned_docs/version-26.x/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/website/versioned_docs/version-26.x/WatchPlugins.md b/website/versioned_docs/version-26.x/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/website/versioned_docs/version-26.x/WatchPlugins.md +++ b/website/versioned_docs/version-26.x/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/website/versioned_docs/version-26.x/Webpack.md b/website/versioned_docs/version-26.x/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/website/versioned_docs/version-26.x/Webpack.md +++ b/website/versioned_docs/version-26.x/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/website/versioned_docs/version-27.0/BypassingModuleMocks.md b/website/versioned_docs/version-27.0/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/website/versioned_docs/version-27.0/BypassingModuleMocks.md +++ b/website/versioned_docs/version-27.0/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/website/versioned_docs/version-27.0/CLI.md b/website/versioned_docs/version-27.0/CLI.md index 437254712a87..58d2a91f09d3 100644 --- a/website/versioned_docs/version-27.0/CLI.md +++ b/website/versioned_docs/version-27.0/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -272,6 +276,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -280,16 +292,16 @@ A list of paths to directories that Jest should use to search for files in. Alias: `-i`. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. -### `--selectProjects ... ` - -Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. - ### `--runTestsByPath` Run only the tests that were specified with their exact paths. _Note: The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files_ +### `--selectProjects ... ` + +Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. + ### `--setupFilesAfterEnv ... ` A list of paths to modules that run some code to configure or to set up the testing framework before each test. Beware that files imported by the setup scripts will not be mocked during testing. @@ -302,12 +314,6 @@ Print your Jest config and then exits. Prevent tests from printing messages through the console. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -321,9 +327,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ ### `--testPathIgnorePatterns=|[array]` @@ -331,6 +339,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/website/versioned_docs/version-27.0/CodeTransformation.md b/website/versioned_docs/version-27.0/CodeTransformation.md index a7a71094f728..8da5d7a72bc8 100644 --- a/website/versioned_docs/version-27.0/CodeTransformation.md +++ b/website/versioned_docs/version-27.0/CodeTransformation.md @@ -19,12 +19,12 @@ If you override the `transform` configuration option `babel-jest` will no longer ## Writing custom transformers -You can write you own transformer. The API of a transformer is as follows: +You can write your own transformer. The API of a transformer is as follows: ```ts interface SyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -59,7 +59,7 @@ interface SyncTransformer { interface AsyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -120,11 +120,11 @@ type TransformedSource = | {code: string; map?: RawSourceMap | string | null} | string; -// Config.ProjectConfig can be seen in in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) +// Config.ProjectConfig can be seen in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) // RawSourceMap comes from [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12) ``` -As can be seen, only `process` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. +As can be seen, only `process` or `processAsync` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. 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. @@ -138,8 +138,7 @@ While `babel-jest` by default will transpile TypeScript files, Babel will not ve Importing images is a way to include them in your browser bundle, but they are not valid JavaScript. One way of handling it in Jest is to replace the imported value with its filename. -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -149,9 +148,7 @@ module.exports = { }; ``` -```js -// jest.config.js - +```js title="jest.config.js" module.exports = { transform: { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': diff --git a/website/versioned_docs/version-27.0/Configuration.md b/website/versioned_docs/version-27.0/Configuration.md index 6a3f6f66cb96..321b7e74d129 100644 --- a/website/versioned_docs/version-27.0/Configuration.md +++ b/website/versioned_docs/version-27.0/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" // Sync object /** @type {import('@jest/types').Config.InitialOptions} */ const config = { @@ -36,8 +35,7 @@ module.exports = async () => { Or through TypeScript (if `ts-node` is installed): -```ts -// jest.config.ts +```ts title="jest.config.ts" import type {Config} from '@jest/types'; // Sync object @@ -73,8 +71,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -99,8 +96,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -150,7 +146,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -404,9 +400,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -464,8 +458,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -473,8 +466,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -735,8 +727,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -773,7 +764,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -814,8 +805,7 @@ For example, if you want to respect Browserify's [`"browser"` field](https://git } ``` -```js -// resolver.js +```js title="resolver.js" const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; @@ -855,7 +845,7 @@ module.exports = (request, options) => { Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -911,15 +901,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1262,8 +1250,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/website/versioned_docs/version-27.0/Es6ClassMocks.md b/website/versioned_docs/version-27.0/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/website/versioned_docs/version-27.0/Es6ClassMocks.md +++ b/website/versioned_docs/version-27.0/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/website/versioned_docs/version-27.0/GettingStarted.md b/website/versioned_docs/version-27.0/GettingStarted.md index fa317619a57b..423b1e4c42b6 100644 --- a/website/versioned_docs/version-27.0/GettingStarted.md +++ b/website/versioned_docs/version-27.0/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```js title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/website/versioned_docs/version-27.0/JestObjectAPI.md b/website/versioned_docs/version-27.0/JestObjectAPI.md index 4f9c95cab35c..ddfd7fafea74 100644 --- a/website/versioned_docs/version-27.0/JestObjectAPI.md +++ b/website/versioned_docs/version-27.0/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -102,8 +106,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -112,8 +115,7 @@ export default { }; ``` -```js -// __tests__/createMockFromModule.test.js +```js title="__tests__/createMockFromModule.test.js" const utils = jest.createMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -147,8 +149,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -178,8 +179,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.createMockFromModule('./example'); test('should run example code', () => { @@ -220,11 +220,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -451,7 +451,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -564,7 +564,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -578,7 +578,7 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +## Mock Timers ### `jest.useFakeTimers(implementation?: 'modern' | 'legacy')` diff --git a/website/versioned_docs/version-27.0/JestPlatform.md b/website/versioned_docs/version-27.0/JestPlatform.md index 2273524221cd..7e638e040b63 100644 --- a/website/versioned_docs/version-27.0/JestPlatform.md +++ b/website/versioned_docs/version-27.0/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `JestWorker` that take ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/website/versioned_docs/version-27.0/ManualMocks.md b/website/versioned_docs/version-27.0/ManualMocks.md index d481a5712e49..178226d727f9 100644 --- a/website/versioned_docs/version-27.0/ManualMocks.md +++ b/website/versioned_docs/version-27.0/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/website/versioned_docs/version-27.0/MockFunctionAPI.md b/website/versioned_docs/version-27.0/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/website/versioned_docs/version-27.0/MockFunctionAPI.md +++ b/website/versioned_docs/version-27.0/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/website/versioned_docs/version-27.0/MockFunctions.md b/website/versioned_docs/version-27.0/MockFunctions.md index d6dc73b999aa..2e686a92e837 100644 --- a/website/versioned_docs/version-27.0/MockFunctions.md +++ b/website/versioned_docs/version-27.0/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/website/versioned_docs/version-27.0/Puppeteer.md b/website/versioned_docs/version-27.0/Puppeteer.md index 53c16767b74e..16ab669a9ab2 100644 --- a/website/versioned_docs/version-27.0/Puppeteer.md +++ b/website/versioned_docs/version-27.0/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/website/versioned_docs/version-27.0/SetupAndTeardown.md b/website/versioned_docs/version-27.0/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/website/versioned_docs/version-27.0/SetupAndTeardown.md +++ b/website/versioned_docs/version-27.0/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/website/versioned_docs/version-27.0/TimerMocks.md b/website/versioned_docs/version-27.0/TimerMocks.md index e97e2af97709..b053c1dbdfc9 100644 --- a/website/versioned_docs/version-27.0/TimerMocks.md +++ b/website/versioned_docs/version-27.0/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -82,8 +80,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -103,8 +100,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -140,8 +136,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/website/versioned_docs/version-27.0/TutorialAsync.md b/website/versioned_docs/version-27.0/TutorialAsync.md index f9418ad6651b..9c283074cabd 100644 --- a/website/versioned_docs/version-27.0/TutorialAsync.md +++ b/website/versioned_docs/version-27.0/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/website/versioned_docs/version-27.0/TutorialReact.md b/website/versioned_docs/version-27.0/TutorialReact.md index 7cce1e08cf10..5fcfa52a098b 100644 --- a/website/versioned_docs/version-27.0/TutorialReact.md +++ b/website/versioned_docs/version-27.0/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/website/versioned_docs/version-27.0/TutorialReactNative.md b/website/versioned_docs/version-27.0/TutorialReactNative.md index d89564980791..ddb60b230c31 100644 --- a/website/versioned_docs/version-27.0/TutorialReactNative.md +++ b/website/versioned_docs/version-27.0/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/website/versioned_docs/version-27.0/WatchPlugins.md b/website/versioned_docs/version-27.0/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/website/versioned_docs/version-27.0/WatchPlugins.md +++ b/website/versioned_docs/version-27.0/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/website/versioned_docs/version-27.0/Webpack.md b/website/versioned_docs/version-27.0/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/website/versioned_docs/version-27.0/Webpack.md +++ b/website/versioned_docs/version-27.0/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/website/versioned_docs/version-27.1/BypassingModuleMocks.md b/website/versioned_docs/version-27.1/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/website/versioned_docs/version-27.1/BypassingModuleMocks.md +++ b/website/versioned_docs/version-27.1/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/website/versioned_docs/version-27.1/CLI.md b/website/versioned_docs/version-27.1/CLI.md index 437254712a87..58d2a91f09d3 100644 --- a/website/versioned_docs/version-27.1/CLI.md +++ b/website/versioned_docs/version-27.1/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -272,6 +276,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -280,16 +292,16 @@ A list of paths to directories that Jest should use to search for files in. Alias: `-i`. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. -### `--selectProjects ... ` - -Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. - ### `--runTestsByPath` Run only the tests that were specified with their exact paths. _Note: The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files_ +### `--selectProjects ... ` + +Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. + ### `--setupFilesAfterEnv ... ` A list of paths to modules that run some code to configure or to set up the testing framework before each test. Beware that files imported by the setup scripts will not be mocked during testing. @@ -302,12 +314,6 @@ Print your Jest config and then exits. Prevent tests from printing messages through the console. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -321,9 +327,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ ### `--testPathIgnorePatterns=|[array]` @@ -331,6 +339,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/website/versioned_docs/version-27.1/CodeTransformation.md b/website/versioned_docs/version-27.1/CodeTransformation.md index a7a71094f728..8da5d7a72bc8 100644 --- a/website/versioned_docs/version-27.1/CodeTransformation.md +++ b/website/versioned_docs/version-27.1/CodeTransformation.md @@ -19,12 +19,12 @@ If you override the `transform` configuration option `babel-jest` will no longer ## Writing custom transformers -You can write you own transformer. The API of a transformer is as follows: +You can write your own transformer. The API of a transformer is as follows: ```ts interface SyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -59,7 +59,7 @@ interface SyncTransformer { interface AsyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -120,11 +120,11 @@ type TransformedSource = | {code: string; map?: RawSourceMap | string | null} | string; -// Config.ProjectConfig can be seen in in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) +// Config.ProjectConfig can be seen in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) // RawSourceMap comes from [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12) ``` -As can be seen, only `process` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. +As can be seen, only `process` or `processAsync` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. 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. @@ -138,8 +138,7 @@ While `babel-jest` by default will transpile TypeScript files, Babel will not ve Importing images is a way to include them in your browser bundle, but they are not valid JavaScript. One way of handling it in Jest is to replace the imported value with its filename. -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -149,9 +148,7 @@ module.exports = { }; ``` -```js -// jest.config.js - +```js title="jest.config.js" module.exports = { transform: { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': diff --git a/website/versioned_docs/version-27.1/Configuration.md b/website/versioned_docs/version-27.1/Configuration.md index 6e72e76cbb70..a5d110e3b1fc 100644 --- a/website/versioned_docs/version-27.1/Configuration.md +++ b/website/versioned_docs/version-27.1/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" // Sync object /** @type {import('@jest/types').Config.InitialOptions} */ const config = { @@ -36,8 +35,7 @@ module.exports = async () => { Or through TypeScript (if `ts-node` is installed): -```ts -// jest.config.ts +```ts title="jest.config.ts" import type {Config} from '@jest/types'; // Sync object @@ -73,8 +71,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -99,8 +96,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -150,7 +146,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -404,9 +400,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -464,8 +458,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -473,8 +466,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -735,8 +727,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -773,7 +764,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -814,8 +805,7 @@ For example, if you want to respect Browserify's [`"browser"` field](https://git } ``` -```js -// resolver.js +```js title="resolver.js" const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; @@ -855,7 +845,7 @@ module.exports = (request, options) => { Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -911,15 +901,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1297,8 +1285,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/website/versioned_docs/version-27.1/Es6ClassMocks.md b/website/versioned_docs/version-27.1/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/website/versioned_docs/version-27.1/Es6ClassMocks.md +++ b/website/versioned_docs/version-27.1/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/website/versioned_docs/version-27.1/GettingStarted.md b/website/versioned_docs/version-27.1/GettingStarted.md index fa317619a57b..423b1e4c42b6 100644 --- a/website/versioned_docs/version-27.1/GettingStarted.md +++ b/website/versioned_docs/version-27.1/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```js title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/website/versioned_docs/version-27.1/JestObjectAPI.md b/website/versioned_docs/version-27.1/JestObjectAPI.md index 4f9c95cab35c..ddfd7fafea74 100644 --- a/website/versioned_docs/version-27.1/JestObjectAPI.md +++ b/website/versioned_docs/version-27.1/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -102,8 +106,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -112,8 +115,7 @@ export default { }; ``` -```js -// __tests__/createMockFromModule.test.js +```js title="__tests__/createMockFromModule.test.js" const utils = jest.createMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -147,8 +149,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -178,8 +179,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.createMockFromModule('./example'); test('should run example code', () => { @@ -220,11 +220,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -451,7 +451,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -564,7 +564,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -578,7 +578,7 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +## Mock Timers ### `jest.useFakeTimers(implementation?: 'modern' | 'legacy')` diff --git a/website/versioned_docs/version-27.1/JestPlatform.md b/website/versioned_docs/version-27.1/JestPlatform.md index 2273524221cd..7e638e040b63 100644 --- a/website/versioned_docs/version-27.1/JestPlatform.md +++ b/website/versioned_docs/version-27.1/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `JestWorker` that take ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/website/versioned_docs/version-27.1/ManualMocks.md b/website/versioned_docs/version-27.1/ManualMocks.md index d481a5712e49..178226d727f9 100644 --- a/website/versioned_docs/version-27.1/ManualMocks.md +++ b/website/versioned_docs/version-27.1/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/website/versioned_docs/version-27.1/MockFunctionAPI.md b/website/versioned_docs/version-27.1/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/website/versioned_docs/version-27.1/MockFunctionAPI.md +++ b/website/versioned_docs/version-27.1/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/website/versioned_docs/version-27.1/MockFunctions.md b/website/versioned_docs/version-27.1/MockFunctions.md index d6dc73b999aa..2e686a92e837 100644 --- a/website/versioned_docs/version-27.1/MockFunctions.md +++ b/website/versioned_docs/version-27.1/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/website/versioned_docs/version-27.1/Puppeteer.md b/website/versioned_docs/version-27.1/Puppeteer.md index 53c16767b74e..16ab669a9ab2 100644 --- a/website/versioned_docs/version-27.1/Puppeteer.md +++ b/website/versioned_docs/version-27.1/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/website/versioned_docs/version-27.1/SetupAndTeardown.md b/website/versioned_docs/version-27.1/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/website/versioned_docs/version-27.1/SetupAndTeardown.md +++ b/website/versioned_docs/version-27.1/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/website/versioned_docs/version-27.1/TimerMocks.md b/website/versioned_docs/version-27.1/TimerMocks.md index e97e2af97709..b053c1dbdfc9 100644 --- a/website/versioned_docs/version-27.1/TimerMocks.md +++ b/website/versioned_docs/version-27.1/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -82,8 +80,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -103,8 +100,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -140,8 +136,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/website/versioned_docs/version-27.1/TutorialAsync.md b/website/versioned_docs/version-27.1/TutorialAsync.md index f9418ad6651b..9c283074cabd 100644 --- a/website/versioned_docs/version-27.1/TutorialAsync.md +++ b/website/versioned_docs/version-27.1/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/website/versioned_docs/version-27.1/TutorialReact.md b/website/versioned_docs/version-27.1/TutorialReact.md index 7cce1e08cf10..5fcfa52a098b 100644 --- a/website/versioned_docs/version-27.1/TutorialReact.md +++ b/website/versioned_docs/version-27.1/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/website/versioned_docs/version-27.1/TutorialReactNative.md b/website/versioned_docs/version-27.1/TutorialReactNative.md index d89564980791..ddb60b230c31 100644 --- a/website/versioned_docs/version-27.1/TutorialReactNative.md +++ b/website/versioned_docs/version-27.1/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/website/versioned_docs/version-27.1/WatchPlugins.md b/website/versioned_docs/version-27.1/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/website/versioned_docs/version-27.1/WatchPlugins.md +++ b/website/versioned_docs/version-27.1/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/website/versioned_docs/version-27.1/Webpack.md b/website/versioned_docs/version-27.1/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/website/versioned_docs/version-27.1/Webpack.md +++ b/website/versioned_docs/version-27.1/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/website/versioned_docs/version-27.2/BypassingModuleMocks.md b/website/versioned_docs/version-27.2/BypassingModuleMocks.md index 5e48a05b9fb4..96dfa7462016 100644 --- a/website/versioned_docs/version-27.2/BypassingModuleMocks.md +++ b/website/versioned_docs/version-27.2/BypassingModuleMocks.md @@ -7,8 +7,7 @@ Jest allows you to mock out whole modules in your tests, which can be useful for Consider writing a test case for this `createUser` function: -```javascript -// createUser.js +```javascript title="createUser.js" import fetch from 'node-fetch'; export const createUser = async () => { diff --git a/website/versioned_docs/version-27.2/CLI.md b/website/versioned_docs/version-27.2/CLI.md index e22c5df733e8..24c0f5993bdb 100644 --- a/website/versioned_docs/version-27.2/CLI.md +++ b/website/versioned_docs/version-27.2/CLI.md @@ -138,6 +138,10 @@ When this option is provided, Jest will assume it is running in a CI environment Deletes the Jest cache directory and then exits without running tests. Will delete `cacheDirectory` if the option is passed, or Jest's default cache directory. The default cache directory can be found by calling `jest --showConfig`. _Note: clearing the cache will reduce performance._ +### `--clearMocks` + +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. + ### `--collectCoverageFrom=` A glob pattern relative to `rootDir` matching the files that coverage info needs to be collected from. @@ -272,6 +276,14 @@ Run tests with specified reporters. [Reporter options](configuration#reporters-a `jest --reporters="default" --reporters="jest-junit"` +### `--resetMocks` + +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. + +### `--restoreMocks` + +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. + ### `--roots` A list of paths to directories that Jest should use to search for files in. @@ -280,16 +292,16 @@ A list of paths to directories that Jest should use to search for files in. Alias: `-i`. Run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. This can be useful for debugging. -### `--selectProjects ... ` - -Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. - ### `--runTestsByPath` Run only the tests that were specified with their exact paths. _Note: The default regex matching works fine on small runs, but becomes slow if provided with multiple patterns and/or against a lot of tests. This option replaces the regex matching logic and by that optimizes the time it takes Jest to filter specific test files_ +### `--selectProjects ... ` + +Run only the tests of the specified projects. Jest uses the attribute `displayName` in the configuration to identify each project. If you use this option, you should provide a `displayName` to all your projects. + ### `--setupFilesAfterEnv ... ` A list of paths to modules that run some code to configure or to set up the testing framework before each test. Beware that files imported by the setup scripts will not be mocked during testing. @@ -306,12 +318,6 @@ Prevent tests from printing messages through the console. A JSON string with options that will be passed to the `testEnvironment`. The relevant options depend on the environment. -### `--testNamePattern=` - -Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. - -_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ - ### `--testLocationInResults` Adds a `location` field to test results. Useful if you want to report the location of a test in a reporter. @@ -325,9 +331,11 @@ Note that `column` is 0-indexed while `line` is not. } ``` -### `--testPathPattern=` +### `--testNamePattern=` -A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. +Alias: `-t`. Run only tests with a name that matches the regex. For example, suppose you want to run only tests related to authorization which will have names like `"GET /api/posts with auth"`, then you can use `jest -t=auth`. + +_Note: The regex is matched against the full name, which is a combination of the test name and all its surrounding describe blocks._ ### `--testPathIgnorePatterns=|[array]` @@ -335,6 +343,10 @@ A single or array of regexp pattern strings that are tested against all tests pa To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. +### `--testPathPattern=` + +A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. + ### `--testRunner=` Lets you specify a custom test runner. diff --git a/website/versioned_docs/version-27.2/CodeTransformation.md b/website/versioned_docs/version-27.2/CodeTransformation.md index a7a71094f728..8da5d7a72bc8 100644 --- a/website/versioned_docs/version-27.2/CodeTransformation.md +++ b/website/versioned_docs/version-27.2/CodeTransformation.md @@ -19,12 +19,12 @@ If you override the `transform` configuration option `babel-jest` will no longer ## Writing custom transformers -You can write you own transformer. The API of a transformer is as follows: +You can write your own transformer. The API of a transformer is as follows: ```ts interface SyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -59,7 +59,7 @@ interface SyncTransformer { interface AsyncTransformer { /** - * Indicates if the transformer is capabale of instrumenting the code for code coverage. + * Indicates if the transformer is capable of instrumenting the code for code coverage. * * If V8 coverage is _not_ active, and this is `true`, Jest will assume the code is instrumented. * If V8 coverage is _not_ active, and this is `false`. Jest will instrument the code returned by this transformer using Babel. @@ -120,11 +120,11 @@ type TransformedSource = | {code: string; map?: RawSourceMap | string | null} | string; -// Config.ProjectConfig can be seen in in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) +// Config.ProjectConfig can be seen in code [here](https://github.com/facebook/jest/blob/v26.6.3/packages/jest-types/src/Config.ts#L323) // RawSourceMap comes from [`source-map`](https://github.com/mozilla/source-map/blob/0.6.1/source-map.d.ts#L6-L12) ``` -As can be seen, only `process` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. +As can be seen, only `process` or `processAsync` is mandatory to implement, although we highly recommend implementing `getCacheKey` as well, so we don't waste resources transpiling the same source file when we can read its previous result from disk. You can use [`@jest/create-cache-key-function`](https://www.npmjs.com/package/@jest/create-cache-key-function) to help implement it. 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. @@ -138,8 +138,7 @@ While `babel-jest` by default will transpile TypeScript files, Babel will not ve Importing images is a way to include them in your browser bundle, but they are not valid JavaScript. One way of handling it in Jest is to replace the imported value with its filename. -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -149,9 +148,7 @@ module.exports = { }; ``` -```js -// jest.config.js - +```js title="jest.config.js" module.exports = { transform: { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': diff --git a/website/versioned_docs/version-27.2/Configuration.md b/website/versioned_docs/version-27.2/Configuration.md index d5c9bc73328c..95aa2affc193 100644 --- a/website/versioned_docs/version-27.2/Configuration.md +++ b/website/versioned_docs/version-27.2/Configuration.md @@ -16,8 +16,7 @@ Jest's configuration can be defined in the `package.json` file of your project, Or through JavaScript: -```js -// jest.config.js +```js title="jest.config.js" // Sync object /** @type {import('@jest/types').Config.InitialOptions} */ const config = { @@ -36,8 +35,7 @@ module.exports = async () => { Or through TypeScript (if `ts-node` is installed): -```ts -// jest.config.ts +```ts title="jest.config.ts" import type {Config} from '@jest/types'; // Sync object @@ -73,8 +71,7 @@ These options let you control Jest's behavior in your `package.json` file. The J You can retrieve Jest's default options to expand them if needed: -```js -// jest.config.js +```js title="jest.config.js" const {defaults} = require('jest-config'); module.exports = { // ... @@ -99,8 +96,7 @@ This option tells Jest that all imported modules in your tests should be mocked Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -150,7 +146,7 @@ Jest attempts to scan your dependency tree once (up-front) and cache it in order Default: `false` -Automatically clear mock calls and instances before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. +Automatically clear mock calls, instances and results before every test. Equivalent to calling [`jest.clearAllMocks()`](JestObjectAPI.md#jestclearallmocks) before each test. This does not remove any mock implementation that may have been provided. ### `collectCoverage` \[boolean] @@ -404,9 +400,7 @@ Test files are normally ignored from collecting code coverage. With this option, For example, if you have tests in source files named with `.t.js` extension as following: -```javascript -// sum.t.js - +```javascript title="sum.t.js" export function sum(a, b) { return a + b; } @@ -464,8 +458,7 @@ _Note: While code transformation is applied to the linked setup-file, Jest will Example: -```js -// setup.js +```js title="setup.js" module.exports = async () => { // ... // Set reference to mongod in order to close the server during teardown. @@ -473,8 +466,7 @@ module.exports = async () => { }; ``` -```js -// teardown.js +```js title="teardown.js" module.exports = async function () { await global.__MONGOD__.stop(); }; @@ -735,8 +727,7 @@ Custom reporter modules must define a class that takes a `GlobalConfig` and repo Example reporter: -```js -// my-custom-reporter.js +```js title="my-custom-reporter.js" class MyCustomReporter { constructor(globalConfig, options) { this._globalConfig = globalConfig; @@ -773,7 +764,7 @@ For the full list of methods and argument types see `Reporter` interface in [pac Default: `false` -Automatically reset mock state before every test. Equivalent to calling `jest.resetAllMocks()` before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. +Automatically reset mock state before every test. Equivalent to calling [`jest.resetAllMocks()`](JestObjectAPI.md#jestresetallmocks) before each test. This will lead to any mocks having their fake implementations removed but does not restore their initial implementation. ### `resetModules` \[boolean] @@ -816,8 +807,7 @@ For example, if you want to respect Browserify's [`"browser"` field](https://git } ``` -```js -// resolver.js +```js title="resolver.js" const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; @@ -859,7 +849,7 @@ While Jest does not support [package `exports`](https://nodejs.org/api/packages. Default: `false` -Automatically restore mock state before every test. Equivalent to calling `jest.restoreAllMocks()` before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. +Automatically restore mock state and implementation before every test. Equivalent to calling [`jest.restoreAllMocks()`](JestObjectAPI.md#jestrestoreallmocks) before each test. This will lead to any mocks having their fake implementations removed and restores their initial implementation. ### `rootDir` \[string] @@ -915,15 +905,13 @@ If you need to restrict your test-runner to only run in serial rather than being Default: `[]` -A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment immediately before executing the test code itself. - -It's also worth noting that `setupFiles` will execute _before_ [`setupFilesAfterEnv`](#setupfilesafterenv-array). +A list of paths to modules that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing [`setupFilesAfterEnv`](#setupfilesafterenv-array) and before the test code itself. ### `setupFilesAfterEnv` \[array] Default: `[]` -A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment. +A list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed. Since [`setupFiles`](#setupfiles-array) executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself. If you want a path to be [relative to the root directory of your project](#rootdir-string), please include `` inside a path's string, like `"/a-configs-folder"`. @@ -1301,8 +1289,7 @@ Example: Sort test path alphabetically. -```js -// testSequencer.js +```js title="testSequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { diff --git a/website/versioned_docs/version-27.2/Es6ClassMocks.md b/website/versioned_docs/version-27.2/Es6ClassMocks.md index 334e98a8a83f..37d26d744624 100644 --- a/website/versioned_docs/version-27.2/Es6ClassMocks.md +++ b/website/versioned_docs/version-27.2/Es6ClassMocks.md @@ -11,8 +11,7 @@ ES6 classes are constructor functions with some syntactic sugar. Therefore, any We'll use a contrived example of a class that plays sound files, `SoundPlayer`, and a consumer class which uses that class, `SoundPlayerConsumer`. We'll mock `SoundPlayer` in our tests for `SoundPlayerConsumer`. -```javascript -// sound-player.js +```javascript title="sound-player.js" export default class SoundPlayer { constructor() { this.foo = 'bar'; @@ -24,8 +23,7 @@ export default class SoundPlayer { } ``` -```javascript -// sound-player-consumer.js +```javascript title="sound-player-consumer.js" import SoundPlayer from './sound-player'; export default class SoundPlayerConsumer { @@ -90,9 +88,7 @@ it('We can check if the consumer called a method on the class instance', () => { Create a [manual mock](ManualMocks.md) by saving a mock implementation in the `__mocks__` folder. This allows you to specify the implementation, and it can be used across test files. -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file: export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -104,8 +100,7 @@ export default mock; Import the mock and the mock method shared by all instances: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer, {mockPlaySoundFile} from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor @@ -198,8 +193,7 @@ If you define an ES6 class using the same filename as the mocked class in the `_ For the contrived example, the mock might look like this: -```javascript -// __mocks__/sound-player.js +```javascript title="__mocks__/sound-player.js" export default class SoundPlayer { constructor() { console.log('Mock SoundPlayer: constructor was called'); @@ -297,9 +291,7 @@ jest.mock('./sound-player', () => { The manual mock equivalent of this would be: -```javascript -// __mocks__/sound-player.js - +```javascript title="__mocks__/sound-player.js" // Import this named export into your test file export const mockPlaySoundFile = jest.fn(); const mock = jest.fn().mockImplementation(() => { @@ -326,8 +318,7 @@ beforeEach(() => { Here's a complete test file which uses the module factory parameter to `jest.mock`: -```javascript -// sound-player-consumer.test.js +```javascript title="sound-player-consumer.test.js" import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; diff --git a/website/versioned_docs/version-27.2/GettingStarted.md b/website/versioned_docs/version-27.2/GettingStarted.md index fa317619a57b..423b1e4c42b6 100644 --- a/website/versioned_docs/version-27.2/GettingStarted.md +++ b/website/versioned_docs/version-27.2/GettingStarted.md @@ -89,8 +89,7 @@ yarn add --dev babel-jest @babel/core @babel/preset-env Configure Babel to target your current version of Node by creating a `babel.config.js` file in the root of your project: -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = { presets: [['@babel/preset-env', {targets: {node: 'current'}}]], }; @@ -102,8 +101,7 @@ _The ideal configuration for Babel will depend on your project._ See [Babel's do Jest will set `process.env.NODE_ENV` to `'test'` if it's not set to something else. You can use that in your configuration to conditionally setup only the compilation needed for Jest, e.g. -```javascript -// babel.config.js +```javascript title="babel.config.js" module.exports = api => { const isTest = api.env('test'); // You can use isTest to determine what presets and plugins to use. @@ -116,8 +114,7 @@ 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: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { transform: {}, }; @@ -148,7 +145,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana ### Using parcel -Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/getting_started.html) to get started. +Jest can be used in projects that use [parcel-bundler](https://parceljs.org/) to manage assets, styles, and compilation similar to webpack. Parcel requires zero configuration. Refer to the official [docs](https://parceljs.org/docs/) to get started. ### Using TypeScript @@ -160,12 +157,12 @@ yarn add --dev @babel/preset-typescript Then add `@babel/preset-typescript` to the list of presets in your `babel.config.js`. -```diff -// babel.config.js +```js title="babel.config.js" module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], -+ '@babel/preset-typescript', + // highlight-next-line + '@babel/preset-typescript', ], }; ``` diff --git a/website/versioned_docs/version-27.2/JestObjectAPI.md b/website/versioned_docs/version-27.2/JestObjectAPI.md index 4f9c95cab35c..ddfd7fafea74 100644 --- a/website/versioned_docs/version-27.2/JestObjectAPI.md +++ b/website/versioned_docs/version-27.2/JestObjectAPI.md @@ -5,6 +5,14 @@ title: The Jest Object The `jest` object is automatically in scope within every test file. The methods in the `jest` object help create mocks and let you control Jest's overall behavior. It can also be imported explicitly by via `import {jest} from '@jest/globals'`. +## Methods + +import TOCInline from "@theme/TOCInline" + + + +--- + ## Mock Modules ### `jest.disableAutomock()` @@ -25,8 +33,7 @@ Jest configuration: Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -34,8 +41,7 @@ export default { }; ``` -```js -// __tests__/disableAutomocking.js +```js title="__tests__/disableAutomocking.js" import utils from '../utils'; jest.disableAutomock(); @@ -65,8 +71,7 @@ Returns the `jest` object for chaining. Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -75,8 +80,7 @@ export default { }; ``` -```js -// __tests__/enableAutomocking.js +```js title="__tests__/enableAutomocking.js" jest.enableAutomock(); import utils from '../utils'; @@ -102,8 +106,7 @@ This is useful when you want to create a [manual mock](ManualMocks.md) that exte Example: -```js -// utils.js +```js title="utils.js" export default { authorize: () => { return 'token'; @@ -112,8 +115,7 @@ export default { }; ``` -```js -// __tests__/createMockFromModule.test.js +```js title="__tests__/createMockFromModule.test.js" const utils = jest.createMockFromModule('../utils').default; utils.isAuthorized = jest.fn(secret => secret === 'not wizard'); @@ -147,8 +149,7 @@ Creates a new property with the same primitive value as the original property. Example: -```js -// example.js +```js title="example.js" module.exports = { function: function square(a, b) { return a * b; @@ -178,8 +179,7 @@ module.exports = { }; ``` -```js -// __tests__/example.test.js +```js title="__tests__/example.test.js" const example = jest.createMockFromModule('./example'); test('should run example code', () => { @@ -220,11 +220,11 @@ test('should run example code', () => { Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example: -```js -// banana.js +```js title="banana.js" module.exports = () => 'banana'; +``` -// __tests__/test.js +```js title="__tests__/test.js" jest.mock('../banana'); const banana = require('../banana'); // banana will be explicitly mocked. @@ -451,7 +451,7 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` -## Mock functions +## Mock Functions ### `jest.fn(implementation)` @@ -564,7 +564,7 @@ test('plays audio', () => { ### `jest.clearAllMocks()` -Clears the `mock.calls` and `mock.instances` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. +Clears the `mock.calls`, `mock.instances` and `mock.results` properties of all mocks. Equivalent to calling [`.mockClear()`](MockFunctionAPI.md#mockfnmockclear) on every mocked function. Returns the `jest` object for chaining. @@ -578,7 +578,7 @@ Returns the `jest` object for chaining. Restores all mocks back to their original value. Equivalent to calling [`.mockRestore()`](MockFunctionAPI.md#mockfnmockrestore) on every mocked function. Beware that `jest.restoreAllMocks()` only works when the mock was created with `jest.spyOn`; other mocks will require you to manually restore them. -## Mock timers +## Mock Timers ### `jest.useFakeTimers(implementation?: 'modern' | 'legacy')` diff --git a/website/versioned_docs/version-27.2/JestPlatform.md b/website/versioned_docs/version-27.2/JestPlatform.md index 2273524221cd..7e638e040b63 100644 --- a/website/versioned_docs/version-27.2/JestPlatform.md +++ b/website/versioned_docs/version-27.2/JestPlatform.md @@ -123,9 +123,7 @@ Module used for parallelization of tasks. Exports a class `JestWorker` that take ### Example -```javascript -// heavy-task.js - +```javascript title="heavy-task.js" module.exports = { myHeavyTask: args => { // long running CPU intensive task. @@ -133,9 +131,7 @@ module.exports = { }; ``` -```javascript -// main.js - +```javascript title="main.js" async function main() { const worker = new Worker(require.resolve('./heavy-task.js')); diff --git a/website/versioned_docs/version-27.2/ManualMocks.md b/website/versioned_docs/version-27.2/ManualMocks.md index d481a5712e49..178226d727f9 100644 --- a/website/versioned_docs/version-27.2/ManualMocks.md +++ b/website/versioned_docs/version-27.2/ManualMocks.md @@ -40,8 +40,7 @@ When a manual mock exists for a given module, Jest's module system will use that 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. -```javascript -// FileSummarizer.js +```javascript title="FileSummarizer.js" 'use strict'; const fs = require('fs'); @@ -58,8 +57,7 @@ exports.summarizeFilesInDirectorySync = summarizeFilesInDirectorySync; Since we'd like our tests to avoid actually hitting the disk (that's pretty slow and fragile), we create a manual mock for the `fs` module by extending an automatic mock. Our manual mock will implement custom versions of the `fs` APIs that we can build on for our tests: -```javascript -// __mocks__/fs.js +```javascript title="__mocks__/fs.js" 'use strict'; const path = require('path'); @@ -96,8 +94,7 @@ 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: -```javascript -// __tests__/FileSummarizer-test.js +```javascript title="__tests__/FileSummarizer-test.js" 'use strict'; jest.mock('fs'); diff --git a/website/versioned_docs/version-27.2/MockFunctionAPI.md b/website/versioned_docs/version-27.2/MockFunctionAPI.md index 6010aaf573f6..859adfc21361 100644 --- a/website/versioned_docs/version-27.2/MockFunctionAPI.md +++ b/website/versioned_docs/version-27.2/MockFunctionAPI.md @@ -81,13 +81,11 @@ mockFn.mock.instances[1] === b; // true ### `mockFn.mockClear()` -Resets all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances) arrays. +Clears all information stored in the [`mockFn.mock.calls`](#mockfnmockcalls), [`mockFn.mock.instances`](#mockfnmockinstances) and [`mockFn.mock.results`](#mockfnmockresults) arrays. Often this is useful when you want to clean up a mocks usage data between two assertions. -Often this is useful when you want to clean up a mocks usage data between two assertions. +Beware that `mockClear` will replace `mockFn.mock`, not just these three properties! You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. -Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. - -The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically between tests. +The [`clearMocks`](configuration#clearmocks-boolean) configuration option is available to clear mocks automatically before each tests. ### `mockFn.mockReset()` @@ -95,7 +93,7 @@ Does everything that [`mockFn.mockClear()`](#mockfnmockclear) does, and also rem This is useful when you want to completely reset a _mock_ back to its initial state. (Note that resetting a _spy_ will result in a function with no return value). -Beware that `mockReset` will replace `mockFn.mock`, not just [`mockFn.mock.calls`](#mockfnmockcalls) and [`mockFn.mock.instances`](#mockfnmockinstances). You should, therefore, avoid assigning `mockFn.mock` to other variables, temporary or not, to make sure you don't access stale data. +The [`mockReset`](configuration#resetmocks-boolean) configuration option is available to reset mocks automatically before each test. ### `mockFn.mockRestore()` @@ -105,7 +103,7 @@ This is useful when you want to mock functions in certain test cases and restore Beware that `mockFn.mockRestore` only works when the mock was created with `jest.spyOn`. Thus you have to take care of restoration yourself when manually assigning `jest.fn()`. -The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically between tests. +The [`restoreMocks`](configuration#restoremocks-boolean) configuration option is available to restore mocks automatically before each test. ### `mockFn.mockImplementation(fn)` @@ -131,13 +129,13 @@ mockFn.mock.calls[1][0] === 1; // true `mockImplementation` can also be used to mock class constructors: -```js -// SomeClass.js +```js title="SomeClass.js" module.exports = class SomeClass { m(a, b) {} }; +``` -// OtherModule.test.js +```js title="OtherModule.test.js" jest.mock('./SomeClass'); // this happens automatically with automocking const SomeClass = require('./SomeClass'); const mMock = jest.fn(); diff --git a/website/versioned_docs/version-27.2/MockFunctions.md b/website/versioned_docs/version-27.2/MockFunctions.md index d6dc73b999aa..2e686a92e837 100644 --- a/website/versioned_docs/version-27.2/MockFunctions.md +++ b/website/versioned_docs/version-27.2/MockFunctions.md @@ -115,8 +115,7 @@ Most real-world examples actually involve getting ahold of a mock function on a Suppose we have a class that fetches users from our API. The class uses [axios](https://github.com/axios/axios) to call the API then returns the `data` attribute which contains all the users: -```js -// users.js +```js title="users.js" import axios from 'axios'; class Users { @@ -132,8 +131,7 @@ Now, in order to test this method without actually hitting the API (and thus cre Once we mock the module we can provide a `mockResolvedValue` for `.get` that returns the data we want our test to assert against. In effect, we are saying that we want `axios.get('/users.json')` to return a fake response. -```js -// users.test.js +```js title="users.test.js" import axios from 'axios'; import Users from './users'; @@ -155,8 +153,7 @@ test('should fetch users', () => { Subsets of a module can be mocked and the rest of the module can keep their actual implementation: -```js -// foo-bar-baz.js +```js title="foo-bar-baz.js" export const foo = 'foo'; export const bar = () => 'bar'; export default () => 'baz'; @@ -201,13 +198,13 @@ myMockFn((err, val) => console.log(val)); The `mockImplementation` method is useful when you need to define the default implementation of a mock function that is created from another module: -```js -// foo.js +```js title="foo.js" module.exports = function () { // some implementation; }; +``` -// test.js +```js title="test.js" jest.mock('../foo'); // this happens automatically with automocking const foo = require('../foo'); diff --git a/website/versioned_docs/version-27.2/Puppeteer.md b/website/versioned_docs/version-27.2/Puppeteer.md index 53c16767b74e..16ab669a9ab2 100644 --- a/website/versioned_docs/version-27.2/Puppeteer.md +++ b/website/versioned_docs/version-27.2/Puppeteer.md @@ -53,8 +53,7 @@ You can also hook up puppeteer from scratch. The basic idea is to: Here's an example of the GlobalSetup script -```js -// setup.js +```js title="setup.js" const {mkdir, writeFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -76,8 +75,7 @@ module.exports = async function () { Then we need a custom Test Environment for puppeteer -```js -// puppeteer_environment.js +```js title="puppeteer_environment.js" const {readFile} = require('fs').promises; const os = require('os'); const path = require('path'); @@ -119,8 +117,7 @@ module.exports = PuppeteerEnvironment; Finally, we can close the puppeteer instance and clean-up the file -```js -// teardown.js +```js title="teardown.js" const fs = require('fs').promises; const os = require('os'); const path = require('path'); @@ -137,8 +134,7 @@ module.exports = async function () { With all the things set up, we can now write our tests like this: -```js -// test.js +```js title="test.js" const timeout = 5000; describe( diff --git a/website/versioned_docs/version-27.2/SetupAndTeardown.md b/website/versioned_docs/version-27.2/SetupAndTeardown.md index 464e9ecccab0..131376d0de6f 100644 --- a/website/versioned_docs/version-27.2/SetupAndTeardown.md +++ b/website/versioned_docs/version-27.2/SetupAndTeardown.md @@ -63,7 +63,7 @@ test('city database has San Juan', () => { ## Scoping -By default, the `before` and `after` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `before` and `after` blocks only apply to the tests within that `describe` block. +By default, the `beforeAll` and `afterAll` blocks apply to every test in a file. You can also group tests together using a `describe` block. When they are inside a `describe` block, the `beforeAll` and `afterAll` blocks only apply to the tests within that `describe` block. For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests: diff --git a/website/versioned_docs/version-27.2/TimerMocks.md b/website/versioned_docs/version-27.2/TimerMocks.md index e97e2af97709..b053c1dbdfc9 100644 --- a/website/versioned_docs/version-27.2/TimerMocks.md +++ b/website/versioned_docs/version-27.2/TimerMocks.md @@ -5,8 +5,7 @@ title: Timer Mocks The native timer functions (i.e., `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`) are less than ideal for a testing environment since they depend on real time to elapse. Jest can swap out timers with functions that allow you to control the passage of time. [Great Scott!](https://www.youtube.com/watch?v=QZoJ2Pt27BY) -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { @@ -20,8 +19,7 @@ function timerGame(callback) { module.exports = timerGame; ``` -```javascript -// __tests__/timerGame-test.js +```javascript title="__tests__/timerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -82,8 +80,7 @@ test('calls the callback after 1 second', () => { There are also scenarios where you might have a recursive timer -- that is a timer that sets a new timer in its own callback. For these, running all the timers would be an endless loop… so something like `jest.runAllTimers()` is not desirable. For these cases you might use `jest.runOnlyPendingTimers()`: -```javascript -// infiniteTimerGame.js +```javascript title="infiniteTimerGame.js" 'use strict'; function infiniteTimerGame(callback) { @@ -103,8 +100,7 @@ function infiniteTimerGame(callback) { module.exports = infiniteTimerGame; ``` -```javascript -// __tests__/infiniteTimerGame-test.js +```javascript title="__tests__/infiniteTimerGame-test.js" 'use strict'; jest.useFakeTimers(); @@ -140,8 +136,7 @@ describe('infiniteTimerGame', () => { Another possibility is use `jest.advanceTimersByTime(msToRun)`. When this API is called, all timers are advanced by `msToRun` milliseconds. All pending "macro-tasks" that have been queued via setTimeout() or setInterval(), and would be executed during this time frame, will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue that should be run within msToRun milliseconds. -```javascript -// timerGame.js +```javascript title="timerGame.js" 'use strict'; function timerGame(callback) { diff --git a/website/versioned_docs/version-27.2/TutorialAsync.md b/website/versioned_docs/version-27.2/TutorialAsync.md index f9418ad6651b..9c283074cabd 100644 --- a/website/versioned_docs/version-27.2/TutorialAsync.md +++ b/website/versioned_docs/version-27.2/TutorialAsync.md @@ -7,8 +7,7 @@ First, enable Babel support in Jest as documented in the [Getting Started](Getti Let's implement a module that fetches user data from an API and returns the user name. -```js -// user.js +```js title="user.js" import request from './request'; export function getUserName(userID) { @@ -20,8 +19,7 @@ In the above implementation, we expect the `request.js` module to return a promi Now imagine an implementation of `request.js` that goes to the network and fetches some user data: -```js -// request.js +```js title="request.js" const http = require('http'); export default function request(url) { @@ -40,8 +38,7 @@ export default function request(url) { Because we don't want to go to the network in our test, we are going to create a manual mock for our `request.js` module in the `__mocks__` folder (the folder is case-sensitive, `__MOCKS__` will not work). It could look something like this: -```js -// __mocks__/request.js +```js title="__mocks__/request.js" const users = { 4: {name: 'Mark'}, 5: {name: 'Paul'}, @@ -63,8 +60,7 @@ export default function request(url) { Now let's write a test for our async functionality. -```js -// __tests__/user-test.js +```js title="__tests__/user-test.js" jest.mock('../request'); import * as user from '../user'; diff --git a/website/versioned_docs/version-27.2/TutorialReact.md b/website/versioned_docs/version-27.2/TutorialReact.md index 7cce1e08cf10..5fcfa52a098b 100644 --- a/website/versioned_docs/version-27.2/TutorialReact.md +++ b/website/versioned_docs/version-27.2/TutorialReact.md @@ -46,8 +46,7 @@ Your `package.json` should look something like this (where `` i } ``` -```js -// babel.config.js +```js title="babel.config.js" module.exports = { presets: ['@babel/preset-env', '@babel/preset-react'], }; @@ -59,8 +58,7 @@ module.exports = { Let's create a [snapshot test](SnapshotTesting.md) for a Link component that renders hyperlinks: -```tsx -// Link.react.js +```tsx title="Link.react.js" import React, {useState} from 'react'; const STATUS = { @@ -98,8 +96,7 @@ export default Link; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// Link.react.test.js +```tsx title="Link.react.test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Link from '../Link.react'; @@ -127,8 +124,7 @@ test('Link changes the class when hovered', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Link.react.test.js.snap +```javascript title="__tests__/__snapshots__/Link.react.test.js.snap" exports[`Link changes the class when hovered 1`] = ` { @@ -230,8 +225,7 @@ const CheckboxWithLabel = ({labelOn, labelOff}) => { export default CheckboxWithLabel; ``` -```tsx -// __tests__/CheckboxWithLabel-test.js +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {cleanup, fireEvent, render} from '@testing-library/react'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -261,9 +255,7 @@ You have to run `yarn add --dev enzyme` to use Enzyme. If you are using a React Let's rewrite the test from above using Enzyme instead of react-testing-library. We use Enzyme's [shallow renderer](http://airbnb.io/enzyme/docs/api/shallow.html) in this example. -```tsx -// __tests__/CheckboxWithLabel-test.js - +```tsx title="__tests__/CheckboxWithLabel-test.js" import React from 'react'; import {shallow} from 'enzyme'; import CheckboxWithLabel from '../CheckboxWithLabel'; @@ -286,8 +278,7 @@ The code for this example is available at [examples/enzyme](https://github.com/f If you need more advanced functionality, you can also build your own transformer. Instead of using `babel-jest`, here is an example of using `@babel/core`: -```javascript -// custom-transformer.js +```javascript title="custom-transformer.js" 'use strict'; const {transform} = require('@babel/core'); diff --git a/website/versioned_docs/version-27.2/TutorialReactNative.md b/website/versioned_docs/version-27.2/TutorialReactNative.md index d89564980791..ddb60b230c31 100644 --- a/website/versioned_docs/version-27.2/TutorialReactNative.md +++ b/website/versioned_docs/version-27.2/TutorialReactNative.md @@ -30,8 +30,7 @@ Run `yarn test` to run tests with Jest. Let's create a [snapshot test](SnapshotTesting.md) for a small intro component with a few views and text components and some styles: -```tsx -// Intro.js +```tsx title="Intro.js" import React, {Component} from 'react'; import {StyleSheet, Text, View} from 'react-native'; @@ -72,8 +71,7 @@ export default Intro; Now let's use React's test renderer and Jest's snapshot feature to interact with the component and capture the rendered output and create a snapshot file: -```tsx -// __tests__/Intro-test.js +```tsx title="__tests__/Intro-test.js" import React from 'react'; import renderer from 'react-test-renderer'; import Intro from '../Intro'; @@ -86,8 +84,7 @@ test('renders correctly', () => { When you run `yarn test` or `jest`, this will produce an output file like this: -```javascript -// __tests__/__snapshots__/Intro-test.js.snap +```javascript title="__tests__/__snapshots__/Intro-test.js.snap" exports[`Intro renders correctly 1`] = ` { Again, we create a test file in the `__tests__/` folder: -```javascript -// __tests__/displayUser-test.js +```javascript title="__tests__/displayUser-test.js" 'use strict'; jest.mock('../fetchCurrentUser'); diff --git a/website/versioned_docs/version-27.2/WatchPlugins.md b/website/versioned_docs/version-27.2/WatchPlugins.md index f501e1580a83..bcf2991083f1 100644 --- a/website/versioned_docs/version-27.2/WatchPlugins.md +++ b/website/versioned_docs/version-27.2/WatchPlugins.md @@ -24,8 +24,7 @@ class MyWatchPlugin { To connect your watch plugin to Jest, add its path under `watchPlugins` in your Jest configuration: -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: ['path/to/yourWatchPlugin'], @@ -174,8 +173,7 @@ For stability and safety reasons, only part of the global configuration keys can Plugins can be customized via your Jest configuration. -```javascript -// jest.config.js +```javascript title="jest.config.js" module.exports = { // ... watchPlugins: [ diff --git a/website/versioned_docs/version-27.2/Webpack.md b/website/versioned_docs/version-27.2/Webpack.md index e629d32a52b6..842c046f8b1c 100644 --- a/website/versioned_docs/version-27.2/Webpack.md +++ b/website/versioned_docs/version-27.2/Webpack.md @@ -9,8 +9,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana Let's start with a common sort of webpack config file and translate it to a Jest setup. -```js -// webpack.config.js +```js title="webpack.config.js" module.exports = { module: { loaders: [ @@ -42,8 +41,7 @@ If you have JavaScript files that are transformed by Babel, you can [enable supp Next, let's configure Jest to gracefully handle asset files such as stylesheets and images. Usually, these files aren't particularly useful in tests so we can safely mock them out. However, if you are using CSS Modules then it's better to mock a proxy for your className lookups. -```json -// package.json +```json title="package.json" { "jest": { "moduleNameMapper": { @@ -56,15 +54,11 @@ Next, let's configure Jest to gracefully handle asset files such as stylesheets And the mock files themselves: -```js -// __mocks__/styleMock.js - +```js title="__mocks__/styleMock.js" module.exports = {}; ``` -```js -// __mocks__/fileMock.js - +```js title="__mocks__/fileMock.js" module.exports = 'test-file-stub'; ``` @@ -78,8 +72,7 @@ yarn add --dev identity-obj-proxy Then all your className lookups on the styles object will be returned as-is (e.g., `styles.foobar === 'foobar'`). This is pretty handy for React [Snapshot Testing](SnapshotTesting.md). -```json -// package.json (for CSS Modules) +```json title="package.json (for CSS Modules)" { "jest": { "moduleNameMapper": { @@ -94,8 +87,7 @@ Then all your className lookups on the styles object will be returned as-is (e.g If `moduleNameMapper` cannot fulfill your requirements, you can use Jest's [`transform`](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object) config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that `require('logo.jpg');` returns `'logo'`) can be written as: -```js -// fileTransformer.js +```js title="fileTransformer.js" const path = require('path'); module.exports = { @@ -105,8 +97,7 @@ module.exports = { }; ``` -```json -// package.json (for custom transformers and CSS Modules) +```json title="package.json (for custom transformers and CSS Modules)" { "jest": { "moduleNameMapper": { @@ -135,8 +126,7 @@ _Note: if you are using babel-jest with additional code preprocessors, you have Now that Jest knows how to process our files, we need to tell it how to _find_ them. For webpack's `modulesDirectories`, and `extensions` options there are direct analogs in Jest's `moduleDirectories` and `moduleFileExtensions` options. -```json -// package.json +```json title="package.json" { "jest": { "moduleFileExtensions": ["js", "jsx"], @@ -154,8 +144,7 @@ Now that Jest knows how to process our files, we need to tell it how to _find_ t Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH` env variable, which you can set, or make use of the `modulePaths` option. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], @@ -171,8 +160,7 @@ Similarly, webpack's `resolve.root` option functions like setting the `NODE_PATH And finally, we have to handle the webpack `alias`. For that, we can make use of the `moduleNameMapper` option again. -```json -// package.json +```json title="package.json" { "jest": { "modulePaths": ["/shared/vendor/modules"], diff --git a/yarn.lock b/yarn.lock index b5e0704bb0f1..0b9ba8e39953 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2443,30 +2443,30 @@ __metadata: languageName: node linkType: hard -"@jest/console@^27.3.0, @jest/console@workspace:packages/jest-console": +"@jest/console@^27.3.1, @jest/console@workspace:packages/jest-console": version: 0.0.0-use.local resolution: "@jest/console@workspace:packages/jest-console" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/node": "*" chalk: ^4.0.0 - jest-message-util: ^27.3.0 - jest-util: ^27.3.0 + jest-message-util: ^27.3.1 + jest-util: ^27.3.1 slash: ^3.0.0 languageName: unknown linkType: soft -"@jest/core@^27.3.0, @jest/core@workspace:packages/jest-core": +"@jest/core@^27.3.1, @jest/core@workspace:packages/jest-core": version: 0.0.0-use.local resolution: "@jest/core@workspace:packages/jest-core" dependencies: - "@jest/console": ^27.3.0 - "@jest/reporters": ^27.3.0 - "@jest/test-result": ^27.3.0 - "@jest/test-sequencer": ^27.3.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/console": ^27.3.1 + "@jest/reporters": ^27.3.1 + "@jest/test-result": ^27.3.1 + "@jest/test-sequencer": ^27.3.1 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/exit": ^0.1.30 "@types/graceful-fs": ^4.1.2 @@ -2479,19 +2479,19 @@ __metadata: exit: ^0.1.2 graceful-fs: ^4.2.4 jest-changed-files: ^27.3.0 - jest-config: ^27.3.0 - jest-haste-map: ^27.3.0 - jest-message-util: ^27.3.0 + jest-config: ^27.3.1 + jest-haste-map: ^27.3.1 + jest-message-util: ^27.3.1 jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.0 - jest-resolve-dependencies: ^27.3.0 - jest-runner: ^27.3.0 - jest-runtime: ^27.3.0 - jest-snapshot: ^27.3.0 + jest-resolve: ^27.3.1 + jest-resolve-dependencies: ^27.3.1 + jest-runner: ^27.3.1 + jest-runtime: ^27.3.1 + jest-snapshot: ^27.3.1 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 - jest-watcher: ^27.3.0 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 + jest-watcher: ^27.3.1 micromatch: ^4.0.4 rimraf: ^3.0.0 slash: ^3.0.0 @@ -2510,22 +2510,22 @@ __metadata: dependencies: "@jest/types": ^27.2.5 "@types/node": "*" - jest-util: ^27.3.0 + jest-util: ^27.3.1 languageName: unknown linkType: soft -"@jest/environment@^27.3.0, @jest/environment@workspace:packages/jest-environment": +"@jest/environment@^27.3.1, @jest/environment@workspace:packages/jest-environment": version: 0.0.0-use.local resolution: "@jest/environment@workspace:packages/jest-environment" dependencies: - "@jest/fake-timers": ^27.3.0 + "@jest/fake-timers": ^27.3.1 "@jest/types": ^27.2.5 "@types/node": "*" jest-mock: ^27.3.0 languageName: unknown linkType: soft -"@jest/fake-timers@^27.3.0, @jest/fake-timers@workspace:packages/jest-fake-timers": +"@jest/fake-timers@^27.3.1, @jest/fake-timers@workspace:packages/jest-fake-timers": version: 0.0.0-use.local resolution: "@jest/fake-timers@workspace:packages/jest-fake-timers" dependencies: @@ -2533,20 +2533,20 @@ __metadata: "@sinonjs/fake-timers": ^8.0.1 "@types/node": "*" "@types/sinonjs__fake-timers": ^6.0.1 - jest-message-util: ^27.3.0 + jest-message-util: ^27.3.1 jest-mock: ^27.3.0 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 + jest-util: ^27.3.1 languageName: unknown linkType: soft -"@jest/globals@^27.3.0, @jest/globals@workspace:*, @jest/globals@workspace:packages/jest-globals": +"@jest/globals@^27.3.1, @jest/globals@workspace:*, @jest/globals@workspace:packages/jest-globals": version: 0.0.0-use.local resolution: "@jest/globals@workspace:packages/jest-globals" dependencies: - "@jest/environment": ^27.3.0 + "@jest/environment": ^27.3.1 "@jest/types": ^27.2.5 - expect: ^27.3.0 + expect: ^27.3.1 languageName: unknown linkType: soft @@ -2636,15 +2636,15 @@ __metadata: languageName: unknown linkType: soft -"@jest/reporters@^27.3.0, @jest/reporters@workspace:packages/jest-reporters": +"@jest/reporters@^27.3.1, @jest/reporters@workspace:packages/jest-reporters": version: 0.0.0-use.local resolution: "@jest/reporters@workspace:packages/jest-reporters" dependencies: "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^27.3.0 - "@jest/test-result": ^27.3.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/console": ^27.3.1 + "@jest/test-result": ^27.3.1 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/exit": ^0.1.30 "@types/glob": ^7.1.1 @@ -2666,10 +2666,10 @@ __metadata: istanbul-lib-report: ^3.0.0 istanbul-lib-source-maps: ^4.0.0 istanbul-reports: ^3.0.2 - jest-haste-map: ^27.3.0 - jest-resolve: ^27.3.0 - jest-util: ^27.3.0 - jest-worker: ^27.3.0 + jest-haste-map: ^27.3.1 + jest-resolve: ^27.3.1 + jest-util: ^27.3.1 + jest-worker: ^27.3.1 mock-fs: ^4.4.1 slash: ^3.0.0 source-map: ^0.6.0 @@ -2696,30 +2696,30 @@ __metadata: languageName: unknown linkType: soft -"@jest/test-result@^27.3.0, @jest/test-result@workspace:packages/jest-test-result": +"@jest/test-result@^27.3.1, @jest/test-result@workspace:packages/jest-test-result": version: 0.0.0-use.local resolution: "@jest/test-result@workspace:packages/jest-test-result" dependencies: - "@jest/console": ^27.3.0 + "@jest/console": ^27.3.1 "@jest/types": ^27.2.5 "@types/istanbul-lib-coverage": ^2.0.0 collect-v8-coverage: ^1.0.0 languageName: unknown linkType: soft -"@jest/test-sequencer@^27.3.0, @jest/test-sequencer@workspace:packages/jest-test-sequencer": +"@jest/test-sequencer@^27.3.1, @jest/test-sequencer@workspace:packages/jest-test-sequencer": version: 0.0.0-use.local resolution: "@jest/test-sequencer@workspace:packages/jest-test-sequencer" dependencies: - "@jest/test-result": ^27.3.0 + "@jest/test-result": ^27.3.1 "@types/graceful-fs": ^4.1.3 graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.0 - jest-runtime: ^27.3.0 + jest-haste-map: ^27.3.1 + jest-runtime: ^27.3.1 languageName: unknown linkType: soft -"@jest/test-utils@^27.3.0, @jest/test-utils@workspace:*, @jest/test-utils@workspace:packages/test-utils": +"@jest/test-utils@^27.3.1, @jest/test-utils@workspace:*, @jest/test-utils@workspace:packages/test-utils": version: 0.0.0-use.local resolution: "@jest/test-utils@workspace:packages/test-utils" dependencies: @@ -2729,17 +2729,17 @@ __metadata: "@types/semver": ^7.1.0 ansi-regex: ^5.0.1 ansi-styles: ^5.0.0 - pretty-format: ^27.3.0 + pretty-format: ^27.3.1 semver: ^7.3.2 languageName: unknown linkType: soft -"@jest/transform@^27.3.0, @jest/transform@workspace:packages/jest-transform": +"@jest/transform@^27.3.1, @jest/transform@workspace:packages/jest-transform": version: 0.0.0-use.local resolution: "@jest/transform@workspace:packages/jest-transform" dependencies: "@babel/core": ^7.1.0 - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/babel__core": ^7.1.0 "@types/convert-source-map": ^1.5.1 @@ -2753,10 +2753,10 @@ __metadata: dedent: ^0.7.0 fast-json-stable-stringify: ^2.0.0 graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.0 + jest-haste-map: ^27.3.1 jest-regex-util: ^27.0.6 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 + jest-util: ^27.3.1 micromatch: ^4.0.4 pirates: ^4.0.1 slash: ^3.0.0 @@ -6073,8 +6073,8 @@ __metadata: resolution: "babel-jest@workspace:packages/babel-jest" dependencies: "@babel/core": ^7.1.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/babel__core": ^7.1.14 "@types/graceful-fs": ^4.1.3 @@ -9782,19 +9782,19 @@ __metadata: languageName: node linkType: hard -"expect@^27.3.0, expect@workspace:packages/expect": +"expect@^27.3.1, expect@workspace:packages/expect": version: 0.0.0-use.local resolution: "expect@workspace:packages/expect" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 ansi-styles: ^5.0.0 chalk: ^4.0.0 fast-check: ^2.0.0 immutable: ^4.0.0-rc.12 - jest-get-type: ^27.0.6 - jest-matcher-utils: ^27.3.0 - jest-message-util: ^27.3.0 + jest-get-type: ^27.3.1 + jest-matcher-utils: ^27.3.1 + jest-message-util: ^27.3.1 jest-regex-util: ^27.0.6 languageName: unknown linkType: soft @@ -12560,15 +12560,15 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"jest-circus@^27.3.0, jest-circus@workspace:packages/jest-circus": +"jest-circus@^27.3.1, jest-circus@workspace:packages/jest-circus": version: 0.0.0-use.local resolution: "jest-circus@workspace:packages/jest-circus" dependencies: "@babel/core": ^7.1.0 "@babel/register": ^7.0.0 - "@jest/environment": ^27.3.0 - "@jest/test-result": ^27.3.0 - "@jest/test-utils": ^27.3.0 + "@jest/environment": ^27.3.1 + "@jest/test-result": ^27.3.1 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/co": ^4.6.0 "@types/dedent": ^0.7.0 @@ -12579,30 +12579,30 @@ fsevents@^1.2.7: co: ^4.6.0 dedent: ^0.7.0 execa: ^5.0.0 - expect: ^27.3.0 + expect: ^27.3.1 graceful-fs: ^4.2.4 is-generator-fn: ^2.0.0 - jest-each: ^27.3.0 - jest-matcher-utils: ^27.3.0 - jest-message-util: ^27.3.0 - jest-runtime: ^27.3.0 - jest-snapshot: ^27.3.0 + jest-each: ^27.3.1 + jest-matcher-utils: ^27.3.1 + jest-message-util: ^27.3.1 + jest-runtime: ^27.3.1 + jest-snapshot: ^27.3.1 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 - pretty-format: ^27.3.0 + jest-util: ^27.3.1 + pretty-format: ^27.3.1 slash: ^3.0.0 stack-utils: ^2.0.3 throat: ^6.0.1 languageName: unknown linkType: soft -"jest-cli@^27.3.0, jest-cli@workspace:packages/jest-cli": +"jest-cli@^27.3.1, jest-cli@workspace:packages/jest-cli": version: 0.0.0-use.local resolution: "jest-cli@workspace:packages/jest-cli" dependencies: - "@jest/core": ^27.3.0 - "@jest/test-result": ^27.3.0 - "@jest/test-utils": ^27.3.0 + "@jest/core": ^27.3.1 + "@jest/test-result": ^27.3.1 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/exit": ^0.1.30 "@types/graceful-fs": ^4.1.3 @@ -12612,9 +12612,9 @@ fsevents@^1.2.7: exit: ^0.1.2 graceful-fs: ^4.2.4 import-local: ^3.0.2 - jest-config: ^27.3.0 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 + jest-config: ^27.3.1 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 prompts: ^2.0.1 yargs: ^16.2.0 peerDependencies: @@ -12627,37 +12627,38 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"jest-config@^27.3.0, jest-config@workspace:packages/jest-config": +"jest-config@^27.3.1, jest-config@workspace:packages/jest-config": version: 0.0.0-use.local resolution: "jest-config@workspace:packages/jest-config" dependencies: "@babel/core": ^7.1.0 - "@jest/test-sequencer": ^27.3.0 + "@jest/test-sequencer": ^27.3.1 "@jest/types": ^27.2.5 "@types/babel__core": ^7.0.4 "@types/glob": ^7.1.1 "@types/graceful-fs": ^4.1.3 "@types/micromatch": ^4.0.1 - babel-jest: ^27.3.0 + babel-jest: ^27.3.1 chalk: ^4.0.0 ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.1 graceful-fs: ^4.2.4 - jest-circus: ^27.3.0 - jest-environment-jsdom: ^27.3.0 - jest-environment-node: ^27.3.0 - jest-get-type: ^27.0.6 - jest-jasmine2: ^27.3.0 + jest-circus: ^27.3.1 + jest-environment-jsdom: ^27.3.1 + jest-environment-node: ^27.3.1 + jest-get-type: ^27.3.1 + jest-jasmine2: ^27.3.1 jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.0 - jest-runner: ^27.3.0 + jest-resolve: ^27.3.1 + jest-runner: ^27.3.1 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 micromatch: ^4.0.4 - pretty-format: ^27.3.0 + pretty-format: ^27.3.1 semver: ^7.3.5 + slash: ^3.0.0 strip-ansi: ^6.0.0 ts-node: ^9.0.0 typescript: ^4.0.3 @@ -12669,15 +12670,15 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"jest-diff@^27.3.0, jest-diff@workspace:packages/jest-diff": +"jest-diff@^27.3.1, jest-diff@workspace:packages/jest-diff": version: 0.0.0-use.local resolution: "jest-diff@workspace:packages/jest-diff" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 chalk: ^4.0.0 diff-sequences: ^27.0.6 - jest-get-type: ^27.0.6 - pretty-format: ^27.3.0 + jest-get-type: ^27.3.1 + pretty-format: ^27.3.1 strip-ansi: ^6.0.0 languageName: unknown linkType: soft @@ -12712,30 +12713,30 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-each@^27.3.0, jest-each@workspace:packages/jest-each": +"jest-each@^27.3.1, jest-each@workspace:packages/jest-each": version: 0.0.0-use.local resolution: "jest-each@workspace:packages/jest-each" dependencies: "@jest/types": ^27.2.5 chalk: ^4.0.0 - jest-get-type: ^27.0.6 - jest-util: ^27.3.0 - pretty-format: ^27.3.0 + jest-get-type: ^27.3.1 + jest-util: ^27.3.1 + pretty-format: ^27.3.1 languageName: unknown linkType: soft -"jest-environment-jsdom@^27.3.0, jest-environment-jsdom@workspace:packages/jest-environment-jsdom": +"jest-environment-jsdom@^27.3.1, jest-environment-jsdom@workspace:packages/jest-environment-jsdom": version: 0.0.0-use.local resolution: "jest-environment-jsdom@workspace:packages/jest-environment-jsdom" dependencies: - "@jest/environment": ^27.3.0 - "@jest/fake-timers": ^27.3.0 - "@jest/test-utils": ^27.3.0 + "@jest/environment": ^27.3.1 + "@jest/fake-timers": ^27.3.1 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/jsdom": ^16.2.4 "@types/node": "*" jest-mock: ^27.3.0 - jest-util: ^27.3.0 + jest-util: ^27.3.1 jsdom: ^16.6.0 languageName: unknown linkType: soft @@ -12744,17 +12745,17 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "jest-environment-node@workspace:packages/jest-environment-node" dependencies: - "@jest/environment": ^27.3.0 - "@jest/fake-timers": ^27.3.0 - "@jest/test-utils": ^27.3.0 + "@jest/environment": ^27.3.1 + "@jest/fake-timers": ^27.3.1 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/node": "*" jest-mock: ^27.3.0 - jest-util: ^27.3.0 + jest-util: ^27.3.1 languageName: unknown linkType: soft -"jest-get-type@^27.0.6, jest-get-type@workspace:packages/jest-get-type": +"jest-get-type@^27.3.1, jest-get-type@workspace:packages/jest-get-type": version: 0.0.0-use.local resolution: "jest-get-type@workspace:packages/jest-get-type" languageName: unknown @@ -12774,11 +12775,11 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-haste-map@^27.3.0, jest-haste-map@workspace:packages/jest-haste-map": +"jest-haste-map@^27.3.1, jest-haste-map@workspace:packages/jest-haste-map": version: 0.0.0-use.local resolution: "jest-haste-map@workspace:packages/jest-haste-map" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 "@types/fb-watchman": ^2.0.0 "@types/graceful-fs": ^4.1.2 @@ -12791,8 +12792,8 @@ fsevents@^1.2.7: jest-regex-util: ^27.0.6 jest-serializer: ^27.0.6 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 - jest-worker: ^27.3.0 + jest-util: ^27.3.1 + jest-worker: ^27.3.1 micromatch: ^4.0.4 slash: ^3.0.0 walker: ^1.0.7 @@ -12827,29 +12828,29 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-jasmine2@^27.3.0, jest-jasmine2@workspace:packages/jest-jasmine2": +"jest-jasmine2@^27.3.1, jest-jasmine2@workspace:packages/jest-jasmine2": version: 0.0.0-use.local resolution: "jest-jasmine2@workspace:packages/jest-jasmine2" dependencies: "@babel/traverse": ^7.1.0 - "@jest/environment": ^27.3.0 + "@jest/environment": ^27.3.1 "@jest/source-map": ^27.0.6 - "@jest/test-result": ^27.3.0 + "@jest/test-result": ^27.3.1 "@jest/types": ^27.2.5 "@types/babel__traverse": ^7.0.4 "@types/co": ^4.6.2 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - expect: ^27.3.0 + expect: ^27.3.1 is-generator-fn: ^2.0.0 - jest-each: ^27.3.0 - jest-matcher-utils: ^27.3.0 - jest-message-util: ^27.3.0 - jest-runtime: ^27.3.0 - jest-snapshot: ^27.3.0 - jest-util: ^27.3.0 - pretty-format: ^27.3.0 + jest-each: ^27.3.1 + jest-matcher-utils: ^27.3.1 + jest-message-util: ^27.3.1 + jest-runtime: ^27.3.1 + jest-snapshot: ^27.3.1 + jest-util: ^27.3.1 + pretty-format: ^27.3.1 throat: ^6.0.1 languageName: unknown linkType: soft @@ -12866,31 +12867,31 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-leak-detector@^27.3.0, jest-leak-detector@workspace:packages/jest-leak-detector": +"jest-leak-detector@^27.3.1, jest-leak-detector@workspace:packages/jest-leak-detector": version: 0.0.0-use.local resolution: "jest-leak-detector@workspace:packages/jest-leak-detector" dependencies: "@types/weak-napi": ^2.0.0 - jest-get-type: ^27.0.6 - pretty-format: ^27.3.0 + jest-get-type: ^27.3.1 + pretty-format: ^27.3.1 weak-napi: ^2.0.1 languageName: unknown linkType: soft -"jest-matcher-utils@^27.3.0, jest-matcher-utils@workspace:packages/jest-matcher-utils": +"jest-matcher-utils@^27.3.1, jest-matcher-utils@workspace:packages/jest-matcher-utils": version: 0.0.0-use.local resolution: "jest-matcher-utils@workspace:packages/jest-matcher-utils" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@types/node": "*" chalk: ^4.0.0 - jest-diff: ^27.3.0 - jest-get-type: ^27.0.6 - pretty-format: ^27.3.0 + jest-diff: ^27.3.1 + jest-get-type: ^27.3.1 + pretty-format: ^27.3.1 languageName: unknown linkType: soft -"jest-message-util@^27.3.0, jest-message-util@workspace:packages/jest-message-util": +"jest-message-util@^27.3.1, jest-message-util@workspace:packages/jest-message-util": version: 0.0.0-use.local resolution: "jest-message-util@workspace:packages/jest-message-util" dependencies: @@ -12903,7 +12904,7 @@ fsevents@^1.2.7: chalk: ^4.0.0 graceful-fs: ^4.2.4 micromatch: ^4.0.4 - pretty-format: ^27.3.0 + pretty-format: ^27.3.1 slash: ^3.0.0 stack-utils: ^2.0.3 languageName: unknown @@ -12922,7 +12923,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "jest-phabricator@workspace:packages/jest-phabricator" dependencies: - "@jest/test-result": ^27.3.0 + "@jest/test-result": ^27.3.1 languageName: unknown linkType: soft @@ -12957,18 +12958,18 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "jest-repl@workspace:packages/jest-repl" dependencies: - "@jest/console": ^27.3.0 - "@jest/environment": ^27.3.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/console": ^27.3.1 + "@jest/environment": ^27.3.1 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/yargs": ^16.0.0 chalk: ^4.0.0 execa: ^5.0.0 - jest-config: ^27.3.0 - jest-runtime: ^27.3.0 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 + jest-config: ^27.3.1 + jest-runtime: ^27.3.1 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 repl: ^0.1.3 yargs: ^16.2.0 bin: @@ -12977,21 +12978,21 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"jest-resolve-dependencies@^27.3.0, jest-resolve-dependencies@workspace:packages/jest-resolve-dependencies": +"jest-resolve-dependencies@^27.3.1, jest-resolve-dependencies@workspace:packages/jest-resolve-dependencies": version: 0.0.0-use.local resolution: "jest-resolve-dependencies@workspace:packages/jest-resolve-dependencies" dependencies: - "@jest/test-utils": ^27.3.0 + "@jest/test-utils": ^27.3.1 "@jest/types": ^27.2.5 - jest-haste-map: ^27.3.0 + jest-haste-map: ^27.3.1 jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.0 - jest-runtime: ^27.3.0 - jest-snapshot: ^27.3.0 + jest-resolve: ^27.3.1 + jest-runtime: ^27.3.1 + jest-snapshot: ^27.3.1 languageName: unknown linkType: soft -"jest-resolve@^27.3.0, jest-resolve@workspace:packages/jest-resolve": +"jest-resolve@^27.3.1, jest-resolve@workspace:packages/jest-resolve": version: 0.0.0-use.local resolution: "jest-resolve@workspace:packages/jest-resolve" dependencies: @@ -13000,10 +13001,10 @@ fsevents@^1.2.7: "@types/resolve": ^1.20.0 chalk: ^4.0.0 graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.0 + jest-haste-map: ^27.3.1 jest-pnp-resolver: ^1.2.2 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 resolve: ^1.20.0 resolve.exports: ^1.1.0 slash: ^3.0.0 @@ -13021,14 +13022,14 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-runner@^27.3.0, jest-runner@workspace:packages/jest-runner": +"jest-runner@^27.3.1, jest-runner@workspace:packages/jest-runner": version: 0.0.0-use.local resolution: "jest-runner@workspace:packages/jest-runner" dependencies: - "@jest/console": ^27.3.0 - "@jest/environment": ^27.3.0 - "@jest/test-result": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/console": ^27.3.1 + "@jest/environment": ^27.3.1 + "@jest/test-result": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/exit": ^0.1.30 "@types/graceful-fs": ^4.1.2 @@ -13039,33 +13040,33 @@ fsevents@^1.2.7: exit: ^0.1.2 graceful-fs: ^4.2.4 jest-docblock: ^27.0.6 - jest-environment-jsdom: ^27.3.0 - jest-environment-node: ^27.3.0 - jest-haste-map: ^27.3.0 - jest-jasmine2: ^27.3.0 - jest-leak-detector: ^27.3.0 - jest-message-util: ^27.3.0 - jest-resolve: ^27.3.0 - jest-runtime: ^27.3.0 - jest-util: ^27.3.0 - jest-worker: ^27.3.0 + jest-environment-jsdom: ^27.3.1 + jest-environment-node: ^27.3.1 + jest-haste-map: ^27.3.1 + jest-jasmine2: ^27.3.1 + jest-leak-detector: ^27.3.1 + jest-message-util: ^27.3.1 + jest-resolve: ^27.3.1 + jest-runtime: ^27.3.1 + jest-util: ^27.3.1 + jest-worker: ^27.3.1 source-map-support: ^0.5.6 throat: ^6.0.1 languageName: unknown linkType: soft -"jest-runtime@^27.3.0, jest-runtime@workspace:packages/jest-runtime": +"jest-runtime@^27.3.1, jest-runtime@workspace:packages/jest-runtime": version: 0.0.0-use.local resolution: "jest-runtime@workspace:packages/jest-runtime" dependencies: - "@jest/console": ^27.3.0 - "@jest/environment": ^27.3.0 - "@jest/fake-timers": ^27.3.0 - "@jest/globals": ^27.3.0 + "@jest/console": ^27.3.1 + "@jest/environment": ^27.3.1 + "@jest/fake-timers": ^27.3.1 + "@jest/globals": ^27.3.1 "@jest/source-map": ^27.0.6 - "@jest/test-result": ^27.3.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/test-result": ^27.3.1 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/exit": ^0.1.30 "@types/glob": ^7.1.1 @@ -13079,16 +13080,16 @@ fsevents@^1.2.7: exit: ^0.1.2 glob: ^7.1.3 graceful-fs: ^4.2.4 - jest-environment-node: ^27.3.0 - jest-haste-map: ^27.3.0 - jest-message-util: ^27.3.0 + jest-environment-node: ^27.3.1 + jest-haste-map: ^27.3.1 + jest-message-util: ^27.3.1 jest-mock: ^27.3.0 jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.0 - jest-snapshot: ^27.3.0 + jest-resolve: ^27.3.1 + jest-snapshot: ^27.3.1 jest-snapshot-serializer-raw: ^1.1.0 - jest-util: ^27.3.0 - jest-validate: ^27.3.0 + jest-util: ^27.3.1 + jest-validate: ^27.3.1 slash: ^3.0.0 strip-bom: ^4.0.0 yargs: ^16.2.0 @@ -13132,7 +13133,7 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-snapshot@^27.3.0, jest-snapshot@workspace:*, jest-snapshot@workspace:packages/jest-snapshot": +"jest-snapshot@^27.3.1, jest-snapshot@workspace:*, jest-snapshot@workspace:packages/jest-snapshot": version: 0.0.0-use.local resolution: "jest-snapshot@workspace:packages/jest-snapshot" dependencies: @@ -13144,8 +13145,8 @@ fsevents@^1.2.7: "@babel/preset-react": ^7.7.2 "@babel/traverse": ^7.7.2 "@babel/types": ^7.0.0 - "@jest/test-utils": ^27.3.0 - "@jest/transform": ^27.3.0 + "@jest/test-utils": ^27.3.1 + "@jest/transform": ^27.3.1 "@jest/types": ^27.2.5 "@types/babel__traverse": ^7.0.4 "@types/graceful-fs": ^4.1.3 @@ -13156,23 +13157,23 @@ fsevents@^1.2.7: ansi-styles: ^5.0.0 babel-preset-current-node-syntax: ^1.0.0 chalk: ^4.0.0 - expect: ^27.3.0 + expect: ^27.3.1 graceful-fs: ^4.2.4 - jest-diff: ^27.3.0 - jest-get-type: ^27.0.6 - jest-haste-map: ^27.3.0 - jest-matcher-utils: ^27.3.0 - jest-message-util: ^27.3.0 - jest-resolve: ^27.3.0 - jest-util: ^27.3.0 + jest-diff: ^27.3.1 + jest-get-type: ^27.3.1 + jest-haste-map: ^27.3.1 + jest-matcher-utils: ^27.3.1 + jest-message-util: ^27.3.1 + jest-resolve: ^27.3.1 + jest-util: ^27.3.1 natural-compare: ^1.4.0 prettier: ^2.0.0 - pretty-format: ^27.3.0 + pretty-format: ^27.3.1 semver: ^7.3.2 languageName: unknown linkType: soft -"jest-util@^27.3.0, jest-util@workspace:packages/jest-util": +"jest-util@^27.3.1, jest-util@workspace:packages/jest-util": version: 0.0.0-use.local resolution: "jest-util@workspace:packages/jest-util" dependencies: @@ -13202,7 +13203,7 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-validate@^27.3.0, jest-validate@workspace:packages/jest-validate": +"jest-validate@^27.3.1, jest-validate@workspace:packages/jest-validate": version: 0.0.0-use.local resolution: "jest-validate@workspace:packages/jest-validate" dependencies: @@ -13210,9 +13211,9 @@ fsevents@^1.2.7: "@types/yargs": ^16.0.0 camelcase: ^6.2.0 chalk: ^4.0.0 - jest-get-type: ^27.0.6 + jest-get-type: ^27.3.1 leven: ^3.1.0 - pretty-format: ^27.3.0 + pretty-format: ^27.3.1 languageName: unknown linkType: soft @@ -13247,16 +13248,16 @@ fsevents@^1.2.7: languageName: node linkType: hard -"jest-watcher@^27.0.0, jest-watcher@^27.3.0, jest-watcher@workspace:packages/jest-watcher": +"jest-watcher@^27.0.0, jest-watcher@^27.3.1, jest-watcher@workspace:packages/jest-watcher": version: 0.0.0-use.local resolution: "jest-watcher@workspace:packages/jest-watcher" dependencies: - "@jest/test-result": ^27.3.0 + "@jest/test-result": ^27.3.1 "@jest/types": ^27.2.5 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 - jest-util: ^27.3.0 + jest-util: ^27.3.1 string-length: ^4.0.1 languageName: unknown linkType: soft @@ -13284,7 +13285,7 @@ fsevents@^1.2.7: languageName: unknown linkType: soft -"jest-worker@^27.0.6, jest-worker@^27.3.0, jest-worker@workspace:packages/jest-worker": +"jest-worker@^27.0.6, jest-worker@^27.3.1, jest-worker@workspace:packages/jest-worker": version: 0.0.0-use.local resolution: "jest-worker@workspace:packages/jest-worker" dependencies: @@ -13292,7 +13293,7 @@ fsevents@^1.2.7: "@types/node": "*" "@types/supports-color": ^8.1.0 get-stream: ^6.0.0 - jest-leak-detector: ^27.3.0 + jest-leak-detector: ^27.3.1 merge-stream: ^2.0.0 supports-color: ^8.0.0 worker-farm: ^1.6.0 @@ -13333,9 +13334,9 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "jest@workspace:packages/jest" dependencies: - "@jest/core": ^27.3.0 + "@jest/core": ^27.3.1 import-local: ^3.0.2 - jest-cli: ^27.3.0 + jest-cli: ^27.3.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -17419,7 +17420,7 @@ fsevents@^1.2.7: languageName: node linkType: hard -"pretty-format@^27.3.0, pretty-format@workspace:packages/pretty-format": +"pretty-format@^27.3.1, pretty-format@workspace:packages/pretty-format": version: 0.0.0-use.local resolution: "pretty-format@workspace:packages/pretty-format" dependencies: @@ -17430,7 +17431,7 @@ fsevents@^1.2.7: ansi-regex: ^5.0.1 ansi-styles: ^5.0.0 immutable: 4.0.0-rc.9 - jest-util: ^27.3.0 + jest-util: ^27.3.1 react: "*" react-dom: "*" react-is: ^17.0.1