diff --git a/integration_tests/__tests__/__snapshots__/module_name_mapper.test.js.snap b/integration_tests/__tests__/__snapshots__/module_name_mapper.test.js.snap new file mode 100644 index 000000000000..d6895f2ed461 --- /dev/null +++ b/integration_tests/__tests__/__snapshots__/module_name_mapper.test.js.snap @@ -0,0 +1,24 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`moduleNameMapper correct configuration 1`] = ` +" PASS __tests__/index.js + ✓ moduleNameMapping correct configuration + +" +`; + +exports[`moduleNameMapper wrong configuration 1`] = ` +" FAIL __tests__/index.js + ● Test suite failed to run + + Configuration error: + + Unknown module in configuration option moduleNameMapper + Please check: + + \\"moduleNameMapper\\": { + \\"/\\\\.(css|less)$/\\": \\"no-such-module\\" + } + +" +`; diff --git a/integration_tests/__tests__/module_name_mapper.test.js b/integration_tests/__tests__/module_name_mapper.test.js new file mode 100644 index 000000000000..9338e10fa35a --- /dev/null +++ b/integration_tests/__tests__/module_name_mapper.test.js @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const runJest = require('../runJest'); +const {extractSummary} = require('../utils'); +const skipOnWindows = require('skipOnWindows'); + +// Works on windows, we just need to adjust snapshot test output +skipOnWindows.suite(); + +test('moduleNameMapper wrong configuration', () => { + const {stderr, status} = runJest('module_name_mapper_wrong_config'); + const {rest} = extractSummary(stderr); + + expect(status).toBe(1); + expect(rest).toMatchSnapshot(); +}); + +test('moduleNameMapper correct configuration', () => { + const {stderr, status} = runJest('module_name_mapper_correct_config'); + const {rest} = extractSummary(stderr); + + expect(status).toBe(0); + expect(rest).toMatchSnapshot(); +}); diff --git a/integration_tests/auto-clear-mocks/without-auto-clear/index.js b/integration_tests/auto-clear-mocks/without-auto-clear/index.js index caf03bcf32d8..1fb2500df77f 100644 --- a/integration_tests/auto-clear-mocks/without-auto-clear/index.js +++ b/integration_tests/auto-clear-mocks/without-auto-clear/index.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @flow */ module.exports = () => {}; diff --git a/integration_tests/module_name_mapper_correct_config/__mocks__/style_mock.js b/integration_tests/module_name_mapper_correct_config/__mocks__/style_mock.js new file mode 100644 index 000000000000..de50a547e3de --- /dev/null +++ b/integration_tests/module_name_mapper_correct_config/__mocks__/style_mock.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +module.exports = {}; diff --git a/integration_tests/module_name_mapper_correct_config/__tests__/index.js b/integration_tests/module_name_mapper_correct_config/__tests__/index.js new file mode 100644 index 000000000000..b0f43f7eca11 --- /dev/null +++ b/integration_tests/module_name_mapper_correct_config/__tests__/index.js @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +const importedFn = require('../'); + +test('moduleNameMapping correct configuration', () => { + expect(importedFn).toBeDefined(); +}); diff --git a/integration_tests/module_name_mapper_correct_config/index.js b/integration_tests/module_name_mapper_correct_config/index.js new file mode 100644 index 000000000000..c48c62617105 --- /dev/null +++ b/integration_tests/module_name_mapper_correct_config/index.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +require('./style.css'); + +module.exports = () => 'test'; diff --git a/integration_tests/module_name_mapper_correct_config/package.json b/integration_tests/module_name_mapper_correct_config/package.json new file mode 100644 index 000000000000..52a664c7c235 --- /dev/null +++ b/integration_tests/module_name_mapper_correct_config/package.json @@ -0,0 +1,7 @@ +{ + "jest": { + "moduleNameMapper": { + "\\.(css|less)$": "./__mocks__/style_mock.js" + } + } +} diff --git a/integration_tests/module_name_mapper_correct_config/style.css b/integration_tests/module_name_mapper_correct_config/style.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/integration_tests/module_name_mapper_wrong_config/__tests__/index.js b/integration_tests/module_name_mapper_wrong_config/__tests__/index.js new file mode 100644 index 000000000000..332d28be3043 --- /dev/null +++ b/integration_tests/module_name_mapper_wrong_config/__tests__/index.js @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +const importedFn = require('../'); + +test('moduleNameMapping wrong configuration', () => { + expect(importedFn).toBeDefined(); +}); diff --git a/integration_tests/module_name_mapper_wrong_config/index.js b/integration_tests/module_name_mapper_wrong_config/index.js new file mode 100644 index 000000000000..c48c62617105 --- /dev/null +++ b/integration_tests/module_name_mapper_wrong_config/index.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +require('./style.css'); + +module.exports = () => 'test'; diff --git a/integration_tests/module_name_mapper_wrong_config/package.json b/integration_tests/module_name_mapper_wrong_config/package.json new file mode 100644 index 000000000000..59634293724b --- /dev/null +++ b/integration_tests/module_name_mapper_wrong_config/package.json @@ -0,0 +1,7 @@ +{ + "jest": { + "moduleNameMapper": { + "\\.(css|less)$": "no-such-module" + } + } +} diff --git a/integration_tests/module_name_mapper_wrong_config/style.css b/integration_tests/module_name_mapper_wrong_config/style.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 265e53bd4665..03d24c27bc03 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -9,6 +9,7 @@ "main": "build/index.js", "dependencies": { "browser-resolve": "^1.11.2", + "chalk": "^1.1.3", "is-builtin-module": "^1.0.0", "resolve": "^1.3.2" }, diff --git a/packages/jest-resolve/src/index.js b/packages/jest-resolve/src/index.js index 0feb1008698d..6b4eade2c8e5 100644 --- a/packages/jest-resolve/src/index.js +++ b/packages/jest-resolve/src/index.js @@ -16,6 +16,7 @@ import path from 'path'; import nodeModulesPaths from 'resolve/lib/node-modules-paths'; import isBuiltinModule from 'is-builtin-module'; import defaultResolver from './default_resolver.js'; +import chalk from 'chalk'; type ResolverConfig = {| browser?: boolean, @@ -317,8 +318,8 @@ class Resolver { const paths = this._options.modulePaths; const extensions = this._options.extensions; const moduleDirectory = this._options.moduleDirectories; - const moduleNameMapper = this._options.moduleNameMapper; + if (moduleNameMapper) { for (const {moduleName: mappedModuleName, regex} of moduleNameMapper) { if (regex.test(moduleName)) { @@ -331,7 +332,8 @@ class Resolver { (_, index) => matches[parseInt(index, 10)], ); } - return ( + + const module = this.getModule(moduleName) || Resolver.findNodeModule(moduleName, { basedir: dirname, @@ -339,8 +341,22 @@ class Resolver { extensions, moduleDirectory, paths, - }) - ); + }); + if (!module) { + const error = new Error( + chalk.red(`${chalk.bold('Configuration error')}: + +Unknown module in configuration option ${chalk.bold('moduleNameMapper')} +Please check: + +"moduleNameMapper": { + "${regex.toString()}": "${chalk.bold(moduleName)}" +}`), + ); + error.stack = ''; + throw error; + } + return module; } } }