From dda77e5c0228d6dd7306ca8b899fdf40ce118dba Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 25 Aug 2022 14:01:43 +0200 Subject: [PATCH] docs: collapse 28.0 and 28.1 docs (#13104) --- docs/UpgradingToJest29.md | 2 +- .../version-28.0/UpgradingToJest28.md | 222 --- .../Architecture.md | 0 .../BypassingModuleMocks.md | 0 .../{version-28.0 => version-28.x}/CLI.md | 0 .../CodeTransformation.md | 0 .../Configuration.md | 0 .../DynamoDB.md | 0 .../ECMAScriptModules.md | 0 .../EnvironmentVariables.md | 0 .../Es6ClassMocks.md | 0 .../ExpectAPI.md | 0 .../GettingStarted.md | 0 .../GlobalAPI.md | 0 .../JestCommunity.md | 0 .../JestObjectAPI.md | 0 .../JestPlatform.md | 0 .../ManualMocks.md | 0 .../MigrationGuide.md | 0 .../MockFunctionAPI.md | 0 .../MockFunctions.md | 0 .../{version-28.0 => version-28.x}/MongoDB.md | 0 .../MoreResources.md | 0 .../Puppeteer.md | 0 .../SetupAndTeardown.md | 0 .../SnapshotTesting.md | 0 .../TestingAsyncCode.md | 0 .../TestingFrameworks.md | 0 .../TimerMocks.md | 0 .../Troubleshooting.md | 0 .../TutorialAsync.md | 0 .../TutorialReact.md | 0 .../TutorialReactNative.md | 0 .../TutorialjQuery.md | 0 .../UpgradingToJest28.md | 0 .../UsingMatchers.md | 0 .../WatchPlugins.md | 0 .../{version-28.0 => version-28.x}/Webpack.md | 0 .../Architecture.md | 0 .../BypassingModuleMocks.md | 0 .../{version-28.1 => version-29.0}/CLI.md | 0 .../CodeTransformation.md | 0 .../Configuration.md | 1191 +++++++++++++---- .../DynamoDB.md | 0 .../ECMAScriptModules.md | 0 .../EnvironmentVariables.md | 0 .../Es6ClassMocks.md | 0 .../ExpectAPI.md | 0 .../GettingStarted.md | 25 +- .../GlobalAPI.md | 187 ++- .../JestCommunity.md | 2 +- .../JestObjectAPI.md | 60 +- .../JestPlatform.md | 0 .../ManualMocks.md | 0 .../MigrationGuide.md | 0 .../MockFunctionAPI.md | 76 ++ .../MockFunctions.md | 0 .../{version-28.1 => version-29.0}/MongoDB.md | 0 .../MoreResources.md | 0 .../Puppeteer.md | 0 .../SetupAndTeardown.md | 0 .../SnapshotTesting.md | 0 .../TestingAsyncCode.md | 0 .../TestingFrameworks.md | 0 .../TimerMocks.md | 0 .../Troubleshooting.md | 0 .../TutorialAsync.md | 0 .../TutorialReact.md | 0 .../TutorialReactNative.md | 0 .../TutorialjQuery.md | 0 .../version-29.0/UpgradingToJest29.md | 77 ++ .../UsingMatchers.md | 0 .../WatchPlugins.md | 0 .../{version-28.1 => version-29.0}/Webpack.md | 0 ...debars.json => version-28.x-sidebars.json} | 0 ...debars.json => version-29.0-sidebars.json} | 2 +- website/versions.json | 4 +- 77 files changed, 1277 insertions(+), 571 deletions(-) delete mode 100644 website/versioned_docs/version-28.0/UpgradingToJest28.md rename website/versioned_docs/{version-28.0 => version-28.x}/Architecture.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/BypassingModuleMocks.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/CLI.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/CodeTransformation.md (100%) rename website/versioned_docs/{version-28.1 => version-28.x}/Configuration.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/DynamoDB.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/ECMAScriptModules.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/EnvironmentVariables.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/Es6ClassMocks.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/ExpectAPI.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/GettingStarted.md (100%) rename website/versioned_docs/{version-28.1 => version-28.x}/GlobalAPI.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/JestCommunity.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/JestObjectAPI.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/JestPlatform.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/ManualMocks.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/MigrationGuide.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/MockFunctionAPI.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/MockFunctions.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/MongoDB.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/MoreResources.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/Puppeteer.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/SetupAndTeardown.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/SnapshotTesting.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TestingAsyncCode.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TestingFrameworks.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TimerMocks.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/Troubleshooting.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TutorialAsync.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TutorialReact.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TutorialReactNative.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/TutorialjQuery.md (100%) rename website/versioned_docs/{version-28.1 => version-28.x}/UpgradingToJest28.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/UsingMatchers.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/WatchPlugins.md (100%) rename website/versioned_docs/{version-28.0 => version-28.x}/Webpack.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/Architecture.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/BypassingModuleMocks.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/CLI.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/CodeTransformation.md (100%) rename website/versioned_docs/{version-28.0 => version-29.0}/Configuration.md (76%) rename website/versioned_docs/{version-28.1 => version-29.0}/DynamoDB.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/ECMAScriptModules.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/EnvironmentVariables.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/Es6ClassMocks.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/ExpectAPI.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/GettingStarted.md (80%) rename website/versioned_docs/{version-28.0 => version-29.0}/GlobalAPI.md (84%) rename website/versioned_docs/{version-28.1 => version-29.0}/JestCommunity.md (95%) rename website/versioned_docs/{version-28.1 => version-29.0}/JestObjectAPI.md (95%) rename website/versioned_docs/{version-28.1 => version-29.0}/JestPlatform.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/ManualMocks.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/MigrationGuide.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/MockFunctionAPI.md (88%) rename website/versioned_docs/{version-28.1 => version-29.0}/MockFunctions.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/MongoDB.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/MoreResources.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/Puppeteer.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/SetupAndTeardown.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/SnapshotTesting.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TestingAsyncCode.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TestingFrameworks.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TimerMocks.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/Troubleshooting.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TutorialAsync.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TutorialReact.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TutorialReactNative.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/TutorialjQuery.md (100%) create mode 100644 website/versioned_docs/version-29.0/UpgradingToJest29.md rename website/versioned_docs/{version-28.1 => version-29.0}/UsingMatchers.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/WatchPlugins.md (100%) rename website/versioned_docs/{version-28.1 => version-29.0}/Webpack.md (100%) rename website/versioned_sidebars/{version-28.0-sidebars.json => version-28.x-sidebars.json} (100%) rename website/versioned_sidebars/{version-28.1-sidebars.json => version-29.0-sidebars.json} (97%) diff --git a/docs/UpgradingToJest29.md b/docs/UpgradingToJest29.md index 89dacba4beca..07ec834fd453 100644 --- a/docs/UpgradingToJest29.md +++ b/docs/UpgradingToJest29.md @@ -13,7 +13,7 @@ See [changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md#2900) fo :::note -Upgrading from an older version? You can see the upgrade guide from v27 to v28 [here](/docs/upgrading-to-jest28). +Upgrading from an older version? You can see the upgrade guide from v27 to v28 [here](/docs/28.x/upgrading-to-jest28). ::: diff --git a/website/versioned_docs/version-28.0/UpgradingToJest28.md b/website/versioned_docs/version-28.0/UpgradingToJest28.md deleted file mode 100644 index 0b60a237dfe3..000000000000 --- a/website/versioned_docs/version-28.0/UpgradingToJest28.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -id: upgrading-to-jest28 -title: From v27 to v28 ---- - -Upgrading Jest from v27 to v28? This guide aims to help refactoring your configuration and tests. - -:::info - -See [changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md#2800) for the full list of changes. - -::: - -## Compatibility - -The supported Node versions are 12.13, 14.15, 16.10 and above. - -If you plan to use type definitions of Jest (or any of its packages), make sure to install TypeScript version 4.3 or above. - -## Configuration Options - -### `extraGlobals` - -The `extraGlobals` option was renamed to [`sandboxInjectedGlobals`](Configuration.md#sandboxinjectedglobals-arraystring): - -```diff -- extraGlobals: ['Math'] -+ sandboxInjectedGlobals: ['Math'] -``` - -### `timers` - -The `timers` option was renamed to [`fakeTimers`](Configuration.md#faketimers-object). See [Fake Timers](#fake-timers) section below for details. - -### `testURL` - -The `testURL` option is removed. Now you should use [`testEnvironmentOptions`](Configuration.md#testenvironmentoptions-object) to pass `url` option to JSDOM environment: - -```diff -- testURL: 'https://jestjs.io' -+ testEnvironmentOptions: { -+ url: 'https://jestjs.io' -+ } -``` - -### Babel config - -`babel-jest` now passes `root: config.rootDir` to Babel when resolving configuration. This improves compatibility when using `projects` with differing configuration, but it might mean your babel config isn't picked up in the same way anymore. You can override this option by passing options to `babel-jest` in your [configuration](Configuration.md#transform-objectstring-pathtotransformer--pathtotransformer-object). - -## `expect` - -In versions prior to Jest 28, `toHaveProperty` checked for equality instead of existence, which means that e.g. `expect({}).toHaveProperty('a', undefined)` is a passing test. This has been changed in Jest 28 to fail. - -Additionally, if you import `expect` directly, it has been changed from default export to a named export. - -```diff -- import expect from 'expect'; -+ import {expect} from 'expect'; -``` - -```diff -- const expect = require('expect'); -+ const {expect} = require('expect'); -``` - -## Fake Timers - -Fake timers were refactored to allow passing options to the underlying [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers). - -### `fakeTimers` - -The `timers` configuration option was renamed to [`fakeTimers`](Configuration.md#faketimers-object) and now takes an object with options: - -```diff -- timers: 'real' -+ fakeTimers: { -+ enableGlobally: false -+ } -``` - -```diff -- timers: 'fake' -+ fakeTimers: { -+ enableGlobally: true -+ } -``` - -```diff -- timers: 'modern' -+ fakeTimers: { -+ enableGlobally: true -+ } -``` - -```diff -- timers: 'legacy' -+ fakeTimers: { -+ enableGlobally: true, -+ legacyFakeTimers: true -+ } -``` - -### `jest.useFakeTimers()` - -An object with options now should be passed to [`jest.useFakeTimers()`](JestObjectAPI.md#jestusefaketimersfaketimersconfig) as well: - -```diff -- jest.useFakeTimers('modern') -+ jest.useFakeTimers() -``` - -```diff -- jest.useFakeTimers('legacy') -+ jest.useFakeTimers({ -+ legacyFakeTimers: true -+ }) -``` - -If legacy fake timers are enabled in Jest config file, but you would like to disable them in a particular test file: - -```diff -- jest.useFakeTimers('modern') -+ jest.useFakeTimers({ -+ legacyFakeTimers: false -+ }) -``` - -## Test Environment - -### Custom Environment - -The constructor of [test environment](Configuration.md#testenvironment-string) class now receives an object with Jest's `globalConfig` and `projectConfig` as its first argument. The second argument is now mandatory. - -```diff - class CustomEnvironment extends NodeEnvironment { -- constructor(config) { -- super(config); -+ constructor({globalConfig, projectConfig}, context) { -+ super({globalConfig, projectConfig}, context); -+ const config = projectConfig; -``` - -In addition, test environments are now exported with the name `TestEnvironment`, instead of simply exporting the class directly: - -```diff -- const TestEnvironment = require('jest-environment-node'); -+ const {TestEnvironment} = require('jest-environment-node'); - -- const TestEnvironment = require('jest-environment-jsdom'); -+ const {TestEnvironment} = require('jest-environment-jsdom'); -``` - -### `jsdom` - -If you are using JSDOM [test environment](Configuration.md#testenvironment-string), `jest-environment-jsdom` package now must be installed separately: - -```bash npm2yarn -npm install --save-dev jest-environment-jsdom -``` - -## Test Runner - -If you are using Jasmine [test runner](Configuration.md#testrunner-string), `jest-jasmine2` package now must be installed separately: - -```bash npm2yarn -npm install --save-dev jest-jasmine2 -``` - -## Transformer - -`process()` and `processAsync()` methods of a custom [transformer module](CodeTransformation.md) cannot return a string anymore. They must always return an object: - -```diff - process(sourceText, sourcePath, options) { -- return `module.exports = ${JSON.stringify(path.basename(sourcePath))};`; -+ return { -+ code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`, -+ }; - } -``` - -## `package.json` `exports` - -Jest now includes full support for [package `exports`](https://nodejs.org/api/packages.html#exports), which might mean that files you import are not resolved correctly. - -Additionally, Jest now supplies more conditions. `jest-environment-node` has `node` and `node-addons`, while `jest-environment-jsdom` has `browser`. As a result, you might e.g. get browser code which assumes ESM, when Jest provides `['require', 'browser']`. You can either report a bug to the library (or Jest, the implementation is new and might have bugs!), override the conditions Jest passes (via a custom test environment and overriding `exportConditions()`), using a custom resolver or `moduleMapper`. Lots of options, and you'll need to pick the correct one for your project. - -Known examples of packages that fails in Jest 28 are [`uuid`](https://npmjs.com/package/uuid) and [`nanoid`](https://npmjs.com/package/nanoid) when using the `jest-environment-jsdom` environment. For an analysis, and a potential workaround, see [this comment](https://github.com/microsoft/accessibility-insights-web/pull/5421#issuecomment-1109168149). - -## TypeScript - -:::info - -The TypeScript examples from this page will only work as documented if you import `jest` from `'@jest/globals'`: - -```ts -import {jest} from '@jest/globals'; -``` - -::: - -### `jest.fn()` - -`jest.fn()` now takes only one generic type argument. See [Mock Functions API](MockFunctionAPI.md) page for more usage examples. - -```diff - import add from './add'; -- const mockAdd = jest.fn, Parameters>(); -+ const mockAdd = jest.fn(); -``` - -```diff -- const mock = jest.fn() -+ const mock = jest.fn<() => number>() - .mockReturnValue(42) - .mockReturnValueOnce(12); - -- const asyncMock = jest.fn, []>() -+ const asyncMock = jest.fn<() => Promise>() - .mockResolvedValue('default') - .mockResolvedValueOnce('first call'); -``` diff --git a/website/versioned_docs/version-28.0/Architecture.md b/website/versioned_docs/version-28.x/Architecture.md similarity index 100% rename from website/versioned_docs/version-28.0/Architecture.md rename to website/versioned_docs/version-28.x/Architecture.md diff --git a/website/versioned_docs/version-28.0/BypassingModuleMocks.md b/website/versioned_docs/version-28.x/BypassingModuleMocks.md similarity index 100% rename from website/versioned_docs/version-28.0/BypassingModuleMocks.md rename to website/versioned_docs/version-28.x/BypassingModuleMocks.md diff --git a/website/versioned_docs/version-28.0/CLI.md b/website/versioned_docs/version-28.x/CLI.md similarity index 100% rename from website/versioned_docs/version-28.0/CLI.md rename to website/versioned_docs/version-28.x/CLI.md diff --git a/website/versioned_docs/version-28.0/CodeTransformation.md b/website/versioned_docs/version-28.x/CodeTransformation.md similarity index 100% rename from website/versioned_docs/version-28.0/CodeTransformation.md rename to website/versioned_docs/version-28.x/CodeTransformation.md diff --git a/website/versioned_docs/version-28.1/Configuration.md b/website/versioned_docs/version-28.x/Configuration.md similarity index 100% rename from website/versioned_docs/version-28.1/Configuration.md rename to website/versioned_docs/version-28.x/Configuration.md diff --git a/website/versioned_docs/version-28.0/DynamoDB.md b/website/versioned_docs/version-28.x/DynamoDB.md similarity index 100% rename from website/versioned_docs/version-28.0/DynamoDB.md rename to website/versioned_docs/version-28.x/DynamoDB.md diff --git a/website/versioned_docs/version-28.0/ECMAScriptModules.md b/website/versioned_docs/version-28.x/ECMAScriptModules.md similarity index 100% rename from website/versioned_docs/version-28.0/ECMAScriptModules.md rename to website/versioned_docs/version-28.x/ECMAScriptModules.md diff --git a/website/versioned_docs/version-28.0/EnvironmentVariables.md b/website/versioned_docs/version-28.x/EnvironmentVariables.md similarity index 100% rename from website/versioned_docs/version-28.0/EnvironmentVariables.md rename to website/versioned_docs/version-28.x/EnvironmentVariables.md diff --git a/website/versioned_docs/version-28.0/Es6ClassMocks.md b/website/versioned_docs/version-28.x/Es6ClassMocks.md similarity index 100% rename from website/versioned_docs/version-28.0/Es6ClassMocks.md rename to website/versioned_docs/version-28.x/Es6ClassMocks.md diff --git a/website/versioned_docs/version-28.0/ExpectAPI.md b/website/versioned_docs/version-28.x/ExpectAPI.md similarity index 100% rename from website/versioned_docs/version-28.0/ExpectAPI.md rename to website/versioned_docs/version-28.x/ExpectAPI.md diff --git a/website/versioned_docs/version-28.0/GettingStarted.md b/website/versioned_docs/version-28.x/GettingStarted.md similarity index 100% rename from website/versioned_docs/version-28.0/GettingStarted.md rename to website/versioned_docs/version-28.x/GettingStarted.md diff --git a/website/versioned_docs/version-28.1/GlobalAPI.md b/website/versioned_docs/version-28.x/GlobalAPI.md similarity index 100% rename from website/versioned_docs/version-28.1/GlobalAPI.md rename to website/versioned_docs/version-28.x/GlobalAPI.md diff --git a/website/versioned_docs/version-28.0/JestCommunity.md b/website/versioned_docs/version-28.x/JestCommunity.md similarity index 100% rename from website/versioned_docs/version-28.0/JestCommunity.md rename to website/versioned_docs/version-28.x/JestCommunity.md diff --git a/website/versioned_docs/version-28.0/JestObjectAPI.md b/website/versioned_docs/version-28.x/JestObjectAPI.md similarity index 100% rename from website/versioned_docs/version-28.0/JestObjectAPI.md rename to website/versioned_docs/version-28.x/JestObjectAPI.md diff --git a/website/versioned_docs/version-28.0/JestPlatform.md b/website/versioned_docs/version-28.x/JestPlatform.md similarity index 100% rename from website/versioned_docs/version-28.0/JestPlatform.md rename to website/versioned_docs/version-28.x/JestPlatform.md diff --git a/website/versioned_docs/version-28.0/ManualMocks.md b/website/versioned_docs/version-28.x/ManualMocks.md similarity index 100% rename from website/versioned_docs/version-28.0/ManualMocks.md rename to website/versioned_docs/version-28.x/ManualMocks.md diff --git a/website/versioned_docs/version-28.0/MigrationGuide.md b/website/versioned_docs/version-28.x/MigrationGuide.md similarity index 100% rename from website/versioned_docs/version-28.0/MigrationGuide.md rename to website/versioned_docs/version-28.x/MigrationGuide.md diff --git a/website/versioned_docs/version-28.0/MockFunctionAPI.md b/website/versioned_docs/version-28.x/MockFunctionAPI.md similarity index 100% rename from website/versioned_docs/version-28.0/MockFunctionAPI.md rename to website/versioned_docs/version-28.x/MockFunctionAPI.md diff --git a/website/versioned_docs/version-28.0/MockFunctions.md b/website/versioned_docs/version-28.x/MockFunctions.md similarity index 100% rename from website/versioned_docs/version-28.0/MockFunctions.md rename to website/versioned_docs/version-28.x/MockFunctions.md diff --git a/website/versioned_docs/version-28.0/MongoDB.md b/website/versioned_docs/version-28.x/MongoDB.md similarity index 100% rename from website/versioned_docs/version-28.0/MongoDB.md rename to website/versioned_docs/version-28.x/MongoDB.md diff --git a/website/versioned_docs/version-28.0/MoreResources.md b/website/versioned_docs/version-28.x/MoreResources.md similarity index 100% rename from website/versioned_docs/version-28.0/MoreResources.md rename to website/versioned_docs/version-28.x/MoreResources.md diff --git a/website/versioned_docs/version-28.0/Puppeteer.md b/website/versioned_docs/version-28.x/Puppeteer.md similarity index 100% rename from website/versioned_docs/version-28.0/Puppeteer.md rename to website/versioned_docs/version-28.x/Puppeteer.md diff --git a/website/versioned_docs/version-28.0/SetupAndTeardown.md b/website/versioned_docs/version-28.x/SetupAndTeardown.md similarity index 100% rename from website/versioned_docs/version-28.0/SetupAndTeardown.md rename to website/versioned_docs/version-28.x/SetupAndTeardown.md diff --git a/website/versioned_docs/version-28.0/SnapshotTesting.md b/website/versioned_docs/version-28.x/SnapshotTesting.md similarity index 100% rename from website/versioned_docs/version-28.0/SnapshotTesting.md rename to website/versioned_docs/version-28.x/SnapshotTesting.md diff --git a/website/versioned_docs/version-28.0/TestingAsyncCode.md b/website/versioned_docs/version-28.x/TestingAsyncCode.md similarity index 100% rename from website/versioned_docs/version-28.0/TestingAsyncCode.md rename to website/versioned_docs/version-28.x/TestingAsyncCode.md diff --git a/website/versioned_docs/version-28.0/TestingFrameworks.md b/website/versioned_docs/version-28.x/TestingFrameworks.md similarity index 100% rename from website/versioned_docs/version-28.0/TestingFrameworks.md rename to website/versioned_docs/version-28.x/TestingFrameworks.md diff --git a/website/versioned_docs/version-28.0/TimerMocks.md b/website/versioned_docs/version-28.x/TimerMocks.md similarity index 100% rename from website/versioned_docs/version-28.0/TimerMocks.md rename to website/versioned_docs/version-28.x/TimerMocks.md diff --git a/website/versioned_docs/version-28.0/Troubleshooting.md b/website/versioned_docs/version-28.x/Troubleshooting.md similarity index 100% rename from website/versioned_docs/version-28.0/Troubleshooting.md rename to website/versioned_docs/version-28.x/Troubleshooting.md diff --git a/website/versioned_docs/version-28.0/TutorialAsync.md b/website/versioned_docs/version-28.x/TutorialAsync.md similarity index 100% rename from website/versioned_docs/version-28.0/TutorialAsync.md rename to website/versioned_docs/version-28.x/TutorialAsync.md diff --git a/website/versioned_docs/version-28.0/TutorialReact.md b/website/versioned_docs/version-28.x/TutorialReact.md similarity index 100% rename from website/versioned_docs/version-28.0/TutorialReact.md rename to website/versioned_docs/version-28.x/TutorialReact.md diff --git a/website/versioned_docs/version-28.0/TutorialReactNative.md b/website/versioned_docs/version-28.x/TutorialReactNative.md similarity index 100% rename from website/versioned_docs/version-28.0/TutorialReactNative.md rename to website/versioned_docs/version-28.x/TutorialReactNative.md diff --git a/website/versioned_docs/version-28.0/TutorialjQuery.md b/website/versioned_docs/version-28.x/TutorialjQuery.md similarity index 100% rename from website/versioned_docs/version-28.0/TutorialjQuery.md rename to website/versioned_docs/version-28.x/TutorialjQuery.md diff --git a/website/versioned_docs/version-28.1/UpgradingToJest28.md b/website/versioned_docs/version-28.x/UpgradingToJest28.md similarity index 100% rename from website/versioned_docs/version-28.1/UpgradingToJest28.md rename to website/versioned_docs/version-28.x/UpgradingToJest28.md diff --git a/website/versioned_docs/version-28.0/UsingMatchers.md b/website/versioned_docs/version-28.x/UsingMatchers.md similarity index 100% rename from website/versioned_docs/version-28.0/UsingMatchers.md rename to website/versioned_docs/version-28.x/UsingMatchers.md diff --git a/website/versioned_docs/version-28.0/WatchPlugins.md b/website/versioned_docs/version-28.x/WatchPlugins.md similarity index 100% rename from website/versioned_docs/version-28.0/WatchPlugins.md rename to website/versioned_docs/version-28.x/WatchPlugins.md diff --git a/website/versioned_docs/version-28.0/Webpack.md b/website/versioned_docs/version-28.x/Webpack.md similarity index 100% rename from website/versioned_docs/version-28.0/Webpack.md rename to website/versioned_docs/version-28.x/Webpack.md diff --git a/website/versioned_docs/version-28.1/Architecture.md b/website/versioned_docs/version-29.0/Architecture.md similarity index 100% rename from website/versioned_docs/version-28.1/Architecture.md rename to website/versioned_docs/version-29.0/Architecture.md diff --git a/website/versioned_docs/version-28.1/BypassingModuleMocks.md b/website/versioned_docs/version-29.0/BypassingModuleMocks.md similarity index 100% rename from website/versioned_docs/version-28.1/BypassingModuleMocks.md rename to website/versioned_docs/version-29.0/BypassingModuleMocks.md diff --git a/website/versioned_docs/version-28.1/CLI.md b/website/versioned_docs/version-29.0/CLI.md similarity index 100% rename from website/versioned_docs/version-28.1/CLI.md rename to website/versioned_docs/version-29.0/CLI.md diff --git a/website/versioned_docs/version-28.1/CodeTransformation.md b/website/versioned_docs/version-29.0/CodeTransformation.md similarity index 100% rename from website/versioned_docs/version-28.1/CodeTransformation.md rename to website/versioned_docs/version-29.0/CodeTransformation.md diff --git a/website/versioned_docs/version-28.0/Configuration.md b/website/versioned_docs/version-29.0/Configuration.md similarity index 76% rename from website/versioned_docs/version-28.0/Configuration.md rename to website/versioned_docs/version-29.0/Configuration.md index a2c33ea92547..d6762ea4b695 100644 --- a/website/versioned_docs/version-28.0/Configuration.md +++ b/website/versioned_docs/version-29.0/Configuration.md @@ -3,29 +3,41 @@ id: configuration title: Configuring Jest --- -Jest's configuration can be defined in the `package.json` file of your project, or through a `jest.config.js`, or `jest.config.ts` file or through the `--config ` option. If you'd like to use your `package.json` to store Jest's config, the `"jest"` key should be used on the top level so Jest will know how to find your settings: +The Jest philosophy is to work great by default, but sometimes you just need more configuration power. -```json -{ - "name": "my-project", - "jest": { - "verbose": true - } -} -``` +It is recommended to define the configuration in a dedicated JavaScript, TypeScript or JSON file. The file will be discovered automatically, if it is named `jest.config.js|ts|mjs|cjs|json`. You can use [`--config`](CLI.md#--configpath) flag to pass an explicit path to the file. + +:::note + +Keep in mind that the resulting configuration object must always be JSON-serializable. + +::: -Or through JavaScript: +The configuration file should simply export an object: -```js title="jest.config.js" -// Sync object -/** @type {import('@jest/types').Config.InitialOptions} */ +```js tab +/** @type {import('jest').Config} */ const config = { verbose: true, }; module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + verbose: true, +}; + +export default config; +``` + +Or a function returning an object: -// Or async function +```js tab +/** @returns {Promise} */ module.exports = async () => { return { verbose: true, @@ -33,53 +45,72 @@ module.exports = async () => { }; ``` -Or through TypeScript (if `ts-node` is installed): +```ts tab +import type {Config} from 'jest'; -```ts title="jest.config.ts" -import type {Config} from '@jest/types'; - -// Sync object -const config: Config.InitialOptions = { - verbose: true, -}; -export default config; - -// Or async function -export default async (): Promise => { +export default async (): Promise => { return { verbose: true, }; }; ``` -Please keep in mind that the resulting configuration must be JSON-serializable. +:::tip + +To read TypeScript configuration files Jest requires [`ts-node`](https://npmjs.com/package/ts-node). Make sure it is installed in your project. -When using the `--config` option, the JSON file must not contain a "jest" key: +::: -```json +The configuration also can be stored in a JSON file as a plain object: + +```json title="jest.config.json" { "bail": 1, "verbose": true } ``` -## Options +Alternatively Jest's configuration can be defined through the `"jest"` key in the `package.json` of your project: + +```json title="package.json" +{ + "name": "my-project", + "jest": { + "verbose": true + } +} +``` -These options let you control Jest's behavior in your `package.json` file. The Jest philosophy is to work great by default, but sometimes you just need more configuration power. +## Options -### Defaults +:::info -You can retrieve Jest's default options to expand them if needed: +You can retrieve Jest's defaults from `jest-config` to extend them if needed: -```js title="jest.config.js" +```js tab const {defaults} = require('jest-config'); -module.exports = { - // ... - moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], - // ... + +/** @type {import('jest').Config} */ +const config = { + moduleFileExtensions: [...defaults.moduleFileExtensions, 'mts', 'cts'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; +import {defaults} from 'jest-config'; + +const config: Config = { + moduleFileExtensions: [...defaults.moduleFileExtensions, 'mts'], }; + +export default config; ``` +::: + import TOCInline from '@theme/TOCInline'; @@ -98,15 +129,12 @@ Example: ```js title="utils.js" export default { - authorize: () => { - return 'token'; - }, + authorize: () => 'token', isAuthorized: secret => secret === 'wizard', }; ``` -```js -//__tests__/automocking.test.js +```js title="__tests__/automock.test.js" import utils from '../utils'; test('if utils mocked automatically', () => { @@ -172,16 +200,31 @@ Default: `undefined` An array of [glob patterns](https://github.com/micromatch/micromatch) indicating a set of files for which coverage information should be collected. If a file matches the specified glob pattern, coverage information will be collected for it even if no tests exist for this file and it's never required in the test suite. -Example: +```js tab +/** @type {import('jest').Config} */ +const config = { + collectCoverageFrom: [ + '**/*.{js,jsx}', + '!**/node_modules/**', + '!**/vendor/**', + ], +}; -```json -{ - "collectCoverageFrom": [ - "**/*.{js,jsx}", - "!**/node_modules/**", - "!**/vendor/**" - ] -} +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + collectCoverageFrom: [ + '**/*.{js,jsx}', + '!**/node_modules/**', + '!**/vendor/**', + ], +}; + +export default config; ``` This will collect coverage information for all the files inside the project's `rootDir`, except the ones that match `**/node_modules/**` or `**/vendor/**`. @@ -250,10 +293,23 @@ Setting this option overwrites the default values. Add `"text"` or `"text-summar Additional options can be passed using the tuple form. For example, you may hide coverage report lines for all fully-covered files: -```json -{ - "coverageReporters": ["clover", "json", "lcov", ["text", {"skipFull": true}]] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + coverageReporters: ['clover', 'json', 'lcov', ['text', {skipFull: true}]], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + coverageReporters: ['clover', 'json', 'lcov', ['text', {skipFull: true}]], +}; + +export default config; ``` For more information about the options object shape refer to `CoverageReporterWithOptions` type in the [type definitions](https://github.com/facebook/jest/tree/main/packages/jest-types/src/Config.ts). @@ -266,53 +322,100 @@ This will be used to configure minimum threshold enforcement for coverage result For example, with the following configuration jest will fail if there is less than 80% branch, line, and function coverage, or if there are more than 10 uncovered statements: -```json -{ - ... - "jest": { - "coverageThreshold": { - "global": { - "branches": 80, - "functions": 80, - "lines": 80, - "statements": -10 - } - } - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + coverageThreshold: { + global: { + branches: 80, + functions: 80, + lines: 80, + statements: -10, + }, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + coverageThreshold: { + global: { + branches: 80, + functions: 80, + lines: 80, + statements: -10, + }, + }, +}; + +export default config; ``` If globs or paths are specified alongside `global`, coverage data for matching paths will be subtracted from overall coverage and thresholds will be applied independently. Thresholds for globs are applied to all files matching the glob. If the file specified by path is not found, an error is returned. For example, with the following configuration: -```json -{ - ... - "jest": { - "coverageThreshold": { - "global": { - "branches": 50, - "functions": 50, - "lines": 50, - "statements": 50 - }, - "./src/components/": { - "branches": 40, - "statements": 40 - }, - "./src/reducers/**/*.js": { - "statements": 90 - }, - "./src/api/very-important-module.js": { - "branches": 100, - "functions": 100, - "lines": 100, - "statements": 100 - } - } - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + coverageThreshold: { + global: { + branches: 50, + functions: 50, + lines: 50, + statements: 50, + }, + './src/components/': { + branches: 40, + statements: 40, + }, + './src/reducers/**/*.js': { + statements: 90, + }, + './src/api/very-important-module.js': { + branches: 100, + functions: 100, + lines: 100, + statements: 100, + }, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + coverageThreshold: { + global: { + branches: 50, + functions: 50, + lines: 50, + statements: 50, + }, + './src/components/': { + branches: 40, + statements: 40, + }, + './src/reducers/**/*.js': { + statements: 90, + }, + './src/api/very-important-module.js': { + branches: 100, + functions: 100, + lines: 100, + statements: 100, + }, + }, +}; + +export default config; ``` Jest will fail if: @@ -355,26 +458,53 @@ That module can also contain a `getCacheKey` function to generate a cache key to default: `undefined` -Allows for a label to be printed alongside a test while it is running. This becomes more useful in multi-project repositories where there can be many jest configuration files. This visually tells which project a test belongs to. Here are sample valid values. +Allows for a label to be printed alongside a test while it is running. This becomes more useful in multi-project repositories where there can be many jest configuration files. This visually tells which project a test belongs to. -```js -module.exports = { +```js tab +/** @type {import('jest').Config} */ +const config = { displayName: 'CLIENT', }; + +module.exports = config; ``` -or +```ts tab +import type {Config} from 'jest'; -```js -module.exports = { +const config: Config = { + displayName: 'CLIENT', +}; + +export default config; +``` + +Alternatively, an object with the properties `name` and `color` can be passed. This allows for a custom configuration of the background color of the displayName. `displayName` defaults to white when its value is a string. Jest uses [`chalk`](https://github.com/chalk/chalk) to provide the color. As such, all of the valid options for colors supported by `chalk` are also supported by Jest. + +```js tab +/** @type {import('jest').Config} */ +const config = { displayName: { name: 'CLIENT', color: 'blue', }, }; + +module.exports = config; ``` -As a secondary option, an object with the properties `name` and `color` can be passed. This allows for a custom configuration of the background color of the displayName. `displayName` defaults to white when its value is a string. Jest uses [chalk](https://github.com/chalk/chalk) to provide the color. As such, all of the valid options for colors supported by chalk are also supported by jest. +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + displayName: { + name: 'CLIENT', + color: 'blue', + }, +}; + +export default config; +``` ### `errorOnDeprecated` \[boolean] @@ -388,21 +518,31 @@ Default: `[]` Jest will run `.mjs` and `.js` files with nearest `package.json`'s `type` field set to `module` as ECMAScript Modules. If you have any other files that should run with native ESM, you need to specify their file extension here. +```js tab +/** @type {import('jest').Config} */ +const config = { + extensionsToTreatAsEsm: ['.ts'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + extensionsToTreatAsEsm: ['.ts'], +}; + +export default config; +``` + :::caution Jest's ESM support is still experimental, see [its docs for more details](ECMAScriptModules.md). ::: -```json -{ - ... - "jest": { - "extensionsToTreatAsEsm": [".ts"] - } -} -``` - ### `fakeTimers` \[object] Default: `{}` @@ -411,13 +551,29 @@ The fake timers may be useful when a piece of code sets a long timeout that we d This option provides the default configuration of fake timers for all tests. Calling `jest.useFakeTimers()` in a test file will use these options or will override them if a configuration object is passed. For example, you can tell Jest to keep the original implementation of `process.nextTick()` and adjust the limit of recursive timers that will be run: -```json -{ - "fakeTimers": { - "doNotFake": ["nextTick"], - "timerLimit": 1000 - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + fakeTimers: { + doNotFake: ['nextTick'], + timerLimit: 1000, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + fakeTimers: { + doNotFake: ['nextTick'], + timerLimit: 1000, + }, +}; + +export default config; ``` ```js title="fakeTime.test.js" @@ -432,14 +588,29 @@ test('increase the limit of recursive timers for this and following tests', () = :::tip -Instead of including `jest.useFakeTimers()` in each test file, you can enable fake timers globally for all tests: +Instead of including `jest.useFakeTimers()` in each test file, you can enable fake timers globally for all tests in your Jest configuration: -```json -{ - "fakeTimers": { - "enableGlobally": true - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + fakeTimers: { + enableGlobally: true, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + fakeTimers: { + enableGlobally: true, + }, +}; + +export default config; ``` ::: @@ -494,13 +665,29 @@ type ModernFakeTimersConfig = { For some reason you might have to use legacy implementation of fake timers. Here is how to enable it globally (additional options are not supported): -```json -{ - "fakeTimers": { - "enableGlobally": true, - "legacyFakeTimers": true - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + fakeTimers: { + enableGlobally: true, + legacyFakeTimers: true, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + fakeTimers: { + enableGlobally: true, + legacyFakeTimers: true, + }, +}; + +export default config; ``` ::: @@ -527,13 +714,23 @@ if (process.env.NODE_ENV === 'test') { You can collect coverage from those files with setting `forceCoverageMatch`. -```json -{ - ... - "jest": { - "forceCoverageMatch": ["**/*.t.js"] - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + forceCoverageMatch: ['**/*.t.js'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + forceCoverageMatch: ['**/*.t.js'], +}; + +export default config; ``` ### `globals` \[object] @@ -544,15 +741,27 @@ A set of global variables that need to be available in all test environments. For example, the following would create a global `__DEV__` variable set to `true` in all test environments: -```json -{ - ... - "jest": { - "globals": { - "__DEV__": true - } - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + globals: { + __DEV__: true, + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + globals: { + __DEV__: true, + }, +}; + +export default config; ``` Note that, if you specify a global reference value (like an object or array) here, and some code mutates that value in the midst of running a test, that mutation will _not_ be persisted across test runs for other test files. In addition, the `globals` object must be json-serializable, so it can't be used to specify global functions. For that, you should use `setupFiles`. @@ -671,13 +880,51 @@ A number limiting the number of tests that are allowed to run at the same time w Specifies the maximum number of workers the worker-pool will spawn for running tests. In single run mode, this defaults to the number of the cores available on your machine minus one for the main thread. In watch mode, this defaults to half of the available cores on your machine to ensure Jest is unobtrusive and does not grind your machine to a halt. It may be useful to adjust this in resource limited environments like CIs but the defaults should be adequate for most use-cases. -For environments with variable CPUs available, you can use percentage based configuration: `"maxWorkers": "50%"` +For environments with variable CPUs available, you can use percentage based configuration: + +```js tab +/** @type {import('jest').Config} */ +const config = { + maxWorkers: '50%', +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + maxWorkers: '50%', +}; + +export default config; +``` ### `moduleDirectories` \[array<string>] Default: `["node_modules"]` -An array of directory names to be searched recursively up from the requiring module's location. Setting this option will _override_ the default, if you wish to still search `node_modules` for packages include it along with any other options: `["node_modules", "bower_components"]` +An array of directory names to be searched recursively up from the requiring module's location. Setting this option will _override_ the default, if you wish to still search `node_modules` for packages include it along with any other options: + +```js tab +/** @type {import('jest').Config} */ +const config = { + moduleDirectories: ['node_modules', 'bower_components'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + moduleDirectories: ['node_modules', 'bower_components'], +}; + +export default config; +``` ### `moduleFileExtensions` \[array<string>] @@ -699,21 +946,41 @@ Use `` string token to refer to [`rootDir`](#rootdir-string) value if y Additionally, you can substitute captured regex groups using numbered backreferences. -Example: +```js tab +/** @type {import('jest').Config} */ +const config = { + moduleNameMapper: { + '^image![a-zA-Z0-9$_-]+$': 'GlobalImageStub', + '^[./a-zA-Z0-9$_-]+\\.png$': '/RelativeImageStub.js', + 'module_name_(.*)': '/substituted_module_$1.js', + 'assets/(.*)': [ + '/images/$1', + '/photos/$1', + '/recipes/$1', + ], + }, +}; -```json -{ - "moduleNameMapper": { - "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub", - "^[./a-zA-Z0-9$_-]+\\.png$": "/RelativeImageStub.js", - "module_name_(.*)": "/substituted_module_$1.js", - "assets/(.*)": [ - "/images/$1", - "/photos/$1", - "/recipes/$1" - ] - } -} +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + moduleNameMapper: { + '^image![a-zA-Z0-9$_-]+$': 'GlobalImageStub', + '^[./a-zA-Z0-9$_-]+\\.png$': '/RelativeImageStub.js', + 'module_name_(.*)': '/substituted_module_$1.js', + 'assets/(.*)': [ + '/images/$1', + '/photos/$1', + '/recipes/$1', + ], + }, +}; + +export default config; ``` The order in which the mappings are defined matters. Patterns are checked one by one until one fits. The most specific rule should be listed first. This is true for arrays of module names as well. @@ -730,13 +997,51 @@ Default: `[]` An array of regexp pattern strings that are matched against all module paths before those paths are to be considered 'visible' to the module loader. If a given module's path matches any of the patterns, it will not be `require()`-able in the test environment. -These pattern strings match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. Example: `["/build/"]`. +These pattern strings match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. + +```js tab +/** @type {import('jest').Config} */ +const config = { + modulePathIgnorePatterns: ['/build/'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + modulePathIgnorePatterns: ['/build/'], +}; + +export default config; +``` ### `modulePaths` \[array<string>] Default: `[]` -An alternative API to setting the `NODE_PATH` env variable, `modulePaths` is an array of absolute paths to additional locations to search when resolving modules. Use the `` string token to include the path to your project's root directory. Example: `["/app/"]`. +An alternative API to setting the `NODE_PATH` env variable, `modulePaths` is an array of absolute paths to additional locations to search when resolving modules. Use the `` string token to include the path to your project's root directory. + +```js tab +/** @type {import('jest').Config} */ +const config = { + modulePaths: ['/app/'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + modulePaths: ['/app/'], +}; + +export default config; +``` ### `notify` \[boolean] @@ -779,20 +1084,44 @@ A preset that is used as a base for Jest's configuration. A preset should point For example, this preset `foo-bar/jest-preset.js` will be configured as follows: -```js -/** @type { import('@jest/types').Config.InitialOptions } */ -module.exports = { +```js tab +/** @type {import('jest').Config} */ +const config = { preset: 'foo-bar', }; + +module.exports = config; ``` -Presets may also be relative to filesystem paths. +```ts tab +import type {Config} from 'jest'; -```js -/** @type { import('@jest/types').Config.InitialOptions } */ -module.exports = { +const config: Config = { + preset: 'foo-bar', +}; + +export default config; +``` + +Presets may also be relative to filesystem paths: + +```js tab +/** @type {import('jest').Config} */ +const config = { + preset: './node_modules/foo-bar/jest-preset.js', +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { preset: './node_modules/foo-bar/jest-preset.js', }; + +export default config; ``` :::info @@ -813,29 +1142,64 @@ Default: `undefined` When the `projects` configuration is provided with an array of paths or glob patterns, Jest will run tests in all of the specified projects at the same time. This is great for monorepos or when working on multiple projects at the same time. -```json -{ - "projects": ["", "/examples/*"] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + projects: ['', '/examples/*'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + projects: ['', '/examples/*'], +}; + +export default config; ``` This example configuration will run Jest in the root directory as well as in every folder in the examples directory. You can have an unlimited amount of projects running in the same Jest instance. The projects feature can also be used to run multiple configurations or multiple [runners](#runner-string). For this purpose, you can pass an array of configuration objects. For example, to run both tests and ESLint (via [jest-runner-eslint](https://github.com/jest-community/jest-runner-eslint)) in the same invocation of Jest: -```json -{ - "projects": [ +```js tab +/** @type {import('jest').Config} */ +const config = { + projects: [ { - "displayName": "test" + displayName: 'test', }, { - "displayName": "lint", - "runner": "jest-runner-eslint", - "testMatch": ["/**/*.js"] - } - ] -} + displayName: 'lint', + runner: 'jest-runner-eslint', + testMatch: ['/**/*.js'], + }, + ], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + projects: [ + { + displayName: 'test', + }, + { + displayName: 'lint', + runner: 'jest-runner-eslint', + testMatch: ['/**/*.js'], + }, + ], +}; + +export default config; ``` :::tip @@ -850,46 +1214,104 @@ Default: `undefined` Use this configuration option to add reporters to Jest. It must be a list of reporter names, additional options can be passed to a reporter using the tuple form: -```json -{ - "reporters": [ - "default", - ["/custom-reporter.js", {"banana": "yes", "pineapple": "no"}] - ] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + reporters: [ + 'default', + ['/custom-reporter.js', {banana: 'yes', pineapple: 'no'}], + ], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + reporters: [ + 'default', + ['/custom-reporter.js', {banana: 'yes', pineapple: 'no'}], + ], +}; + +export default config; ``` #### Default Reporter If custom reporters are specified, the default Jest reporter will be overridden. If you wish to keep it, `'default'` must be passed as a reporters name: -```json -{ - "reporters": [ - "default", - ["jest-junit", {"outputDirectory": "reports", "outputName": "report.xml"}] - ] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + reporters: [ + 'default', + ['jest-junit', {outputDirectory: 'reports', outputName: 'report.xml'}], + ], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + reporters: [ + 'default', + ['jest-junit', {outputDirectory: 'reports', outputName: 'report.xml'}], + ], +}; + +export default config; ``` #### GitHub Actions Reporter If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages: -```json -{ - "reporters": ["default", "github-actions"] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + reporters: ['default', 'github-actions'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + reporters: ['default', 'github-actions'], +}; + +export default config; ``` #### Summary Reporter Summary reporter prints out summary of all tests. It is a part of default reporter, hence it will be enabled if `'default'` is included in the list. For instance, you might want to use it as stand-alone reporter instead of the default one, or together with [Silent Reporter](https://github.com/rickhanlonii/jest-silent-reporter): -```json -{ - "reporters": ["jest-silent-reporter", "summary"] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + reporters: ['jest-silent-reporter', 'summary'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + reporters: ['jest-silent-reporter', 'summary'], +}; + +export default config; ``` #### Custom Reporters @@ -981,13 +1403,7 @@ The `defaultResolver` passed as an option is the Jest default resolver which mig ::: -For example, if you want to respect Browserify's [`"browser"` field](https://github.com/browserify/browserify-handbook/blob/master/readme.markdown#browser-field), you can use the following configuration: - -```json -{ - "resolver": "/resolver.js" -} -``` +For example, if you want to respect Browserify's [`"browser"` field](https://github.com/browserify/browserify-handbook/blob/master/readme.markdown#browser-field), you can use the following resolver: ```js title="resolver.js" const browserResolve = require('browser-resolve'); @@ -995,6 +1411,27 @@ const browserResolve = require('browser-resolve'); module.exports = browserResolve.sync; ``` +And add it to Jest configuration: + +```js tab +/** @type {import('jest').Config} */ +const config = { + resolver: '/resolver.js', +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + resolver: '/resolver.js', +}; + +export default config; +``` + By combining `defaultResolver` and `packageFilter` we can implement a `package.json` "pre-processor" that allows us to change how the default resolver will resolve modules. For example, imagine we want to use the field `"module"` if it is present, otherwise fallback to `"main"`: ```js @@ -1096,13 +1533,23 @@ Test files run inside a [vm](https://nodejs.org/api/vm.html), which slows calls For example, if your tests call `Math` often, you can pass it by setting `sandboxInjectedGlobals`. -```json -{ - ... - "jest": { - "sandboxInjectedGlobals": ["Math"] - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + sandboxInjectedGlobals: ['Math'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + sandboxInjectedGlobals: ['Math'], +}; + +export default config; ``` :::note @@ -1140,10 +1587,23 @@ afterEach(() => { }); ``` -```js -module.exports = { +```js tab +/** @type {import('jest').Config} */ +const config = { setupFilesAfterEnv: ['/setup-jest.js'], }; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + setupFilesAfterEnv: ['/setup-matchers.js'], +}; + +export default config; ``` ### `slowTestThreshold` \[number] @@ -1154,23 +1614,34 @@ The number of seconds after which a test is considered as slow and reported as s ### `snapshotFormat` \[object] -Default: `undefined` +Default: `{escapeString: false, printBasicPrototype: false}` Allows overriding specific snapshot formatting options documented in the [pretty-format readme](https://www.npmjs.com/package/pretty-format#usage-with-options), with the exceptions of `compareKeys` and `plugins`. For example, this config would have the snapshot formatter not print a prefix for "Object" and "Array": -```json -{ - "jest": { - "snapshotFormat": { - "printBasicPrototype": false - } - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + snapshotFormat: { + printBasicPrototype: false, + }, +}; + +module.exports = config; ``` -```ts -import {expect, test} from '@jest/globals'; +```ts tab +import type {Config} from 'jest'; +const config: Config = { + snapshotFormat: { + printBasicPrototype: false, + }, +}; + +export default config; +``` + +```js title="some.test.js" test('does not show prototypes for object and array inline', () => { const object = { array: [{hello: 'Danger'}], @@ -1193,9 +1664,7 @@ Default: `undefined` The path to a module that can resolve test<->snapshot path. This config option lets you customize where Jest stores snapshot files on disk. -Example snapshot resolver module: - -```js +```js title="custom-resolver.js" module.exports = { // resolves from test to snapshot path resolveSnapshotPath: (testPath, snapshotExtension) => @@ -1220,10 +1689,7 @@ A list of paths to snapshot serializer modules Jest should use for snapshot test Jest has default serializers for built-in JavaScript types, HTML elements (Jest 20.0.0+), ImmutableJS (Jest 20.0.0+) and for React elements. See [snapshot test tutorial](TutorialReactNative.md#snapshot-test) for more information. -Example serializer module: - -```js -// my-serializer-module +```js title="custom-serializer.js" module.exports = { serialize(val, config, indentation, depth, refs, printer) { return `Pretty foo: ${printer(val.foo)}`; @@ -1237,15 +1703,25 @@ module.exports = { `printer` is a function that serializes a value using existing plugins. -To use `my-serializer-module` as a serializer, configuration would be as follows: +Add `custom-serializer` to your Jest configuration: -```json -{ - ... - "jest": { - "snapshotSerializers": ["my-serializer-module"] - } -} +```js tab +/** @type {import('jest').Config} */ +const config = { + snapshotSerializers: ['path/to/custom-serializer.js'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + snapshotSerializers: ['path/to/custom-serializer.js'], +}; + +export default config; ``` Finally tests would look as follows: @@ -1377,7 +1853,11 @@ beforeAll(() => { Default: `{}` -Test environment options that will be passed to the `testEnvironment`. The relevant options depend on the environment. For example, you can override options given to [`jsdom`](https://github.com/jsdom/jsdom) such as `{html: "", url: 'https://jestjs.io/', userAgent: "Agent/007"}`. +Test environment options that will be passed to the `testEnvironment`. The relevant options depend on the environment. + +For example, in `jest-environment-jsdom`, you can override options given to [`jsdom`](https://github.com/jsdom/jsdom) such as `{html: "", url: 'https://jestjs.io/', userAgent: "Agent/007"}`. + +Both `jest-environment-jsdom` and `jest-environment-node` allow specifying `customExportConditions`, which allow you to control which versions of a library are loaded from `exports` in `package.json`. `jest-environment-jsdom` defaults to `['browser']`. `jest-environment-node` defaults to `['node', 'node-addons']`. These options can also be passed in a docblock, similar to `testEnvironment`. Note that it must be parseable by `JSON.parse`. Example: @@ -1540,11 +2020,9 @@ Both `sort` and `shard` may optionally return a `Promise`. ::: -Example: - -Sort test path alphabetically. +For example, you may sort test paths alphabetically: -```js title="testSequencer.js" +```js title="custom-sequencer.js" const Sequencer = require('@jest/test-sequencer').default; class CustomSequencer extends Sequencer { @@ -1577,12 +2055,25 @@ class CustomSequencer extends Sequencer { module.exports = CustomSequencer; ``` -Use it in your Jest config file like this: +Add `custom-sequencer` to your Jest configuration: -```json -{ - "testSequencer": "path/to/testSequencer.js" -} +```js tab +/** @type {import('jest').Config} */ +const config = { + testSequencer: 'path/to/custom-sequencer.js', +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + testSequencer: 'path/to/custom-sequencer.js', +}; + +export default config; ``` ### `testTimeout` \[number] @@ -1607,11 +2098,29 @@ Keep in mind that a transformer only runs once per file unless the file has chan Remember to include the default `babel-jest` transformer explicitly, if you wish to use it alongside with additional code preprocessors: -```json -"transform": { - "\\.[jt]sx?$": "babel-jest", - "\\.css$": "some-css-transformer", -} +```js tab +/** @type {import('jest').Config} */ +const config = { + transform: { + '\\.[jt]sx?$': 'babel-jest', + '\\.css$': 'some-css-transformer', + }, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + transform: { + '\\.[jt]sx?$': 'babel-jest', + '\\.css$': 'some-css-transformer', + }, +}; + +export default config; ``` ::: @@ -1624,10 +2133,23 @@ An array of regexp pattern strings that are matched against all source file path Providing regexp patterns that overlap with each other may result in files not being transformed that you expected to be transformed. For example: -```json -{ - "transformIgnorePatterns": ["/node_modules/(?!(foo|bar)/)", "/bar/"] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + transformIgnorePatterns: ['/node_modules/(?!(foo|bar)/)', '/bar/'], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + transformIgnorePatterns: ['/node_modules/(?!(foo|bar)/)', '/bar/'], +}; + +export default config; ``` The first pattern will match (and therefore not transform) files inside `/node_modules` except for those in `/node_modules/foo/` and `/node_modules/bar/`. The second pattern will match (and therefore not transform) files inside any path with `/bar/` in it. With the two together, files in `/node_modules/bar/` will not be transformed because it does match the second pattern, even though it was excluded by the first. @@ -1636,27 +2158,56 @@ Sometimes it happens (especially in React Native or TypeScript projects) that 3r These pattern strings match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. -Example: +```js tab +/** @type {import('jest').Config} */ +const config = { + transformIgnorePatterns: [ + '/bower_components/', + '/node_modules/', + ], +}; -```json -{ - "transformIgnorePatterns": [ - "/bower_components/", - "/node_modules/" - ] -} +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + transformIgnorePatterns: [ + '/bower_components/', + '/node_modules/', + ], +}; + +export default config; ``` :::tip If you use `pnpm` and need to convert some packages under `node_modules`, you need to note that the packages in this folder (e.g. `node_modules/package-a/`) have been symlinked to the path under `.pnpm` (e.g. `node_modules/.pnpm/package-a@x.x.x/node_modules/pakcage-a/`), so using `/node_modules/(?!(package-a|package-b)/)` directly will not be recognized, while is to use: -```json -{ - "transformIgnorePatterns": [ - "/node_modules/.pnpm/(?!(package-a|package-b)@)" - ] -} +```js tab +/** @type {import('jest').Config} */ +const config = { + transformIgnorePatterns: [ + '/node_modules/.pnpm/(?!(package-a|package-b)@)', + ], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + transformIgnorePatterns: [ + '/node_modules/.pnpm/(?!(package-a|package-b)@)', + ], +}; + +export default config; ``` It should be noted that the folder name of pnpm under `.pnpm` is the package name plus `@` and version number, so writing `/` will not be recognized, but using `@` can. @@ -1689,12 +2240,23 @@ These patterns match against the full path. Use the `` string token to Even if nothing is specified here, the watcher will ignore changes to the version control folders (.git, .hg). Other hidden files and directories, i.e. those that begin with a dot (`.`), are watched by default. Remember to escape the dot when you add them to `watchPathIgnorePatterns` as it is a special RegExp character. -Example: +```js tab +/** @type {import('jest').Config} */ +const config = { + watchPathIgnorePatterns: ['/\\.tmp/', '/bar/'], +}; -```json -{ - "watchPathIgnorePatterns": ["/\\.tmp/", "/bar/"] -} +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + watchPathIgnorePatterns: ['/\\.tmp/', '/bar/'], +}; + +export default config; ``` ### `watchPlugins` \[array<string | \[string, Object]>] @@ -1723,15 +2285,52 @@ Default: `true` Whether to use [`watchman`](https://facebook.github.io/watchman/) for file crawling. -### `//` \[string] +### `workerIdleMemoryLimit` \[number|string] -No default +Default: `undefined` -This option allows comments in `package.json`. Include the comment text as the value of this key anywhere in `package.json`. +Specifies the memory limit for workers before they are recycled and is primarily a work-around for [this issue](https://github.com/facebook/jest/issues/11956); -Example: +After the worker has executed a test the memory usage of it is checked. If it exceeds the value specified the worker is killed and restarted. The limit can be specified in a number of different ways and whatever the result is `Math.floor` is used to turn it into an integer value: -```json +- `<= 1` - The value is assumed to be a percentage of system memory. So 0.5 sets the memory limit of the worker to half of the total system memory +- `\> 1` - Assumed to be a fixed byte value. Because of the previous rule if you wanted a value of 1 byte (I don't know why) you could use `1.1`. +- With units + - `50%` - As above, a percentage of total system memory + - `100KB`, `65MB`, etc - With units to denote a fixed memory limit. + - `K` / `KB` - Kilobytes (x1000) + - `KiB` - Kibibytes (x1024) + - `M` / `MB` - Megabytes + - `MiB` - Mebibytes + - `G` / `GB` - Gigabytes + - `GiB` - Gibibytes + +**NOTE:** [% based memory does not work on Linux CircleCI workers](https://github.com/facebook/jest/issues/11956#issuecomment-1212925677) due to incorrect system memory being reported. + +```js tab +/** @type {import('jest').Config} */ +const config = { + workerIdleMemoryLimit: 0.2, +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + workerIdleMemoryLimit: 0.2, +}; + +export default config; +``` + +### `//` \[string] + +This option allows comments in `package.json`. Include the comment text as the value of this key: + +```json title="package.json" { "name": "my-project", "jest": { diff --git a/website/versioned_docs/version-28.1/DynamoDB.md b/website/versioned_docs/version-29.0/DynamoDB.md similarity index 100% rename from website/versioned_docs/version-28.1/DynamoDB.md rename to website/versioned_docs/version-29.0/DynamoDB.md diff --git a/website/versioned_docs/version-28.1/ECMAScriptModules.md b/website/versioned_docs/version-29.0/ECMAScriptModules.md similarity index 100% rename from website/versioned_docs/version-28.1/ECMAScriptModules.md rename to website/versioned_docs/version-29.0/ECMAScriptModules.md diff --git a/website/versioned_docs/version-28.1/EnvironmentVariables.md b/website/versioned_docs/version-29.0/EnvironmentVariables.md similarity index 100% rename from website/versioned_docs/version-28.1/EnvironmentVariables.md rename to website/versioned_docs/version-29.0/EnvironmentVariables.md diff --git a/website/versioned_docs/version-28.1/Es6ClassMocks.md b/website/versioned_docs/version-29.0/Es6ClassMocks.md similarity index 100% rename from website/versioned_docs/version-28.1/Es6ClassMocks.md rename to website/versioned_docs/version-29.0/Es6ClassMocks.md diff --git a/website/versioned_docs/version-28.1/ExpectAPI.md b/website/versioned_docs/version-29.0/ExpectAPI.md similarity index 100% rename from website/versioned_docs/version-28.1/ExpectAPI.md rename to website/versioned_docs/version-29.0/ExpectAPI.md diff --git a/website/versioned_docs/version-28.1/GettingStarted.md b/website/versioned_docs/version-29.0/GettingStarted.md similarity index 80% rename from website/versioned_docs/version-28.1/GettingStarted.md rename to website/versioned_docs/version-29.0/GettingStarted.md index 870942cac091..7b6e4b17de31 100644 --- a/website/versioned_docs/version-28.1/GettingStarted.md +++ b/website/versioned_docs/version-29.0/GettingStarted.md @@ -156,10 +156,31 @@ npm install --save-dev ts-jest #### Type definitions -You may also want to install the [`@types/jest`](https://www.npmjs.com/package/@types/jest) module for the version of Jest you're using. This will help provide full typing when writing your tests with TypeScript. +There are two ways have [Jest global APIs](GlobalAPI.md) typed for test files written in TypeScript. -> For `@types/*` modules it's recommended to try to match the version of the associated module. For example, if you are using `26.4.0` of `jest` then using `26.4.x` of `@types/jest` is ideal. In general, try to match the major (`26`) and minor (`4`) version as closely as possible. +You can use type definitions which ships with Jest and will update each time you update Jest. Simply import the APIs from `@jest/globals` package: + +```ts title="sum.test.ts" +import {describe, expect, test} from '@jest/globals'; +import {sum} from './sum'; + +describe('sum module', () => { + test('adds 1 + 2 to equal 3', () => { + expect(sum(1, 2)).toBe(3); + }); +}); +``` + +:::tip + +See the additional usage documentation of [`describe.each`/`test.each`](GlobalAPI.md#typescript-usage) and [`mock functions`](MockFunctionAPI.md#typescript-usage). + +::: + +Or you may choose to install the [`@types/jest`](https://npmjs.com/package/@types/jest) package. It provides types for Jest globals without a need to import them. ```bash npm2yarn npm install --save-dev @types/jest ``` + +Note that `@types/jest` is a third party library maintained at [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest), hence the latest Jest features or versions may not be covered yet. Try to match versions of Jest and `@types/jest` as closely as possible. For example, if you are using Jest `27.4.0` then installing `27.4.x` of `@types/jest` is ideal. diff --git a/website/versioned_docs/version-28.0/GlobalAPI.md b/website/versioned_docs/version-29.0/GlobalAPI.md similarity index 84% rename from website/versioned_docs/version-28.0/GlobalAPI.md rename to website/versioned_docs/version-29.0/GlobalAPI.md index 12f9f9a87c56..383ce6845e98 100644 --- a/website/versioned_docs/version-28.0/GlobalAPI.md +++ b/website/versioned_docs/version-29.0/GlobalAPI.md @@ -9,7 +9,7 @@ In your test files, Jest puts each of these methods and objects into the global import TOCInline from '@theme/TOCInline'; - + --- @@ -731,6 +731,86 @@ test.each` }); ``` +### `test.failing(name, fn, timeout)` + +Also under the alias: `it.failing(name, fn, timeout)` + +:::note + +This is only available with the default [jest-circus](https://github.com/facebook/jest/tree/main/packages/jest-circus) runner. + +::: + +Use `test.failing` when you are writing a test and expecting it to fail. These tests will behave the other way normal tests do. If `failing` test will throw any errors then it will pass. If it does not throw it will fail. + +:::tip + +You can use this type of tests i.e. when writing code in a BDD way. In that case the tests will not show up as failing until they pass. Then you can just remove the `failing` modifier to make them pass. + +It can also be a nice way to contribute failing tests to a project, even if you don't know how to fix the bug. + +::: + +Example: + +```js +test.failing('it is not equal', () => { + expect(5).toBe(6); // this test will pass +}); + +test.failing('it is equal', () => { + expect(10).toBe(10); // this test will fail +}); +``` + +### `test.failing.each(name, fn, timeout)` + +Also under the alias: `it.failing.each(table)(name, fn)` and `` it.failing.each`table`(name, fn) `` + +:::note + +This is only available with the default [jest-circus](https://github.com/facebook/jest/tree/main/packages/jest-circus) runner. + +::: + +You can also run multiple tests at once by adding `each` after `failing`. + +Example: + +```js +test.failing.each([ + {a: 1, b: 1, expected: 2}, + {a: 1, b: 2, expected: 3}, + {a: 2, b: 1, expected: 3}, +])('.add($a, $b)', ({a, b, expected}) => { + expect(a + b).toBe(expected); +}); +``` + +### `test.only.failing(name, fn, timeout)` + +Also under the aliases: `it.only.failing(name, fn, timeout)`, `fit.failing(name, fn, timeout)` + +:::note + +This is only available with the default [jest-circus](https://github.com/facebook/jest/tree/main/packages/jest-circus) runner. + +::: + +Use `test.only.failing` if you want to only run a specific failing test. + +### `test.skip.failing(name, fn, timeout)` + +Also under the aliases: `it.skip.failing(name, fn, timeout)`, `xit.failing(name, fn, timeout)`, `xtest.failing(name, fn, timeout)` + +:::note + +This is only available with the default [jest-circus](https://github.com/facebook/jest/tree/main/packages/jest-circus) runner. + +::: + +Use `test.skip.failing` if you want to skip running a specific failing test. + ### `test.only(name, fn, timeout)` Also under the aliases: `it.only(name, fn, timeout)`, and `fit(name, fn, timeout)` @@ -878,3 +958,108 @@ const add = (a, b) => a + b; test.todo('add should be associative'); ``` + +## TypeScript Usage + +:::info + +These TypeScript usage tips and caveats are only applicable if you import from `'@jest/globals'`: + +```ts +import {describe, test} from '@jest/globals'; +``` + +::: + +### `.each` + +The `.each` modifier offers few different ways to define a table of the test cases. Some of the APIs have caveats related with the type inference of the arguments which are passed to `describe` or `test` callback functions. Let's take a look at each of them. + +:::note + +For simplicity `test.each` is picked for the examples, but the type inference is identical in all cases where `.each` modifier can be used: `describe.each`, `test.concurrent.only.each`, `test.skip.each`, etc. + +::: + +#### Array of objects + +The array of objects API is most verbose, but it makes the type inference a painless task. A `table` can be inlined: + +```ts +test.each([ + {name: 'a', path: 'path/to/a', count: 1, write: true}, + {name: 'b', path: 'path/to/b', count: 3}, +])('inline table', ({name, path, count, write}) => { + // arguments are typed as expected, e.g. `write: boolean | undefined` +}); +``` + +Or declared separately as a variable: + +```ts +const table = [ + {a: 1, b: 2, expected: 'three', extra: true}, + {a: 3, b: 4, expected: 'seven', extra: false}, + {a: 5, b: 6, expected: 'eleven'}, +]; + +test.each(table)('table as a variable', ({a, b, expected, extra}) => { + // again everything is typed as expected, e.g. `extra: boolean | undefined` +}); +``` + +#### Array of arrays + +The array of arrays style will work smoothly with inlined tables: + +```ts +test.each([ + [1, 2, 'three', true], + [3, 4, 'seven', false], + [5, 6, 'eleven'], +])('inline table example', (a, b, expected, extra) => { + // arguments are typed as expected, e.g. `extra: boolean | undefined` +}); +``` + +However, if a table is declared as a separate variable, it must be typed as an array of tuples for correct type inference (this is not needed only if all elements of a row are of the same type): + +```ts +const table: Array<[number, number, string, boolean?]> = [ + [1, 2, 'three', true], + [3, 4, 'seven', false], + [5, 6, 'eleven'], +]; + +test.each(table)('table as a variable example', (a, b, expected, extra) => { + // without the annotation types are incorrect, e.g. `a: number | string | boolean` +}); +``` + +#### Template literal + +If all values are of the same type, the template literal API will type the arguments correctly: + +```ts +test.each` + a | b | expected + ${1} | ${2} | ${3} + ${3} | ${4} | ${7} + ${5} | ${6} | ${11} +`('template literal example', ({a, b, expected}) => { + // all arguments are of type `number` +}); +``` + +Otherwise it will require a generic type argument: + +```ts +test.each<{a: number; b: number; expected: string; extra?: boolean}>` + a | b | expected | extra + ${1} | ${2} | ${'three'} | ${true} + ${3} | ${4} | ${'seven'} | ${false} + ${5} | ${6} | ${'eleven'} +`('template literal example', ({a, b, expected, extra}) => { + // without the generic argument in this case types would default to `unknown` +}); +``` diff --git a/website/versioned_docs/version-28.1/JestCommunity.md b/website/versioned_docs/version-29.0/JestCommunity.md similarity index 95% rename from website/versioned_docs/version-28.1/JestCommunity.md rename to website/versioned_docs/version-29.0/JestCommunity.md index af71f2e575ae..efeab0b3adf6 100644 --- a/website/versioned_docs/version-28.1/JestCommunity.md +++ b/website/versioned_docs/version-29.0/JestCommunity.md @@ -12,7 +12,7 @@ The community around Jest is working hard to make the testing experience even gr - [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) - [awesome-jest](https://github.com/jest-community/awesome-jest) -Community projects under one organisation are a great way for Jest to experiment with new ideas/techniques and approaches. Encourage contributions from the community and publish contributions independently at a faster pace. +Community projects under one organization are a great way for Jest to experiment with new ideas/techniques and approaches. Encourage contributions from the community and publish contributions independently at a faster pace. ## Awesome Jest diff --git a/website/versioned_docs/version-28.1/JestObjectAPI.md b/website/versioned_docs/version-29.0/JestObjectAPI.md similarity index 95% rename from website/versioned_docs/version-28.1/JestObjectAPI.md rename to website/versioned_docs/version-29.0/JestObjectAPI.md index c68f4d009133..add6b8c49a6c 100644 --- a/website/versioned_docs/version-28.1/JestObjectAPI.md +++ b/website/versioned_docs/version-29.0/JestObjectAPI.md @@ -282,6 +282,20 @@ Modules that are mocked with `jest.mock` are mocked only for the file that calls Returns the `jest` object for chaining. +:::tip + +Writing tests in TypeScript? Use [`jest.Mocked`](MockFunctionAPI.md/#jestmockedsource) utility type or [`jest.mocked()`](MockFunctionAPI.md/#jestmockedsource-options) helper method to have your mocked modules typed. + +::: + +### `jest.Mocked` + +See [TypeScript Usage](MockFunctionAPI.md/#jestmockedsource) chapter of Mock Functions page for documentation. + +### `jest.mocked(source, options?)` + +See [TypeScript Usage](MockFunctionAPI.md/#jestmockedsource-options) chapter of Mock Functions page for documentation. + ### `jest.unmock(moduleName)` Indicates that the module system should never return a mocked version of the specified module from `require()` (e.g. that it should always return the real module). @@ -467,7 +481,7 @@ const returnsTrue = jest.fn(() => true); console.log(returnsTrue()); // true; ``` -:::note +:::tip See [Mock Functions](MockFunctionAPI.md#jestfnimplementation) page for details on TypeScript usage. @@ -598,50 +612,6 @@ 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. -### `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(jest.mocked(foo.name).mock.calls).toHaveLength(1); -}); -``` - ## Fake Timers ### `jest.useFakeTimers(fakeTimersConfig?)` diff --git a/website/versioned_docs/version-28.1/JestPlatform.md b/website/versioned_docs/version-29.0/JestPlatform.md similarity index 100% rename from website/versioned_docs/version-28.1/JestPlatform.md rename to website/versioned_docs/version-29.0/JestPlatform.md diff --git a/website/versioned_docs/version-28.1/ManualMocks.md b/website/versioned_docs/version-29.0/ManualMocks.md similarity index 100% rename from website/versioned_docs/version-28.1/ManualMocks.md rename to website/versioned_docs/version-29.0/ManualMocks.md diff --git a/website/versioned_docs/version-28.1/MigrationGuide.md b/website/versioned_docs/version-29.0/MigrationGuide.md similarity index 100% rename from website/versioned_docs/version-28.1/MigrationGuide.md rename to website/versioned_docs/version-29.0/MigrationGuide.md diff --git a/website/versioned_docs/version-28.1/MockFunctionAPI.md b/website/versioned_docs/version-29.0/MockFunctionAPI.md similarity index 88% rename from website/versioned_docs/version-28.1/MockFunctionAPI.md rename to website/versioned_docs/version-29.0/MockFunctionAPI.md index db8f2d5ea4b3..526110167a84 100644 --- a/website/versioned_docs/version-28.1/MockFunctionAPI.md +++ b/website/versioned_docs/version-29.0/MockFunctionAPI.md @@ -520,3 +520,79 @@ test('calculate calls add', () => { expect(mockAdd).toBeCalledWith(1, 2); }); ``` + +### `jest.Mocked` + +The `jest.Mocked` utility type returns the `Source` type wrapped with type definitions of Jest mock function. + +```ts +import {expect, jest, test} from '@jest/globals'; +import type {fetch} from 'node-fetch'; + +jest.mock('node-fetch'); + +let mockedFetch: jest.Mocked; + +afterEach(() => { + mockedFetch.mockClear(); +}); + +test('makes correct call', () => { + mockedFetch = getMockedFetch(); + // ... +}); + +test('returns correct data', () => { + mockedFetch = getMockedFetch(); + // ... +}); +``` + +Types of classes, functions or objects can be passed as type argument to `jest.Mocked`. If you prefer to constrain the input type, use: `jest.MockedClass`, `jest.MockedFunction` or `jest.MockedObject`. + +### `jest.mocked(source, options?)` + +The `mocked()` helper method wraps types of the `source` object and its deep nested members with type definitions of Jest mock function. You can pass `{shallow: true}` as the `options` argument to disable the deeply mocked behavior. + +Returns the `source` object. + +```ts title="song.ts" +export const song = { + one: { + more: { + time: (t: number) => { + return t; + }, + }, + }, +}; +``` + +```ts title="song.test.ts" +import {expect, jest, test} from '@jest/globals'; +import {song} from './song'; + +jest.mock('./song'); +jest.spyOn(console, 'log'); + +const mockedSong = jest.mocked(song); +// or through `jest.Mocked` +// const mockedSong = song as jest.Mocked; + +test('deep method is typed correctly', () => { + mockedSong.one.more.time.mockReturnValue(12); + + expect(mockedSong.one.more.time(10)).toBe(12); + expect(mockedSong.one.more.time.mock.calls).toHaveLength(1); +}); + +test('direct usage', () => { + jest.mocked(console.log).mockImplementation(() => { + return; + }); + + console.log('one more time'); + + expect(jest.mocked(console.log).mock.calls).toHaveLength(1); +}); +``` diff --git a/website/versioned_docs/version-28.1/MockFunctions.md b/website/versioned_docs/version-29.0/MockFunctions.md similarity index 100% rename from website/versioned_docs/version-28.1/MockFunctions.md rename to website/versioned_docs/version-29.0/MockFunctions.md diff --git a/website/versioned_docs/version-28.1/MongoDB.md b/website/versioned_docs/version-29.0/MongoDB.md similarity index 100% rename from website/versioned_docs/version-28.1/MongoDB.md rename to website/versioned_docs/version-29.0/MongoDB.md diff --git a/website/versioned_docs/version-28.1/MoreResources.md b/website/versioned_docs/version-29.0/MoreResources.md similarity index 100% rename from website/versioned_docs/version-28.1/MoreResources.md rename to website/versioned_docs/version-29.0/MoreResources.md diff --git a/website/versioned_docs/version-28.1/Puppeteer.md b/website/versioned_docs/version-29.0/Puppeteer.md similarity index 100% rename from website/versioned_docs/version-28.1/Puppeteer.md rename to website/versioned_docs/version-29.0/Puppeteer.md diff --git a/website/versioned_docs/version-28.1/SetupAndTeardown.md b/website/versioned_docs/version-29.0/SetupAndTeardown.md similarity index 100% rename from website/versioned_docs/version-28.1/SetupAndTeardown.md rename to website/versioned_docs/version-29.0/SetupAndTeardown.md diff --git a/website/versioned_docs/version-28.1/SnapshotTesting.md b/website/versioned_docs/version-29.0/SnapshotTesting.md similarity index 100% rename from website/versioned_docs/version-28.1/SnapshotTesting.md rename to website/versioned_docs/version-29.0/SnapshotTesting.md diff --git a/website/versioned_docs/version-28.1/TestingAsyncCode.md b/website/versioned_docs/version-29.0/TestingAsyncCode.md similarity index 100% rename from website/versioned_docs/version-28.1/TestingAsyncCode.md rename to website/versioned_docs/version-29.0/TestingAsyncCode.md diff --git a/website/versioned_docs/version-28.1/TestingFrameworks.md b/website/versioned_docs/version-29.0/TestingFrameworks.md similarity index 100% rename from website/versioned_docs/version-28.1/TestingFrameworks.md rename to website/versioned_docs/version-29.0/TestingFrameworks.md diff --git a/website/versioned_docs/version-28.1/TimerMocks.md b/website/versioned_docs/version-29.0/TimerMocks.md similarity index 100% rename from website/versioned_docs/version-28.1/TimerMocks.md rename to website/versioned_docs/version-29.0/TimerMocks.md diff --git a/website/versioned_docs/version-28.1/Troubleshooting.md b/website/versioned_docs/version-29.0/Troubleshooting.md similarity index 100% rename from website/versioned_docs/version-28.1/Troubleshooting.md rename to website/versioned_docs/version-29.0/Troubleshooting.md diff --git a/website/versioned_docs/version-28.1/TutorialAsync.md b/website/versioned_docs/version-29.0/TutorialAsync.md similarity index 100% rename from website/versioned_docs/version-28.1/TutorialAsync.md rename to website/versioned_docs/version-29.0/TutorialAsync.md diff --git a/website/versioned_docs/version-28.1/TutorialReact.md b/website/versioned_docs/version-29.0/TutorialReact.md similarity index 100% rename from website/versioned_docs/version-28.1/TutorialReact.md rename to website/versioned_docs/version-29.0/TutorialReact.md diff --git a/website/versioned_docs/version-28.1/TutorialReactNative.md b/website/versioned_docs/version-29.0/TutorialReactNative.md similarity index 100% rename from website/versioned_docs/version-28.1/TutorialReactNative.md rename to website/versioned_docs/version-29.0/TutorialReactNative.md diff --git a/website/versioned_docs/version-28.1/TutorialjQuery.md b/website/versioned_docs/version-29.0/TutorialjQuery.md similarity index 100% rename from website/versioned_docs/version-28.1/TutorialjQuery.md rename to website/versioned_docs/version-29.0/TutorialjQuery.md diff --git a/website/versioned_docs/version-29.0/UpgradingToJest29.md b/website/versioned_docs/version-29.0/UpgradingToJest29.md new file mode 100644 index 000000000000..07ec834fd453 --- /dev/null +++ b/website/versioned_docs/version-29.0/UpgradingToJest29.md @@ -0,0 +1,77 @@ +--- +id: upgrading-to-jest29 +title: From v28 to v29 +--- + +Upgrading Jest from v28 to v29? This guide aims to help refactoring your configuration and tests. + +:::info + +See [changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md#2900) for the full list of changes. + +::: + +:::note + +Upgrading from an older version? You can see the upgrade guide from v27 to v28 [here](/docs/28.x/upgrading-to-jest28). + +::: + +## Compatibility + +The supported Node versions are 14.15, 16.10, 18.0 and above. + +## Snapshot format + +As announced in the [Jest 28 blog post](/blog/2022/04/25/jest-28#future), Jest 29 has changed the default snapshot formatting to `{escapeString: false, printBasicPrototype: false}`. + +If you want to keep the old behavior, you can set the `snapshotFormat` property to: + +```diff ++ snapshotFormat: { ++ escapeString: true, ++ printBasicPrototype: true ++ } +``` + +## JSDOM upgrade + +`jest-environment-jsdom` has upgraded `jsdom` from v19 to v20. Note that _if_ you use `jest-environment-jsdom`, the minimum TypeScript version is set to `4.5`. + +Notably, `jsdom@20` includes support for `crypto.getRandomValues()`, which means packages like `jsdom` and `nanoid`, which doesn't work properly in Jest@28, can work without extra polyfills. + +## `pretty-format` + +`ConvertAnsi` plugin is removed from `pretty-format` package in favour of [`jest-serializer-ansi-escapes`](https://github.com/mrazauskas/jest-serializer-ansi-escapes). + +### `jest-mock` + +Exports of `Mocked*` utility types from `jest-mock` package have changed. `MaybeMockedDeep` and `MaybeMocked` now are exported as `Mocked` and `MockedShallow` respectively; only deep mocked variants of `MockedClass`, `MockedFunction` and `MockedObject` are exposed. + +## TypeScript + +:::info + +The TypeScript examples from this page will only work as documented if you import `jest` from `'@jest/globals'`: + +```ts +import {jest} from '@jest/globals'; +``` + +::: + +### `jest.mocked()` + +The [`jest.mocked()`](MockFunctionAPI.md/#jestmockedsource-options) helper method now wraps types of deep members of passed object by default. If you have used the method with `true` as the second argument, remove it to avoid type errors: + +```diff +- const mockedObject = jest.mocked(someObject, true); ++ const mockedObject = jest.mocked(someObject); +``` + +To have the old shallow mocked behavior, pass `{shallow: true}` as the second argument: + +```diff +- const mockedObject = jest.mocked(someObject); ++ const mockedObject = jest.mocked(someObject, {shallow: true}); +``` diff --git a/website/versioned_docs/version-28.1/UsingMatchers.md b/website/versioned_docs/version-29.0/UsingMatchers.md similarity index 100% rename from website/versioned_docs/version-28.1/UsingMatchers.md rename to website/versioned_docs/version-29.0/UsingMatchers.md diff --git a/website/versioned_docs/version-28.1/WatchPlugins.md b/website/versioned_docs/version-29.0/WatchPlugins.md similarity index 100% rename from website/versioned_docs/version-28.1/WatchPlugins.md rename to website/versioned_docs/version-29.0/WatchPlugins.md diff --git a/website/versioned_docs/version-28.1/Webpack.md b/website/versioned_docs/version-29.0/Webpack.md similarity index 100% rename from website/versioned_docs/version-28.1/Webpack.md rename to website/versioned_docs/version-29.0/Webpack.md diff --git a/website/versioned_sidebars/version-28.0-sidebars.json b/website/versioned_sidebars/version-28.x-sidebars.json similarity index 100% rename from website/versioned_sidebars/version-28.0-sidebars.json rename to website/versioned_sidebars/version-28.x-sidebars.json diff --git a/website/versioned_sidebars/version-28.1-sidebars.json b/website/versioned_sidebars/version-29.0-sidebars.json similarity index 97% rename from website/versioned_sidebars/version-28.1-sidebars.json rename to website/versioned_sidebars/version-29.0-sidebars.json index 7e109761b982..72f8506cbd5d 100644 --- a/website/versioned_sidebars/version-28.1-sidebars.json +++ b/website/versioned_sidebars/version-29.0-sidebars.json @@ -34,7 +34,7 @@ "testing-frameworks" ], "Upgrade Guides": [ - "upgrading-to-jest28" + "upgrading-to-jest29" ] }, "api": [ diff --git a/website/versions.json b/website/versions.json index d1926a2b78d0..17c7b3f91ef3 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,6 +1,6 @@ [ - "28.1", - "28.0", + "29.0", + "28.x", "27.x", "26.x", "25.x"