test_runner: support mocking json modules
PR-URL: https://github.com/nodejs/node/pull/58007 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
ffe7e1ace0
commit
1bd7a2edf9
@ -2108,6 +2108,11 @@ test('spies on an object method', (t) => {
|
|||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v22.3.0
|
added: v22.3.0
|
||||||
|
changes:
|
||||||
|
- version:
|
||||||
|
- REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/58007
|
||||||
|
description: Support JSON modules.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
> Stability: 1.0 - Early development
|
> Stability: 1.0 - Early development
|
||||||
@ -2131,10 +2136,10 @@ added: v22.3.0
|
|||||||
mock will throw an exception when used as a CJS or builtin module.
|
mock will throw an exception when used as a CJS or builtin module.
|
||||||
* Returns: {MockModuleContext} An object that can be used to manipulate the mock.
|
* Returns: {MockModuleContext} An object that can be used to manipulate the mock.
|
||||||
|
|
||||||
This function is used to mock the exports of ECMAScript modules, CommonJS
|
This function is used to mock the exports of ECMAScript modules, CommonJS modules, JSON modules, and
|
||||||
modules, and Node.js builtin modules. Any references to the original module
|
Node.js builtin modules. Any references to the original module prior to mocking are not impacted. In
|
||||||
prior to mocking are not impacted. In order to enable module mocking, Node.js must
|
order to enable module mocking, Node.js must be started with the
|
||||||
be started with the [`--experimental-test-module-mocks`][] command-line flag.
|
[`--experimental-test-module-mocks`][] command-line flag.
|
||||||
|
|
||||||
The following example demonstrates how a mock is created for a module.
|
The following example demonstrates how a mock is created for a module.
|
||||||
|
|
||||||
|
@ -118,10 +118,17 @@ async function load(url, context, nextLoad) {
|
|||||||
// Treat builtins as commonjs because customization hooks do not allow a
|
// Treat builtins as commonjs because customization hooks do not allow a
|
||||||
// core module to be replaced.
|
// core module to be replaced.
|
||||||
// Also collapse 'commonjs-sync' and 'require-commonjs' to 'commonjs'.
|
// Also collapse 'commonjs-sync' and 'require-commonjs' to 'commonjs'.
|
||||||
const format = (
|
let format = original.format;
|
||||||
original.format === 'builtin' ||
|
switch (original.format) {
|
||||||
original.format === 'commonjs-sync' ||
|
case 'builtin': // Deliberate fallthrough
|
||||||
original.format === 'require-commonjs') ? 'commonjs' : original.format;
|
case 'commonjs-sync': // Deliberate fallthrough
|
||||||
|
case 'require-commonjs':
|
||||||
|
format = 'commonjs';
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
format = 'module';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
|
@ -70,7 +70,14 @@ const kMockUnknownMessage = 3;
|
|||||||
const kWaitTimeout = 5_000;
|
const kWaitTimeout = 5_000;
|
||||||
const kBadExportsMessage = 'Cannot create mock because named exports ' +
|
const kBadExportsMessage = 'Cannot create mock because named exports ' +
|
||||||
'cannot be applied to the provided default export.';
|
'cannot be applied to the provided default export.';
|
||||||
const kSupportedFormats = ['builtin', 'commonjs', 'module', 'module-typescript', 'commonjs-typescript'];
|
const kSupportedFormats = [
|
||||||
|
'builtin',
|
||||||
|
'commonjs-typescript',
|
||||||
|
'commonjs',
|
||||||
|
'json',
|
||||||
|
'module-typescript',
|
||||||
|
'module',
|
||||||
|
];
|
||||||
let sharedModuleState;
|
let sharedModuleState;
|
||||||
|
|
||||||
class MockFunctionContext {
|
class MockFunctionContext {
|
||||||
|
1
test/fixtures/module-mocking/basic.json
vendored
Normal file
1
test/fixtures/module-mocking/basic.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"foo":"bar"}
|
@ -365,6 +365,34 @@ test('ESM mocking with namedExports option', async (t) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('JSON mocking', async (t) => {
|
||||||
|
await t.test('with defaultExport', async (t) => {
|
||||||
|
const fixturePath = fixtures.path('module-mocking', 'basic.json');
|
||||||
|
const fixture = pathToFileURL(fixturePath);
|
||||||
|
const { default: original } = await import(fixture, { with: { type: 'json' } });
|
||||||
|
|
||||||
|
assert.deepStrictEqual(original, { foo: 'bar' });
|
||||||
|
|
||||||
|
const defaultExport = { qux: 'zed' };
|
||||||
|
|
||||||
|
t.mock.module(fixture, { defaultExport });
|
||||||
|
|
||||||
|
const { default: mocked } = await import(fixture, { with: { type: 'json' } });
|
||||||
|
|
||||||
|
assert.deepStrictEqual(mocked, defaultExport);
|
||||||
|
});
|
||||||
|
|
||||||
|
await t.test('throws without appropriate import attributes', async (t) => {
|
||||||
|
const fixturePath = fixtures.path('module-mocking', 'basic.json');
|
||||||
|
const fixture = pathToFileURL(fixturePath);
|
||||||
|
|
||||||
|
const defaultExport = { qux: 'zed' };
|
||||||
|
t.mock.module(fixture, { defaultExport });
|
||||||
|
|
||||||
|
await assert.rejects(() => import(fixture), /import attribute/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('modules cannot be mocked multiple times at once', async (t) => {
|
test('modules cannot be mocked multiple times at once', async (t) => {
|
||||||
await t.test('CJS', async (t) => {
|
await t.test('CJS', async (t) => {
|
||||||
const fixture = fixtures.path('module-mocking', 'basic-cjs.js');
|
const fixture = fixtures.path('module-mocking', 'basic-cjs.js');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user