Skip to content

Commit

Permalink
feat(runtime): populate require.cache (#9841)
Browse files Browse the repository at this point in the history
  • Loading branch information
antongolub committed Apr 20, 2020
1 parent 1039ed1 commit 470ef2d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-runtime]` Populate `require.cache` ([#9841](https://github.com/facebook/jest/pull/9841))

### Fixes

### Chore & Maintenance
Expand Down
41 changes: 41 additions & 0 deletions packages/jest-runtime/src/__tests__/runtime_require_cache.test.js
@@ -0,0 +1,41 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

'use strict';

let createRuntime;

describe('Runtime require.cache', () => {
beforeEach(() => {
createRuntime = require('createRuntime');
});

it('require.cache returns loaded module list as native Nodejs require does', () =>
createRuntime(__filename).then(runtime => {
const regularModule = runtime.requireModule(
runtime.__mockRootPath,
'RegularModule',
).module;

expect(regularModule.require.cache[regularModule.id]).toBe(regularModule);
}));

it('require.cache is tolerant readonly', () =>
createRuntime(__filename).then(runtime => {
const regularModule = runtime.requireModule(
runtime.__mockRootPath,
'RegularModule',
).module;

delete regularModule.require.cache[regularModule.id];
expect(regularModule.require.cache[regularModule.id]).toBe(regularModule);

regularModule.require.cache[regularModule.id] = 'something';
expect(regularModule.require.cache[regularModule.id]).toBe(regularModule);
}));
});
18 changes: 17 additions & 1 deletion packages/jest-runtime/src/index.ts
Expand Up @@ -80,6 +80,8 @@ type ResolveOptions = Parameters<typeof require.resolve>[1];
type BooleanObject = Record<string, boolean>;
type CacheFS = {[path: string]: string};

type RequireCache = {[key: string]: Module};

namespace Runtime {
export type Context = JestContext;
// ditch this export when moving to esm - for now we need it for to avoid faulty type elision
Expand Down Expand Up @@ -1270,11 +1272,25 @@ class Runtime {
this,
from.filename,
)) as LocalModuleRequire;
moduleRequire.cache = Object.create(null);
moduleRequire.extensions = Object.create(null);
moduleRequire.requireActual = this.requireActual.bind(this, from.filename);
moduleRequire.requireMock = this.requireMock.bind(this, from.filename);
moduleRequire.resolve = resolve;
moduleRequire.cache = (() => {
const notPermittedMethod = () => {
console.warn('`require.cache` modification is not permitted');
return true;
};
return new Proxy<RequireCache>(Object.create(null), {
defineProperty: notPermittedMethod,
deleteProperty: notPermittedMethod,
get: (_target, key) =>
typeof key === 'string' ? this._moduleRegistry.get(key) : undefined,
has: (_target, key) =>
typeof key === 'string' && this._moduleRegistry.has(key),
set: notPermittedMethod,
});
})();

Object.defineProperty(moduleRequire, 'main', {
enumerable: true,
Expand Down

0 comments on commit 470ef2d

Please sign in to comment.