215 lines
6.1 KiB
JavaScript
215 lines
6.1 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.default = exports.TestEnvironment = void 0;
|
|
function _vm() {
|
|
const data = require('vm');
|
|
_vm = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _fakeTimers() {
|
|
const data = require('@jest/fake-timers');
|
|
_fakeTimers = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _jestMock() {
|
|
const data = require('jest-mock');
|
|
_jestMock = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _jestUtil() {
|
|
const data = require('jest-util');
|
|
_jestUtil = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
// some globals we do not want, either because deprecated or we set it ourselves
|
|
const denyList = new Set([
|
|
'GLOBAL',
|
|
'root',
|
|
'global',
|
|
'Buffer',
|
|
'ArrayBuffer',
|
|
'Uint8Array',
|
|
// if env is loaded within a jest test
|
|
'jest-symbol-do-not-touch'
|
|
]);
|
|
const nodeGlobals = new Map(
|
|
Object.getOwnPropertyNames(globalThis)
|
|
.filter(global => !denyList.has(global))
|
|
.map(nodeGlobalsKey => {
|
|
const descriptor = Object.getOwnPropertyDescriptor(
|
|
globalThis,
|
|
nodeGlobalsKey
|
|
);
|
|
if (!descriptor) {
|
|
throw new Error(
|
|
`No property descriptor for ${nodeGlobalsKey}, this is a bug in Jest.`
|
|
);
|
|
}
|
|
return [nodeGlobalsKey, descriptor];
|
|
})
|
|
);
|
|
function isString(value) {
|
|
return typeof value === 'string';
|
|
}
|
|
class NodeEnvironment {
|
|
context;
|
|
fakeTimers;
|
|
fakeTimersModern;
|
|
global;
|
|
moduleMocker;
|
|
customExportConditions = ['node', 'node-addons'];
|
|
|
|
// while `context` is unused, it should always be passed
|
|
constructor(config, _context) {
|
|
const {projectConfig} = config;
|
|
this.context = (0, _vm().createContext)();
|
|
const global = (0, _vm().runInContext)(
|
|
'this',
|
|
Object.assign(this.context, projectConfig.testEnvironmentOptions)
|
|
);
|
|
this.global = global;
|
|
const contextGlobals = new Set(Object.getOwnPropertyNames(global));
|
|
for (const [nodeGlobalsKey, descriptor] of nodeGlobals) {
|
|
if (!contextGlobals.has(nodeGlobalsKey)) {
|
|
if (descriptor.configurable) {
|
|
Object.defineProperty(global, nodeGlobalsKey, {
|
|
configurable: true,
|
|
enumerable: descriptor.enumerable,
|
|
get() {
|
|
// @ts-expect-error: no index signature
|
|
const val = globalThis[nodeGlobalsKey];
|
|
|
|
// override lazy getter
|
|
Object.defineProperty(global, nodeGlobalsKey, {
|
|
configurable: true,
|
|
enumerable: descriptor.enumerable,
|
|
value: val,
|
|
writable:
|
|
descriptor.writable === true ||
|
|
// Node 19 makes performance non-readable. This is probably not the correct solution.
|
|
nodeGlobalsKey === 'performance'
|
|
});
|
|
return val;
|
|
},
|
|
set(val) {
|
|
// override lazy getter
|
|
Object.defineProperty(global, nodeGlobalsKey, {
|
|
configurable: true,
|
|
enumerable: descriptor.enumerable,
|
|
value: val,
|
|
writable: true
|
|
});
|
|
}
|
|
});
|
|
} else if ('value' in descriptor) {
|
|
Object.defineProperty(global, nodeGlobalsKey, {
|
|
configurable: false,
|
|
enumerable: descriptor.enumerable,
|
|
value: descriptor.value,
|
|
writable: descriptor.writable
|
|
});
|
|
} else {
|
|
Object.defineProperty(global, nodeGlobalsKey, {
|
|
configurable: false,
|
|
enumerable: descriptor.enumerable,
|
|
get: descriptor.get,
|
|
set: descriptor.set
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// @ts-expect-error - Buffer and gc is "missing"
|
|
global.global = global;
|
|
global.Buffer = Buffer;
|
|
global.ArrayBuffer = ArrayBuffer;
|
|
// TextEncoder (global or via 'util') references a Uint8Array constructor
|
|
// different than the global one used by users in tests. This makes sure the
|
|
// same constructor is referenced by both.
|
|
global.Uint8Array = Uint8Array;
|
|
(0, _jestUtil().installCommonGlobals)(global, projectConfig.globals);
|
|
|
|
// Node's error-message stack size is limited at 10, but it's pretty useful
|
|
// to see more than that when a test fails.
|
|
global.Error.stackTraceLimit = 100;
|
|
if ('customExportConditions' in projectConfig.testEnvironmentOptions) {
|
|
const {customExportConditions} = projectConfig.testEnvironmentOptions;
|
|
if (
|
|
Array.isArray(customExportConditions) &&
|
|
customExportConditions.every(isString)
|
|
) {
|
|
this.customExportConditions = customExportConditions;
|
|
} else {
|
|
throw new Error(
|
|
'Custom export conditions specified but they are not an array of strings'
|
|
);
|
|
}
|
|
}
|
|
this.moduleMocker = new (_jestMock().ModuleMocker)(global);
|
|
const timerIdToRef = id => ({
|
|
id,
|
|
ref() {
|
|
return this;
|
|
},
|
|
unref() {
|
|
return this;
|
|
}
|
|
});
|
|
const timerRefToId = timer => timer?.id;
|
|
this.fakeTimers = new (_fakeTimers().LegacyFakeTimers)({
|
|
config: projectConfig,
|
|
global,
|
|
moduleMocker: this.moduleMocker,
|
|
timerConfig: {
|
|
idToRef: timerIdToRef,
|
|
refToId: timerRefToId
|
|
}
|
|
});
|
|
this.fakeTimersModern = new (_fakeTimers().ModernFakeTimers)({
|
|
config: projectConfig,
|
|
global
|
|
});
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
async setup() {}
|
|
async teardown() {
|
|
if (this.fakeTimers) {
|
|
this.fakeTimers.dispose();
|
|
}
|
|
if (this.fakeTimersModern) {
|
|
this.fakeTimersModern.dispose();
|
|
}
|
|
this.context = null;
|
|
this.fakeTimers = null;
|
|
this.fakeTimersModern = null;
|
|
}
|
|
exportConditions() {
|
|
return this.customExportConditions;
|
|
}
|
|
getVmContext() {
|
|
return this.context;
|
|
}
|
|
}
|
|
exports.default = NodeEnvironment;
|
|
const TestEnvironment = NodeEnvironment;
|
|
exports.TestEnvironment = TestEnvironment;
|