From bde98f69f5c9ea549edd0b5d0c449830be5aa164 Mon Sep 17 00:00:00 2001 From: levk Date: Sun, 3 Nov 2019 11:03:47 +0200 Subject: [PATCH] adds freezeCoreModules configuration option to mitigate memory leaks --- CHANGELOG.md | 1 + TestUtils.ts | 3 ++ docs/Configuration.md | 16 +++++++ .../__snapshots__/showConfig.test.ts.snap | 5 ++ .../__tests__/__snapshots__/init.test.js.snap | 8 ++++ packages/jest-config/src/Defaults.ts | 2 + packages/jest-config/src/Descriptions.ts | 4 ++ packages/jest-config/src/ValidConfig.ts | 2 + packages/jest-config/src/index.ts | 3 ++ packages/jest-config/src/normalize.ts | 2 + .../log_debug_messages.test.ts.snap | 5 ++ .../__tests__/runtime_require_module.test.js | 48 +++++++++++++++++++ packages/jest-runtime/src/index.ts | 45 ++++++++++++++++- .../script_transformer.test.js.snap | 9 +++- packages/jest-types/src/Config.ts | 7 +++ 15 files changed, 156 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 975de612d35c..55616cf735d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- `[jest-config]` Add `freezeCoreModules` configuration option to mitigate memory leaks described in the following issues: [#6399](https://github.com/facebook/jest/issues/6399), [#6814](https://github.com/facebook/jest/issues/6814) ([#8331](https://github.com/facebook/jest/pull/8331)) - `[babel-plugin-jest-hoist]` Show codeframe on static hoisting issues ([#8865](https://github.com/facebook/jest/pull/8865)) - `[babel-plugin-jest-hoist]` Add `BigInt` to `WHITELISTED_IDENTIFIERS` ([#8382](https://github.com/facebook/jest/pull/8382)) - `[babel-preset-jest]` Add `@babel/plugin-syntax-bigint` ([#8382](https://github.com/facebook/jest/pull/8382)) diff --git a/TestUtils.ts b/TestUtils.ts index 7bfca86f8bba..d580bb2a36d0 100644 --- a/TestUtils.ts +++ b/TestUtils.ts @@ -81,6 +81,8 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = { extraGlobals: [], filter: null, forceCoverageMatch: [], + freezeCoreModules: false, + freezeCoreModulesWhitelist: ['crypto'], globalSetup: null, globalTeardown: null, globals: {}, @@ -120,6 +122,7 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = { transform: [], transformIgnorePatterns: [], unmockedModulePathPatterns: null, + verbose: false, watchPathIgnorePatterns: [], }; diff --git a/docs/Configuration.md b/docs/Configuration.md index 23af2d858c76..de1ef3877702 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -367,6 +367,22 @@ You can collect coverage from those files with setting `forceCoverageMatch`. } ``` +### `freezeCoreModules` [boolean] + +Default: `false` + +Prevents overriding node's core module methods so to prevent memory leaks. + +Attempt to override such a property will fail silently. + +Running with [`verbose`](#verbose-boolean) flag will enable informative print outs. + +### `freezeCoreModulesWhitelist` [Array] + +Default: `['crypto']` + +Array of node core modules which will not be frozen. + ### `globals` [object] Default: `{}` diff --git a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap index dbafaaad3ca1..2e31f213b225 100644 --- a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap +++ b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap @@ -19,6 +19,10 @@ exports[`--showConfig outputs config info and exits 1`] = ` "errorOnDeprecated": false, "filter": null, "forceCoverageMatch": [], + "freezeCoreModules": false, + "freezeCoreModulesWhitelist": [ + "crypto" + ], "globalSetup": null, "globalTeardown": null, "globals": {}, @@ -78,6 +82,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` "transformIgnorePatterns": [ "/node_modules/" ], + "verbose": null, "watchPathIgnorePatterns": [] } ], diff --git a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap index 768ccc23e640..00a1b89fa74e 100644 --- a/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap @@ -72,6 +72,14 @@ module.exports = { // Force coverage collection from ignored files using an array of glob patterns // forceCoverageMatch: [], + // Prevents overriding node's core module methods so to prevent memory leaks + // freezeCoreModules: false, + + // Array of node core modules which will not be frozen + // freezeCoreModulesWhitelist: [ + // \\"crypto\\" + // ], + // A path to a module which exports an async function that is triggered once before all test suites // globalSetup: null, diff --git a/packages/jest-config/src/Defaults.ts b/packages/jest-config/src/Defaults.ts index 26c40f2f912f..cec1a1df08ba 100644 --- a/packages/jest-config/src/Defaults.ts +++ b/packages/jest-config/src/Defaults.ts @@ -31,6 +31,8 @@ const defaultOptions: Config.DefaultOptions = { expand: false, filter: null, forceCoverageMatch: [], + freezeCoreModules: false, + freezeCoreModulesWhitelist: ['crypto'], globalSetup: null, globalTeardown: null, globals: {}, diff --git a/packages/jest-config/src/Descriptions.ts b/packages/jest-config/src/Descriptions.ts index 3ff6d9b38b11..0d85cf3fd96f 100644 --- a/packages/jest-config/src/Descriptions.ts +++ b/packages/jest-config/src/Descriptions.ts @@ -31,6 +31,10 @@ const descriptions: {[key in keyof Config.InitialOptions]: string} = { 'Make calling deprecated APIs throw helpful error messages', forceCoverageMatch: 'Force coverage collection from ignored files using an array of glob patterns', + freezeCoreModules: + "Prevents overriding node's core module methods so to prevent memory leaks", + freezeCoreModulesWhitelist: + 'Array of node core modules which will not be frozen', globalSetup: 'A path to a module which exports an async function that is triggered once before all test suites', globalTeardown: diff --git a/packages/jest-config/src/ValidConfig.ts b/packages/jest-config/src/ValidConfig.ts index 28178876d529..0e0a049b829c 100644 --- a/packages/jest-config/src/ValidConfig.ts +++ b/packages/jest-config/src/ValidConfig.ts @@ -48,6 +48,8 @@ const initialOptions: Config.InitialOptions = { filter: '/filter.js', forceCoverageMatch: ['**/*.t.js'], forceExit: false, + freezeCoreModules: false, + freezeCoreModulesWhitelist: ['crypto'], globalSetup: 'setup.js', globalTeardown: 'teardown.js', globals: {__DEV__: true}, diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 1e414212a8e8..8e05ec9bc4ca 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -174,6 +174,8 @@ const groupOptions = ( extraGlobals: options.extraGlobals, filter: options.filter, forceCoverageMatch: options.forceCoverageMatch, + freezeCoreModules: options.freezeCoreModules, + freezeCoreModulesWhitelist: options.freezeCoreModulesWhitelist, globalSetup: options.globalSetup, globalTeardown: options.globalTeardown, globals: options.globals, @@ -211,6 +213,7 @@ const groupOptions = ( transform: options.transform, transformIgnorePatterns: options.transformIgnorePatterns, unmockedModulePathPatterns: options.unmockedModulePathPatterns, + verbose: options.verbose, watchPathIgnorePatterns: options.watchPathIgnorePatterns, }), }); diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 90ac9f57a8af..a3f597bfd424 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -852,6 +852,8 @@ export default function normalize( case 'findRelatedTests': case 'forceCoverageMatch': case 'forceExit': + case 'freezeCoreModules': + case 'freezeCoreModulesWhitelist': case 'lastCommit': case 'listTests': case 'logHeapUsage': diff --git a/packages/jest-core/src/lib/__tests__/__snapshots__/log_debug_messages.test.ts.snap b/packages/jest-core/src/lib/__tests__/__snapshots__/log_debug_messages.test.ts.snap index 95f5df413db5..f1a641cab932 100644 --- a/packages/jest-core/src/lib/__tests__/__snapshots__/log_debug_messages.test.ts.snap +++ b/packages/jest-core/src/lib/__tests__/__snapshots__/log_debug_messages.test.ts.snap @@ -16,6 +16,10 @@ exports[`prints the config object 1`] = ` "extraGlobals": [], "filter": null, "forceCoverageMatch": [], + "freezeCoreModules": false, + "freezeCoreModulesWhitelist": [ + "crypto" + ], "globalSetup": null, "globalTeardown": null, "globals": {}, @@ -61,6 +65,7 @@ exports[`prints the config object 1`] = ` "transform": [], "transformIgnorePatterns": [], "unmockedModulePathPatterns": null, + "verbose": false, "watchPathIgnorePatterns": [] }, "globalConfig": { diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js index 4f678f9daac2..44405178e292 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -184,6 +184,54 @@ describe('Runtime requireModule', () => { }).not.toThrow(); })); + it('prevents overriding core module methods when `config.freezeCoreModules` is set', () => + createRuntime(__filename, {freezeCoreModules: true}).then(runtime => { + const fs = runtime.requireModule(runtime.__mockRootPath, 'fs'); + const originalFsClose = fs.close; + + fs.close = () => {}; + + expect(fs.close).toBe(originalFsClose); + })); + + it('allows mocking core module methods when `config.freezeCoreModules` is set', () => + createRuntime(__filename, {freezeCoreModules: true}).then(runtime => { + const root = runtime.requireModule(runtime.__mockRootPath); + const fs = runtime.requireModule(runtime.__mockRootPath, 'fs'); + let mockImplementationCalled = false; + const spy = root.jest.spyOn(fs, 'close').mockImplementation(() => { + mockImplementationCalled = true; + }); + + fs.close(); + + expect(mockImplementationCalled).toBe(true); + expect(spy).toHaveBeenCalled(); + })); + + it('allows overriding `crypto` core module methods by default', () => + createRuntime(__filename, {freezeCoreModules: true}).then(runtime => { + const crypto = runtime.requireModule(runtime.__mockRootPath, 'crypto'); + const cryptoRandomBytesOverride = () => {}; + + crypto.randomBytes = cryptoRandomBytesOverride; + + expect(crypto.randomBytes).toBe(cryptoRandomBytesOverride); + })); + + it('allows overriding core module methods when module is in `config.freezeCoreModulesWhitelist`', () => + createRuntime(__filename, { + freezeCoreModules: true, + freezeCoreModulesWhitelist: ['fs'], + }).then(runtime => { + const fs = runtime.requireModule(runtime.__mockRootPath, 'fs'); + const fsCloseOverride = () => {}; + + fs.close = fsCloseOverride; + + expect(fs.close).toBe(fsCloseOverride); + })); + it('finds and loads JSON files without file extension', () => createRuntime(__filename).then(runtime => { const exports = runtime.requireModule( diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 18921b7825bd..4697ec195e61 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -18,7 +18,7 @@ import jestMock = require('jest-mock'); import HasteMap = require('jest-haste-map'); import {formatStackTrace, separateMessageFromStack} from 'jest-message-util'; import Resolver = require('jest-resolve'); -import {createDirectory, deepCyclicCopy} from 'jest-util'; +import {ErrorWithStack, createDirectory, deepCyclicCopy} from 'jest-util'; import {escapePathForRegex} from 'jest-regex-util'; import Snapshot = require('jest-snapshot'); import { @@ -84,6 +84,7 @@ class Runtime { private _cacheFS: CacheFS; private _config: Config.ProjectConfig; + private _coreModulesProxyCache: {[moduleName: string]: any}; private _coverageOptions: ShouldInstrumentOptions; private _currentlyExecutingModulePath: string; private _environment: JestEnvironment; @@ -125,6 +126,7 @@ class Runtime { collectCoverageFrom: [], collectCoverageOnlyFrom: null, }; + this._coreModulesProxyCache = Object.create(null); this._currentlyExecutingModulePath = ''; this._environment = environment; this._explicitShouldMock = Object.create(null); @@ -776,7 +778,46 @@ class Runtime { return this._environment.global.process; } - return require(moduleName); + const module = require(moduleName); + + if ( + !this._config.freezeCoreModules || + this._config.freezeCoreModulesWhitelist.includes(moduleName) + ) { + return module; + } + + if (this._coreModulesProxyCache[moduleName]) { + return this._coreModulesProxyCache[moduleName]; + } + + const set = ( + target: object, + property: PropertyKey, + value: any, + receiver: any, + ) => { + if (typeof value !== 'function' || value._isMockFunction) { + return Reflect.set(target, property, value, receiver); + } + + if (this._config.verbose) { + console.warn( + new ErrorWithStack( + `Trying to override method '${property.toString()}' of a frozen core module '${moduleName}'`, + set, + ), + ); + } + + return true; + }; + + const proxy = new Proxy(module, {set}); + + this._coreModulesProxyCache[moduleName] = proxy; + + return proxy; } private _generateMock(from: Config.Path, moduleName: string) { diff --git a/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap b/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap index 49de0f86ac1c..1a446937d432 100644 --- a/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap +++ b/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap @@ -17,6 +17,10 @@ Object { "extraGlobals": Array [], "filter": null, "forceCoverageMatch": Array [], + "freezeCoreModules": false, + "freezeCoreModulesWhitelist": Array [ + "crypto", + ], "globalSetup": null, "globalTeardown": null, "globals": Object {}, @@ -67,6 +71,7 @@ Object { "/node_modules/", ], "unmockedModulePathPatterns": null, + "verbose": false, "watchPathIgnorePatterns": Array [], }, "instrument": true, @@ -218,7 +223,7 @@ exports[`ScriptTransformer uses multiple preprocessors 1`] = ` const TRANSFORMED = { filename: '/fruits/banana.js', script: 'module.exports = \\"banana\\";', - config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"],[\\"^.+\\\\\\\\.css$\\",\\"css-preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}', + config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"freezeCoreModules\\":false,\\"freezeCoreModulesWhitelist\\":[\\"crypto\\"],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"],[\\"^.+\\\\\\\\.css$\\",\\"css-preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"verbose\\":false,\\"watchPathIgnorePatterns\\":[]}', }; }});" @@ -244,7 +249,7 @@ exports[`ScriptTransformer uses the supplied preprocessor 1`] = ` const TRANSFORMED = { filename: '/fruits/banana.js', script: 'module.exports = \\"banana\\";', - config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}', + config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"freezeCoreModules\\":false,\\"freezeCoreModulesWhitelist\\":[\\"crypto\\"],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"verbose\\":false,\\"watchPathIgnorePatterns\\":[]}', }; }});" diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts index ec9ad63921b0..04cd607820ba 100644 --- a/packages/jest-types/src/Config.ts +++ b/packages/jest-types/src/Config.ts @@ -52,6 +52,8 @@ export type DefaultOptions = { expand: boolean; filter: Path | null | undefined; forceCoverageMatch: Array; + freezeCoreModules: boolean; + freezeCoreModulesWhitelist: Array; globals: ConfigGlobals; globalSetup: string | null | undefined; globalTeardown: string | null | undefined; @@ -150,6 +152,8 @@ export type InitialOptions = Partial<{ findRelatedTests: boolean; forceCoverageMatch: Array; forceExit: boolean; + freezeCoreModules?: boolean; + freezeCoreModulesWhitelist?: Array; json: boolean; globals: ConfigGlobals; globalSetup: string | null | undefined; @@ -386,6 +390,8 @@ export type ProjectConfig = { extraGlobals: Array; filter: Path | null | undefined; forceCoverageMatch: Array; + freezeCoreModules: boolean; + freezeCoreModulesWhitelist: Array; globalSetup: string | null | undefined; globalTeardown: string | null | undefined; globals: ConfigGlobals; @@ -424,6 +430,7 @@ export type ProjectConfig = { transformIgnorePatterns: Array; watchPathIgnorePatterns: Array; unmockedModulePathPatterns: Array | null | undefined; + verbose: boolean | null | undefined; }; export type Argv = Arguments<