diff --git a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js index d9b8229a285b..1d10eea8cf20 100644 --- a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js +++ b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js @@ -34,8 +34,6 @@ jest.mock('child_process', () => ({ }), })); -let mockHasReaddirWithFileTypesSupport = false; - jest.mock('graceful-fs', () => { const slash = require('slash'); let mtime = 32; @@ -73,55 +71,42 @@ jest.mock('graceful-fs', () => { throw new Error('readdir: callback is not a function!'); } - if (mockHasReaddirWithFileTypesSupport) { - if (slash(dir) === '/project/fruits') { - setTimeout( - () => - callback(null, [ - { - isDirectory: () => true, - isSymbolicLink: () => false, - name: 'directory', - }, - { - isDirectory: () => false, - isSymbolicLink: () => false, - name: 'tomato.js', - }, - { - isDirectory: () => false, - isSymbolicLink: () => true, - name: 'symlink', - }, - ]), - 0, - ); - } else if (slash(dir) === '/project/fruits/directory') { - setTimeout( - () => - callback(null, [ - { - isDirectory: () => false, - isSymbolicLink: () => false, - name: 'strawberry.js', - }, - ]), - 0, - ); - } else if (slash(dir) == '/error') { - setTimeout(() => callback({code: 'ENOTDIR'}, undefined), 0); - } - } else { - if (slash(dir) === '/project/fruits') { - setTimeout( - () => callback(null, ['directory', 'tomato.js', 'symlink']), - 0, - ); - } else if (slash(dir) === '/project/fruits/directory') { - setTimeout(() => callback(null, ['strawberry.js']), 0); - } else if (slash(dir) == '/error') { - setTimeout(() => callback({code: 'ENOTDIR'}, undefined), 0); - } + if (slash(dir) === '/project/fruits') { + setTimeout( + () => + callback(null, [ + { + isDirectory: () => true, + isSymbolicLink: () => false, + name: 'directory', + }, + { + isDirectory: () => false, + isSymbolicLink: () => false, + name: 'tomato.js', + }, + { + isDirectory: () => false, + isSymbolicLink: () => true, + name: 'symlink', + }, + ]), + 0, + ); + } else if (slash(dir) === '/project/fruits/directory') { + setTimeout( + () => + callback(null, [ + { + isDirectory: () => false, + isSymbolicLink: () => false, + name: 'strawberry.js', + }, + ]), + 0, + ); + } else if (slash(dir) == '/error') { + setTimeout(() => callback({code: 'ENOTDIR'}, undefined), 0); } }), stat: jest.fn(stat), @@ -379,65 +364,30 @@ describe('node crawler', () => { expect(removedFiles).toEqual(new Map()); }); - describe('readdir withFileTypes support', () => { - it('calls lstat for directories and symlinks if readdir withFileTypes is not supported', async () => { - nodeCrawl = require('../node'); - const fs = require('graceful-fs'); - - const files = new Map(); - const {hasteMap, removedFiles} = await nodeCrawl({ - data: {files}, - extensions: ['js'], - forceNodeFilesystemAPI: true, - ignore: pearMatcher, - rootDir, - roots: ['/project/fruits'], - }); - - expect(hasteMap.files).toEqual( - createMap({ - 'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null], - 'fruits/tomato.js': ['', 32, 42, 0, '', null], - }), - ); - expect(removedFiles).toEqual(new Map()); - // once for /project/fruits, once for /project/fruits/directory - expect(fs.readdir).toHaveBeenCalledTimes(2); - // once for each of: - // 1. /project/fruits/directory - // 2. /project/fruits/directory/strawberry.js - // 3. /project/fruits/tomato.js - // 4. /project/fruits/symlink - // (we never call lstat on the root /project/fruits, since we know it's a directory) - expect(fs.lstat).toHaveBeenCalledTimes(4); - }); + it('avoids calling lstat for directories and symlinks', async () => { + nodeCrawl = require('../node'); + const fs = require('graceful-fs'); - it('avoids calling lstat for directories and symlinks if readdir withFileTypes is supported', async () => { - mockHasReaddirWithFileTypesSupport = true; - nodeCrawl = require('../node'); - const fs = require('graceful-fs'); - - const files = new Map(); - const {hasteMap, removedFiles} = await nodeCrawl({ - data: {files}, - extensions: ['js'], - forceNodeFilesystemAPI: true, - ignore: pearMatcher, - rootDir, - roots: ['/project/fruits'], - }); - - expect(hasteMap.files).toEqual( - createMap({ - 'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null], - 'fruits/tomato.js': ['', 32, 42, 0, '', null], - }), - ); - expect(removedFiles).toEqual(new Map()); - // once for /project/fruits, once for /project/fruits/directory - expect(fs.readdir).toHaveBeenCalledTimes(2); - // once for strawberry.js, once for tomato.js - expect(fs.lstat).toHaveBeenCalledTimes(2); + const files = new Map(); + const {hasteMap, removedFiles} = await nodeCrawl({ + data: {files}, + extensions: ['js'], + forceNodeFilesystemAPI: true, + ignore: pearMatcher, + rootDir, + roots: ['/project/fruits'], }); + + expect(hasteMap.files).toEqual( + createMap({ + 'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null], + 'fruits/tomato.js': ['', 32, 42, 0, '', null], + }), + ); + expect(removedFiles).toEqual(new Map()); + // once for /project/fruits, once for /project/fruits/directory + expect(fs.readdir).toHaveBeenCalledTimes(2); + // once for strawberry.js, once for tomato.js + expect(fs.lstat).toHaveBeenCalledTimes(2); }); }); diff --git a/packages/jest-haste-map/src/crawlers/node.ts b/packages/jest-haste-map/src/crawlers/node.ts index 58fc9ccf442d..88d15678706d 100644 --- a/packages/jest-haste-map/src/crawlers/node.ts +++ b/packages/jest-haste-map/src/crawlers/node.ts @@ -74,27 +74,19 @@ function find( callback(result); return; } - // node < v10.10 does not support the withFileTypes option, and - // entry will be a string. - entries.forEach((entry: string | fs.Dirent) => { - const file = path.join( - directory, - typeof entry === 'string' ? entry : entry.name, - ); + entries.forEach(entry => { + const file = path.join(directory, entry.name); if (ignore(file)) { return; } - if (typeof entry !== 'string') { - if (entry.isSymbolicLink()) { - return; - } - - if (entry.isDirectory()) { - search(file); - return; - } + if (entry.isSymbolicLink()) { + return; + } + if (entry.isDirectory()) { + search(file); + return; } activeCalls++; diff --git a/packages/jest-resolve/src/isBuiltinModule.ts b/packages/jest-resolve/src/isBuiltinModule.ts index df64cc3d422f..a80fa949e540 100644 --- a/packages/jest-resolve/src/isBuiltinModule.ts +++ b/packages/jest-resolve/src/isBuiltinModule.ts @@ -7,12 +7,7 @@ import module = require('module'); -// TODO: remove when we drop support for node v10 - it is included from node v12 -const EXPERIMENTAL_MODULES = ['worker_threads']; - -const BUILTIN_MODULES = new Set( - module.builtinModules.concat(EXPERIMENTAL_MODULES), -); +const BUILTIN_MODULES = new Set(module.builtinModules); export default function isBuiltinModule(module: string): boolean { return BUILTIN_MODULES.has(module); diff --git a/packages/jest-worker/src/__tests__/process-integration.test.js b/packages/jest-worker/src/__tests__/process-integration.test.js index 50fffc721e17..d5e3f0950504 100644 --- a/packages/jest-worker/src/__tests__/process-integration.test.js +++ b/packages/jest-worker/src/__tests__/process-integration.test.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - import EventEmitter from 'events'; import {CHILD_MESSAGE_CALL, PARENT_MESSAGE_OK} from '../types'; @@ -37,10 +35,6 @@ function assertCallsToChild(childNum, ...calls) { }); } -jest.mock('worker_threads', () => { - throw Error('Unsupported'); -}); - describe('Jest Worker Integration', () => { beforeEach(() => { mockForkedProcesses = []; diff --git a/packages/jest-worker/src/workers/messageParent.ts b/packages/jest-worker/src/workers/messageParent.ts index d4a389055fc0..8c9127395aa6 100644 --- a/packages/jest-worker/src/workers/messageParent.ts +++ b/packages/jest-worker/src/workers/messageParent.ts @@ -5,29 +5,15 @@ * LICENSE file in the root directory of this source tree. */ +import {isMainThread, parentPort} from 'worker_threads'; import {PARENT_MESSAGE_CUSTOM} from '../types'; -const isWorkerThread: boolean = (() => { - try { - // `Require` here to support Node v10 - const {isMainThread, parentPort} = - require('worker_threads') as typeof import('worker_threads'); - return !isMainThread && parentPort != null; - } catch { - return false; - } -})(); - export default function messageParent( message: unknown, parentProcess = process, ): void { - if (isWorkerThread) { - // `Require` here to support Node v10 - const {parentPort} = - require('worker_threads') as typeof import('worker_threads'); - // ! is safe due to `null` check in `isWorkerThread` - parentPort!.postMessage([PARENT_MESSAGE_CUSTOM, message]); + if (!isMainThread && parentPort != null) { + parentPort.postMessage([PARENT_MESSAGE_CUSTOM, message]); } else if (typeof parentProcess.send === 'function') { parentProcess.send([PARENT_MESSAGE_CUSTOM, message]); } else {