diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c200448e3e..45f2fd4e0eb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - `[jest-config]` [**BREAKING**] Default to Node testing environment instead of browser (JSDOM) ([#9874](https://github.com/facebook/jest/pull/9874)) - `[jest-config]` [**BREAKING**] Use `jest-circus` as default test runner ([#10686](https://github.com/facebook/jest/pull/10686)) - `[jest-config, jest-runtime]` Support ESM for files other than `.js` and `.mjs` ([#10823](https://github.com/facebook/jest/pull/10823)) +- `[jest-core]` make `TestWatcher` extend `emittery` ([#10324](https://github.com/facebook/jest/pull/10324)) - `[jest-repl, jest-runner]` [**BREAKING**] Run transforms over environment ([#8751](https://github.com/facebook/jest/pull/8751)) - `[jest-runner]` [**BREAKING**] set exit code to 1 if test logs after teardown ([#10728](https://github.com/facebook/jest/pull/10728)) - `[jest-snapshot]` [**BREAKING**] Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792)) diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index 4b9e0f1d16f1..3634e2f993f2 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -17,6 +17,7 @@ "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.7.2", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^26.6.2", diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index 4af975dfe96c..fa75861835af 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -419,7 +419,7 @@ export default class TestScheduler { throw new Error('Reporter should be either a string or an array'); } - private _bailIfNeeded( + private async _bailIfNeeded( contexts: Set, aggregatedResults: AggregatedResult, watcher: TestWatcher, @@ -429,17 +429,16 @@ export default class TestScheduler { aggregatedResults.numFailedTests >= this._globalConfig.bail ) { if (watcher.isWatchMode()) { - watcher.setState({interrupted: true}); - } else { - const failureExit = () => exit(1); - - return this._dispatcher - .onRunComplete(contexts, aggregatedResults) - .then(failureExit) - .catch(failureExit); + await watcher.setState({interrupted: true}); + return; + } + + try { + await this._dispatcher.onRunComplete(contexts, aggregatedResults); + } finally { + exit(1); } } - return Promise.resolve(); } } diff --git a/packages/jest-core/src/TestWatcher.ts b/packages/jest-core/src/TestWatcher.ts index 750dcbe45efc..3dbacb3fb5e4 100644 --- a/packages/jest-core/src/TestWatcher.ts +++ b/packages/jest-core/src/TestWatcher.ts @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import {EventEmitter} from 'events'; +import emittery = require('emittery'); type State = { interrupted: boolean; }; -export default class TestWatcher extends EventEmitter { +export default class TestWatcher extends emittery.Typed<{change: State}> { state: State; private _isWatchMode: boolean; @@ -21,9 +21,9 @@ export default class TestWatcher extends EventEmitter { this._isWatchMode = isWatchMode; } - setState(state: State): void { + async setState(state: State): Promise { Object.assign(this.state, state); - this.emit('change', this.state); + await this.emit('change', this.state); } isInterrupted(): boolean { diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index da911414832a..e32636fd9a36 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -25,7 +25,6 @@ import type { TestRunnerContext, TestRunnerOptions, TestWatcher, - WatcherState, } from './types'; const TEST_WORKER_PATH = require.resolve('./testWorker'); @@ -239,7 +238,7 @@ export default class TestRunner { }; const onInterrupt = new Promise((_, reject) => { - watcher.on('change', (state: WatcherState) => { + watcher.on('change', state => { if (state.interrupted) { reject(new CancelRun()); } diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 3d425c045f24..e87d1b126816 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import type {EventEmitter} from 'events'; +import type {Typed as EmitteryTyped} from 'emittery'; import type {JestEnvironment} from '@jest/environment'; import type { AssertionResult, @@ -79,10 +79,8 @@ export type TestRunnerSerializedContext = { }; // TODO: Should live in `@jest/core` or `jest-watcher` -export type WatcherState = { - interrupted: boolean; -}; -export interface TestWatcher extends EventEmitter { +type WatcherState = {interrupted: boolean}; +export interface TestWatcher extends EmitteryTyped<{change: WatcherState}> { state: WatcherState; setState(state: WatcherState): void; isInterrupted(): boolean; diff --git a/yarn.lock b/yarn.lock index 363699de02e6..f819c6bc8bdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1784,6 +1784,7 @@ __metadata: "@types/rimraf": ^3.0.0 ansi-escapes: ^4.2.1 chalk: ^4.0.0 + emittery: ^0.7.2 exit: ^0.1.2 graceful-fs: ^4.2.4 jest-changed-files: ^26.6.2 @@ -7623,7 +7624,7 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.7.1": +"emittery@npm:^0.7.1, emittery@npm:^0.7.2": version: 0.7.2 resolution: "emittery@npm:0.7.2" checksum: 34acfef51922a1b73d75cb658bf43ecb279633b263ffa831fb87697abbbd3aa4241ef15d204eeaa6a3c62656bd7563de7145c416a2bb18c4805e54ce6d7cdac6