Skip to content

Commit

Permalink
fix: vendor node crawler from sane (#10919)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Dec 5, 2020
1 parent e7ad911 commit 2b30d8b
Show file tree
Hide file tree
Showing 15 changed files with 581 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Expand Up @@ -100,7 +100,7 @@ module.exports = {
'packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts',
'packages/jest-fake-timers/src/legacyFakeTimers.ts',
'packages/jest-haste-map/src/index.ts',
'packages/jest-haste-map/src/lib/FSEventsWatcher.ts',
'packages/jest-haste-map/src/watchers/FSEventsWatcher.ts',
'packages/jest-jasmine2/src/jasmine/SpyStrategy.ts',
'packages/jest-jasmine2/src/jasmine/Suite.ts',
'packages/jest-leak-detector/src/index.ts',
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@
- `[jest-circus]` Fix `testLocation` on Windows when using `test.each` ([#10871](https://github.com/facebook/jest/pull/10871))
- `[jest-console]` `console.dir` now respects the second argument correctly ([#10638](https://github.com/facebook/jest/pull/10638))
- `[jest-environment-jsdom]` Use inner realm’s `ArrayBuffer` constructor ([#10885](https://github.com/facebook/jest/pull/10885))
- `[jest-haste-map]` Vendor `NodeWatcher` from `sane` ([#10919](https://github.com/facebook/jest/pull/10919))
- `[jest-jasmine2]` Fixed the issue of beforeAll & afterAll hooks getting executed even if it is inside a skipped `describe` block when it has child `tests` marked as either `only` or `todo` [#10451](https://github.com/facebook/jest/issues/10451)
- `[jest-jasmine2]` Fixed the issues of child `tests` marked with `only` or `todo` getting executed even if it is inside a skipped parent `describe` block [#10451](https://github.com/facebook/jest/issues/10451)
- `[jest-reporter]` Handle empty files when reporting code coverage with V8 ([#10819](https://github.com/facebook/jest/pull/10819))
Expand All @@ -30,7 +31,7 @@
- `[jest-runtime]` Fix stack overflow and promise deadlock when importing mutual dependant ES module ([#10892](https://github.com/facebook/jest/pull/10892))
- `[jest-transform]` Show enhanced `SyntaxError` message for all `SyntaxError`s ([#10749](https://github.com/facebook/jest/pull/10749))
- `[jest-transform]` [**BREAKING**] Refactor API to pass an options bag around rather than multiple boolean options ([#10753](https://github.com/facebook/jest/pull/10753))
- `[jest-transform]` [**BREAKING**] Refactor API of transformers to pass an options bag rather than separate `config` and other options
- `[jest-transform]` [**BREAKING**] Refactor API of transformers to pass an options bag rather than separate `config` and other options ([#10834](https://github.com/facebook/jest/pull/10834))
- `[pretty-format]` [**BREAKING**] Convert to ES Modules ([#10515](https://github.com/facebook/jest/pull/10515))

### Chore & Maintenance
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Expand Up @@ -23,6 +23,7 @@ module.exports = {
modulePathIgnorePatterns: [
'examples/.*',
'packages/.*/build',
'packages/.*/tsconfig.*',
'packages/jest-runtime/src/__tests__/test_root.*',
'website/.*',
'e2e/runtime-internal-module-registry/__mocks__',
Expand Down
3 changes: 1 addition & 2 deletions package.json
Expand Up @@ -148,7 +148,6 @@
"@testing-library/dom/pretty-format": "26.6.1",
"@types/jest/jest-diff": "^25.1.0",
"@types/jest/pretty-format": "^25.1.0",
"fbjs-scripts": "patch:fbjs-scripts@^1.1.0#./patches/fbjs-scripts.patch",
"jest-haste-map/fsevents": "patch:fsevents@^2.1.2#./patches/fsevents.patch"
"fbjs-scripts": "patch:fbjs-scripts@^1.1.0#./patches/fbjs-scripts.patch"
}
}
2 changes: 0 additions & 2 deletions packages/jest-haste-map/package.json
Expand Up @@ -25,15 +25,13 @@
"jest-util": "^26.6.2",
"jest-worker": "^26.6.2",
"micromatch": "^4.0.2",
"sane": "^4.0.3",
"walker": "^1.0.7"
},
"devDependencies": {
"@jest/test-utils": "^26.6.2",
"@types/anymatch": "^1.3.1",
"@types/fb-watchman": "^2.0.0",
"@types/micromatch": "^4.0.0",
"@types/sane": "^2.0.0",
"jest-snapshot-serializer-raw": "^1.1.0",
"slash": "^3.0.0"
},
Expand Down
10 changes: 3 additions & 7 deletions packages/jest-haste-map/src/__tests__/index.test.js
Expand Up @@ -72,17 +72,13 @@ jest.mock('../crawlers/watchman', () =>
const mockWatcherConstructor = jest.fn(root => {
const EventEmitter = require('events').EventEmitter;
mockEmitters[root] = new EventEmitter();
mockEmitters[root].close = jest.fn(callback => callback());
mockEmitters[root].close = jest.fn();
setTimeout(() => mockEmitters[root].emit('ready'), 0);
return mockEmitters[root];
});

jest.mock('sane', () => ({
NodeWatcher: mockWatcherConstructor,
WatchmanWatcher: mockWatcherConstructor,
}));

jest.mock('../lib/WatchmanWatcher', () => mockWatcherConstructor);
jest.mock('../watchers/NodeWatcher', () => mockWatcherConstructor);
jest.mock('../watchers/WatchmanWatcher', () => mockWatcherConstructor);

let mockChangedFiles;
let mockFs;
Expand Down
41 changes: 18 additions & 23 deletions packages/jest-haste-map/src/index.ts
Expand Up @@ -13,7 +13,6 @@ import {EventEmitter} from 'events';
import {tmpdir} from 'os';
import * as path from 'path';
import type {Stats} from 'graceful-fs';
import {NodeWatcher, Watcher as SaneWatcher} from 'sane';
import type {Config} from '@jest/types';
import {escapePathForRegex} from 'jest-regex-util';
import serializer from 'jest-serializer';
Expand All @@ -24,9 +23,6 @@ import H from './constants';
import nodeCrawl = require('./crawlers/node');
import watchmanCrawl = require('./crawlers/watchman');
import getMockName from './getMockName';
import FSEventsWatcher = require('./lib/FSEventsWatcher');
// @ts-expect-error: not converted to TypeScript - it's a fork: https://github.com/facebook/jest/pull/5387
import WatchmanWatcher from './lib/WatchmanWatcher';
import * as fastPath from './lib/fast_path';
import getPlatformExtension from './lib/getPlatformExtension';
import normalizePathSep from './lib/normalizePathSep';
Expand All @@ -44,6 +40,11 @@ import type {
ModuleMetaData,
WorkerMetadata,
} from './types';
import FSEventsWatcher = require('./watchers/FSEventsWatcher');
// @ts-expect-error: not converted to TypeScript - it's a fork: https://github.com/facebook/jest/pull/10919
import NodeWatcher from './watchers/NodeWatcher';
// @ts-expect-error: not converted to TypeScript - it's a fork: https://github.com/facebook/jest/pull/5387
import WatchmanWatcher from './watchers/WatchmanWatcher';
import {getSha1, worker} from './worker';
// TypeScript doesn't like us importing from outside `rootDir`, but it doesn't
// understand `require`.
Expand Down Expand Up @@ -97,7 +98,7 @@ type InternalOptions = {
};

type Watcher = {
close(callback: () => void): void;
close(): Promise<void>;
};

type WorkerInterface = {worker: typeof worker; getSha1: typeof getSha1};
Expand Down Expand Up @@ -210,7 +211,7 @@ function invariant(condition: unknown, message?: string): asserts condition {
export default class HasteMap extends EventEmitter {
private _buildPromise: Promise<InternalHasteMapObject> | null;
private _cachePath: Config.Path;
private _changeInterval?: NodeJS.Timeout;
private _changeInterval?: ReturnType<typeof setInterval>;
private _console: Console;
private _options: InternalOptions;
private _watchers: Array<Watcher>;
Expand Down Expand Up @@ -781,7 +782,7 @@ export default class HasteMap extends EventEmitter {
this._options.retainAllFiles = true;

// WatchmanWatcher > FSEventsWatcher > sane.NodeWatcher
const Watcher: SaneWatcher =
const Watcher =
canUseWatchman && this._options.useWatchman
? WatchmanWatcher
: FSEventsWatcher.isSupported()
Expand All @@ -798,7 +799,6 @@ export default class HasteMap extends EventEmitter {
let mustCopy = true;

const createWatcher = (root: Config.Path): Promise<Watcher> => {
// @ts-expect-error: TODO how? "Cannot use 'new' with an expression whose type lacks a call or construct signature."
const watcher = new Watcher(root, {
dot: true,
glob: extensions.map(extension => '**/*.' + extension),
Expand All @@ -824,10 +824,7 @@ export default class HasteMap extends EventEmitter {
mustCopy = true;
const changeEvent: ChangeEvent = {
eventsQueue,
hasteFS: new HasteFS({
files: hasteMap.files,
rootDir,
}),
hasteFS: new HasteFS({files: hasteMap.files, rootDir}),
moduleMap: new HasteModuleMap({
duplicates: hasteMap.duplicates,
map: hasteMap.map,
Expand Down Expand Up @@ -1043,20 +1040,18 @@ export default class HasteMap extends EventEmitter {
}
}

end(): Promise<void> {
// @ts-expect-error: TODO TS cannot decide if `setInterval` and `clearInterval` comes from NodeJS or the DOM
clearInterval(this._changeInterval);
async end(): Promise<void> {
if (this._changeInterval) {
clearInterval(this._changeInterval);
}

if (!this._watchers.length) {
return Promise.resolve();
return;
}

return Promise.all(
this._watchers.map(
watcher => new Promise(resolve => watcher.close(resolve)),
),
).then(() => {
this._watchers = [];
});
await Promise.all(this._watchers.map(watcher => watcher.close()));

this._watchers = [];
}

/**
Expand Down

0 comments on commit 2b30d8b

Please sign in to comment.