Skip to content

Commit

Permalink
simplify some code now that we do not support node 10
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Feb 5, 2022
1 parent fd3adba commit 10ea2d8
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 154 deletions.
168 changes: 59 additions & 109 deletions packages/jest-haste-map/src/crawlers/__tests__/node.test.js
Expand Up @@ -34,8 +34,6 @@ jest.mock('child_process', () => ({
}),
}));

let mockHasReaddirWithFileTypesSupport = false;

jest.mock('graceful-fs', () => {
const slash = require('slash');
let mtime = 32;
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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);
});
});
24 changes: 8 additions & 16 deletions packages/jest-haste-map/src/crawlers/node.ts
Expand Up @@ -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++;
Expand Down
7 changes: 1 addition & 6 deletions packages/jest-resolve/src/isBuiltinModule.ts
Expand Up @@ -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);
Expand Down
Expand Up @@ -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';

Expand Down Expand Up @@ -37,10 +35,6 @@ function assertCallsToChild(childNum, ...calls) {
});
}

jest.mock('worker_threads', () => {
throw Error('Unsupported');
});

describe('Jest Worker Integration', () => {
beforeEach(() => {
mockForkedProcesses = [];
Expand Down
20 changes: 3 additions & 17 deletions packages/jest-worker/src/workers/messageParent.ts
Expand Up @@ -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 {
Expand Down

0 comments on commit 10ea2d8

Please sign in to comment.