Skip to content

Commit 2dc7da7

Browse files
eps1lonclaude
andauthored
[test] Bump Jest to 30.4 (react#37382)
Bumps Jest to latest 30.x The `resolutions` pin that kept jsdom at 22.1.0 is removed, so the test environment now runs the jsdom version that jest-environment-jsdom declares (26.1.0 on Jest 30). The matcher aliases that Jest 30 deleted are replaced with their canonical forms across the test suites: `toBeCalled`, `toBeCalledTimes`, `toBeCalledWith`, and `lastCalledWith` become the corresponding `toHaveBeenCalled*` matchers, and `toThrowError` becomes `toThrow`. The custom `toThrow` matcher override is removed in the PR below this one. Jest 30 activates the `node` export condition for CommonJS requires in every test environment, so in the jsdom-based Flight suites `react-server-dom-webpack/client` now resolves to the Node build (which requires an options argument) instead of the browser build. Those suites now map the client entry to `client.browser` explicitly, matching the existing mocks for the `server` and `static` entries, and the Turbopack Node test uses `jest.requireActual` because `client` and `client.node` now resolve to the same file, which otherwise made the mock factory recurse. For the same reason `react-dom/static` resolves to the lazily-initialized Node entry in source mode, so its version-mismatch test is gated to build mode like the other server-entry tests. The obsolete `prettierPath` override is dropped from the base Jest config because Jest 30 works with Prettier 3 for inline snapshots, which also fixes `yarn test -u` crashing on the repo's Prettier 3-only hermes plugin, and the now unused `prettier-2` alias dependency is removed with it. Snapshot files are regenerated for Jest 30's updated snapshot header and formatting. One test now passes a number instead of a string to `jest.advanceTimersByTime`, which fake-timers v13 no longer coerces. --------- Co-authored-by: Claude Code (kimi-k3[1m]) <noreply@anthropic.com>
1 parent 29d9d31 commit 2dc7da7

56 files changed

Lines changed: 1660 additions & 1220 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"@typescript-eslint/parser": "^6.21.0",
5151
"abortcontroller-polyfill": "^1.7.5",
5252
"art": "0.10.1",
53+
"babel-jest": "^30.4.1",
5354
"babel-plugin-syntax-hermes-parser": "^0.36.1",
5455
"babel-plugin-syntax-trailing-function-commas": "^6.5.0",
5556
"busboy": "^1.6.0",
@@ -83,20 +84,19 @@
8384
"gzip-size": "^5.1.1",
8485
"hermes-eslint": "^0.36.1",
8586
"hermes-parser": "^0.36.1",
86-
"jest": "^29.4.2",
87-
"jest-cli": "^29.4.2",
88-
"jest-diff": "^29.4.2",
89-
"jest-environment-jsdom": "^29.4.2",
87+
"jest": "^30.4.1",
88+
"jest-cli": "^30.4.1",
89+
"jest-diff": "^30.4.1",
90+
"jest-environment-jsdom": "^30.4.1",
9091
"jest-silent-reporter": "^0.6.0",
9192
"jest-snapshot-serializer-raw": "^1.2.0",
9293
"minimatch": "^3.0.4",
9394
"minimist": "^1.2.3",
9495
"mkdirp": "^0.5.1",
9596
"ncp": "^2.0.0",
9697
"prettier": "^3.3.3",
97-
"prettier-2": "npm:prettier@^2",
9898
"prettier-plugin-hermes-parser": "^0.36.1",
99-
"pretty-format": "^29.4.1",
99+
"pretty-format": "^30.4.1",
100100
"prop-types": "^15.6.2",
101101
"random-seed": "^0.3.0",
102102
"react-lifecycles-compat": "^3.0.4",
@@ -158,8 +158,7 @@
158158
"flags": "node ./scripts/flags/flags.js"
159159
},
160160
"resolutions": {
161-
"react-is": "npm:react-is",
162-
"jsdom": "22.1.0"
161+
"react-is": "npm:react-is"
163162
},
164163
"packageManager": "yarn@1.22.22"
165164
}

