diff --git a/CHANGELOG.md b/CHANGELOG.md index 96547b440a06..6373e35b745b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,28 @@ ### Fixes -- `[jest-snapshot]` Pass `snapshotFormat` through when diffing snapshots ([#13181](https://github.com/facebook/jest/pull/13181)) - ### Chore & Maintenance ### Performance +## 29.0.2 + +### Features + +- `[jest-transform]` Expose `TransformFactory` type ([#13184](https://github.com/facebook/jest/pull/13184)) + +### Fixes + +- `[babel-plugin-jest-hoist]` Support imported `jest` in mock factory ([#13188](https://github.com/facebook/jest/pull/13188)) +- `[jest-mock]` Align the behavior and return type of `generateFromMetadata` method ([#13207](https://github.com/facebook/jest/pull/13207)) +- `[jest-runtime]` Support `jest.resetModules()` with ESM ([#13211](https://github.com/facebook/jest/pull/13211)) + +## 29.0.1 + +### Fixes + +- `[jest-snapshot]` Pass `snapshotFormat` through when diffing snapshots ([#13181](https://github.com/facebook/jest/pull/13181)) + ## 29.0.0 ### Features diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa0ccdb5b328..68902505e39f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -108,7 +108,7 @@ Code that is written needs to be tested to ensure that it achieves the desired b ##### Unit tests -Some of the packages within jest have a `__tests__` directory. This is where unit tests reside in. If the scope of your work only requires a unit test, this is where you will write it in. Tests here usually don't require much if any setup. +Some of the packages within jest have a `__tests__` directory. This is where unit tests reside in. If the scope of your work only requires a unit test, this is where you will write it in. Tests here usually don't require much of any setup. ##### Integration tests diff --git a/docs/Configuration.md b/docs/Configuration.md index d6762ea4b695..ac2047fff049 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -2305,7 +2305,11 @@ After the worker has executed a test the memory usage of it is checked. If it ex - `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. +:::caution + +Percentage based memory limit [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} */ diff --git a/docs/ExpectAPI.md b/docs/ExpectAPI.md index aa25136d861b..34291ecbec20 100644 --- a/docs/ExpectAPI.md +++ b/docs/ExpectAPI.md @@ -7,6 +7,16 @@ When you're writing tests, you often need to check that values meet certain cond For additional Jest matchers maintained by the Jest Community check out [`jest-extended`](https://github.com/jest-community/jest-extended). +:::info + +The TypeScript examples from this page will only work as documented if you import `expect` from `'@jest/globals'`: + +```ts +import {expect} from '@jest/globals'; +``` + +::: + ## Methods import TOCInline from '@theme/TOCInline'; @@ -37,29 +47,141 @@ The argument to `expect` should be the value that your code produces, and any ar You can use `expect.extend` to add your own matchers to Jest. For example, let's say that you're testing a number utility library and you're frequently asserting that numbers appear within particular ranges of other numbers. You could abstract that into a `toBeWithinRange` matcher: -```js +```js tab={"span":3} title="toBeWithinRange.js" +import {expect} from '@jest/globals'; + +function toBeWithinRange(actual, floor, ceiling) { + if ( + typeof actual !== 'number' || + typeof floor !== 'number' || + typeof ceiling !== 'number' + ) { + throw new Error('These must be of type number!'); + } + + const pass = actual >= floor && actual <= ceiling; + if (pass) { + return { + message: () => + `expected ${this.utils.printReceived( + actual, + )} not to be within range ${this.utils.printExpected( + `${floor} - ${ceiling}`, + )}`, + pass: true, + }; + } else { + return { + message: () => + `expected ${this.utils.printReceived( + actual, + )} to be within range ${this.utils.printExpected( + `${floor} - ${ceiling}`, + )}`, + pass: false, + }; + } +} + expect.extend({ - toBeWithinRange(received, floor, ceiling) { - const pass = received >= floor && received <= ceiling; + toBeWithinRange, +}); +``` + +```js title="__tests__/ranges.test.js" +import {expect, test} from '@jest/globals'; +import '../toBeWithinRange'; + +test('is within range', () => expect(100).toBeWithinRange(90, 110)); + +test('is NOT within range', () => expect(101).not.toBeWithinRange(0, 100)); + +test('asymmetric ranges', () => { + expect({apples: 6, bananas: 3}).toEqual({ + apples: expect.toBeWithinRange(1, 10), + bananas: expect.not.toBeWithinRange(11, 20), + }); +}); +``` + +```ts title="toBeWithinRange.d.ts" +// optionally add a type declaration, e.g. it enables autocompletion in IDEs +declare module 'expect' { + interface AsymmetricMatchers { + toBeWithinRange(floor: number, ceiling: number): void; + } + interface Matchers { + toBeWithinRange(floor: number, ceiling: number): R; + } +} + +export {}; +``` + +```ts tab={"span":2} title="toBeWithinRange.ts" +import {expect} from '@jest/globals'; +import type {MatcherFunction} from 'expect'; + +const toBeWithinRange: MatcherFunction<[floor: unknown, ceiling: unknown]> = + // `floor` and `ceiling` get types from the line above + // it is recommended to type them as `unknown` and to validate the values + function (actual, floor, ceiling) { + if ( + typeof actual !== 'number' || + typeof floor !== 'number' || + typeof ceiling !== 'number' + ) { + throw new Error('These must be of type number!'); + } + + const pass = actual >= floor && actual <= ceiling; if (pass) { return { message: () => - `expected ${received} not to be within range ${floor} - ${ceiling}`, + // `this` context will have correct typings + `expected ${this.utils.printReceived( + actual, + )} not to be within range ${this.utils.printExpected( + `${floor} - ${ceiling}`, + )}`, pass: true, }; } else { return { message: () => - `expected ${received} to be within range ${floor} - ${ceiling}`, + `expected ${this.utils.printReceived( + actual, + )} to be within range ${this.utils.printExpected( + `${floor} - ${ceiling}`, + )}`, pass: false, }; } - }, + }; + +expect.extend({ + toBeWithinRange, }); -test('numeric ranges', () => { - expect(100).toBeWithinRange(90, 110); - expect(101).not.toBeWithinRange(0, 100); +declare module 'expect' { + interface AsymmetricMatchers { + toBeWithinRange(floor: number, ceiling: number): void; + } + interface Matchers { + toBeWithinRange(floor: number, ceiling: number): R; + } +} +``` + +```ts tab title="__tests__/ranges.test.ts" +import {expect, test} from '@jest/globals'; +import '../toBeWithinRange'; + +test('is within range', () => expect(100).toBeWithinRange(90, 110)); + +test('is NOT within range', () => expect(101).not.toBeWithinRange(0, 100)); + +test('asymmetric ranges', () => { expect({apples: 6, bananas: 3}).toEqual({ apples: expect.toBeWithinRange(1, 10), bananas: expect.not.toBeWithinRange(11, 20), @@ -67,22 +189,24 @@ test('numeric ranges', () => { }); ``` -:::note +:::tip -In TypeScript, when using `@types/jest` for example, you can declare the new `toBeWithinRange` matcher in the imported module like this: +The type declaration of the matcher can live in a `.d.ts` file or in an imported `.ts` module (see JS and TS examples above respectively). If you keep the declaration in a `.d.ts` file, make sure that it is included in the program and that it is a valid module, i.e. it has at least an empty `export {}`. -```ts -interface CustomMatchers { - toBeWithinRange(floor: number, ceiling: number): R; -} +::: -declare global { - namespace jest { - interface Expect extends CustomMatchers {} - interface Matchers extends CustomMatchers {} - interface InverseAsymmetricMatchers extends CustomMatchers {} - } -} +:::tip + +Instead of importing `toBeWithinRange` module to the test file, you can enable the matcher for all tests by moving the `expect.extend` call to a [`setupFilesAfterEnv`](Configuration.md/#setupfilesafterenv-array) script: + +```js +import {expect} from '@jest/globals'; +// remember to export `toBeWithinRange` as well +import {toBeWithinRange} from './toBeWithinRange'; + +expect.extend({ + toBeWithinRange, +}); ``` ::: diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 7b6e4b17de31..15632501f53a 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -156,7 +156,7 @@ npm install --save-dev ts-jest #### Type definitions -There are two ways have [Jest global APIs](GlobalAPI.md) typed for test files written in TypeScript. +There are two ways to have [Jest global APIs](GlobalAPI.md) typed for test files written in TypeScript. 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: diff --git a/docs/GlobalAPI.md b/docs/GlobalAPI.md index 383ce6845e98..f41f1eedcbc4 100644 --- a/docs/GlobalAPI.md +++ b/docs/GlobalAPI.md @@ -19,7 +19,7 @@ import TOCInline from '@theme/TOCInline'; Runs a function after all the tests in this file have completed. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to clean up some global setup state that is shared across tests. @@ -59,7 +59,7 @@ If you want to run some cleanup after every test instead of after all tests, use Runs a function after each one of the tests in this file completes. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to clean up some temporary state that is created by each test. @@ -99,7 +99,7 @@ If you want to run some cleanup just once, after all of the tests run, use `afte Runs a function before any of the tests in this file run. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running tests. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to set up some global state that will be used by many tests. @@ -135,7 +135,7 @@ If you want to run something before every test instead of before any test runs, Runs a function before each of the tests in this file runs. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running the test. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to reset some global state that will be used by many tests. @@ -232,8 +232,8 @@ Use `describe.each` if you keep duplicating the same test suites with different #### 1. `describe.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]`. + - `name`: `String` the title of the test suite. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -250,7 +250,7 @@ Use `describe.each` if you keep duplicating the same test suites with different - You can use `$#` to inject the index of the test case - You cannot use `$variable` with the `printf` formatting except for `%%` - `fn`: `Function` the suite of tests to be ran, this is the function that will receive the parameters in each row as function arguments. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -302,7 +302,7 @@ describe.each([ - `name`: `String` the title of the test suite, use `$variable` to inject test data into the suite title from the tagged template expressions, and `$#` for the index of the row. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the suite of tests to be ran, this is the function that will receive the test data object. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -475,11 +475,9 @@ test('did not rain', () => { }); ``` -The first argument is the test name; the second argument is a function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ - -> Note: If a **promise is returned** from `test`, Jest will wait for the promise to resolve before letting the test complete. Jest will also wait if you **provide an argument to the test function**, usually called `done`. This could be handy when you want to test callbacks. See how to test async code [here](TestingAsyncCode.md#callbacks). +The first argument is the test name; the second argument is a function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. -For example, let's say `fetchBeverageList()` returns a promise that is supposed to resolve to a list that has `lemon` in it. You can test this with: +If a **promise is returned** from `test`, Jest will wait for the promise to resolve before letting the test complete. For example, let's say `fetchBeverageList()` returns a promise that is supposed to resolve to a list that has `lemon` in it. You can test this with: ```js test('has lemon in it', () => { @@ -489,19 +487,29 @@ test('has lemon in it', () => { }); ``` -Even though the call to `test` will return right away, the test doesn't complete until the promise resolves as well. +Even though the call to `test` will return right away, the test doesn't complete until the promise resolves. For more details, see [Testing Asynchronous Code](TestingAsyncCode.md) page. + +:::tip + +Jest will also wait if you **provide an argument to the test function**, usually called `done`. This could be handy when you want to test [callbacks](TestingAsyncCode.md#callbacks). + +::: ### `test.concurrent(name, fn, timeout)` Also under the alias: `it.concurrent(name, fn, timeout)` -Use `test.concurrent` if you want the test to run concurrently. +:::caution -> Note: `test.concurrent` is considered experimental - see [here](https://github.com/facebook/jest/labels/Area%3A%20Concurrent) for details on missing features and other issues +`test.concurrent` is considered experimental - see [here](https://github.com/facebook/jest/labels/Area%3A%20Concurrent) for details on missing features and other issues. -The first argument is the test name; the second argument is an asynchronous function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +::: -``` +Use `test.concurrent` if you want the test to run concurrently. + +The first argument is the test name; the second argument is an asynchronous function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. + +```js test.concurrent('addition of 2 numbers', async () => { expect(5 + 3).toBe(8); }); @@ -511,7 +519,11 @@ test.concurrent('subtraction 2 numbers', async () => { }); ``` -> Note: Use `maxConcurrency` in configuration to prevents Jest from executing more than the specified amount of tests at the same time +:::tip + +Use [`maxConcurrency`](Configuration.md/#maxconcurrency-number) configuration option to prevent Jest from executing more than the specified amount of tests at the same time. + +::: ### `test.concurrent.each(table)(name, fn, timeout)` @@ -523,8 +535,7 @@ Use `test.concurrent.each` if you keep duplicating the same test with different #### 1. `test.concurrent.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` - `name`: `String` the title of the test block. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -537,7 +548,7 @@ Use `test.concurrent.each` if you keep duplicating the same test with different - `%#` - Index of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - `fn`: `Function` the test to be ran, this is the function that will receive the parameters in each row as function arguments, **this will have to be an asynchronous function**. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -559,7 +570,7 @@ test.concurrent.each([ - `name`: `String` the title of the test, use `$variable` to inject test data into the test title from the tagged template expressions. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the test to be ran, this is the function that will receive the test data object, **this will have to be an asynchronous function**. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -666,8 +677,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test #### 1. `test.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` - `name`: `String` the title of the test block. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -684,7 +694,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test - You can use `$#` to inject the index of the test case - You cannot use `$variable` with the `printf` formatting except for `%%` - `fn`: `Function` the test to be ran, this is the function that will receive the parameters in each row as function arguments. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -716,7 +726,7 @@ test.each([ - `name`: `String` the title of the test, use `$variable` to inject test data into the test title from the tagged template expressions. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the test to be ran, this is the function that will receive the test data object. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -817,7 +827,7 @@ Also under the aliases: `it.only(name, fn, timeout)`, and `fit(name, fn, timeout When you are debugging a large test file, you will often only want to run a subset of tests. You can use `.only` to specify which tests are the only ones you want to run in that test file. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. For example, let's say you had these tests: @@ -945,20 +955,18 @@ Also under the alias: `it.todo(name)` Use `test.todo` when you are planning on writing tests. These tests will be highlighted in the summary output at the end so you know how many tests you still need todo. -_Note_: If you supply a test callback function then the `test.todo` will throw an error. If you have already implemented the test and it is broken and you do not want it to run, then use `test.skip` instead. - -#### API - -- `name`: `String` the title of the test plan. - -Example: - ```js const add = (a, b) => a + b; test.todo('add should be associative'); ``` +:::tip + +`test.todo` will throw an error, if you will pass it a test callback function. Use [`test.skip`](#testskipname-fn) instead, if you already implemented the test, but do not want it to run. + +::: + ## TypeScript Usage :::info diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index 1e6cd80fa82e..4324b26d16c4 100644 --- a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -10,7 +10,7 @@ Ran all test suites matching /native-esm-deep-cjs-reexport.test.js/i." exports[`runs test with native ESM 1`] = ` "Test Suites: 1 passed, 1 total -Tests: 33 passed, 33 total +Tests: 34 passed, 34 total Snapshots: 0 total Time: <> Ran all test suites matching /native-esm.test.js/i." diff --git a/e2e/__tests__/__snapshots__/testFailingJasmine.test.ts.snap b/e2e/__tests__/__snapshots__/testFailingJasmine.test.ts.snap index 2a6200f91f69..b78baf85b380 100644 --- a/e2e/__tests__/__snapshots__/testFailingJasmine.test.ts.snap +++ b/e2e/__tests__/__snapshots__/testFailingJasmine.test.ts.snap @@ -46,7 +46,7 @@ FAIL __tests__/worksWithConcurrentMode.test.js 15 | }); 16 | - at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:197:11) + at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:198:11) at Suite.failing (__tests__/worksWithConcurrentMode.test.js:13:17) at Object.describe (__tests__/worksWithConcurrentMode.test.js:8:1) @@ -80,7 +80,7 @@ FAIL __tests__/worksWithConcurrentOnlyMode.test.js 15 | }); 16 | - at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:197:11) + at Function.failing (../../packages/jest-jasmine2/build/jasmineAsyncInstall.js:198:11) at Suite.failing (__tests__/worksWithConcurrentOnlyMode.test.js:13:22) at Object.describe (__tests__/worksWithConcurrentOnlyMode.test.js:8:1) diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js index aeac49331cb7..767f1cbf27c7 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -46,6 +46,7 @@ test('should support importing node core modules', () => { expect(JSON.parse(readFileSync(packageJsonPath, 'utf8'))).toEqual({ devDependencies: { 'discord.js': '14.3.0', + yargs: '^17.5.1', }, jest: { testEnvironment: 'node', @@ -234,31 +235,29 @@ test('supports imports from "data:text/javascript" URI without explicit encoding test('imports from "data:text/javascript" URI with invalid encoding fail', async () => { const code = 'export const something = "some value"'; - await expect( - async () => - await import( - `data:text/javascript;charset=badEncoding,${encodeURIComponent(code)}` - ), + await expect(() => + import( + `data:text/javascript;charset=badEncoding,${encodeURIComponent(code)}` + ), ).rejects.toThrow('Invalid data URI'); }); test('imports from "data:" URI with invalid mime type fail', async () => { const code = 'export const something = "some value"'; - await expect( - async () => await import(`data:something/else,${encodeURIComponent(code)}`), + await expect(() => + import(`data:something/else,${encodeURIComponent(code)}`), ).rejects.toThrow('Invalid data URI'); }); test('imports from "data:text/javascript" URI with invalid data fail', async () => { - await expect( - async () => - await import('data:text/javascript;charset=utf-8,so(me)+.-gibberish'), + await expect(() => + import('data:text/javascript;charset=utf-8,so(me)+.-gibberish'), ).rejects.toThrow("Unexpected token '.'"); }); test('imports from "data:application/wasm" URI not supported', async () => { - await expect( - async () => await import('data:application/wasm,96cafe00babe'), + await expect(() => + import('data:application/wasm,96cafe00babe'), ).rejects.toThrow('WASM is currently not supported'); }); @@ -302,3 +301,24 @@ test('can mock "data:" URI module', async () => { const mocked = await import(dataModule); expect(mocked.foo).toBe('bar'); }); + +test('can import with module reset', async () => { + const {default: yargs} = await import('yargs'); + const {default: yargsAgain} = await import('yargs'); + + expect(yargs).toBe(yargsAgain); + + let args = yargs().parse([]); + + expect(args._).toEqual([]); + + jestObject.resetModules(); + + const {default: yargsYetAgain} = await import('yargs'); + + expect(yargs).not.toBe(yargsYetAgain); + + args = yargsYetAgain().parse([]); + + expect(args._).toEqual([]); +}); diff --git a/e2e/native-esm/package.json b/e2e/native-esm/package.json index 7e5307b71f1d..60993c0776ca 100644 --- a/e2e/native-esm/package.json +++ b/e2e/native-esm/package.json @@ -1,7 +1,8 @@ { "type": "module", "devDependencies": { - "discord.js": "14.3.0" + "discord.js": "14.3.0", + "yargs": "^17.5.1" }, "jest": { "testEnvironment": "node", diff --git a/e2e/native-esm/yarn.lock b/e2e/native-esm/yarn.lock index 737d96c077d9..227ec7c5703f 100644 --- a/e2e/native-esm/yarn.lock +++ b/e2e/native-esm/yarn.lock @@ -48,12 +48,12 @@ __metadata: linkType: hard "@sapphire/shapeshift@npm:^3.5.1": - version: 3.5.1 - resolution: "@sapphire/shapeshift@npm:3.5.1" + version: 3.6.0 + resolution: "@sapphire/shapeshift@npm:3.6.0" dependencies: fast-deep-equal: ^3.1.3 lodash.uniqwith: ^4.5.0 - checksum: caecfef844c9e43e921a5051da888fae7da8980bfd9f9bb4f7fee85931d40929ffb9b6dfae464c0dccee61e56f7698f998e4d9a54d25f35fad39a51ba1a4f391 + checksum: 31b426424d064c516144c6eda07dfa0e44d7cbb8309dde919b923aa6ae939faac6384fa4d08db391a8da11efa3a83c18c9be1ebd053ba29403e61f5e2450b788 languageName: node linkType: hard @@ -72,9 +72,9 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 18.7.13 - resolution: "@types/node@npm:18.7.13" - checksum: 45431e7e89ecaf85c7d2c180d801c132a7c59e2f8ad578726b6d71cc74e3267c18f9ccdcad738bc0479790c078f0c79efb0e58da2c6be535c15995dbb19050c9 + version: 18.7.14 + resolution: "@types/node@npm:18.7.14" + checksum: 99cf28ff854100158de875cca23c7acc3cc01dfee526a52b90b7f36767c821bcbaf2be0a98a70f06f3b78f3c60639168ff949d725b61e2e124f9f71f1fb8043d languageName: node linkType: hard @@ -87,10 +87,53 @@ __metadata: languageName: node linkType: hard +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: ^2.0.1 + checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 + languageName: node + linkType: hard + +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^7.0.0 + checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: ~1.1.4 + checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + "discord-api-types@npm:^0.37.3": - version: 0.37.4 - resolution: "discord-api-types@npm:0.37.4" - checksum: 18b74acfcd5f6c554668eb5cb31a5db9076dfb5cb6b5c538a342ab9d22816644bada22a66285468fe7dd9980287921d5d50ba3b11cc8e391fe4f09e761bcd179 + version: 0.37.5 + resolution: "discord-api-types@npm:0.37.5" + checksum: 10a23b813d9a30d836aa27169f768883eeed971ab67e58325ff272bfe6b63b169d727ae983d7c1b69c7e0b02ed9072e66e79319ce48174b36cd4a2a5fafe2e9f languageName: node linkType: hard @@ -113,6 +156,20 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -131,6 +188,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + "ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -145,6 +209,13 @@ __metadata: languageName: node linkType: hard +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + "lodash.snakecase@npm:^4.1.1": version: 4.1.1 resolution: "lodash.snakecase@npm:4.1.1" @@ -186,11 +257,19 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 + languageName: node + linkType: hard + "root-workspace-0b6124@workspace:.": version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: discord.js: 14.3.0 + yargs: ^17.5.1 languageName: unknown linkType: soft @@ -201,6 +280,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: ^8.0.0 + is-fullwidth-code-point: ^3.0.0 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + "string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" @@ -210,6 +300,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + "strtok3@npm:^7.0.0-alpha.9": version: 7.0.0 resolution: "strtok3@npm:7.0.0" @@ -258,6 +357,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + "ws@npm:^8.8.1": version: 8.8.1 resolution: "ws@npm:8.8.1" @@ -272,3 +382,32 @@ __metadata: checksum: 2152cf862cae0693f3775bc688a6afb2e989d19d626d215e70f5fcd8eb55b1c3b0d3a6a4052905ec320e2d7734e20aeedbf9744496d62f15a26ad79cf4cf7dae languageName: node linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 + languageName: node + linkType: hard + +"yargs-parser@npm:^21.0.0": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: ed2d96a616a9e3e1cc7d204c62ecc61f7aaab633dcbfab2c6df50f7f87b393993fe6640d017759fe112d0cb1e0119f2b4150a87305cc873fd90831c6a58ccf1c + languageName: node + linkType: hard + +"yargs@npm:^17.5.1": + version: 17.5.1 + resolution: "yargs@npm:17.5.1" + dependencies: + cliui: ^7.0.2 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.0.0 + checksum: 00d58a2c052937fa044834313f07910fd0a115dec5ee35919e857eeee3736b21a4eafa8264535800ba8bac312991ce785ecb8a51f4d2cc8c4676d865af1cfbde + languageName: node + linkType: hard diff --git a/examples/angular/package.json b/examples/angular/package.json index d7e38c7293e0..4e651adc9bd8 100644 --- a/examples/angular/package.json +++ b/examples/angular/package.json @@ -15,7 +15,7 @@ "core-js": "^3.2.1", "rxjs": "^7.5.5", "tslib": "^2.0.0", - "typescript": "^4.7.4", + "typescript": "^4.8.2", "zone.js": "~0.11.3" }, "devDependencies": { diff --git a/examples/expect-extend/package.json b/examples/expect-extend/package.json index 161c3c2b5b3b..c1c5e8ea2798 100644 --- a/examples/expect-extend/package.json +++ b/examples/expect-extend/package.json @@ -9,7 +9,8 @@ "@jest/globals": "workspace:*", "babel-jest": "workspace:*", "expect": "workspace:*", - "jest": "workspace:*" + "jest": "workspace:*", + "typescript": "^4.8.2" }, "scripts": { "test": "jest" diff --git a/examples/expect-extend/toBeWithinRange.ts b/examples/expect-extend/toBeWithinRange.ts index 43be8cfe431a..a7492603b9ab 100644 --- a/examples/expect-extend/toBeWithinRange.ts +++ b/examples/expect-extend/toBeWithinRange.ts @@ -8,8 +8,8 @@ import {expect} from '@jest/globals'; import type {MatcherFunction} from 'expect'; -const toBeWithinRange: MatcherFunction<[floor: number, ceiling: number]> = - function (actual: unknown, floor: unknown, ceiling: unknown) { +const toBeWithinRange: MatcherFunction<[floor: unknown, ceiling: unknown]> = + function (actual, floor, ceiling) { if ( typeof actual !== 'number' || typeof floor !== 'number' || diff --git a/examples/typescript/package.json b/examples/typescript/package.json index 938f9aa1698c..6799e61d96dc 100644 --- a/examples/typescript/package.json +++ b/examples/typescript/package.json @@ -5,7 +5,7 @@ "dependencies": { "react": "17.0.2", "react-dom": "^17.0.1", - "typescript": "^4.7.4" + "typescript": "^4.8.2" }, "devDependencies": { "@babel/core": "^7.11.6", diff --git a/lerna.json b/lerna.json index f68543e352db..890e2122ce7e 100644 --- a/lerna.json +++ b/lerna.json @@ -8,5 +8,5 @@ "syncWorkspaceLock": true } }, - "version": "29.0.1" + "version": "29.0.2" } diff --git a/package.json b/package.json index b78221f4388a..82eea80f8b1d 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@lerna-lite/cli": "^1.10.0", "@microsoft/api-extractor": "^7.29.0", "@tsconfig/node14": "^1.0.3", - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/babel__core": "^7.1.14", "@types/babel__generator": "^7.0.0", "@types/babel__template": "^7.0.2", @@ -82,7 +82,7 @@ "tempy": "^1.0.0", "ts-node": "^10.5.0", "type-fest": "^2.11.2", - "typescript": "^4.7.4", + "typescript": "^4.8.2", "which": "^2.0.1" }, "scripts": { @@ -171,6 +171,7 @@ }, "resolutions": { "@types/node": "~14.14.45", + "ansi-escapes/type-fest": "^2.0.0", "babel-jest": "workspace:*", "enzyme/cheerio": "=1.0.0-rc.3", "jest": "workspace:*", diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index 087b7cc4248f..73f788f07203 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -1,7 +1,7 @@ { "name": "babel-jest", "description": "Jest plugin to use babel for transformation.", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/babel-plugin-jest-hoist/package.json b/packages/babel-plugin-jest-hoist/package.json index 3bc83b17ed15..b242dc0b0998 100644 --- a/packages/babel-plugin-jest-hoist/package.json +++ b/packages/babel-plugin-jest-hoist/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-jest-hoist", - "version": "29.0.0", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap b/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap index 584845c2dda4..3a5a0817baed 100644 --- a/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap +++ b/packages/babel-plugin-jest-hoist/src/__tests__/__snapshots__/hoistPlugin.test.ts.snap @@ -38,6 +38,113 @@ function _getJestObj() { } +`; + +exports[`babel-plugin-jest-hoist global jest.mock within jest.mock: global jest.mock within jest.mock 1`] = ` + +jest.mock('some-module', () => { + jest.mock('some-module'); +}); + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().mock('some-module'); +}); + +function _getJestObj() { + const {jest} = require('@jest/globals'); + + _getJestObj = () => jest; + + return jest; +} + + +`; + +exports[`babel-plugin-jest-hoist global jest.requireActual in jest.mock: global jest.requireActual in jest.mock 1`] = ` + +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + +jest.requireActual('some-module'); + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().requireActual('some-module'); +}); + +function _getJestObj() { + const {jest} = require('@jest/globals'); + + _getJestObj = () => jest; + + return jest; +} + +jest.requireActual('some-module'); + + +`; + +exports[`babel-plugin-jest-hoist imported jest.mock within jest.mock: imported jest.mock within jest.mock 1`] = ` + +import {jest} from '@jest/globals'; + +jest.mock('some-module', () => { + jest.mock('some-module'); +}); + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().mock('some-module'); +}); + +function _getJestObj() { + const {jest} = require('@jest/globals'); + + _getJestObj = () => jest; + + return jest; +} + +import {jest} from '@jest/globals'; + + +`; + +exports[`babel-plugin-jest-hoist imported jest.requireActual in jest.mock: imported jest.requireActual in jest.mock 1`] = ` + +import {jest} from '@jest/globals'; + +jest.mock('some-module', () => { + jest.requireActual('some-module'); +}); + +jest.requireActual('some-module'); + + ↓ ↓ ↓ ↓ ↓ ↓ + +_getJestObj().mock('some-module', () => { + _getJestObj().requireActual('some-module'); +}); + +function _getJestObj() { + const {jest} = require('@jest/globals'); + + _getJestObj = () => jest; + + return jest; +} + +import {jest} from '@jest/globals'; +jest.requireActual('some-module'); + + `; exports[`babel-plugin-jest-hoist required \`jest\` within \`jest\`: required \`jest\` within \`jest\` 1`] = ` diff --git a/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts b/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts index c6ad87de8107..685ab680aa75 100644 --- a/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts +++ b/packages/babel-plugin-jest-hoist/src/__tests__/hoistPlugin.test.ts @@ -90,6 +90,50 @@ pluginTester({ formatResult, snapshot: true, }, + 'imported jest.mock within jest.mock': { + code: formatResult(` + import {jest} from '@jest/globals'; + + jest.mock('some-module', () => { + jest.mock('some-module'); + }); + `), + formatResult, + snapshot: true, + }, + 'global jest.mock within jest.mock': { + code: formatResult(` + jest.mock('some-module', () => { + jest.mock('some-module'); + }); + `), + formatResult, + snapshot: true, + }, + 'imported jest.requireActual in jest.mock': { + code: formatResult(` + import {jest} from '@jest/globals'; + + jest.mock('some-module', () => { + jest.requireActual('some-module'); + }); + + jest.requireActual('some-module'); + `), + formatResult, + snapshot: true, + }, + 'global jest.requireActual in jest.mock': { + code: formatResult(` + jest.mock('some-module', () => { + jest.requireActual('some-module'); + }); + + jest.requireActual('some-module'); + `), + formatResult, + snapshot: true, + }, }, /* eslint-enable */ }); diff --git a/packages/babel-plugin-jest-hoist/src/index.ts b/packages/babel-plugin-jest-hoist/src/index.ts index 2218dcec5421..21af10f6c2a2 100644 --- a/packages/babel-plugin-jest-hoist/src/index.ts +++ b/packages/babel-plugin-jest-hoist/src/index.ts @@ -14,6 +14,7 @@ import { CallExpression, Expression, Identifier, + ImportDeclaration, MemberExpression, Node, Program, @@ -31,6 +32,7 @@ const JEST_GLOBALS_MODULE_NAME = '@jest/globals'; const JEST_GLOBALS_MODULE_JEST_EXPORT_NAME = 'jest'; const hoistedVariables = new WeakSet(); +const hoistedJestExpressions = new WeakSet(); // We allow `jest`, `expect`, `require`, all default Node.js globals and all // ES2015 built-ins to be used inside of a `jest.mock` factory. @@ -161,6 +163,19 @@ FUNCTIONS.mock = args => { hoistedVariables.add(node); isAllowedIdentifier = true; } + } else if (binding?.path.isImportSpecifier()) { + const importDecl = binding.path + .parentPath as NodePath; + const imported = binding.path.node.imported; + if ( + importDecl.node.source.value === JEST_GLOBALS_MODULE_NAME && + (isIdentifier(imported) ? imported.name : imported.value) === + JEST_GLOBALS_MODULE_JEST_EXPORT_NAME + ) { + isAllowedIdentifier = true; + // Imports are already hoisted, so we don't need to add it + // to hoistedVariables. + } } } @@ -264,9 +279,26 @@ const extractJestObjExprIfHoistable = ( // Important: Call the function check last // It might throw an error to display to the user, // which should only happen if we're already sure it's a call on the Jest object. - const functionLooksHoistable = FUNCTIONS[propertyName]?.(args); + let functionLooksHoistableOrInHoistable = FUNCTIONS[propertyName]?.(args); + + for ( + let path: NodePath | null = expr; + path && !functionLooksHoistableOrInHoistable; + path = path.parentPath + ) { + functionLooksHoistableOrInHoistable = hoistedJestExpressions.has( + // @ts-expect-error: it's ok if path.node is not an Expression, .has will + // just return false. + path.node, + ); + } + + if (functionLooksHoistableOrInHoistable) { + hoistedJestExpressions.add(expr.node); + return jestObjExpr; + } - return functionLooksHoistable ? jestObjExpr : null; + return null; }; /* eslint-disable sort-keys */ diff --git a/packages/babel-preset-jest/package.json b/packages/babel-preset-jest/package.json index 2fdfd6c8630d..b44264cc6e10 100644 --- a/packages/babel-preset-jest/package.json +++ b/packages/babel-preset-jest/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-jest", - "version": "29.0.0", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/expect-utils/package.json b/packages/expect-utils/package.json index ce9597b17152..a578e06ba9b6 100644 --- a/packages/expect-utils/package.json +++ b/packages/expect-utils/package.json @@ -1,6 +1,6 @@ { "name": "@jest/expect-utils", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/expect/package.json b/packages/expect/package.json index 1395ca1baeec..b0b2383438a7 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -1,6 +1,6 @@ { "name": "expect", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -26,7 +26,7 @@ }, "devDependencies": { "@jest/test-utils": "workspace:^", - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "chalk": "^4.0.0", "fast-check": "^3.0.0", "immutable": "^4.0.0", diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index 36aabb7bb62a..163a18c5c680 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -1,6 +1,6 @@ { "name": "jest-circus", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index ad9429cd7b11..81ed3738928a 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -1,7 +1,7 @@ { "name": "jest-cli", "description": "Delightful JavaScript Testing.", - "version": "29.0.1", + "version": "29.0.2", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index 160ac1c3c3e7..0cc48f07e139 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -1,6 +1,6 @@ { "name": "jest-config", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -58,7 +58,7 @@ "@types/micromatch": "^4.0.1", "semver": "^7.3.5", "ts-node": "^10.5.0", - "typescript": "^4.7.4" + "typescript": "^4.8.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index da4bb5977e16..b069b8a876d5 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -90,29 +90,16 @@ function verifyDirectoryExists(path: string, key: string) { } } -// TS 3.5 forces us to split these into 2 -const mergeModuleNameMapperWithPreset = ( - options: Config.InitialOptionsWithRootDir, - preset: Config.InitialOptions, -) => { - if (options['moduleNameMapper'] && preset['moduleNameMapper']) { - options['moduleNameMapper'] = { - ...options['moduleNameMapper'], - ...preset['moduleNameMapper'], - ...options['moduleNameMapper'], - }; - } -}; - -const mergeTransformWithPreset = ( - options: Config.InitialOptionsWithRootDir, +const mergeOptionWithPreset = ( + options: Config.InitialOptions, preset: Config.InitialOptions, + optionName: T, ) => { - if (options['transform'] && preset['transform']) { - options['transform'] = { - ...options['transform'], - ...preset['transform'], - ...options['transform'], + if (options[optionName] && preset[optionName]) { + options[optionName] = { + ...options[optionName], + ...preset[optionName], + ...options[optionName], }; } }; @@ -206,8 +193,8 @@ const setupPreset = async ( options.modulePathIgnorePatterns, ); } - mergeModuleNameMapperWithPreset(options, preset); - mergeTransformWithPreset(options, preset); + mergeOptionWithPreset(options, preset, 'moduleNameMapper'); + mergeOptionWithPreset(options, preset, 'transform'); mergeGlobalsWithPreset(options, preset); return {...preset, ...options}; diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index e5611aef8890..be82e6c6a63d 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@jest/console", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index 0f89eea53f65..d50ce8cf8a55 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -1,7 +1,7 @@ { "name": "@jest/core", "description": "Delightful JavaScript Testing.", - "version": "29.0.1", + "version": "29.0.2", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts index 1961a13611cc..84842abf8c90 100644 --- a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts +++ b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts @@ -16,7 +16,7 @@ class UpdateSnapshotInteractivePlugin extends BaseWatchPlugin { private _snapshotInteractiveMode: SnapshotInteractiveMode = new SnapshotInteractiveMode(this._stdout); private _failedSnapshotTestAssertions: Array = []; - isInternal: true = true; + isInternal = true as const; getFailedSnapshotTestAssertions( testResults: AggregatedResult, diff --git a/packages/jest-create-cache-key-function/package.json b/packages/jest-create-cache-key-function/package.json index bcc0fd6608fb..6178d0604918 100644 --- a/packages/jest-create-cache-key-function/package.json +++ b/packages/jest-create-cache-key-function/package.json @@ -1,6 +1,6 @@ { "name": "@jest/create-cache-key-function", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 48aa12745b88..31fa25b6f520 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -1,6 +1,6 @@ { "name": "jest-diff", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index 564792b3d510..f1809e5c7eb2 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -1,6 +1,6 @@ { "name": "jest-each", - "version": "29.0.1", + "version": "29.0.2", "description": "Parameterised tests for Jest", "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/jest-environment-jsdom/package.json b/packages/jest-environment-jsdom/package.json index 57d01c047823..e72fa7a7d0d5 100644 --- a/packages/jest-environment-jsdom/package.json +++ b/packages/jest-environment-jsdom/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-jsdom", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-environment-node/package.json b/packages/jest-environment-node/package.json index 34a7c2af6a1a..05ecffae15f5 100644 --- a/packages/jest-environment-node/package.json +++ b/packages/jest-environment-node/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-node", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-environment/package.json b/packages/jest-environment/package.json index a870e2606807..a360d7b291ae 100644 --- a/packages/jest-environment/package.json +++ b/packages/jest-environment/package.json @@ -1,6 +1,6 @@ { "name": "@jest/environment", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-expect/package.json b/packages/jest-expect/package.json index ddf9d35e3809..3998ce9d47f6 100644 --- a/packages/jest-expect/package.json +++ b/packages/jest-expect/package.json @@ -1,6 +1,6 @@ { "name": "@jest/expect", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -21,7 +21,7 @@ "jest-snapshot": "workspace:^" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "tsd-lite": "^0.6.0" }, "engines": { diff --git a/packages/jest-fake-timers/package.json b/packages/jest-fake-timers/package.json index fa098bcaf518..e7e10df0dea3 100644 --- a/packages/jest-fake-timers/package.json +++ b/packages/jest-fake-timers/package.json @@ -1,6 +1,6 @@ { "name": "@jest/fake-timers", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-globals/package.json b/packages/jest-globals/package.json index 027cdd8279a5..b52c89dbb2a7 100644 --- a/packages/jest-globals/package.json +++ b/packages/jest-globals/package.json @@ -1,6 +1,6 @@ { "name": "@jest/globals", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index f8f3c31c5ef4..d37241f001e6 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -1,6 +1,6 @@ { "name": "jest-haste-map", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index 9f00c2b4b2e7..9db83c027c13 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -1,6 +1,6 @@ { "name": "jest-jasmine2", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 693966fded07..2971d361f068 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -79,6 +79,7 @@ function promisifyLifeCycleFunction( // didn't return a promise. const asyncJestLifecycle = function (done: DoneFn) { const wrappedFn = isGeneratorFn(fn) ? co.wrap(fn) : fn; + // @ts-expect-error: TS thinks `wrappedFn` is a generator function const returnValue = wrappedFn.call({}, doneFnNoop); if (isPromise(returnValue)) { diff --git a/packages/jest-leak-detector/package.json b/packages/jest-leak-detector/package.json index 39d6c176ca20..487646224c71 100644 --- a/packages/jest-leak-detector/package.json +++ b/packages/jest-leak-detector/package.json @@ -1,6 +1,6 @@ { "name": "jest-leak-detector", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index 072ff4f9fb23..f9ecb1fe03d7 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -1,7 +1,7 @@ { "name": "jest-matcher-utils", "description": "A set of utility functions for expect and related packages", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index a574474a135a..2efd4057b284 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-message-util", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-mock/__typetests__/ModuleMocker.test.ts b/packages/jest-mock/__typetests__/ModuleMocker.test.ts new file mode 100644 index 000000000000..c7b275bfebe3 --- /dev/null +++ b/packages/jest-mock/__typetests__/ModuleMocker.test.ts @@ -0,0 +1,75 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {expectType} from 'tsd-lite'; +import {MockMetadata, Mocked, ModuleMocker} from 'jest-mock'; + +class ExampleClass { + memberA: Array; + + constructor() { + this.memberA = [1, 2, 3]; + } + memberB() {} +} + +const exampleModule = { + instance: new ExampleClass(), + + methodA: function square(a: number, b: number) { + return a * b; + }, + methodB: async function asyncSquare(a: number, b: number) { + const result = (await a) * b; + return result; + }, + + propertyA: { + one: 'foo', + three: { + nine: 1, + ten: [1, 2, 3], + }, + two() {}, + }, + propertyB: [1, 2, 3], + propertyC: 123, + propertyD: 'baz', + propertyE: true, + propertyF: Symbol.for('a.b.c'), +}; + +const moduleMocker = new ModuleMocker(globalThis); + +// getMetadata + +const exampleMetadata = moduleMocker.getMetadata(exampleModule); + +expectType | null>(exampleMetadata); + +// generateFromMetadata + +const exampleMock = moduleMocker.generateFromMetadata(exampleMetadata!); + +expectType>(exampleMock); + +expectType>(exampleMock.methodA.mock.calls); +expectType>(exampleMock.methodB.mock.calls); + +expectType>(exampleMock.instance.memberA); +expectType>(exampleMock.instance.memberB.mock.calls); + +expectType(exampleMock.propertyA.one); +expectType>(exampleMock.propertyA.two.mock.calls); +expectType(exampleMock.propertyA.three.nine); +expectType>(exampleMock.propertyA.three.ten); + +expectType>(exampleMock.propertyB); +expectType(exampleMock.propertyC); +expectType(exampleMock.propertyD); +expectType(exampleMock.propertyE); +expectType(exampleMock.propertyF); diff --git a/packages/jest-mock/package.json b/packages/jest-mock/package.json index ba46c280dedf..75b82641feb4 100644 --- a/packages/jest-mock/package.json +++ b/packages/jest-mock/package.json @@ -1,6 +1,6 @@ { "name": "jest-mock", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -21,7 +21,7 @@ "@types/node": "*" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "tsd-lite": "^0.6.0" }, "engines": { diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 305699b0a50c..224ac7e9c70a 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -7,7 +7,7 @@ /* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */ -export type MockFunctionMetadataType = +export type MockMetadataType = | 'object' | 'array' | 'regexp' @@ -17,20 +17,26 @@ export type MockFunctionMetadataType = | 'null' | 'undefined'; -export type MockFunctionMetadata< - T extends UnknownFunction = UnknownFunction, - MetadataType = MockFunctionMetadataType, -> = { +// TODO remove re-export in Jest 30 +export type MockFunctionMetadataType = MockMetadataType; + +export type MockMetadata = { ref?: number; - members?: Record>; + members?: Record>; mockImpl?: T; name?: string; refID?: number; type?: MetadataType; - value?: ReturnType; + value?: T; length?: number; }; +// TODO remove re-export in Jest 30 +export type MockFunctionMetadata< + T = unknown, + MetadataType = MockMetadataType, +> = MockMetadata; + export type ClassLike = {new (...args: any): any}; export type FunctionLike = (...args: any) => any; @@ -75,7 +81,7 @@ type MockedObjectShallow = { : T[K]; } & T; -export type Mocked = T extends ClassLike +export type Mocked = T extends ClassLike ? MockedClass : T extends FunctionLike ? MockedFunction @@ -83,7 +89,7 @@ export type Mocked = T extends ClassLike ? MockedObject : T; -export type MockedShallow = T extends ClassLike +export type MockedShallow = T extends ClassLike ? MockedClass : T extends FunctionLike ? MockedFunctionShallow @@ -386,7 +392,7 @@ function getObjectType(value: unknown): string { return Object.prototype.toString.apply(value).slice(8, -1); } -function getType(ref?: unknown): MockFunctionMetadataType | null { +function getType(ref?: unknown): MockMetadataType | null { const typeName = getObjectType(ref); if ( typeName === 'Function' || @@ -560,39 +566,30 @@ export class ModuleMocker { }; } - private _makeComponent( - metadata: MockFunctionMetadata, + private _makeComponent>( + metadata: MockMetadata, restore?: () => void, - ): Record; - private _makeComponent( - metadata: MockFunctionMetadata, + ): T; + private _makeComponent>( + metadata: MockMetadata, restore?: () => void, - ): Array; - private _makeComponent( - metadata: MockFunctionMetadata, + ): T; + private _makeComponent( + metadata: MockMetadata, restore?: () => void, - ): RegExp; - private _makeComponent( - metadata: MockFunctionMetadata< - T, - 'constant' | 'collection' | 'null' | 'undefined' - >, + ): T; + private _makeComponent( + metadata: MockMetadata, restore?: () => void, ): T; private _makeComponent( - metadata: MockFunctionMetadata, + metadata: MockMetadata, restore?: () => void, ): Mock; private _makeComponent( - metadata: MockFunctionMetadata, + metadata: MockMetadata, restore?: () => void, - ): - | Record - | Array - | RegExp - | ReturnType - | undefined - | Mock { + ): Record | Array | RegExp | T | Mock | undefined { if (metadata.type === 'object') { return new this._environmentGlobal.Object(); } else if (metadata.type === 'array') { @@ -808,7 +805,7 @@ export class ModuleMocker { } private _createMockFunction( - metadata: MockFunctionMetadata, + metadata: MockMetadata, mockConstructor: Function, ): Function { let name = metadata.name; @@ -828,15 +825,13 @@ export class ModuleMocker { } while (name && name.startsWith(boundFunctionPrefix)); } - // Special case functions named `mockConstructor` to guard for infinite - // loops. + // Special case functions named `mockConstructor` to guard for infinite loops if (name === MOCK_CONSTRUCTOR_NAME) { return mockConstructor; } if ( - // It's a syntax error to define functions with a reserved keyword - // as name. + // It's a syntax error to define functions with a reserved keyword as name RESERVED_KEYWORDS.has(name) || // It's also a syntax error to define functions with a name that starts with a number /^\d/.test(name) @@ -862,19 +857,14 @@ export class ModuleMocker { return createConstructor(mockConstructor); } - private _generateMock( - metadata: MockFunctionMetadata, + private _generateMock( + metadata: MockMetadata, callbacks: Array, - refs: { - [key: string]: - | Record - | Array - | RegExp - | UnknownFunction - | undefined - | Mock; - }, - ): Mock { + refs: Record< + number, + Record | Array | RegExp | T | Mock | undefined + >, + ): Mocked { // metadata not compatible but it's the same type, maybe problem with // overloading of _makeComponent and not _generateMock? // @ts-expect-error - unsure why TSC complains here? @@ -905,7 +895,7 @@ export class ModuleMocker { mock.prototype.constructor = mock; } - return mock as Mock; + return mock as Mocked; } /** @@ -913,12 +903,10 @@ export class ModuleMocker { * @param metadata Metadata for the mock in the schema returned by the * getMetadata method of this module. */ - generateFromMetadata( - metadata: MockFunctionMetadata, - ): Mock { + generateFromMetadata(metadata: MockMetadata): Mocked { const callbacks: Array = []; const refs = {}; - const mock = this._generateMock(metadata, callbacks, refs); + const mock = this._generateMock(metadata, callbacks, refs); callbacks.forEach(setter => setter()); return mock; } @@ -927,11 +915,11 @@ export class ModuleMocker { * @see README.md * @param component The component for which to retrieve metadata. */ - getMetadata( - component: ReturnType, - _refs?: Map, number>, - ): MockFunctionMetadata | null { - const refs = _refs || new Map, number>(); + getMetadata( + component: T, + _refs?: Map, + ): MockMetadata | null { + const refs = _refs || new Map(); const ref = refs.get(component); if (ref != null) { return {ref}; @@ -942,7 +930,7 @@ export class ModuleMocker { return null; } - const metadata: MockFunctionMetadata = {type}; + const metadata: MockMetadata = {type}; if ( type === 'constant' || type === 'collection' || @@ -966,9 +954,7 @@ export class ModuleMocker { metadata.refID = refs.size; refs.set(component, metadata.refID); - let members: { - [key: string]: MockFunctionMetadata; - } | null = null; + let members: Record> | null = null; // Leave arrays alone if (type !== 'array') { // @ts-expect-error component is object @@ -1007,7 +993,7 @@ export class ModuleMocker { ): fn is Mock<(...args: P) => R>; isMockFunction(fn: unknown): fn is Mock; isMockFunction(fn: unknown): fn is Mock { - return fn != null && (fn as any)._isMockFunction === true; + return fn != null && (fn as Mock)._isMockFunction === true; } fn(implementation?: T): Mock { diff --git a/packages/jest-phabricator/package.json b/packages/jest-phabricator/package.json index 723a2a09d267..ee4a74e6f63d 100644 --- a/packages/jest-phabricator/package.json +++ b/packages/jest-phabricator/package.json @@ -1,6 +1,6 @@ { "name": "jest-phabricator", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index b230748844d2..e146ab4a3434 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -1,6 +1,6 @@ { "name": "jest-repl", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index 53aa9c3536b8..d5e5ad3be82d 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -1,7 +1,7 @@ { "name": "@jest/reporters", "description": "Jest's reporters", - "version": "29.0.1", + "version": "29.0.2", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { @@ -40,7 +40,7 @@ }, "devDependencies": { "@jest/test-utils": "workspace:^", - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/exit": "^0.1.30", "@types/glob": "^7.1.1", "@types/graceful-fs": "^4.1.3", diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index e68e7747f3c6..62a2be163f73 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve-dependencies", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 8f0aeb311c86..626b7002808b 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -28,7 +28,7 @@ "slash": "^3.0.0" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/graceful-fs": "^4.1.3", "@types/pnpapi": "^0.0.2", "@types/resolve": "^1.20.2", diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index 90d48ec3b90b..e92e1066b5d9 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -1,6 +1,6 @@ { "name": "jest-runner", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -40,7 +40,7 @@ "source-map-support": "0.5.13" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/exit": "^0.1.30", "@types/graceful-fs": "^4.1.3", "@types/source-map-support": "^0.5.0", diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 20ec6d275465..c36c109e397e 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -1,6 +1,6 @@ { "name": "jest-runtime", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 4541cd44d6e0..639ccc9371c3 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1109,6 +1109,7 @@ export default class Runtime { this._mockRegistry.clear(); this._moduleRegistry.clear(); this._esmoduleRegistry.clear(); + this._fileTransformsMutex.clear(); this._cjsNamedExports.clear(); this._moduleMockRegistry.clear(); this._cacheFS.clear(); @@ -1278,7 +1279,6 @@ export default class Runtime { this._sourceMapRegistry.clear(); this._fileTransforms.clear(); - this._fileTransformsMutex.clear(); this.jestObjectCaches.clear(); this._v8CoverageSources?.clear(); diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index e5ad8a2cf05b..9725ece848a8 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -1,6 +1,6 @@ { "name": "jest-snapshot", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -46,7 +46,7 @@ "@babel/preset-flow": "^7.7.2", "@babel/preset-react": "^7.12.1", "@jest/test-utils": "workspace:^", - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/graceful-fs": "^4.1.3", "@types/natural-compare": "^1.4.0", "@types/semver": "^7.1.0", diff --git a/packages/jest-test-result/package.json b/packages/jest-test-result/package.json index 2e233996104d..42c7b4d69cdd 100644 --- a/packages/jest-test-result/package.json +++ b/packages/jest-test-result/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-result", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-test-sequencer/package.json b/packages/jest-test-sequencer/package.json index 4f15bff2a7f0..9a48fe1ede47 100644 --- a/packages/jest-test-sequencer/package.json +++ b/packages/jest-test-sequencer/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-sequencer", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-transform/package.json b/packages/jest-transform/package.json index c4624ee8efce..983425d25226 100644 --- a/packages/jest-transform/package.json +++ b/packages/jest-transform/package.json @@ -1,6 +1,6 @@ { "name": "@jest/transform", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-transform/src/index.ts b/packages/jest-transform/src/index.ts index e81fe036ba4f..3ea57ce07ca8 100644 --- a/packages/jest-transform/src/index.ts +++ b/packages/jest-transform/src/index.ts @@ -22,5 +22,6 @@ export type { TransformOptions, TransformResult, TransformedSource, + TransformerFactory, } from './types'; export {default as handlePotentialSyntaxError} from './enhanceUnexpectedTokenMessage'; diff --git a/packages/jest-types/package.json b/packages/jest-types/package.json index 143d85d2fb11..56927e6d98ed 100644 --- a/packages/jest-types/package.json +++ b/packages/jest-types/package.json @@ -1,6 +1,6 @@ { "name": "@jest/types", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -28,7 +28,7 @@ "chalk": "^4.0.0" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "tsd-lite": "^0.6.0" }, "publishConfig": { diff --git a/packages/jest-util/package.json b/packages/jest-util/package.json index e39106be8f22..7ac4a8bcf52e 100644 --- a/packages/jest-util/package.json +++ b/packages/jest-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-util", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-validate/package.json b/packages/jest-validate/package.json index 91d53bd13d17..ec526d588db3 100644 --- a/packages/jest-validate/package.json +++ b/packages/jest-validate/package.json @@ -1,6 +1,6 @@ { "name": "jest-validate", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-watcher/package.json b/packages/jest-watcher/package.json index 31e655a7fa14..96d21382abb7 100644 --- a/packages/jest-watcher/package.json +++ b/packages/jest-watcher/package.json @@ -1,7 +1,7 @@ { "name": "jest-watcher", "description": "Delightful JavaScript Testing.", - "version": "29.0.1", + "version": "29.0.2", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-worker/package.json b/packages/jest-worker/package.json index d15f651d8a6f..86d171e86a95 100644 --- a/packages/jest-worker/package.json +++ b/packages/jest-worker/package.json @@ -1,6 +1,6 @@ { "name": "jest-worker", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -22,7 +22,7 @@ "supports-color": "^8.0.0" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "@types/merge-stream": "^1.1.2", "@types/supports-color": "^8.1.0", "get-stream": "^6.0.0", diff --git a/packages/jest/package.json b/packages/jest/package.json index e45d01b9f23d..38750bd5fcce 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -1,7 +1,7 @@ { "name": "jest", "description": "Delightful JavaScript Testing.", - "version": "29.0.1", + "version": "29.0.2", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { @@ -19,7 +19,7 @@ "jest-cli": "workspace:^" }, "devDependencies": { - "@tsd/typescript": "~4.7.4", + "@tsd/typescript": "~4.8.2", "tsd-lite": "^0.6.0" }, "peerDependencies": { diff --git a/packages/pretty-format/package.json b/packages/pretty-format/package.json index 68662e185e2f..67a1cfff8941 100644 --- a/packages/pretty-format/package.json +++ b/packages/pretty-format/package.json @@ -1,6 +1,6 @@ { "name": "pretty-format", - "version": "29.0.1", + "version": "29.0.2", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 71a5393f2eae..33848b5e87a7 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-utils", - "version": "29.0.1", + "version": "29.0.2", "private": true, "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/website/versioned_docs/version-29.0/Configuration.md b/website/versioned_docs/version-29.0/Configuration.md index d6762ea4b695..ac2047fff049 100644 --- a/website/versioned_docs/version-29.0/Configuration.md +++ b/website/versioned_docs/version-29.0/Configuration.md @@ -2305,7 +2305,11 @@ After the worker has executed a test the memory usage of it is checked. If it ex - `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. +:::caution + +Percentage based memory limit [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} */ diff --git a/website/versioned_docs/version-29.0/GettingStarted.md b/website/versioned_docs/version-29.0/GettingStarted.md index 7b6e4b17de31..15632501f53a 100644 --- a/website/versioned_docs/version-29.0/GettingStarted.md +++ b/website/versioned_docs/version-29.0/GettingStarted.md @@ -156,7 +156,7 @@ npm install --save-dev ts-jest #### Type definitions -There are two ways have [Jest global APIs](GlobalAPI.md) typed for test files written in TypeScript. +There are two ways to have [Jest global APIs](GlobalAPI.md) typed for test files written in TypeScript. 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: diff --git a/website/versioned_docs/version-29.0/GlobalAPI.md b/website/versioned_docs/version-29.0/GlobalAPI.md index 383ce6845e98..f41f1eedcbc4 100644 --- a/website/versioned_docs/version-29.0/GlobalAPI.md +++ b/website/versioned_docs/version-29.0/GlobalAPI.md @@ -19,7 +19,7 @@ import TOCInline from '@theme/TOCInline'; Runs a function after all the tests in this file have completed. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to clean up some global setup state that is shared across tests. @@ -59,7 +59,7 @@ If you want to run some cleanup after every test instead of after all tests, use Runs a function after each one of the tests in this file completes. If the function returns a promise or is a generator, Jest waits for that promise to resolve before continuing. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to clean up some temporary state that is created by each test. @@ -99,7 +99,7 @@ If you want to run some cleanup just once, after all of the tests run, use `afte Runs a function before any of the tests in this file run. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running tests. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to set up some global state that will be used by many tests. @@ -135,7 +135,7 @@ If you want to run something before every test instead of before any test runs, Runs a function before each of the tests in this file runs. If the function returns a promise or is a generator, Jest waits for that promise to resolve before running the test. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. This is often useful if you want to reset some global state that will be used by many tests. @@ -232,8 +232,8 @@ Use `describe.each` if you keep duplicating the same test suites with different #### 1. `describe.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]`. + - `name`: `String` the title of the test suite. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -250,7 +250,7 @@ Use `describe.each` if you keep duplicating the same test suites with different - You can use `$#` to inject the index of the test case - You cannot use `$variable` with the `printf` formatting except for `%%` - `fn`: `Function` the suite of tests to be ran, this is the function that will receive the parameters in each row as function arguments. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -302,7 +302,7 @@ describe.each([ - `name`: `String` the title of the test suite, use `$variable` to inject test data into the suite title from the tagged template expressions, and `$#` for the index of the row. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the suite of tests to be ran, this is the function that will receive the test data object. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -475,11 +475,9 @@ test('did not rain', () => { }); ``` -The first argument is the test name; the second argument is a function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ - -> Note: If a **promise is returned** from `test`, Jest will wait for the promise to resolve before letting the test complete. Jest will also wait if you **provide an argument to the test function**, usually called `done`. This could be handy when you want to test callbacks. See how to test async code [here](TestingAsyncCode.md#callbacks). +The first argument is the test name; the second argument is a function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. -For example, let's say `fetchBeverageList()` returns a promise that is supposed to resolve to a list that has `lemon` in it. You can test this with: +If a **promise is returned** from `test`, Jest will wait for the promise to resolve before letting the test complete. For example, let's say `fetchBeverageList()` returns a promise that is supposed to resolve to a list that has `lemon` in it. You can test this with: ```js test('has lemon in it', () => { @@ -489,19 +487,29 @@ test('has lemon in it', () => { }); ``` -Even though the call to `test` will return right away, the test doesn't complete until the promise resolves as well. +Even though the call to `test` will return right away, the test doesn't complete until the promise resolves. For more details, see [Testing Asynchronous Code](TestingAsyncCode.md) page. + +:::tip + +Jest will also wait if you **provide an argument to the test function**, usually called `done`. This could be handy when you want to test [callbacks](TestingAsyncCode.md#callbacks). + +::: ### `test.concurrent(name, fn, timeout)` Also under the alias: `it.concurrent(name, fn, timeout)` -Use `test.concurrent` if you want the test to run concurrently. +:::caution -> Note: `test.concurrent` is considered experimental - see [here](https://github.com/facebook/jest/labels/Area%3A%20Concurrent) for details on missing features and other issues +`test.concurrent` is considered experimental - see [here](https://github.com/facebook/jest/labels/Area%3A%20Concurrent) for details on missing features and other issues. -The first argument is the test name; the second argument is an asynchronous function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +::: -``` +Use `test.concurrent` if you want the test to run concurrently. + +The first argument is the test name; the second argument is an asynchronous function that contains the expectations to test. The third argument (optional) is `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. + +```js test.concurrent('addition of 2 numbers', async () => { expect(5 + 3).toBe(8); }); @@ -511,7 +519,11 @@ test.concurrent('subtraction 2 numbers', async () => { }); ``` -> Note: Use `maxConcurrency` in configuration to prevents Jest from executing more than the specified amount of tests at the same time +:::tip + +Use [`maxConcurrency`](Configuration.md/#maxconcurrency-number) configuration option to prevent Jest from executing more than the specified amount of tests at the same time. + +::: ### `test.concurrent.each(table)(name, fn, timeout)` @@ -523,8 +535,7 @@ Use `test.concurrent.each` if you keep duplicating the same test with different #### 1. `test.concurrent.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` - `name`: `String` the title of the test block. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -537,7 +548,7 @@ Use `test.concurrent.each` if you keep duplicating the same test with different - `%#` - Index of the test case. - `%%` - single percent sign ('%'). This does not consume an argument. - `fn`: `Function` the test to be ran, this is the function that will receive the parameters in each row as function arguments, **this will have to be an asynchronous function**. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -559,7 +570,7 @@ test.concurrent.each([ - `name`: `String` the title of the test, use `$variable` to inject test data into the test title from the tagged template expressions. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the test to be ran, this is the function that will receive the test data object, **this will have to be an asynchronous function**. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -666,8 +677,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test #### 1. `test.each(table)(name, fn, timeout)` -- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. - - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` +- `table`: `Array` of Arrays with the arguments that are passed into the test `fn` for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]` - `name`: `String` the title of the test block. - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args): - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format). @@ -684,7 +694,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test - You can use `$#` to inject the index of the test case - You cannot use `$variable` with the `printf` formatting except for `%%` - `fn`: `Function` the test to be ran, this is the function that will receive the parameters in each row as function arguments. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -716,7 +726,7 @@ test.each([ - `name`: `String` the title of the test, use `$variable` to inject test data into the test title from the tagged template expressions. - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` - `fn`: `Function` the test to be ran, this is the function that will receive the test data object. -- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. _Note: The default timeout is 5 seconds._ +- Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait for each row before aborting. The default timeout is 5 seconds. Example: @@ -817,7 +827,7 @@ Also under the aliases: `it.only(name, fn, timeout)`, and `fit(name, fn, timeout When you are debugging a large test file, you will often only want to run a subset of tests. You can use `.only` to specify which tests are the only ones you want to run in that test file. -Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ +Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. The default timeout is 5 seconds. For example, let's say you had these tests: @@ -945,20 +955,18 @@ Also under the alias: `it.todo(name)` Use `test.todo` when you are planning on writing tests. These tests will be highlighted in the summary output at the end so you know how many tests you still need todo. -_Note_: If you supply a test callback function then the `test.todo` will throw an error. If you have already implemented the test and it is broken and you do not want it to run, then use `test.skip` instead. - -#### API - -- `name`: `String` the title of the test plan. - -Example: - ```js const add = (a, b) => a + b; test.todo('add should be associative'); ``` +:::tip + +`test.todo` will throw an error, if you will pass it a test callback function. Use [`test.skip`](#testskipname-fn) instead, if you already implemented the test, but do not want it to run. + +::: + ## TypeScript Usage :::info diff --git a/yarn.lock b/yarn.lock index d873b176e743..5a21627a1b28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2693,7 +2693,7 @@ __metadata: version: 0.0.0-use.local resolution: "@jest/expect@workspace:packages/jest-expect" dependencies: - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 expect: "workspace:^" jest-snapshot: "workspace:^" tsd-lite: ^0.6.0 @@ -2742,7 +2742,7 @@ __metadata: "@lerna-lite/cli": ^1.10.0 "@microsoft/api-extractor": ^7.29.0 "@tsconfig/node14": ^1.0.3 - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/babel__core": ^7.1.14 "@types/babel__generator": ^7.0.0 "@types/babel__template": ^7.0.2 @@ -2809,7 +2809,7 @@ __metadata: tempy: ^1.0.0 ts-node: ^10.5.0 type-fest: ^2.11.2 - typescript: ^4.7.4 + typescript: ^4.8.2 which: ^2.0.1 languageName: unknown linkType: soft @@ -2825,7 +2825,7 @@ __metadata: "@jest/transform": "workspace:^" "@jest/types": "workspace:^" "@jridgewell/trace-mapping": ^0.3.15 - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/exit": ^0.1.30 "@types/glob": ^7.1.1 "@types/graceful-fs": ^4.1.3 @@ -3017,7 +3017,7 @@ __metadata: resolution: "@jest/types@workspace:packages/jest-types" dependencies: "@jest/schemas": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" @@ -3331,25 +3331,25 @@ __metadata: languageName: node linkType: hard -"@microsoft/api-extractor-model@npm:7.23.0": - version: 7.23.0 - resolution: "@microsoft/api-extractor-model@npm:7.23.0" +"@microsoft/api-extractor-model@npm:7.23.3": + version: 7.23.3 + resolution: "@microsoft/api-extractor-model@npm:7.23.3" dependencies: "@microsoft/tsdoc": 0.14.1 "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.50.1 - checksum: 9c16aebb7fd508bbf6ee413b9469640212ea32f5a4b11196047d702013b18b74a72946b5cf6c7f697d66ba8c185608caa922a66a9f77a26616328f73907a5a79 + "@rushstack/node-core-library": 3.51.1 + checksum: 00ec7a31d1f6d1583c3fcd97b16130bf8570e27cd3be2ecd07cf601b0c91ef63885a55bf068932c5d9278f8a9ab2046dc8305c0047158e6df5e86f5e56e35b77 languageName: node linkType: hard "@microsoft/api-extractor@npm:^7.29.0": - version: 7.29.0 - resolution: "@microsoft/api-extractor@npm:7.29.0" + version: 7.29.5 + resolution: "@microsoft/api-extractor@npm:7.29.5" dependencies: - "@microsoft/api-extractor-model": 7.23.0 + "@microsoft/api-extractor-model": 7.23.3 "@microsoft/tsdoc": 0.14.1 "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.50.1 + "@rushstack/node-core-library": 3.51.1 "@rushstack/rig-package": 0.3.14 "@rushstack/ts-command-line": 4.12.2 colors: ~1.2.1 @@ -3360,7 +3360,7 @@ __metadata: typescript: ~4.7.4 bin: api-extractor: bin/api-extractor - checksum: 6c154dc69145b2e0ee0c1f2a2cf0b59e2a308eb8296e1895296a7e6d40c6183670da3bcb6f9caa8be602ae6db2a48d0556aad21d6d594db5a8add838a0373b0c + checksum: f80f5963591384029f71c8db2f3cd32eb098ce4f622e420b695ac947c104612a5a483126428aade638d5d751e840f79e4f36cb0c8e59c363663cf72971937b73 languageName: node linkType: hard @@ -3924,9 +3924,9 @@ __metadata: languageName: node linkType: hard -"@rushstack/node-core-library@npm:3.50.1": - version: 3.50.1 - resolution: "@rushstack/node-core-library@npm:3.50.1" +"@rushstack/node-core-library@npm:3.51.1": + version: 3.51.1 + resolution: "@rushstack/node-core-library@npm:3.51.1" dependencies: "@types/node": 12.20.24 colors: ~1.2.1 @@ -3935,9 +3935,8 @@ __metadata: jju: ~1.4.0 resolve: ~1.17.0 semver: ~7.3.0 - timsort: ~0.3.0 z-schema: ~5.0.2 - checksum: 2ce07e8462fa332ac270335e1cdf9a4dcd0b0df438ad4d6dd33b1fd82c864c9d74091a51ac04bc4871c645782cc8d70bbb6ccd79a294c19355f6f3aa094eb299 + checksum: 92f7e39f03f4931a7007b4a79427d82bfe078146133a138219205abf873607898f7667fa368e3cb28c93bb1a2b9dc70ddaf2d316bc47a9a17b591d69d1025068 languageName: node linkType: hard @@ -4276,13 +4275,10 @@ __metadata: languageName: node linkType: hard -"@tsd/typescript@npm:~4.7.4": - version: 4.7.4 - resolution: "@tsd/typescript@npm:4.7.4" - bin: - tsc: typescript/bin/tsc - tsserver: typescript/bin/tsserver - checksum: 1a84773cb4bb01898fb0b6011ec5c2fb3e3c91585ea009bbf9d525b46d40f1827417dfc5f7b1efdf534b111a5947b063ae04490d147bda37b038e1a7d264672d +"@tsd/typescript@npm:~4.8.2": + version: 4.8.2 + resolution: "@tsd/typescript@npm:4.8.2" + checksum: c193a64d2347ba7da7e426e41d9cf9186ad71e782be2404db8ead310b3975a17ad206e0ba5f2c60bf9d8714cbccd7fbebde0345f2dce1938c1d1a8168e23f6b7 languageName: node linkType: hard @@ -5104,12 +5100,12 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.14.0": - version: 5.32.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.32.0" + version: 5.36.1 + resolution: "@typescript-eslint/eslint-plugin@npm:5.36.1" dependencies: - "@typescript-eslint/scope-manager": 5.32.0 - "@typescript-eslint/type-utils": 5.32.0 - "@typescript-eslint/utils": 5.32.0 + "@typescript-eslint/scope-manager": 5.36.1 + "@typescript-eslint/type-utils": 5.36.1 + "@typescript-eslint/utils": 5.36.1 debug: ^4.3.4 functional-red-black-tree: ^1.0.1 ignore: ^5.2.0 @@ -5122,42 +5118,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9785c34d9742b51130237bfe244924ca6dfd529bdcc5932a5cf81558f0235099c963a11125df393037db51ce451f7ab9442aba3c3a8bb2e0607569a0e31480c8 + checksum: a4c555688d840c3ff0d3d71ceca583291e206cc523eade45c56fb8e1c8af84ae50ef8d344cdf8e3f9c38f430bc03c95eb8d49870094e0e5b57e0fa3e61c0ec91 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.14.0": - version: 5.32.0 - resolution: "@typescript-eslint/parser@npm:5.32.0" + version: 5.36.1 + resolution: "@typescript-eslint/parser@npm:5.36.1" dependencies: - "@typescript-eslint/scope-manager": 5.32.0 - "@typescript-eslint/types": 5.32.0 - "@typescript-eslint/typescript-estree": 5.32.0 + "@typescript-eslint/scope-manager": 5.36.1 + "@typescript-eslint/types": 5.36.1 + "@typescript-eslint/typescript-estree": 5.36.1 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 3fcfa183cad125c3198fd63701c6e13dad1cc984d309e8cd40ec9a2eb857902abfd7e9ee3f030b18eb1c18c795a61ea289ef147a7f9dfac38df905e7514316af + checksum: 0f0f94e56ae1d55b6e7223ce5a2b0c93e5cc082ef2951a2b24ae4b22bb8ffbeb90d2d16682bfa8bc972ba2c7fb4703aedd79b7dbd09bcee397e1ab90d11506d9 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.32.0": - version: 5.32.0 - resolution: "@typescript-eslint/scope-manager@npm:5.32.0" +"@typescript-eslint/scope-manager@npm:5.36.1": + version: 5.36.1 + resolution: "@typescript-eslint/scope-manager@npm:5.36.1" dependencies: - "@typescript-eslint/types": 5.32.0 - "@typescript-eslint/visitor-keys": 5.32.0 - checksum: 69bdeb029f39d1112299dc0cb0ddef30e51bdb782fdb79cc4e72fa448e00d71e39938d3bff3fa4ee43b3416c2e3b4564de2c37252914772b07eeedafb14412d6 + "@typescript-eslint/types": 5.36.1 + "@typescript-eslint/visitor-keys": 5.36.1 + checksum: c46497226af75baed7458838ec0bfbddf19f8084115d78b915b46a8ceb4c05619ac61da127dfd3c8ee11bc916896d57bf8b9f936b0306ce69658160f910e3ad0 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.32.0": - version: 5.32.0 - resolution: "@typescript-eslint/type-utils@npm:5.32.0" +"@typescript-eslint/type-utils@npm:5.36.1": + version: 5.36.1 + resolution: "@typescript-eslint/type-utils@npm:5.36.1" dependencies: - "@typescript-eslint/utils": 5.32.0 + "@typescript-eslint/typescript-estree": 5.36.1 + "@typescript-eslint/utils": 5.36.1 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -5165,23 +5162,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 4063808ca054789bebc6adb376d15c13e38f8ea14fa2842c38ae616d77fb77681b67a04b77887cf9ceb6f801ab3fc5eddfb6325779ab821404c62f36c56310bb + checksum: d2905289e253a83a9eacbad765cfba03440663086c8beb1b19345b46593c9053fb051ee13d3cc27ccd800fe95ffbf3be2b1273b0f0ac6a59452fc94e6460898b languageName: node linkType: hard -"@typescript-eslint/types@npm:5.32.0": - version: 5.32.0 - resolution: "@typescript-eslint/types@npm:5.32.0" - checksum: 6758f54d8d7763893cd7c1753f525ef1777eee8b558bf3d54fd2a2ce691ca0cf813c68a26e4db83a1deae4e4a62b247f1195e15a1f3577f1293849f9e55a232c +"@typescript-eslint/types@npm:5.36.1": + version: 5.36.1 + resolution: "@typescript-eslint/types@npm:5.36.1" + checksum: 10c8965c64e16bc6920dc0c62aae2b139062aca945d03df2ad6fe7c299d2faa684621d571f8d9807a67643d4e9fa5217c69d5f538f9936fc757f9df5ded57623 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.32.0": - version: 5.32.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.32.0" +"@typescript-eslint/typescript-estree@npm:5.36.1": + version: 5.36.1 + resolution: "@typescript-eslint/typescript-estree@npm:5.36.1" dependencies: - "@typescript-eslint/types": 5.32.0 - "@typescript-eslint/visitor-keys": 5.32.0 + "@typescript-eslint/types": 5.36.1 + "@typescript-eslint/visitor-keys": 5.36.1 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -5190,33 +5187,33 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 6aee08be5d36603d038fb8340f324f5cb38519150c9b37c012f0c1ff2a4d8cf22fbc6835de31d069949c2b3d8ed3e729076a724ef29db4289d9fe73b97c9d310 + checksum: acaf2938001673918dbbe690a353cf92e2cfabc79f74cd5946e303a8c24eb9c08ae2053dd261810ed0c9c471ebe879f386564c1b01dd2504dc84f4ce5f4dc696 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.32.0, @typescript-eslint/utils@npm:^5.10.0": - version: 5.32.0 - resolution: "@typescript-eslint/utils@npm:5.32.0" +"@typescript-eslint/utils@npm:5.36.1, @typescript-eslint/utils@npm:^5.10.0": + version: 5.36.1 + resolution: "@typescript-eslint/utils@npm:5.36.1" dependencies: "@types/json-schema": ^7.0.9 - "@typescript-eslint/scope-manager": 5.32.0 - "@typescript-eslint/types": 5.32.0 - "@typescript-eslint/typescript-estree": 5.32.0 + "@typescript-eslint/scope-manager": 5.36.1 + "@typescript-eslint/types": 5.36.1 + "@typescript-eslint/typescript-estree": 5.36.1 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: cfd88d93508c8fb0db17d2726691e1383db390357fa0637bd8111558fbe72da5130d995294001d71b1d929d620fbce3f20a70b277a77ca21a4241b3b470dc758 + checksum: 77853d526af86ac508d7938916046ed4ad6374c7414981064c5122a2baa96fa234751137f481ac264a07387fd4dcec1cd26b33e29732cc58e855aae77a001d7c languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.32.0": - version: 5.32.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.32.0" +"@typescript-eslint/visitor-keys@npm:5.36.1": + version: 5.36.1 + resolution: "@typescript-eslint/visitor-keys@npm:5.36.1" dependencies: - "@typescript-eslint/types": 5.32.0 + "@typescript-eslint/types": 5.36.1 eslint-visitor-keys: ^3.3.0 - checksum: 1f9b756d648c2346a6e8538ffde729d3d9ce6621fded3d9f15c96aa0ebf8f511daf8232470423fb36359c2113538a4daaf3336181be78a0cfbfd297af91ce9ba + checksum: 45ab7c2fd455a8e4beff418bed6c9e7e1f9f66bcaad3bfaed868f97a3f8cfec1fa4faa45948af1a1c32ce573a7b1c6d10427119c257622445b06b488fefd8b49 languageName: node linkType: hard @@ -5673,7 +5670,7 @@ __metadata: jest-zone-patch: "*" rxjs: ^7.5.5 tslib: ^2.0.0 - typescript: ^4.7.4 + typescript: ^4.8.2 zone.js: ~0.11.3 languageName: unknown linkType: soft @@ -9395,6 +9392,7 @@ __metadata: babel-jest: "workspace:*" expect: "workspace:*" jest: "workspace:*" + typescript: ^4.8.2 languageName: unknown linkType: soft @@ -9540,7 +9538,7 @@ __metadata: jest: "workspace:*" react: 17.0.2 react-dom: ^17.0.1 - typescript: ^4.7.4 + typescript: ^4.8.2 languageName: unknown linkType: soft @@ -9604,7 +9602,7 @@ __metadata: dependencies: "@jest/expect-utils": "workspace:^" "@jest/test-utils": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 chalk: ^4.0.0 fast-check: ^3.0.0 immutable: ^4.0.0 @@ -12345,7 +12343,7 @@ __metadata: slash: ^3.0.0 strip-json-comments: ^3.1.1 ts-node: ^10.5.0 - typescript: ^4.7.4 + typescript: ^4.8.2 peerDependencies: "@types/node": "*" ts-node: ">=9.0.0" @@ -12615,7 +12613,7 @@ __metadata: resolution: "jest-mock@workspace:packages/jest-mock" dependencies: "@jest/types": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/node": "*" tsd-lite: ^0.6.0 languageName: unknown @@ -12704,7 +12702,7 @@ __metadata: version: 0.0.0-use.local resolution: "jest-resolve@workspace:packages/jest-resolve" dependencies: - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/graceful-fs": ^4.1.3 "@types/pnpapi": ^0.0.2 "@types/resolve": ^1.20.2 @@ -12744,7 +12742,7 @@ __metadata: "@jest/test-result": "workspace:^" "@jest/transform": "workspace:^" "@jest/types": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/exit": ^0.1.30 "@types/graceful-fs": ^4.1.3 "@types/node": "*" @@ -12845,7 +12843,7 @@ __metadata: "@jest/test-utils": "workspace:^" "@jest/transform": "workspace:^" "@jest/types": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/babel__traverse": ^7.0.6 "@types/graceful-fs": ^4.1.3 "@types/natural-compare": ^1.4.0 @@ -13034,7 +13032,7 @@ __metadata: version: 0.0.0-use.local resolution: "jest-worker@workspace:packages/jest-worker" dependencies: - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 "@types/merge-stream": ^1.1.2 "@types/node": "*" "@types/supports-color": ^8.1.0 @@ -13084,7 +13082,7 @@ __metadata: dependencies: "@jest/core": "workspace:^" "@jest/types": "workspace:^" - "@tsd/typescript": ~4.7.4 + "@tsd/typescript": ~4.8.2 import-local: ^3.0.2 jest-cli: "workspace:^" tsd-lite: ^0.6.0 @@ -19885,13 +19883,6 @@ __metadata: languageName: node linkType: hard -"timsort@npm:~0.3.0": - version: 0.3.0 - resolution: "timsort@npm:0.3.0" - checksum: 1a66cb897dacabd7dd7c91b7e2301498ca9e224de2edb9e42d19f5b17c4b6dc62a8d4cbc64f28be82aaf1541cb5a78ab49aa818f42a2989ebe049a64af731e2a - languageName: node - linkType: hard - "tiny-glob@npm:^0.2.9": version: 0.2.9 resolution: "tiny-glob@npm:0.2.9" @@ -20217,13 +20208,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.21.3": - version: 0.21.3 - resolution: "type-fest@npm:0.21.3" - checksum: e6b32a3b3877f04339bae01c193b273c62ba7bfc9e325b8703c4ee1b32dc8fe4ef5dfa54bf78265e069f7667d058e360ae0f37be5af9f153b22382cd55a9afe0 - languageName: node - linkType: hard - "type-fest@npm:^0.4.1": version: 0.4.1 resolution: "type-fest@npm:0.4.1" @@ -20252,17 +20236,10 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^1.0.2": - version: 1.4.0 - resolution: "type-fest@npm:1.4.0" - checksum: b011c3388665b097ae6a109a437a04d6f61d81b7357f74cbcb02246f2f5bd72b888ae33631b99871388122ba0a87f4ff1c94078e7119ff22c70e52c0ff828201 - languageName: node - linkType: hard - -"type-fest@npm:^2.11.2, type-fest@npm:^2.5.0": - version: 2.18.0 - resolution: "type-fest@npm:2.18.0" - checksum: 0737128d9d77b93793c6ee443e304462a792f5b723a6be035d6cb488c5610a8baa00522805421341c04324c80efba9849885bbfbc5a9623d0672fe8712969f62 +"type-fest@npm:^2.0.0, type-fest@npm:^2.11.2, type-fest@npm:^2.5.0": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 languageName: node linkType: hard @@ -20292,7 +20269,17 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^4.7.4, typescript@npm:~4.7.4": +"typescript@npm:^4.8.2": + version: 4.8.2 + resolution: "typescript@npm:4.8.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 7f5b81d0d558c9067f952c7af52ab7f19c2e70a916817929e4a5b256c93990bf3178eccb1ac8a850bc75df35f6781b6f4cb3370ce20d8b1ded92ed462348f628 + languageName: node + linkType: hard + +"typescript@npm:~4.7.4": version: 4.7.4 resolution: "typescript@npm:4.7.4" bin: @@ -20302,7 +20289,17 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^4.7.4#~builtin, typescript@patch:typescript@~4.7.4#~builtin": +"typescript@patch:typescript@^4.8.2#~builtin": + version: 4.8.2 + resolution: "typescript@patch:typescript@npm%3A4.8.2#~builtin::version=4.8.2&hash=a1c5e5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 5cb0f02f414f5405f4b0e7ee1fd7fa9177b6a8783c9017b6cad85f56ce4c4f93e0e6f2ce37e863cb597d44227cd009474c9fbd85bf7a50004e5557426cb58079 + languageName: node + linkType: hard + +"typescript@patch:typescript@~4.7.4#~builtin": version: 4.7.4 resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=a1c5e5" bin: