mirror of
https://github.com/nodejs/node.git
synced 2025-05-20 22:43:26 +00:00

This will be a start to generalize all argument validation errors. As currently we throw ARG/OPT, OUT_OF_RANGE, and other more specific errors. The OPT errors didn't bring much to the errors as it's just another variant of ARG error which is sometimes more confusing (some of our code used OPT errors to denote just argument validation errors presumably because of similarity of OPT to 'option' and not 'options-object') and they don't specify the name of the options object where the invalid value is located. Much better approach would be to just specify path to the invalid value in the name of the value as it is done in this PR (i.e. 'options.format', 'options.publicKey.type' etc) Also since this decreases a variety of errors we have it'd be easier to reuse validation code across the codebase. Refs: https://github.com/nodejs/node/pull/31251 Refs: https://github.com/nodejs/node/pull/34070#discussion_r467251009 Signed-off-by: Denys Otrishko <shishugi@gmail.com> PR-URL: https://github.com/nodejs/node/pull/34682 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
163 lines
4.3 KiB
JavaScript
163 lines
4.3 KiB
JavaScript
'use strict';
|
|
|
|
// Flags: --experimental-vm-modules
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const {
|
|
Module,
|
|
SourceTextModule,
|
|
SyntheticModule,
|
|
createContext
|
|
} = require('vm');
|
|
const util = require('util');
|
|
|
|
(async function test1() {
|
|
const context = createContext({
|
|
foo: 'bar',
|
|
baz: undefined,
|
|
typeofProcess: undefined,
|
|
});
|
|
const m = new SourceTextModule(
|
|
'baz = foo; typeofProcess = typeof process; typeof Object;',
|
|
{ context }
|
|
);
|
|
assert.strictEqual(m.status, 'unlinked');
|
|
await m.link(common.mustNotCall());
|
|
assert.strictEqual(m.status, 'linked');
|
|
assert.strictEqual(await m.evaluate(), undefined);
|
|
assert.strictEqual(m.status, 'evaluated');
|
|
assert.deepStrictEqual(context, {
|
|
foo: 'bar',
|
|
baz: 'bar',
|
|
typeofProcess: 'undefined'
|
|
});
|
|
}().then(common.mustCall()));
|
|
|
|
(async () => {
|
|
const m = new SourceTextModule(`
|
|
global.vmResultFoo = "foo";
|
|
global.vmResultTypeofProcess = Object.prototype.toString.call(process);
|
|
`);
|
|
await m.link(common.mustNotCall());
|
|
await m.evaluate();
|
|
assert.strictEqual(global.vmResultFoo, 'foo');
|
|
assert.strictEqual(global.vmResultTypeofProcess, '[object process]');
|
|
delete global.vmResultFoo;
|
|
delete global.vmResultTypeofProcess;
|
|
})().then(common.mustCall());
|
|
|
|
(async () => {
|
|
const m = new SourceTextModule('while (true) {}');
|
|
await m.link(common.mustNotCall());
|
|
await m.evaluate({ timeout: 500 })
|
|
.then(() => assert(false), () => {});
|
|
})().then(common.mustCall());
|
|
|
|
// Check the generated identifier for each module
|
|
(async () => {
|
|
const context1 = createContext({ });
|
|
const context2 = createContext({ });
|
|
|
|
const m1 = new SourceTextModule('1', { context: context1 });
|
|
assert.strictEqual(m1.identifier, 'vm:module(0)');
|
|
const m2 = new SourceTextModule('2', { context: context1 });
|
|
assert.strictEqual(m2.identifier, 'vm:module(1)');
|
|
const m3 = new SourceTextModule('3', { context: context2 });
|
|
assert.strictEqual(m3.identifier, 'vm:module(0)');
|
|
})().then(common.mustCall());
|
|
|
|
// Check inspection of the instance
|
|
{
|
|
const context = createContext({ foo: 'bar' });
|
|
const m = new SourceTextModule('1', { context });
|
|
|
|
assert.strictEqual(
|
|
util.inspect(m),
|
|
`SourceTextModule {
|
|
status: 'unlinked',
|
|
identifier: 'vm:module(0)',
|
|
context: { foo: 'bar' }
|
|
}`
|
|
);
|
|
|
|
assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]');
|
|
|
|
assert.throws(
|
|
() => m[util.inspect.custom].call(Object.create(null)),
|
|
{
|
|
code: 'ERR_VM_MODULE_NOT_MODULE',
|
|
message: 'Provided module is not an instance of Module'
|
|
},
|
|
);
|
|
}
|
|
|
|
{
|
|
const context = createContext({ foo: 'bar' });
|
|
const m = new SyntheticModule([], () => {}, { context });
|
|
|
|
assert.strictEqual(
|
|
util.inspect(m),
|
|
`SyntheticModule {
|
|
status: 'unlinked',
|
|
identifier: 'vm:module(0)',
|
|
context: { foo: 'bar' }
|
|
}`
|
|
);
|
|
|
|
assert.strictEqual(util.inspect(m, { depth: -1 }), '[SyntheticModule]');
|
|
}
|
|
|
|
// Check dependencies getter returns same object every time
|
|
{
|
|
const m = new SourceTextModule('');
|
|
const dep = m.dependencySpecifiers;
|
|
assert.notStrictEqual(dep, undefined);
|
|
assert.strictEqual(dep, m.dependencySpecifiers);
|
|
}
|
|
|
|
// Check the impossibility of creating an abstract instance of the Module.
|
|
{
|
|
assert.throws(() => new Module(), {
|
|
message: 'Module is not a constructor',
|
|
name: 'TypeError'
|
|
});
|
|
}
|
|
|
|
// Check to throws invalid exportNames
|
|
{
|
|
assert.throws(() => new SyntheticModule(undefined, () => {}, {}), {
|
|
message: 'The "exportNames" argument must be an ' +
|
|
'Array of unique strings.' +
|
|
' Received undefined',
|
|
name: 'TypeError'
|
|
});
|
|
}
|
|
|
|
// Check to throws duplicated exportNames
|
|
// https://github.com/nodejs/node/issues/32806
|
|
{
|
|
assert.throws(() => new SyntheticModule(['x', 'x'], () => {}, {}), {
|
|
message: 'The property \'exportNames.x\' is duplicated. Received \'x\'',
|
|
name: 'TypeError',
|
|
});
|
|
}
|
|
|
|
// Check to throws invalid evaluateCallback
|
|
{
|
|
assert.throws(() => new SyntheticModule([], undefined, {}), {
|
|
message: 'The "evaluateCallback" argument must be of type function.' +
|
|
' Received undefined',
|
|
name: 'TypeError'
|
|
});
|
|
}
|
|
|
|
// Check to throws invalid options
|
|
{
|
|
assert.throws(() => new SyntheticModule([], () => {}, null), {
|
|
message: 'The "options" argument must be of type object.' +
|
|
' Received null',
|
|
name: 'TypeError'
|
|
});
|
|
}
|