Skip to content

Commit 38bb798

Browse files
authored
[jest-circus] Omit expect.hasAssertions() errors if a test already has errors (#14866)
1 parent 8c78a08 commit 38bb798

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
- `[expect]` Check error instance type for `toThrow/toThrowError` ([#14576](https://github.com/jestjs/jest/pull/14576))
3232
- `[jest-circus]` [**BREAKING**] Prevent false test failures caused by promise rejections handled asynchronously ([#14315](https://github.com/jestjs/jest/pull/14315))
3333
- `[jest-circus]` Replace recursive `makeTestResults` implementation with iterative one ([#14760](https://github.com/jestjs/jest/pull/14760))
34+
- `[jest-circus]` Omit `expect.hasAssertions()` errors if a test already has errors ([#14866](https://github.com/jestjs/jest/pull/14866))
3435
- `[jest-circus, jest-expect, jest-snapshot]` Pass `test.failing` tests when containing failing snapshot matchers ([#14313](https://github.com/jestjs/jest/pull/14313))
3536
- `[jest-cli]` [**BREAKING**] Validate CLI flags that require arguments receives them ([#14783](https://github.com/jestjs/jest/pull/14783))
3637
- `[jest-config]` Make sure to respect `runInBand` option ([#14578](https://github.com/jestjs/jest/pull/14578))
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import {beforeEach, it} from '@jest/globals';
9+
import type {Circus} from '@jest/types';
10+
import {eventHandler} from '../jestAdapterInit';
11+
12+
beforeEach(() => expect.hasAssertions());
13+
14+
it("pushes a hasAssertion() error if there's no assertions/errors", () => {
15+
const event: Circus.Event = {
16+
name: 'test_done',
17+
test: {errors: []} as unknown as Circus.TestEntry,
18+
};
19+
const beforeLength = event.test.errors.length;
20+
21+
eventHandler(event);
22+
23+
expect(event.test.errors).toHaveLength(beforeLength + 1);
24+
expect(event.test.errors).toEqual([
25+
expect.getState().isExpectingAssertionsError,
26+
]);
27+
});
28+
29+
it("omits hasAssertion() errors if there's already an error", () => {
30+
const errors = [new Error('ruh roh'), new Error('not good')];
31+
const event: Circus.Event = {
32+
name: 'test_done',
33+
test: {errors} as unknown as Circus.TestEntry,
34+
};
35+
const beforeLength = event.test.errors.length;
36+
37+
eventHandler(event);
38+
39+
expect(event.test.errors).toHaveLength(beforeLength);
40+
expect(event.test.errors).not.toContain(
41+
expect.getState().isExpectingAssertionsError,
42+
);
43+
44+
// Ensure test state is not accidentally leaked by e.g. not calling extractExpectedAssertionsErrors() at all.
45+
expect(expect.getState().isExpectingAssertions).toBe(false);
46+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "../../../../../tsconfig.test.json",
3+
"include": ["./**/*"],
4+
"references": [{"path": "../../../"}]
5+
}

packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ const handleSnapshotStateAfterRetry =
254254
}
255255
};
256256

257-
const eventHandler = async (event: Circus.Event) => {
257+
// Exported for direct access from unit tests.
258+
export const eventHandler = async (event: Circus.Event): Promise<void> => {
258259
switch (event.name) {
259260
case 'test_start': {
260261
jestExpect.setState({
@@ -273,9 +274,13 @@ const eventHandler = async (event: Circus.Event) => {
273274
};
274275

275276
const _addExpectedAssertionErrors = (test: Circus.TestEntry) => {
277+
const {isExpectingAssertions} = jestExpect.getState();
276278
const failures = jestExpect.extractExpectedAssertionsErrors();
277-
const errors = failures.map(failure => failure.error);
278-
test.errors = [...test.errors, ...errors];
279+
if (isExpectingAssertions && test.errors.length > 0) {
280+
// Only show errors from `expect.hasAssertions()` when no other failure has happened.
281+
return;
282+
}
283+
test.errors.push(...failures.map(failure => failure.error));
279284
};
280285

281286
// Get suppressed errors from ``jest-matchers`` that weren't throw during
@@ -285,6 +290,6 @@ const _addSuppressedErrors = (test: Circus.TestEntry) => {
285290
const {suppressedErrors} = jestExpect.getState();
286291
jestExpect.setState({suppressedErrors: []});
287292
if (suppressedErrors.length > 0) {
288-
test.errors = [...test.errors, ...suppressedErrors];
293+
test.errors.push(...suppressedErrors);
289294
}
290295
};

0 commit comments

Comments
 (0)