Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: vendor node crawler from sane #10919

Merged
merged 1 commit into from Dec 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -19,6 +19,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 @@ -29,7 +30,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.*',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noticed while debugging watch events

'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