packages/dom-event-testing-library/__tests__/__snapshots__/index-test.internal.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`describeWithPointerEvent: MouseEvent/TouchEvent provides boolean to tests 1`] = `false`;
44

packages/eslint-plugin-react-hooks/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"eslint-v7": "npm:eslint@^7.7.0",
6363
"eslint-v8": "npm:eslint@^8.57.1",
6464
"eslint-v9": "npm:eslint@^9.0.0",
65-
"jest": "^29.5.0",
65+
"jest": "^30.4.1",
6666
"typescript": "^5.4.3"
6767
}
6868
}

packages/internal-test-utils/simulateBrowserEventDispatch.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const DOMException = require('domexception/webidl2js-wrapper');
1+
const DOMException = require('jsdom/lib/jsdom/living/generated/DOMException');
22
const {nodeRoot} = require('jsdom/lib/jsdom/living/helpers/node');
33
const reportException = require('jsdom/lib/jsdom/living/helpers/runtime-script-errors');
44
const {

packages/jest-react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"homepage": "https://react.dev/",
2121
"peerDependencies": {
22-
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0",
22+
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 || ^30.0.0",
2323
"react": "^19.0.0",
2424
"react-test-renderer": "^19.0.0"
2525
},

packages/react-art/src/__tests__/ReactART-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,12 @@ describe('ReactART', () => {
382382
const onClick1 = jest.fn();
383383
let instance = await render(onClick1);
384384
doClick(instance);
385-
expect(onClick1).toBeCalled();
385+
expect(onClick1).toHaveBeenCalled();
386386

387387
const onClick2 = jest.fn();
388388
instance = await render(onClick2);
389389
doClick(instance);
390-
expect(onClick2).toBeCalled();
390+
expect(onClick2).toHaveBeenCalled();
391391
});
392392
});
393393

