Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/jest-on-mock-hook' into jest-on-…
Browse files Browse the repository at this point in the history
…mock-hook
  • Loading branch information
MillerSvt committed Jan 15, 2025
2 parents 9d65bc5 + 583453c commit f3888ef
Show file tree
Hide file tree
Showing 25 changed files with 243 additions and 198 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
- [**BREAKING**] `--testPathPattern` is now `--testPathPatterns`
- [**BREAKING**] Specifying `testPathPatterns` when programmatically calling `watch` must be specified as `new TestPathPatterns(patterns)`, where `TestPathPatterns` can be imported from `@jest/pattern`
- `[jest-reporters, jest-runner]` Unhandled errors without stack get correctly logged to console ([#14619](https://github.com/jestjs/jest/pull/14619))
- `[jest-util]` Always load `mjs` files with `import` ([#15447](https://github.com/jestjs/jest/pull/15447))
- `[jest-worker]` Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular ([#15191](https://github.com/jestjs/jest/pull/15191))
- `[jest-worker]` Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt ([#15191](https://github.com/jestjs/jest/pull/15191))

Expand Down Expand Up @@ -122,6 +123,7 @@
- `[docs]` Link NestJS documentation on testing with Jest ([#14940](https://github.com/jestjs/jest/pull/14940))
- `[docs]` `Revised documentation for .toHaveBeenCalled()` to accurately depict its functionality. ([#14853](https://github.com/jestjs/jest/pull/14853))
- `[docs]` Removed ExpressJS reference link from documentation due to dead link ([#15270](https://github.com/jestjs/jest/pull/15270))
- `[docs]` Removed `Running AngularJS Tests with Jest reference` link from documentation due to dead link ([#15270](https://github.com/jestjs/jest/pull/15311))

## 29.7.0

Expand Down
10 changes: 5 additions & 5 deletions docs/GlobalAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ Use `describe.each` if you keep duplicating the same test suites with different
- `%$` - Number of the test case.
- `%%` - single percent sign ('%'). This does not consume an argument.
- Or generate unique test titles by injecting properties of test case object with `$variable`
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- 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 run, this is the function that will receive the parameters in each row as function arguments.
Expand Down Expand Up @@ -305,7 +305,7 @@ describe.each([
- First row of variable name column headings separated with `|`
- One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
- `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` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- `fn`: `Function` the suite of tests to be run, 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. The default timeout is 5 seconds.

Expand Down Expand Up @@ -574,7 +574,7 @@ test.concurrent.each([
- First row of variable name column headings separated with `|`
- One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
- `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` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- `fn`: `Function` the test to be run, 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. The default timeout is 5 seconds.

Expand Down Expand Up @@ -697,7 +697,7 @@ Use `test.each` if you keep duplicating the same test with different data. `test
- `%$` - Number of the test case.
- `%%` - single percent sign ('%'). This does not consume an argument.
- Or generate unique test titles by injecting properties of test case object with `$variable`
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- 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 run, this is the function that will receive the parameters in each row as function arguments.
Expand Down Expand Up @@ -731,7 +731,7 @@ test.each([
- First row of variable name column headings separated with `|`
- One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
- `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` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- `fn`: `Function` the test to be run, 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. The default timeout is 5 seconds.

Expand Down
1 change: 0 additions & 1 deletion docs/TestingFrameworks.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ Jest is a universal testing platform, with the ability to adapt to any JavaScrip
## AngularJS

- [Testing an AngularJS app with Jest](https://medium.com/aya-experience/testing-an-angularjs-app-with-jest-3029a613251) by Matthieu Lux ([@Swiip](https://twitter.com/Swiip))
- [Running AngularJS Tests with Jest](https://engineering.talentpair.com/running-angularjs-tests-with-jest-49d0cc9c6d26) by Ben Brandt ([@benjaminbrandt](https://twitter.com/benjaminbrandt))
- [AngularJS Unit Tests with Jest Actions (Traditional Chinese)](https://dwatow.github.io/2019/08-14-angularjs/angular-jest/?fbclid=IwAR2SrqYg_o6uvCQ79FdNPeOxs86dUqB6pPKgd9BgnHt1kuIDRyRM-ch11xg) by Chris Wang ([@dwatow](https://github.com/dwatow))

## Angular
Expand Down
4 changes: 3 additions & 1 deletion e2e/esm-config/js/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

const displayName = await Promise.resolve('Config from js file');

export default {
displayName: 'Config from js file',
displayName,
testEnvironment: 'node',
};
4 changes: 3 additions & 1 deletion e2e/esm-config/mjs/jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

const displayName = await Promise.resolve('Config from mjs file');

export default {
displayName: 'Config from mjs file',
displayName,
testEnvironment: 'node',
};
6 changes: 3 additions & 3 deletions e2e/native-esm/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,13 @@ __metadata:
linkType: hard

"cross-spawn@npm:^7.0.0":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
version: 7.0.6
resolution: "cross-spawn@npm:7.0.6"
dependencies:
path-key: ^3.1.0
shebang-command: ^2.0.0
which: ^2.0.1
checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52
checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b
languageName: node
linkType: hard

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"strip-json-comments": "^3.1.1",
"tempy": "^1.0.0",
"ts-node": "^10.5.0",
"tstyche": "^2.0.0",
"tstyche": "^3.0.0",
"typescript": "^5.0.4",
"webpack": "^5.68.0",
"webpack-node-externals": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/diff-sequences/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"devDependencies": {
"@fast-check/jest": "^2.0.0",
"benchmark": "^2.1.4",
"diff": "^5.0.0"
"diff": "^7.0.0"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"@types/graceful-fs": "^4.1.3",
"@types/micromatch": "^4.0.7",
"@types/parse-json": "^4.0.0",
"esbuild": "^0.23.0",
"esbuild": "^0.24.0",
"esbuild-register": "^3.4.0",
"semver": "^7.5.3",
"ts-node": "^10.5.0",
Expand Down
17 changes: 17 additions & 0 deletions packages/jest-config/src/__tests__/normalize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ jest
...realFs,
statSync: () => ({isDirectory: () => true}),
};
})
.mock('jest-util', () => {
const realUtil =
jest.requireActual<typeof import('jest-util')>('jest-util');

return {
...realUtil,
requireOrImportModule: (filePath: string, interop = true) => {
const result = require(filePath);

if (interop) {
return realUtil.interopRequireDefault(result).default;
}

return result;
},
};
});

let root: string;
Expand Down
8 changes: 4 additions & 4 deletions packages/jest-each/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const each = require('jest-each').default;
- `%$` - Number of the test case.
- `%%` - single percent sign ('%'). This does not consume an argument.
- Or generate unique test titles by injecting properties of test case object with `$variable`
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- You can use `$#` to inject the index of the test case
- You cannot use `$variable` with the `printf` formatting except for `%%`
- testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments
Expand All @@ -149,7 +149,7 @@ const each = require('jest-each').default;
- `%$` - Number of the test case.
- `%%` - single percent sign ('%'). This does not consume an argument.
- Or generate unique test titles by injecting properties of test case object with `$variable`
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- You can use `$#` to inject the index of the test case
- You cannot use `$variable` with the `printf` formatting except for `%%`
- suiteFn: `Function` the suite of `test`/`it`s to be ran, this is the function that will receive the parameters in each row as function arguments
Expand Down Expand Up @@ -381,7 +381,7 @@ each`
##### `.test`:

- name: `String` the title of the `test`, use `$variable` in the name string to inject test values 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` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- You can use `$#` to inject the index of the table row.
- testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments

Expand Down Expand Up @@ -418,7 +418,7 @@ each`
##### `.describe`:

- name: `String` the title of the `test`, use `$variable` in the name string to inject test values 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` (only works for ["own" properites](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value` (only works for ["own" properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), e.g. `$variable.constructor.name` wouldn't work)
- suiteFn: `Function` the suite of `test`/`it`s to be ran, this is the function that will receive the parameters in each row as function arguments

### Usage
Expand Down
12 changes: 12 additions & 0 deletions packages/jest-environment/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@ export interface Jest {
moduleFactory?: () => T,
options?: {virtual?: boolean},
): Jest;
/**
* Registers a callback function that is invoked whenever a mock is generated for a module.
* This callback is passed the module name and the newly created mock object, and must return
* the (potentially modified) mock object.
*
* If multiple callbacks are registered, they will be called in the order they were added.
* Each callback receives the result of the previous callback as the `moduleMock` parameter,
* making it possible to apply sequential transformations.
*
* @param cb
*/
onGenerateMock<T>(cb: (moduleName: string, moduleMock: T) => T): Jest;
/**
* Mocks a module with the provided module factory when it is being imported.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-expect/__typetests__/jest-expect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ describe('JestExpect', () => {
});

test('is superset of `Expect`', () => {
expect<typeof jestExpect>().type.toMatch<typeof _expect>();
expect(jestExpect).type.toBeAssignableTo(_expect);

expect<typeof _expect>().type.not.toMatch<typeof jestExpect>();
expect(_expect).type.not.toBeAssignableTo(jestExpect);
});

test('allows type inference of the `actual` argument', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-mock/__typetests__/mock-functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('jest.fn()', () => {

test('models typings of mocked function', () => {
// eslint-disable-next-line @typescript-eslint/ban-types
expect(fn()).type.toMatch<Function>();
expect(fn()).type.toBeAssignableTo<Function>();

expect(fn()).type.toBe<Mock<(...args: Array<unknown>) => unknown>>();
expect(fn(() => {})).type.toBe<Mock<() => void>>();
Expand Down Expand Up @@ -424,7 +424,7 @@ describe('jest.spyOn()', () => {

test('models typings of spied object', () => {
// eslint-disable-next-line @typescript-eslint/ban-types
expect(spy).type.not.toMatch<Function>();
expect(spy).type.not.toBeAssignableTo<Function>();

expect(spy()).type.toRaiseError();
expect(new spy()).type.toRaiseError();
Expand Down
70 changes: 42 additions & 28 deletions packages/jest-util/src/requireOrImportModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,39 @@ import {isAbsolute} from 'path';
import {pathToFileURL} from 'url';
import interopRequireDefault from './interopRequireDefault';

async function importModule(
filePath: string,
applyInteropRequireDefault: boolean,
) {
try {
const moduleUrl = pathToFileURL(filePath);

// node `import()` supports URL, but TypeScript doesn't know that
const importedModule = await import(
/* webpackIgnore: true */ moduleUrl.href
);

if (!applyInteropRequireDefault) {
return importedModule;
}

if (!importedModule.default) {
throw new Error(
`Jest: Failed to load ESM at ${filePath} - did you use a default export?`,
);
}

return importedModule.default;
} catch (error: any) {
if (error.message === 'Not supported') {
throw new Error(
`Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${filePath}`,
);
}
throw error;
}
}

export default async function requireOrImportModule<T>(
filePath: string,
applyInteropRequireDefault = true,
Expand All @@ -19,40 +52,21 @@ export default async function requireOrImportModule<T>(
);
}
try {
if (filePath.endsWith('.mjs')) {
return importModule(filePath, applyInteropRequireDefault);
}

const requiredModule = require(filePath);
if (!applyInteropRequireDefault) {
return requiredModule;
}
return interopRequireDefault(requiredModule).default;
} catch (error: any) {
if (error.code === 'ERR_REQUIRE_ESM') {
try {
const moduleUrl = pathToFileURL(filePath);

// node `import()` supports URL, but TypeScript doesn't know that
const importedModule = await import(
/* webpackIgnore: true */ moduleUrl.href
);

if (!applyInteropRequireDefault) {
return importedModule;
}

if (!importedModule.default) {
throw new Error(
`Jest: Failed to load ESM at ${filePath} - did you use a default export?`,
);
}

return importedModule.default;
} catch (innerError: any) {
if (innerError.message === 'Not supported') {
throw new Error(
`Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${filePath}`,
);
}
throw innerError;
}
if (
error.code === 'ERR_REQUIRE_ESM' ||
error.code === 'ERR_REQUIRE_ASYNC_MODULE'
) {
return importModule(filePath, applyInteropRequireDefault);
} else {
throw error;
}
Expand Down
3 changes: 2 additions & 1 deletion tstyche.config.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"testFileMatch": ["packages/*/__typetests__/*.test.ts"]
"$schema": "https://tstyche.org/schemas/config.json",
"testFileMatch": ["packages/*/__typetests__/**/*.test.ts"]
}
Loading

0 comments on commit f3888ef

Please sign in to comment.