From 7b1568d9162fafe6a630fb425f16a44998894164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brais=20Pi=C3=B1eiro?= Date: Tue, 27 Oct 2020 10:08:57 +0100 Subject: [PATCH] fix(jest-resolve-dependencies): resolve mocks as dependencies (#10713) Co-authored-by: grey275 --- CHANGELOG.md | 1 + .../__mocks__/fake-node-module.js | 9 ++++++ .../__fixtures__/hasMocked/__mocks__/file.js | 9 ++++++ .../__tests__/__fixtures__/hasMocked/file.js | 9 ++++++ .../__fixtures__/hasMocked/file.test.js | 10 +++++++ .../src/__tests__/dependency_resolver.test.ts | 25 ++++++++++++++++ .../jest-resolve-dependencies/src/index.ts | 30 +++++++++++++++++-- 7 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 packages/jest-resolve-dependencies/__mocks__/fake-node-module.js create mode 100644 packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/__mocks__/file.js create mode 100644 packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.js create mode 100644 packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cce32ece1bd..c8f725854262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - `[jest-config]` Fix bug introduced in watch mode by PR[#10678](https://github.com/facebook/jest/pull/10678/files#r511037803) ([#10692](https://github.com/facebook/jest/pull/10692)) - `[expect]` Stop modifying the sample in `expect.objectContaining()` ([#10711](https://github.com/facebook/jest/pull/10711)) +- `[jest-resolve-dependencies]` Resolve mocks as dependencies ([#10713](https://github.com/facebook/jest/pull/10713)) ### Chore & Maintenance diff --git a/packages/jest-resolve-dependencies/__mocks__/fake-node-module.js b/packages/jest-resolve-dependencies/__mocks__/fake-node-module.js new file mode 100644 index 000000000000..f7294048510d --- /dev/null +++ b/packages/jest-resolve-dependencies/__mocks__/fake-node-module.js @@ -0,0 +1,9 @@ +/** + * 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. + * + */ + +module.exports = str => str; diff --git a/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/__mocks__/file.js b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/__mocks__/file.js new file mode 100644 index 000000000000..b64851b9b271 --- /dev/null +++ b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/__mocks__/file.js @@ -0,0 +1,9 @@ +/** + * 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. + * + */ + +module.exports = jest.fn(); diff --git a/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.js b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.js new file mode 100644 index 000000000000..f7294048510d --- /dev/null +++ b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.js @@ -0,0 +1,9 @@ +/** + * 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. + * + */ + +module.exports = str => str; diff --git a/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.test.js b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.test.js new file mode 100644 index 000000000000..ec2ebbc0a1a4 --- /dev/null +++ b/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/hasMocked/file.test.js @@ -0,0 +1,10 @@ +/** + * 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. + * + */ + +require('./file'); +require('fake-node-module'); diff --git a/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts b/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts index d32526f3fd81..3862becf46dd 100644 --- a/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts +++ b/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts @@ -61,6 +61,18 @@ test('resolves dependencies for existing path', () => { ]); }); +test('includes the mocks of dependencies as dependencies', () => { + const resolved = dependencyResolver.resolve( + path.resolve(__dirname, '__fixtures__/hasMocked/file.test.js'), + ); + + expect(resolved).toEqual([ + expect.stringContaining(path.join('hasMocked', 'file.js')), + expect.stringContaining(path.join('hasMocked', '__mocks__', 'file.js')), + expect.stringContaining(path.join('__mocks__', 'fake-node-module.js')), + ]); +}); + test('resolves dependencies for scoped packages', () => { const resolved = dependencyResolver.resolve( path.resolve(__dirname, '__fixtures__', 'scoped.js'), @@ -92,6 +104,19 @@ test('resolves inverse dependencies for existing path', () => { ]); }); +test('resolves inverse dependencies of mock', () => { + const paths = new Set([ + path.resolve(__dirname, '__fixtures__/hasMocked/__mocks__/file.js'), + ]); + const resolved = dependencyResolver.resolveInverse(paths, filter); + + expect(resolved).toEqual([ + expect.stringContaining( + path.join('__tests__/__fixtures__/hasMocked/file.test.js'), + ), + ]); +}); + test('resolves inverse dependencies from available snapshot', () => { const paths = new Set([ path.resolve(__dirname, '__fixtures__/file.js'), diff --git a/packages/jest-resolve-dependencies/src/index.ts b/packages/jest-resolve-dependencies/src/index.ts index c354ed76efc6..779040371ad8 100644 --- a/packages/jest-resolve-dependencies/src/index.ts +++ b/packages/jest-resolve-dependencies/src/index.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import * as path from 'path'; import type {Config} from '@jest/types'; import type {FS as HasteFS} from 'jest-haste-map'; import type {ResolveModuleConfig, ResolverType} from 'jest-resolve'; @@ -49,7 +50,9 @@ class DependencyResolver { if (this._resolver.isCoreModule(dependency)) { return acc; } + let resolvedDependency; + let resolvedMockDependency; try { resolvedDependency = this._resolver.resolveModule( file, @@ -64,8 +67,31 @@ class DependencyResolver { } } - if (resolvedDependency) { - acc.push(resolvedDependency); + if (!resolvedDependency) { + return acc; + } + + acc.push(resolvedDependency); + + // If we resolve a dependency, then look for a mock dependency + // of the same name in that dependency's directory. + resolvedMockDependency = this._resolver.getMockModule( + resolvedDependency, + path.basename(dependency), + ); + + if (resolvedMockDependency) { + const dependencyMockDir = path.resolve( + path.dirname(resolvedDependency), + '__mocks__', + ); + + resolvedMockDependency = path.resolve(resolvedMockDependency); + + // make sure mock is in the correct directory + if (dependencyMockDir === path.dirname(resolvedMockDependency)) { + acc.push(resolvedMockDependency); + } } return acc;