Navigation Menu

Skip to content

Commit

Permalink
Remove providesModuleNodeModules from Jest.
Browse files Browse the repository at this point in the history
  • Loading branch information
cpojer committed Feb 17, 2020
1 parent e2ad3a5 commit 41d3930
Show file tree
Hide file tree
Showing 17 changed files with 42 additions and 185 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -144,6 +144,7 @@
- `[jest-validate]` [**BREAKING**] Use ESM exports ([#8874](https://github.com/facebook/jest/pull/8874))
- `[jest-types]` Mark `InitialOptions` as `Partial` ([#8848](https://github.com/facebook/jest/pull/8848))
- `[jest-config]` Refactor `normalize` to be more type safe ([#8848](https://github.com/facebook/jest/pull/8848))
- `[jest-haste-map]` [**BREAKING**] removed `providesModuleNodeModules` ([#8535](https://github.com/facebook/jest/pull/8535))

### Performance

Expand Down Expand Up @@ -192,7 +193,10 @@

### Chore & Maintenance

<<<<<<< HEAD
- `[docs]` Replace FlowType with TypeScript in CONTRIBUTING.MD code conventions
=======
>>>>>>> 7d76bcbfd... Remove `providesModuleNodeModules` from Jest.
- `[jest-leak-detector]` remove code repeat ([#8438](https://github.com/facebook/jest/pull/8438))
- `[docs]` Add example to `jest.requireActual` ([#8482](https://github.com/facebook/jest/pull/8482))
- `[docs]` Add example to `jest.mock` for mocking ES6 modules with the `factory` parameter ([#8550](https://github.com/facebook/jest/pull/8550))
Expand Down
4 changes: 1 addition & 3 deletions TestUtils.ts
Expand Up @@ -84,9 +84,7 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = {
globalSetup: null,
globalTeardown: null,
globals: {},
haste: {
providesModuleNodeModules: [],
},
haste: {},
moduleDirectories: [],
moduleFileExtensions: ['js'],
moduleLoader: '/test_module_loader_path',
Expand Down
1 change: 0 additions & 1 deletion e2e/__tests__/__snapshots__/showConfig.test.ts.snap
Expand Up @@ -21,7 +21,6 @@ exports[`--showConfig outputs config info and exits 1`] = `
"globals": {},
"haste": {
"computeSha1": false,
"providesModuleNodeModules": [],
"throwOnModuleCollision": false
},
"moduleDirectories": [
Expand Down
1 change: 0 additions & 1 deletion packages/jest-config/src/Defaults.ts
Expand Up @@ -30,7 +30,6 @@ const defaultOptions: Config.DefaultOptions = {
globals: {},
haste: {
computeSha1: false,
providesModuleNodeModules: [],
throwOnModuleCollision: false,
},
maxConcurrency: 5,
Expand Down
1 change: 0 additions & 1 deletion packages/jest-config/src/ValidConfig.ts
Expand Up @@ -57,7 +57,6 @@ const initialOptions: Config.InitialOptions = {
defaultPlatform: 'ios',
hasteImplModulePath: '<rootDir>/haste_impl.js',
platforms: ['ios', 'android'],
providesModuleNodeModules: ['react', 'react-native'],
throwOnModuleCollision: false,
},
json: false,
Expand Down
1 change: 0 additions & 1 deletion packages/jest-core/src/__tests__/SearchSource.test.ts
Expand Up @@ -401,7 +401,6 @@ describe('SearchSource', () => {
'__tests__',
'haste_impl.js',
),
providesModuleNodeModules: [],
},
name: 'SearchSource-findRelatedTests-tests',
rootDir,
Expand Down
Expand Up @@ -19,9 +19,7 @@ exports[`prints the config object 1`] = `
"globalSetup": null,
"globalTeardown": null,
"globals": {},
"haste": {
"providesModuleNodeModules": []
},
"haste": {},
"moduleDirectories": [],
"moduleFileExtensions": [
"js"
Expand Down
30 changes: 0 additions & 30 deletions packages/jest-haste-map/src/__tests__/index.test.js
Expand Up @@ -332,7 +332,6 @@ describe('HasteMap', () => {
const hasteMap = new HasteMap({
...defaultConfig,
mocksPattern: '/__mocks__/',
providesModuleNodeModules: ['react', 'fbjs'],
});

return hasteMap.build().then(({__hasteMapForTest: data}) => {
Expand All @@ -344,23 +343,6 @@ describe('HasteMap', () => {
'fruits/Pear.js': ['Pear', 32, 42, 1, 'Banana\0Strawberry', null],
'fruits/Strawberry.js': ['Strawberry', 32, 42, 1, '', null],
'fruits/__mocks__/Pear.js': ['', 32, 42, 1, 'Melon', null],
// node modules
'fruits/node_modules/fbjs/lib/flatMap.js': [
'flatMap',
32,
42,
1,
'',
null,
],
'fruits/node_modules/react/React.js': [
'React',
32,
42,
1,
'Component',
null,
],
'vegetables/Melon.js': ['Melon', 32, 42, 1, '', null],
}),
);
Expand All @@ -370,21 +352,9 @@ describe('HasteMap', () => {
Banana: {[H.GENERIC_PLATFORM]: ['fruits/Banana.js', H.MODULE]},
Melon: {[H.GENERIC_PLATFORM]: ['vegetables/Melon.js', H.MODULE]},
Pear: {[H.GENERIC_PLATFORM]: ['fruits/Pear.js', H.MODULE]},
React: {
[H.GENERIC_PLATFORM]: [
'fruits/node_modules/react/React.js',
H.MODULE,
],
},
Strawberry: {
[H.GENERIC_PLATFORM]: ['fruits/Strawberry.js', H.MODULE],
},
flatMap: {
[H.GENERIC_PLATFORM]: [
'fruits/node_modules/fbjs/lib/flatMap.js',
H.MODULE,
],
},
}),
);

Expand Down
107 changes: 30 additions & 77 deletions packages/jest-haste-map/src/index.ts
Expand Up @@ -5,17 +5,17 @@
* LICENSE file in the root directory of this source tree.
*/

import {execSync} from 'child_process';
import {createHash} from 'crypto';
import {EventEmitter} from 'events';
import { execSync } from 'child_process';
import { createHash } from 'crypto';
import { EventEmitter } from 'events';
import * as fs from 'fs';
import {tmpdir} from 'os';
import { tmpdir } from 'os';
import * as path from 'path';
import {NodeWatcher, Watcher as SaneWatcher} from 'sane';
import {Config} from '@jest/types';
import { NodeWatcher, Watcher as SaneWatcher } from 'sane';
import { Config } from '@jest/types';
import serializer from 'jest-serializer';
import Worker from 'jest-worker';
import {getSha1, worker} from './worker';
import { getSha1, worker } from './worker';
import getMockName from './getMockName';
import getPlatformExtension from './lib/getPlatformExtension';
import H from './constants';
Expand Down Expand Up @@ -61,7 +61,6 @@ type Options = {
mocksPattern?: string;
name: string;
platforms: Array<string>;
providesModuleNodeModules?: Array<string>;
resetCache?: boolean;
retainAllFiles: boolean;
rootDir: string;
Expand Down Expand Up @@ -99,7 +98,7 @@ type Watcher = {
close(callback: () => void): void;
};

type WorkerInterface = {worker: typeof worker; getSha1: typeof getSha1};
type WorkerInterface = { worker: typeof worker; getSha1: typeof getSha1 };

// TODO: Ditch namespace when this module exports ESM
namespace HasteMap {
Expand All @@ -117,38 +116,16 @@ const PACKAGE_JSON = path.sep + 'package.json';

// TypeScript doesn't like us importing from outside `rootDir`, but it doesn't
// understand `require`.
const {version: VERSION} = require('../package.json');
const { version: VERSION } = require('../package.json');

const canUseWatchman = ((): boolean => {
try {
execSync('watchman --version', {stdio: ['ignore']});
execSync('watchman --version', { stdio: ['ignore'] });
return true;
} catch (e) {}
} catch (e) { }
return false;
})();

const escapePathSeparator = (string: string) =>
path.sep === '\\' ? string.replace(/(\/|\\)/g, '\\\\') : string;

const getWhiteList = (list: Array<string> | undefined): RegExp | null => {
if (list && list.length) {
const newList = list.map(item =>
escapePathSeparator(item.replace(/(\/)/g, path.sep)),
);
return new RegExp(
'(' +
escapePathSeparator(NODE_MODULES) +
'(?:' +
newList.join('|') +
')(?=$|' +
escapePathSeparator(path.sep) +
'))',
'g',
);
}
return null;
};

function invariant(condition: unknown, message?: string): asserts condition {
if (!condition) {
throw new Error(message);
Expand Down Expand Up @@ -241,7 +218,6 @@ class HasteMap extends EventEmitter {
private _console: Console;
private _options: InternalOptions;
private _watchers: Array<Watcher>;
private _whitelist: RegExp | null;
private _worker: WorkerInterface | null;

constructor(options: Options) {
Expand Down Expand Up @@ -277,7 +253,7 @@ class HasteMap extends EventEmitter {
if (options.ignorePattern && !(options.ignorePattern instanceof RegExp)) {
this._console.warn(
'jest-haste-map: the `ignorePattern` options as a function is being ' +
'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.',
'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.',
);
}

Expand Down Expand Up @@ -317,7 +293,6 @@ class HasteMap extends EventEmitter {
hasteImplHash,
dependencyExtractorHash,
);
this._whitelist = getWhiteList(options.providesModuleNodeModules);
this._buildPromise = null;
this._watchers = [];
this._worker = null;
Expand Down Expand Up @@ -433,7 +408,7 @@ class HasteMap extends EventEmitter {
map: ModuleMapData,
mocks: MockData,
filePath: Config.Path,
workerOptions?: {forceInBand: boolean},
workerOptions?: { forceInBand: boolean },
): Promise<void> | null {
const rootDir = this._options.rootDir;

Expand Down Expand Up @@ -552,7 +527,7 @@ class HasteMap extends EventEmitter {

// If we retain all files in the virtual HasteFS representation, we avoid
// reading them if they aren't important (node_modules).
if (this._options.retainAllFiles && this._isNodeModulesDir(filePath)) {
if (this._options.retainAllFiles && filePath.includes(NODE_MODULES)) {
if (computeSha1) {
return this._getWorker(workerOptions)
.getSha1({
Expand Down Expand Up @@ -647,7 +622,7 @@ class HasteMap extends EventEmitter {
changedFiles?: FileData;
hasteMap: InternalHasteMap;
}): Promise<InternalHasteMap> {
const {removedFiles, changedFiles, hasteMap} = data;
const { removedFiles, changedFiles, hasteMap } = data;

// If any files were removed or we did not track what files changed, process
// every file looking for changes. Otherwise, process only changed files.
Expand Down Expand Up @@ -723,10 +698,10 @@ class HasteMap extends EventEmitter {
/**
* Creates workers or parses files and extracts metadata in-process.
*/
private _getWorker(options?: {forceInBand: boolean}): WorkerInterface {
private _getWorker(options?: { forceInBand: boolean }): WorkerInterface {
if (!this._worker) {
if ((options && options.forceInBand) || this._options.maxWorkers <= 1) {
this._worker = {getSha1, worker};
this._worker = { getSha1, worker };
} else {
// @ts-ignore: assignment of a worker with custom properties.
this._worker = new Worker(require.resolve('./worker'), {
Expand Down Expand Up @@ -759,18 +734,18 @@ class HasteMap extends EventEmitter {
if (crawl === watchmanCrawl) {
this._console.warn(
`jest-haste-map: Watchman crawl failed. Retrying once with node ` +
`crawler.\n` +
` Usually this happens when watchman isn't running. Create an ` +
`empty \`.watchmanconfig\` file in your project's root folder or ` +
`initialize a git or hg repository in your project.\n` +
` ` +
error,
`crawler.\n` +
` Usually this happens when watchman isn't running. Create an ` +
`empty \`.watchmanconfig\` file in your project's root folder or ` +
`initialize a git or hg repository in your project.\n` +
` ` +
error,
);
return nodeCrawl(crawlerOptions).catch(e => {
throw new Error(
`Crawler retry failed:\n` +
` Original error: ${error.message}\n` +
` Retry error: ${e.message}\n`,
` Original error: ${error.message}\n` +
` Retry error: ${e.message}\n`,
);
});
}
Expand Down Expand Up @@ -803,8 +778,8 @@ class HasteMap extends EventEmitter {
canUseWatchman && this._options.useWatchman
? WatchmanWatcher
: FSEventsWatcher.isSupported()
? FSEventsWatcher
: NodeWatcher;
? FSEventsWatcher
: NodeWatcher;

const extensions = this._options.extensions;
const ignorePattern = this._options.ignorePattern;
Expand Down Expand Up @@ -902,7 +877,7 @@ class HasteMap extends EventEmitter {
}

const add = () => {
eventsQueue.push({filePath, stat, type});
eventsQueue.push({ filePath, stat, type });
return null;
};

Expand Down Expand Up @@ -962,7 +937,7 @@ class HasteMap extends EventEmitter {
hasteMap.map,
hasteMap.mocks,
filePath,
{forceInBand: true},
{ forceInBand: true },
);
// Cleanup
this._cleanup();
Expand Down Expand Up @@ -1077,32 +1052,10 @@ class HasteMap extends EventEmitter {

return (
ignoreMatched ||
(!this._options.retainAllFiles && this._isNodeModulesDir(filePath))
(!this._options.retainAllFiles && filePath.includes(NODE_MODULES))
);
}

private _isNodeModulesDir(filePath: Config.Path): boolean {
if (!filePath.includes(NODE_MODULES)) {
return false;
}

if (this._whitelist) {
const whitelist = this._whitelist;
const match = whitelist.exec(filePath);
const matchEndIndex = whitelist.lastIndex;
whitelist.lastIndex = 0;

if (!match) {
return true;
}

const filePathInPackage = filePath.substr(matchEndIndex);
return filePathInPackage.startsWith(NODE_MODULES);
}

return true;
}

private _createEmptyMap(): InternalHasteMap {
return {
clocks: new Map(),
Expand Down
16 changes: 0 additions & 16 deletions packages/jest-runtime/src/__tests__/runtime_require_module.test.js
Expand Up @@ -252,22 +252,6 @@ describe('Runtime requireModule', () => {
expect(hastePackage.isHastePackage).toBe(true);
}));

it('resolves node modules properly when crawling node_modules', () =>
// While we are crawling a node module, we shouldn't put package.json
// files of node modules to resolve to `package.json` but rather resolve
// to whatever the package.json's `main` field says.
createRuntime(__filename, {
haste: {
providesModuleNodeModules: ['not-a-haste-package'],
},
}).then(runtime => {
const hastePackage = runtime.requireModule(
runtime.__mockRootPath,
'not-a-haste-package',
);
expect(hastePackage.isNodeModule).toBe(true);
}));

it('resolves platform extensions based on the default platform', () =>
Promise.all([
createRuntime(__filename).then(runtime => {
Expand Down
1 change: 0 additions & 1 deletion packages/jest-runtime/src/index.ts
Expand Up @@ -252,7 +252,6 @@ class Runtime {
mocksPattern: escapePathForRegex(path.sep + '__mocks__' + path.sep),
name: config.name,
platforms: config.haste.platforms || ['ios', 'android'],
providesModuleNodeModules: config.haste.providesModuleNodeModules,
resetCache: options && options.resetCache,
retainAllFiles: false,
rootDir: config.rootDir,
Expand Down

0 comments on commit 41d3930

Please sign in to comment.