packages/react-art/src/__tests__/__snapshots__/ReactART-test.js.snap

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`ReactARTComponents should generate a <Shape> where top radius is 0 if the sum of the top radius is greater than width 1`] = `
44
<Shape
@@ -25,6 +25,7 @@ exports[`ReactARTComponents should generate a <Shape> where top radius is 0 if t
2525
width={50}
2626
/>
2727
`;
28+
2829
exports[`ReactARTComponents should generate a <Shape> with a radius property of 0 when bottom left radius prop is negative 1`] = `
2930
<Shape
3031
d={
@@ -49,6 +50,7 @@ exports[`ReactARTComponents should generate a <Shape> with a radius property of
4950
width={50}
5051
/>
5152
`;
53+
5254
exports[`ReactARTComponents should generate a <Shape> with a radius property of 0 when bottom right radius prop is negative 1`] = `
5355
<Shape
5456
d={
@@ -73,6 +75,7 @@ exports[`ReactARTComponents should generate a <Shape> with a radius property of
7375
width={50}
7476
/>
7577
`;
78+
7679
exports[`ReactARTComponents should generate a <Shape> with a radius property of 0 when top left radius prop is negative 1`] = `
7780
<Shape
7881
d={
@@ -97,6 +100,7 @@ exports[`ReactARTComponents should generate a <Shape> with a radius property of
97100
width={50}
98101
/>
99102
`;
103+
100104
exports[`ReactARTComponents should generate a <Shape> with a radius property of 0 when top right radius prop is negative 1`] = `
101105
<Shape
102106
d={
@@ -121,6 +125,7 @@ exports[`ReactARTComponents should generate a <Shape> with a radius property of
121125
width={50}
122126
/>
123127
`;
128+
124129
exports[`ReactARTComponents should generate a <Shape> with positive height when height prop is negative 1`] = `
125130
<Shape
126131
d={
@@ -145,6 +150,7 @@ exports[`ReactARTComponents should generate a <Shape> with positive height when
145150
width={50}
146151
/>
147152
`;
153+
148154
exports[`ReactARTComponents should generate a <Shape> with positive width when width prop is negative 1`] = `
149155
<Shape
150156
d={
@@ -169,6 +175,7 @@ exports[`ReactARTComponents should generate a <Shape> with positive width when w
169175
width={-50}
170176
/>
171177
`;
178+
172179
exports[`ReactARTComponents should generate a <Shape> with props for drawing the Circle 1`] = `
173180
<Shape
174181
d={

packages/react-dom/src/__tests__/DOMPropertyOperations-test.js

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ describe('DOMPropertyOperations', () => {
5050
const container = document.createElement('div');
5151
const root = ReactDOMClient.createRoot(container);
5252
await act(() => {
53-
root.render(<div role="#" />);
53+
root.render(<div enterKeyHint="go" />);
5454
});
55-
expect(container.firstChild.getAttribute('role')).toBe('#');
56-
expect(container.firstChild.role).toBeUndefined();
55+
expect(container.firstChild.getAttribute('enterkeyhint')).toBe('go');
56+
expect(container.firstChild.enterKeyHint).toBeUndefined();
5757
});
5858

5959
it('should set values as namespace attributes if necessary', async () => {
@@ -809,49 +809,49 @@ describe('DOMPropertyOperations', () => {
809809
// Custom element has no special logic for input/change.
810810
clearMocks();
811811
customElement.dispatchEvent(new Event('input', {bubbles: true}));
812-
expect(onChangeHandler).toBeCalledTimes(0);
813-
expect(onInputHandler).toBeCalledTimes(1);
814-
expect(onClickHandler).toBeCalledTimes(0);
812+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
813+
expect(onInputHandler).toHaveBeenCalledTimes(1);
814+
expect(onClickHandler).toHaveBeenCalledTimes(0);
815815
customElement.dispatchEvent(new Event('change', {bubbles: true}));
816-
expect(onChangeHandler).toBeCalledTimes(1);
817-
expect(onInputHandler).toBeCalledTimes(1);
818-
expect(onClickHandler).toBeCalledTimes(0);
816+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
817+
expect(onInputHandler).toHaveBeenCalledTimes(1);
818+
expect(onClickHandler).toHaveBeenCalledTimes(0);
819819
customElement.dispatchEvent(new Event('click', {bubbles: true}));
820-
expect(onChangeHandler).toBeCalledTimes(1);
821-
expect(onInputHandler).toBeCalledTimes(1);
822-
expect(onClickHandler).toBeCalledTimes(1);
820+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
821+
expect(onInputHandler).toHaveBeenCalledTimes(1);
822+
expect(onClickHandler).toHaveBeenCalledTimes(1);
823823

824824
// Regular input treats browser input as onChange.
825825
clearMocks();
826826
setUntrackedValue.call(regularInput, 'hello');
827827
regularInput.dispatchEvent(new Event('input', {bubbles: true}));
828-
expect(onChangeHandler).toBeCalledTimes(1);
829-
expect(onInputHandler).toBeCalledTimes(1);
830-
expect(onClickHandler).toBeCalledTimes(0);
828+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
829+
expect(onInputHandler).toHaveBeenCalledTimes(1);
830+
expect(onClickHandler).toHaveBeenCalledTimes(0);
831831
regularInput.dispatchEvent(new Event('change', {bubbles: true}));
832-
expect(onChangeHandler).toBeCalledTimes(1);
833-
expect(onInputHandler).toBeCalledTimes(1);
834-
expect(onClickHandler).toBeCalledTimes(0);
832+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
833+
expect(onInputHandler).toHaveBeenCalledTimes(1);
834+
expect(onClickHandler).toHaveBeenCalledTimes(0);
835835
regularInput.dispatchEvent(new Event('click', {bubbles: true}));
836-
expect(onChangeHandler).toBeCalledTimes(1);
837-
expect(onInputHandler).toBeCalledTimes(1);
838-
expect(onClickHandler).toBeCalledTimes(1);
836+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
837+
expect(onInputHandler).toHaveBeenCalledTimes(1);
838+
expect(onClickHandler).toHaveBeenCalledTimes(1);
839839

840840
// Custom input treats browser input as onChange.
841841
clearMocks();
842842
setUntrackedValue.call(customInput, 'hello');
843843
customInput.dispatchEvent(new Event('input', {bubbles: true}));
844-
expect(onChangeHandler).toBeCalledTimes(1);
845-
expect(onInputHandler).toBeCalledTimes(1);
846-
expect(onClickHandler).toBeCalledTimes(0);
844+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
845+
expect(onInputHandler).toHaveBeenCalledTimes(1);
846+
expect(onClickHandler).toHaveBeenCalledTimes(0);
847847
customInput.dispatchEvent(new Event('change', {bubbles: true}));
848-
expect(onChangeHandler).toBeCalledTimes(1);
849-
expect(onInputHandler).toBeCalledTimes(1);
850-
expect(onClickHandler).toBeCalledTimes(0);
848+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
849+
expect(onInputHandler).toHaveBeenCalledTimes(1);
850+
expect(onClickHandler).toHaveBeenCalledTimes(0);
851851
customInput.dispatchEvent(new Event('click', {bubbles: true}));
852-
expect(onChangeHandler).toBeCalledTimes(1);
853-
expect(onInputHandler).toBeCalledTimes(1);
854-
expect(onClickHandler).toBeCalledTimes(1);
852+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
853+
expect(onInputHandler).toHaveBeenCalledTimes(1);
854+
expect(onClickHandler).toHaveBeenCalledTimes(1);
855855
});
856856

857857
it('custom element onChange/onInput/onClick with event target input child', async () => {
@@ -877,18 +877,18 @@ describe('DOMPropertyOperations', () => {
877877
input.dispatchEvent(new Event('input', {bubbles: true}));
878878
// Simulated onChange from the child's input event
879879
// bubbles to the parent custom element.
880-
expect(onChangeHandler).toBeCalledTimes(1);
881-
expect(onInputHandler).toBeCalledTimes(1);
882-
expect(onClickHandler).toBeCalledTimes(0);
880+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
881+
expect(onInputHandler).toHaveBeenCalledTimes(1);
882+
expect(onClickHandler).toHaveBeenCalledTimes(0);
883883
// Consequently, the native change event is ignored.
884884
input.dispatchEvent(new Event('change', {bubbles: true}));
885-
expect(onChangeHandler).toBeCalledTimes(1);
886-
expect(onInputHandler).toBeCalledTimes(1);
887-
expect(onClickHandler).toBeCalledTimes(0);
885+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
886+
expect(onInputHandler).toHaveBeenCalledTimes(1);
887+
expect(onClickHandler).toHaveBeenCalledTimes(0);
888888
input.dispatchEvent(new Event('click', {bubbles: true}));
889-
expect(onChangeHandler).toBeCalledTimes(1);
890-
expect(onInputHandler).toBeCalledTimes(1);
891-
expect(onClickHandler).toBeCalledTimes(1);
889+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
890+
expect(onInputHandler).toHaveBeenCalledTimes(1);
891+
expect(onClickHandler).toHaveBeenCalledTimes(1);
892892
});
893893

894894
it('custom element onChange/onInput/onClick with event target div child', async () => {
@@ -911,21 +911,21 @@ describe('DOMPropertyOperations', () => {
911911

912912
const div = container.querySelector('div');
913913
div.dispatchEvent(new Event('input', {bubbles: true}));
914-
expect(onChangeHandler).toBeCalledTimes(0);
915-
expect(onInputHandler).toBeCalledTimes(1);
916-
expect(onClickHandler).toBeCalledTimes(0);
914+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
915+
expect(onInputHandler).toHaveBeenCalledTimes(1);
916+
expect(onClickHandler).toHaveBeenCalledTimes(0);
917917

918918
div.dispatchEvent(new Event('change', {bubbles: true}));
919919
// React always ignores change event invoked on non-custom and non-input targets.
920920
// So change event emitted on a div does not propagate upwards.
921-
expect(onChangeHandler).toBeCalledTimes(0);
922-
expect(onInputHandler).toBeCalledTimes(1);
923-
expect(onClickHandler).toBeCalledTimes(0);
921+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
922+
expect(onInputHandler).toHaveBeenCalledTimes(1);
923+
expect(onClickHandler).toHaveBeenCalledTimes(0);
924924

925925
div.dispatchEvent(new Event('click', {bubbles: true}));
926-
expect(onChangeHandler).toBeCalledTimes(0);
927-
expect(onInputHandler).toBeCalledTimes(1);
928-
expect(onClickHandler).toBeCalledTimes(1);
926+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
927+
expect(onInputHandler).toHaveBeenCalledTimes(1);
928+
expect(onClickHandler).toHaveBeenCalledTimes(1);
929929
});
930930

931931
it('div onChange/onInput/onClick with event target div child', async () => {
@@ -948,21 +948,21 @@ describe('DOMPropertyOperations', () => {
948948

949949
const div = container.querySelector('div > div');
950950
div.dispatchEvent(new Event('input', {bubbles: true}));
951-
expect(onChangeHandler).toBeCalledTimes(0);
952-
expect(onInputHandler).toBeCalledTimes(1);
953-
expect(onClickHandler).toBeCalledTimes(0);
951+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
952+
expect(onInputHandler).toHaveBeenCalledTimes(1);
953+
expect(onClickHandler).toHaveBeenCalledTimes(0);
954954

955955
div.dispatchEvent(new Event('change', {bubbles: true}));
956956
// React always ignores change event invoked on non-custom and non-input targets.
957957
// So change event emitted on a div does not propagate upwards.
958-
expect(onChangeHandler).toBeCalledTimes(0);
959-
expect(onInputHandler).toBeCalledTimes(1);
960-
expect(onClickHandler).toBeCalledTimes(0);
958+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
959+
expect(onInputHandler).toHaveBeenCalledTimes(1);
960+
expect(onClickHandler).toHaveBeenCalledTimes(0);
961961

962962
div.dispatchEvent(new Event('click', {bubbles: true}));
963-
expect(onChangeHandler).toBeCalledTimes(0);
964-
expect(onInputHandler).toBeCalledTimes(1);
965-
expect(onClickHandler).toBeCalledTimes(1);
963+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
964+
expect(onInputHandler).toHaveBeenCalledTimes(1);
965+
expect(onClickHandler).toHaveBeenCalledTimes(1);
966966
});
967967

968968
it('custom element onChange/onInput/onClick with event target custom element child', async () => {
@@ -986,18 +986,18 @@ describe('DOMPropertyOperations', () => {
986986
const customChild = container.querySelector('other-custom-element');
987987
customChild.dispatchEvent(new Event('input', {bubbles: true}));
988988
// There is no simulated onChange, only raw onInput is dispatched.
989-
expect(onChangeHandler).toBeCalledTimes(0);
990-
expect(onInputHandler).toBeCalledTimes(1);
991-
expect(onClickHandler).toBeCalledTimes(0);
989+
expect(onChangeHandler).toHaveBeenCalledTimes(0);
990+
expect(onInputHandler).toHaveBeenCalledTimes(1);
991+
expect(onClickHandler).toHaveBeenCalledTimes(0);
992992
// The native change event propagates to the parent as onChange.
993993
customChild.dispatchEvent(new Event('change', {bubbles: true}));
994-
expect(onChangeHandler).toBeCalledTimes(1);
995-
expect(onInputHandler).toBeCalledTimes(1);
996-
expect(onClickHandler).toBeCalledTimes(0);
994+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
995+
expect(onInputHandler).toHaveBeenCalledTimes(1);
996+
expect(onClickHandler).toHaveBeenCalledTimes(0);
997997
customChild.dispatchEvent(new Event('click', {bubbles: true}));
998-
expect(onChangeHandler).toBeCalledTimes(1);
999-
expect(onInputHandler).toBeCalledTimes(1);
1000-
expect(onClickHandler).toBeCalledTimes(1);
998+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
999+
expect(onInputHandler).toHaveBeenCalledTimes(1);
1000+
expect(onClickHandler).toHaveBeenCalledTimes(1);
10011001
});
10021002

10031003
it('custom elements should allow custom events with capture event listeners', async () => {

0 commit comments

Comments
 (0)