From 58c18b848a0d5421792168e83c965cc6a9397d3f Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 7 Oct 2017 11:52:44 +0200 Subject: [PATCH 1/3] Make `module.require` non-enumerable --- .../src/__tests__/runtime_require_module.test.js | 16 ++++++++++++++++ .../src/__tests__/test_root/RegularModule.js | 1 + packages/jest-runtime/src/index.js | 4 +++- 3 files changed, 20 insertions(+), 1 deletion(-) 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 c88f0668c930..52bf431c54dd 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -27,6 +27,22 @@ describe('Runtime requireModule', () => { expect(exports.isRealModule).toBe(true); })); + it('provides `module` to modules', () => + createRuntime(__filename).then(runtime => { + const exports = runtime.requireModule( + runtime.__mockRootPath, + 'RegularModule', + ); + expect(Object.keys(exports.module)).toEqual([ + 'exports', + 'filename', + 'id', + 'children', + 'parent', + 'paths', + ]); + })); + it('provides `module.parent` to modules', () => createRuntime(__filename).then(runtime => { const exports = runtime.requireModule( diff --git a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js index c66118146053..aa1bf17798af 100644 --- a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js +++ b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js @@ -39,3 +39,4 @@ exports.object = {}; exports.parent = module.parent; exports.paths = module.paths; exports.setModuleStateValue = setModuleStateValue; +exports.module = module; diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index 991c0e2f2917..d89ea8154725 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -508,7 +508,9 @@ class Runtime { ); localModule.paths = this._resolver.getModulePaths(dirname); - localModule.require = this._createRequireImplementation(filename, options); + Object.defineProperty(localModule, 'require', { + value: this._createRequireImplementation(filename, options), + }); const transformedFile = this._scriptTransformer.transform( filename, From 1705e8bb7511c6eed183899c58b7a4d9577cbe33 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 7 Oct 2017 11:53:25 +0200 Subject: [PATCH 2/3] Add `module.loaded` --- .../src/__tests__/runtime_require_module.test.js | 16 +++++++++++++++- .../src/__tests__/test_root/RegularModule.js | 2 ++ packages/jest-runtime/src/index.js | 10 ++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) 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 52bf431c54dd..0d185833e91c 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -37,6 +37,7 @@ describe('Runtime requireModule', () => { 'exports', 'filename', 'id', + 'loaded', 'children', 'parent', 'paths', @@ -53,10 +54,10 @@ describe('Runtime requireModule', () => { 'exports', 'filename', 'id', + 'loaded', 'children', 'parent', 'paths', - 'require', ]); })); @@ -90,6 +91,19 @@ describe('Runtime requireModule', () => { ); })); + it('provides `module.loaded` to modules', () => + createRuntime(__filename).then(runtime => { + const exports = runtime.requireModule( + runtime.__mockRootPath, + 'RegularModule', + ); + + // `exports.loaded` is set while the module is loaded, so should be `false` + expect(exports.loaded).toEqual(false); + // After the module is loaded we can query `module.loaded` again, at which point it should be `true` + expect(exports.isLoaded()).toEqual(true); + })); + it('provides `module.filename` to modules', () => createRuntime(__filename).then(runtime => { const exports = runtime.requireModule( diff --git a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js index aa1bf17798af..1370098e928a 100644 --- a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js +++ b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js @@ -40,3 +40,5 @@ exports.parent = module.parent; exports.paths = module.paths; exports.setModuleStateValue = setModuleStateValue; exports.module = module; +exports.loaded = module.loaded; +exports.isLoaded = () => module.loaded; diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index d89ea8154725..67b01632045d 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -33,6 +33,7 @@ type Module = {| exports: any, filename: string, id: string, + loaded: boolean, parent?: Module, paths?: Array, require?: Function, @@ -311,10 +312,11 @@ class Runtime { // We must register the pre-allocated module object first so that any // circular dependencies that may arise while evaluating the module can // be satisfied. - const localModule = { + const localModule: Module = { exports: {}, filename: modulePath, id: modulePath, + loaded: false, }; moduleRegistry[modulePath] = localModule; if (path.extname(modulePath) === '.json') { @@ -327,6 +329,8 @@ class Runtime { } else { this._execModule(localModule, options, moduleRegistry, from); } + + localModule.loaded = true; } return moduleRegistry[modulePath].exports; } @@ -381,13 +385,15 @@ class Runtime { } if (manualMock) { - const localModule = { + const localModule: Module = { exports: {}, filename: modulePath, id: modulePath, + loaded: false, }; this._execModule(localModule, undefined, this._mockRegistry, from); this._mockRegistry[moduleID] = localModule.exports; + localModule.loaded = true; } else { // Look for a real module to generate an automock from this._mockRegistry[moduleID] = this._generateMock(from, moduleName); From 32e302c9eda0d09648d808d16b369d36627e2b65 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 7 Oct 2017 12:54:59 +0200 Subject: [PATCH 3/3] Tighten type definition of `Module` --- .../src/__tests__/runtime_require_module.test.js | 4 ++-- packages/jest-runtime/src/index.js | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) 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 0d185833e91c..0bc393f34320 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -34,11 +34,11 @@ describe('Runtime requireModule', () => { 'RegularModule', ); expect(Object.keys(exports.module)).toEqual([ + 'children', 'exports', 'filename', 'id', 'loaded', - 'children', 'parent', 'paths', ]); @@ -51,11 +51,11 @@ describe('Runtime requireModule', () => { 'RequireRegularModule', ); expect(Object.keys(exports.parent)).toEqual([ + 'children', 'exports', 'filename', 'id', 'loaded', - 'children', 'parent', 'paths', ]); diff --git a/packages/jest-runtime/src/index.js b/packages/jest-runtime/src/index.js index 67b01632045d..bf40fdf8f3cb 100644 --- a/packages/jest-runtime/src/index.js +++ b/packages/jest-runtime/src/index.js @@ -29,14 +29,14 @@ import {run as cilRun} from './cli'; import {options as cliOptions} from './cli/args'; type Module = {| - children?: Array, + children: Array, exports: any, filename: string, id: string, loaded: boolean, parent?: Module, paths?: Array, - require?: Function, + require?: (id: string) => any, |}; type HasteMapOptions = {| @@ -313,6 +313,7 @@ class Runtime { // circular dependencies that may arise while evaluating the module can // be satisfied. const localModule: Module = { + children: [], exports: {}, filename: modulePath, id: modulePath, @@ -386,6 +387,7 @@ class Runtime { if (manualMock) { const localModule: Module = { + children: [], exports: {}, filename: modulePath, id: modulePath,