Skip to content

Commit

Permalink
feat(runtime): support require.resolve with options.paths
Browse files Browse the repository at this point in the history
  • Loading branch information
jeysal committed Jun 14, 2018
1 parent f48ac64 commit 8741ee0
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 2 deletions.
16 changes: 16 additions & 0 deletions e2e/__tests__/resolve-with-paths.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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.
*
* @flow
*/
'use strict';

const runJest = require('../runJest');

test('require.resolve with paths', () => {
const {status} = runJest('resolve-with-paths');
expect(status).toBe(0);
});
31 changes: 31 additions & 0 deletions e2e/resolve-with-paths/__tests__/resolve-with-paths.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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';

import {resolve} from 'path';

test('finds a module relative to one of the given paths', () => {
expect(require.resolve('./mod.js', {paths: ['../dir']})).toEqual(
resolve(__dirname, '..', 'dir', 'mod.js')
);
});

test('finds a module without a leading "./" relative to one of the given paths', () => {
expect(require.resolve('mod.js', {paths: ['../dir']})).toEqual(
resolve(__dirname, '..', 'dir', 'mod.js')
);
});

test('finds a native node module when paths are given', () => {
expect(require.resolve('fs', {paths: ['../dir']})).toEqual('fs');
});

test('throws an error if the module cannot be found from given paths', () => {
expect(() => require.resolve('./mod.js', {paths: ['..']})).toThrowError(
"Cannot resolve module './mod.js' from paths ['..'] from "
);
});
8 changes: 8 additions & 0 deletions e2e/resolve-with-paths/dir/mod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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.
*/

module.exports = 'mod';
5 changes: 5 additions & 0 deletions e2e/resolve-with-paths/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"jest": {
"testEnvironment": "node"
}
}
46 changes: 44 additions & 2 deletions packages/jest-runtime/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,48 @@ class Runtime {
return to ? this._resolver.resolveModule(from, to) : from;
}

_requireResolve(
from: Path,
moduleName?: string,
{paths}: {paths?: Path[]} = {},
) {
if (moduleName == null) {
throw new Error(
'The first argument to require.resolve must be a string. Received null or undefined.',
);
}

if (paths) {
for (const p of paths) {
const absolutePath = path.resolve(from, '..', p);
let module = this._resolver._resolveModuleFromDirIfExists(
absolutePath,
moduleName,
);

// require.resolve with options.paths
// in Node allows omitting the leading './',
// so if we haven't been successful yet,
// we try to find the module directly in the path.
module =
module ||
this._resolver._resolveModuleFromDirIfExists(
absolutePath,
path.resolve(absolutePath, moduleName),
);

if (module) return module;
}
throw new Error(
`Cannot resolve module '${moduleName}' from paths ['${paths.join(
"', '",
)}'] from ${from}`,
);
}

return this._resolveModule(from, moduleName);
}

_execModule(
localModule: Module,
options: ?InternalModuleOptions,
Expand Down Expand Up @@ -721,8 +763,8 @@ class Runtime {
moduleRequire.extensions = Object.create(null);
moduleRequire.requireActual = this.requireModule.bind(this, from.filename);
moduleRequire.requireMock = this.requireMock.bind(this, from.filename);
moduleRequire.resolve = moduleName =>
this._resolveModule(from.filename, moduleName);
moduleRequire.resolve = (moduleName, options) =>
this._requireResolve(from.filename, moduleName, options);
Object.defineProperty(
moduleRequire,
'main',
Expand Down

0 comments on commit 8741ee0

Please sign in to comment.