@samitouri / QOS-React / commits / 71cace4d32

Migrate testRunner from jasmine2 to jest-circus (#26144)

## Summary In jest v27, jest-circus as default test runner (https://github.com/facebook/jest/pull/10686) ## How did you test this change? ci green

Ming Ye committed Feb 11, 2023 at 02:39 UTC 71cace4d3267e4527964db51ccaf5eab7234f37f
43 files changed +264 -263
.eslintrc.js
-1
@@ -434,7 +434,6 @@ module.exports = {
434 es6: true,
435 node: true,
436 jest: true,
437 - jasmine: true,
437 },
438
439 globals: {
package.json
-2
@@ -69,12 +69,10 @@
69 "gzip-size": "^5.1.1",
70 "hermes-eslint": "^0.9.0",
71 "hermes-parser": "^0.9.0",
72 - "jasmine-check": "^1.0.0-rc.0",
72 "jest": "^29.4.1",
73 "jest-cli": "^29.4.1",
74 "jest-diff": "^29.4.1",
75 "jest-environment-jsdom": "^29.4.1",
77 - "jest-jasmine2": "^29.4.1",
76 "jest-snapshot-serializer-raw": "^1.1.0",
77 "minimatch": "^3.0.4",
78 "minimist": "^1.2.3",
packages/react-client/src/__tests__/ReactFlight-test.js
+6 -2
@@ -91,6 +91,10 @@ describe('ReactFlight', () => {
91 };
92 });
93
94 + afterEach(() => {
95 + jest.restoreAllMocks();
96 + });
97 +
98 function clientReference(value) {
99 return Object.defineProperties(
100 function () {
@@ -240,7 +244,7 @@ describe('ReactFlight', () => {
244 ReactNoop.render(rootModel);
245 });
246 expect(ReactNoop).toMatchRenderedOutput('Loading...');
243 - spyOnDevAndProd(console, 'error');
247 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
248 await load();
249 expect(console.error).toHaveBeenCalledTimes(1);
250 });
@@ -322,7 +326,7 @@ describe('ReactFlight', () => {
326 ReactNoop.render(rootModel);
327 });
328 expect(ReactNoop).toMatchRenderedOutput('Loading...');
325 - spyOnDevAndProd(console, 'error');
329 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
330 await load();
331 expect(console.error).toHaveBeenCalledTimes(1);
332 });
packages/react-devtools-extensions/flow-typed/jest.js
-23
@@ -1172,28 +1172,5 @@ declare var expect: {
1172 },
1173 };
1174
1175 -// TODO handle return type
1176 -// https://jasmine.github.io/2.4/introduction.html#section-Spies
1177 -declare function spyOn(value: mixed, method: string): Object;
1178 -
1175 /** Holds all functions related to manipulating test runner */
1176 declare var jest: JestObjectType;
1181 -
1182 -/**
1183 - * The global Jasmine object, this is generally not exposed as the public API,
1184 - * using features inside here could break in later versions of Jest.
1185 - */
1186 -declare var jasmine: {
1187 - DEFAULT_TIMEOUT_INTERVAL: number,
1188 - any(value: mixed): JestAsymmetricEqualityType,
1189 - anything(): any,
1190 - arrayContaining(value: Array<mixed>): Array<mixed>,
1191 - clock(): JestClockType,
1192 - createSpy(name: string): JestSpyType,
1193 - createSpyObj(
1194 - baseName: string,
1195 - methodNames: Array<string>
1196 - ): {[methodName: string]: JestSpyType},
1197 - objectContaining(value: Object): Object,
1198 - stringMatching(value: string): string,
1199 -};
packages/react-devtools-shared/src/__tests__/TimelineProfiler-test.js
+12 -8
@@ -47,6 +47,10 @@ describe('Timeline profiler', () => {
47 store = global.store;
48 });
49
50 + afterEach(() => {
51 + jest.restoreAllMocks();
52 + });
53 +
54 describe('User Timing API', () => {
55 let clearedMarks;
56 let featureDetectionMarkName = null;
@@ -517,7 +521,7 @@ describe('Timeline profiler', () => {
521 clearPendingMarks();
522
523 let errorMessage;
520 - spyOn(console, 'error').and.callFake(message => {
524 + jest.spyOn(console, 'error').mockImplementation(message => {
525 errorMessage = message;
526 });
527
@@ -571,7 +575,7 @@ describe('Timeline profiler', () => {
575 clearPendingMarks();
576
577 let errorMessage;
574 - spyOn(console, 'error').and.callFake(message => {
578 + jest.spyOn(console, 'error').mockImplementation(message => {
579 errorMessage = message;
580 });
581
@@ -740,7 +744,7 @@ describe('Timeline profiler', () => {
744 });
745
746 it('should mark sync render that throws', async () => {
743 - spyOn(console, 'error');
747 + jest.spyOn(console, 'error').mockImplementation(() => {});
748
749 class ErrorBoundary extends React.Component {
750 state = {error: null};
@@ -802,7 +806,7 @@ describe('Timeline profiler', () => {
806 });
807
808 it('should mark concurrent render that throws', async () => {
805 - spyOn(console, 'error');
809 + jest.spyOn(console, 'error').mockImplementation(() => {});
810
811 class ErrorBoundary extends React.Component {
812 state = {error: null};
@@ -1697,7 +1701,7 @@ describe('Timeline profiler', () => {
1701 renderRootHelper(<Example />);
1702
1703 let errorMessage;
1700 - spyOn(console, 'error').and.callFake(message => {
1704 + jest.spyOn(console, 'error').mockImplementation(message => {
1705 errorMessage = message;
1706 });
1707
@@ -1766,7 +1770,7 @@ describe('Timeline profiler', () => {
1770 renderRootHelper(<Example />);
1771
1772 let errorMessage;
1769 - spyOn(console, 'error').and.callFake(message => {
1773 + jest.spyOn(console, 'error').mockImplementation(message => {
1774 errorMessage = message;
1775 });
1776
@@ -1993,7 +1997,7 @@ describe('Timeline profiler', () => {
1997 });
1998
1999 it('should mark sync render that throws', async () => {
1996 - spyOn(console, 'error');
2000 + jest.spyOn(console, 'error').mockImplementation(() => {});
2001
2002 class ErrorBoundary extends React.Component {
2003 state = {error: null};
@@ -2088,7 +2092,7 @@ describe('Timeline profiler', () => {
2092 });
2093
2094 it('should mark concurrent render that throws', async () => {
2091 - spyOn(console, 'error');
2095 + jest.spyOn(console, 'error').mockImplementation(() => {});
2096
2097 class ErrorBoundary extends React.Component {
2098 state = {error: null};
packages/react-devtools-shared/src/__tests__/bridge-test.js
+1 -1
@@ -38,7 +38,7 @@ describe('Bridge', () => {
38 expect(wall.send).toHaveBeenCalledWith('shutdown');
39
40 // Verify that the Bridge doesn't send messages after shutdown.
41 - spyOn(console, 'warn');
41 + jest.spyOn(console, 'warn').mockImplementation(() => {});
42 wall.send.mockClear();
43 bridge.send('should not send');
44 jest.runAllTimers();
packages/react-devtools-shared/src/__tests__/inspectedElement-test.js
+2 -2
@@ -2121,7 +2121,7 @@ describe('InspectedElement', () => {
2121 });
2122
2123 it('should gracefully surface backend errors on the frontend rather than timing out', async () => {
2124 - spyOn(console, 'error');
2124 + jest.spyOn(console, 'error').mockImplementation(() => {});
2125
2126 let shouldThrow = false;
2127
@@ -2738,7 +2738,7 @@ describe('InspectedElement', () => {
2738
2739 it('inspecting nested renderers should not throw', async () => {
2740 // Ignoring react art warnings
2741 - spyOn(console, 'error');
2741 + jest.spyOn(console, 'error').mockImplementation(() => {});
2742 const ReactArt = require('react-art');
2743 const ArtSVGMode = require('art/modes/svg');
2744 const ARTCurrentMode = require('art/modes/current');
packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js
+1 -1
@@ -760,7 +760,7 @@ describe('InspectedElementContext', () => {
760 const rendererID = ((store.getRendererIDForElement(id): any): number);
761
762 const logSpy = jest.fn();
763 - spyOn(console, 'log').and.callFake(logSpy);
763 + jest.spyOn(console, 'log').mockImplementation(logSpy);
764
765 // Should store the whole value (not just the hydrated parts)
766 backendAPI.storeAsGlobal({
packages/react-devtools-shared/src/__tests__/preprocessData-test.js
+3 -3
@@ -1135,7 +1135,7 @@ describe('Timeline profiler', () => {
1135 );
1136 const invalidUserTimingData = createUserTimingData(invalidMarks);
1137
1138 - const error = spyOn(console, 'error');
1138 + const error = jest.spyOn(console, 'error').mockImplementation(() => {});
1139 preprocessData([
1140 ...createBoilerplateEntries(),
1141 ...invalidUserTimingData,
@@ -1153,7 +1153,7 @@ describe('Timeline profiler', () => {
1153 );
1154 const invalidUserTimingData = createUserTimingData(invalidMarks);
1155
1156 - const error = spyOn(console, 'error');
1156 + const error = jest.spyOn(console, 'error').mockImplementation(() => {});
1157 preprocessData([
1158 ...createBoilerplateEntries(),
1159 ...invalidUserTimingData,
@@ -1748,7 +1748,7 @@ describe('Timeline profiler', () => {
1748 describe('errors thrown while rendering', () => {
1749 // @reactVersion >= 18.0
1750 it('shoult parse Errors thrown during render', async () => {
1751 - spyOn(console, 'error');
1751 + jest.spyOn(console, 'error');
1752
1753 class ErrorBoundary extends React.Component {
1754 state = {error: null};
packages/react-devtools-shared/src/__tests__/profilerStore-test.js
+1 -1
@@ -73,7 +73,7 @@ describe('ProfilerStore', () => {
73 const fauxProfilingData = {
74 dataForRoots: new Map(),
75 };
76 - spyOn(console, 'warn');
76 + jest.spyOn(console, 'warn').mockImplementation(() => {});
77 store.profilerStore.profilingData = fauxProfilingData;
78 expect(store.profilerStore.profilingData).not.toBe(fauxProfilingData);
79 expect(console.warn).toHaveBeenCalledTimes(1);
packages/react-devtools-shared/src/__tests__/setupTests.js
+2 -3
@@ -32,8 +32,7 @@ if (compactConsole) {
32 global.console = new CustomConsole(process.stdout, process.stderr, formatter);
33 }
34
35 -const env = jasmine.getEnv();
36 -env.beforeEach(() => {
35 +beforeEach(() => {
36 global.mockClipboardCopy = jest.fn();
37
38 // Test environment doesn't support document methods like execCommand()
@@ -169,7 +168,7 @@ env.beforeEach(() => {
168 }
169 global.fetch = mockFetch;
170 });
172 -env.afterEach(() => {
171 +afterEach(() => {
172 delete global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
173
174 // It's important to reset modules between test runs;
packages/react-dom/src/__tests__/InvalidEventListeners-test.js
+1 -1
@@ -65,7 +65,7 @@ describe('InvalidEventListeners', () => {
65
66 if (!__DEV__) {
67 expect(console.error).toHaveBeenCalledTimes(1);
68 - expect(console.error.calls.argsFor(0)[0]).toEqual(
68 + expect(console.error.mock.calls[0][0]).toEqual(
69 expect.objectContaining({
70 detail: expect.objectContaining({
71 message:
packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+8 -4
@@ -24,6 +24,10 @@ describe('ReactDOMComponent', () => {
24 ReactTestUtils = require('react-dom/test-utils');
25 });
26
27 + afterEach(() => {
28 + jest.restoreAllMocks();
29 + });
30 +
31 describe('updateDOM', () => {
32 it('should handle className', () => {
33 const container = document.createElement('div');
@@ -1239,7 +1243,7 @@ describe('ReactDOMComponent', () => {
1243
1244 if (__DEV__) {
1245 expect(console.log).toHaveBeenCalledTimes(1);
1242 - expect(console.log.calls.argsFor(0)[0]).toContain('onError called');
1246 + expect(console.log.mock.calls[0][0]).toContain('onError called');
1247 }
1248 });
1249
@@ -1464,7 +1468,7 @@ describe('ReactDOMComponent', () => {
1468
1469 it('should support custom elements which extend native elements', () => {
1470 const container = document.createElement('div');
1467 - spyOnDevAndProd(document, 'createElement').and.callThrough();
1471 + spyOnDevAndProd(document, 'createElement');
1472 ReactDOM.render(<div is="custom-div" />, container);
1473 expect(document.createElement).toHaveBeenCalledWith('div', {
1474 is: 'custom-div',
@@ -1496,8 +1500,8 @@ describe('ReactDOMComponent', () => {
1500
1501 if (__DEV__) {
1502 expect(console.log).toHaveBeenCalledTimes(2);
1499 - expect(console.log.calls.argsFor(0)[0]).toContain('onError called');
1500 - expect(console.log.calls.argsFor(1)[0]).toContain('onLoad called');
1503 + expect(console.log.mock.calls[0][0]).toContain('onError called');
1504 + expect(console.log.mock.calls[1][0]).toContain('onLoad called');
1505 }
1506 });
1507
packages/react-dom/src/__tests__/ReactDOMConsoleErrorReporting-test.js
+57 -56
@@ -49,6 +49,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
49 afterEach(() => {
50 document.body.removeChild(container);
51 window.removeEventListener('error', windowOnError);
52 + jest.restoreAllMocks();
53 });
54
55 describe('ReactDOMClient.createRoot', () => {
@@ -95,7 +96,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
96 }),
97 ],
98 ]);
98 - expect(console.error.calls.all().map(c => c.args)).toEqual([
99 + expect(console.error.mock.calls).toEqual([
100 [
101 // Reported because we're in a browser click event:
102 expect.objectContaining({
@@ -125,7 +126,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
126 }),
127 ],
128 ]);
128 - expect(console.error.calls.all().map(c => c.args)).toEqual([
129 + expect(console.error.mock.calls).toEqual([
130 [
131 // Reported because we're in a browser click event:
132 expect.objectContaining({
@@ -140,14 +141,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
141
142 // Check next render doesn't throw.
143 windowOnError.mockReset();
143 - console.error.calls.reset();
144 + console.error.mockReset();
145 act(() => {
146 root.render(<NoError />);
147 });
148 expect(container.textContent).toBe('OK');
149 expect(windowOnError.mock.calls).toEqual([]);
150 if (__DEV__) {
150 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
151 + expect(console.error.mock.calls).toEqual([]);
152 }
153 });
154
@@ -181,7 +182,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
182 }),
183 ],
184 ]);
184 - expect(console.error.calls.all().map(c => c.args)).toEqual([
185 + expect(console.error.mock.calls).toEqual([
186 [
187 // Reported due to the guarded callback:
188 expect.objectContaining({
@@ -212,7 +213,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
213 // The top-level error was caught with try/catch, and there's no guarded callback,
214 // so in production we don't see an error event.
215 expect(windowOnError.mock.calls).toEqual([]);
215 - expect(console.error.calls.all().map(c => c.args)).toEqual([
216 + expect(console.error.mock.calls).toEqual([
217 [
218 // Reported by React with no extra message:
219 expect.objectContaining({
@@ -224,14 +225,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
225
226 // Check next render doesn't throw.
227 windowOnError.mockReset();
227 - console.error.calls.reset();
228 + console.error.mockReset();
229 act(() => {
230 root.render(<NoError />);
231 });
232 expect(container.textContent).toBe('OK');
233 expect(windowOnError.mock.calls).toEqual([]);
234 if (__DEV__) {
234 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
235 + expect(console.error.mock.calls).toEqual([]);
236 }
237 });
238
@@ -267,7 +268,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
268 }),
269 ],
270 ]);
270 - expect(console.error.calls.all().map(c => c.args)).toEqual([
271 + expect(console.error.mock.calls).toEqual([
272 [
273 // Reported by jsdom due to the guarded callback:
274 expect.objectContaining({
@@ -298,7 +299,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
299 // The top-level error was caught with try/catch, and there's no guarded callback,
300 // so in production we don't see an error event.
301 expect(windowOnError.mock.calls).toEqual([]);
301 - expect(console.error.calls.all().map(c => c.args)).toEqual([
302 + expect(console.error.mock.calls).toEqual([
303 [
304 // Reported by React with no extra message:
305 expect.objectContaining({
@@ -310,14 +311,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
311
312 // Check next render doesn't throw.
313 windowOnError.mockReset();
313 - console.error.calls.reset();
314 + console.error.mockReset();
315 act(() => {
316 root.render(<NoError />);
317 });
318 expect(container.textContent).toBe('OK');
319 expect(windowOnError.mock.calls).toEqual([]);
320 if (__DEV__) {
320 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
321 + expect(console.error.mock.calls).toEqual([]);
322 }
323 });
324
@@ -347,7 +348,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
348 }),
349 ],
350 ]);
350 - expect(console.error.calls.all().map(c => c.args)).toEqual([
351 + expect(console.error.mock.calls).toEqual([
352 [
353 // Reported due to the guarded callback:
354 expect.objectContaining({
@@ -368,7 +369,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
369 // The top-level error was caught with try/catch, and there's no guarded callback,
370 // so in production we don't see an error event.
371 expect(windowOnError.mock.calls).toEqual([]);
371 - expect(console.error.calls.all().map(c => c.args)).toEqual([
372 + expect(console.error.mock.calls).toEqual([
373 [
374 // Reported by React with no extra message:
375 expect.objectContaining({
@@ -380,14 +381,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
381
382 // Check next render doesn't throw.
383 windowOnError.mockReset();
383 - console.error.calls.reset();
384 + console.error.mockReset();
385 act(() => {
386 root.render(<NoError />);
387 });
388 expect(container.textContent).toBe('OK');
389 expect(windowOnError.mock.calls).toEqual([]);
390 if (__DEV__) {
390 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
391 + expect(console.error.mock.calls).toEqual([]);
392 }
393 });
394
@@ -419,7 +420,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
420 }),
421 ],
422 ]);
422 - expect(console.error.calls.all().map(c => c.args)).toEqual([
423 + expect(console.error.mock.calls).toEqual([
424 [
425 // Reported by jsdom due to the guarded callback:
426 expect.objectContaining({
@@ -440,7 +441,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
441 // The top-level error was caught with try/catch, and there's no guarded callback,
442 // so in production we don't see an error event.
443 expect(windowOnError.mock.calls).toEqual([]);
443 - expect(console.error.calls.all().map(c => c.args)).toEqual([
444 + expect(console.error.mock.calls).toEqual([
445 [
446 // Reported by React with no extra message:
447 expect.objectContaining({
@@ -452,14 +453,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
453
454 // Check next render doesn't throw.
455 windowOnError.mockReset();
455 - console.error.calls.reset();
456 + console.error.mockReset();
457 act(() => {
458 root.render(<NoError />);
459 });
460 expect(container.textContent).toBe('OK');
461 expect(windowOnError.mock.calls).toEqual([]);
462 if (__DEV__) {
462 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
463 + expect(console.error.mock.calls).toEqual([]);
464 }
465 });
466
@@ -489,7 +490,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
490 }),
491 ],
492 ]);
492 - expect(console.error.calls.all().map(c => c.args)).toEqual([
493 + expect(console.error.mock.calls).toEqual([
494 [
495 // Reported due to the guarded callback:
496 expect.objectContaining({
@@ -510,7 +511,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
511 // The top-level error was caught with try/catch, and there's no guarded callback,
512 // so in production we don't see an error event.
513 expect(windowOnError.mock.calls).toEqual([]);
513 - expect(console.error.calls.all().map(c => c.args)).toEqual([
514 + expect(console.error.mock.calls).toEqual([
515 [
516 // Reported by React with no extra message:
517 expect.objectContaining({
@@ -522,14 +523,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
523
524 // Check next render doesn't throw.
525 windowOnError.mockReset();
525 - console.error.calls.reset();
526 + console.error.mockReset();
527 act(() => {
528 root.render(<NoError />);
529 });
530 expect(container.textContent).toBe('OK');
531 expect(windowOnError.mock.calls).toEqual([]);
532 if (__DEV__) {
532 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
533 + expect(console.error.mock.calls).toEqual([]);
534 }
535 });
536
@@ -561,7 +562,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
562 }),
563 ],
564 ]);
564 - expect(console.error.calls.all().map(c => c.args)).toEqual([
565 + expect(console.error.mock.calls).toEqual([
566 [
567 // Reported by jsdom due to the guarded callback:
568 expect.objectContaining({
@@ -582,7 +583,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
583 // The top-level error was caught with try/catch, and there's no guarded callback,
584 // so in production we don't see an error event.
585 expect(windowOnError.mock.calls).toEqual([]);
585 - expect(console.error.calls.all().map(c => c.args)).toEqual([
586 + expect(console.error.mock.calls).toEqual([
587 [
588 // Reported by React with no extra message:
589 expect.objectContaining({
@@ -594,14 +595,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
595
596 // Check next render doesn't throw.
597 windowOnError.mockReset();
597 - console.error.calls.reset();
598 + console.error.mockReset();
599 act(() => {
600 root.render(<NoError />);
601 });
602 expect(container.textContent).toBe('OK');
603 expect(windowOnError.mock.calls).toEqual([]);
604 if (__DEV__) {
604 - expect(console.error.calls.all().map(c => c.args)).toEqual([]);
605 + expect(console.error.mock.calls).toEqual([]);
606 }
607 });
608 });
@@ -649,7 +650,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
650 }),
651 ],
652 ]);
652 - expect(console.error.calls.all().map(c => c.args)).toEqual([
653 + expect(console.error.mock.calls).toEqual([
654 [expect.stringContaining('ReactDOM.render is no longer supported')],
655 [
656 // Reported because we're in a browser click event:
@@ -680,7 +681,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
681 }),
682 ],
683 ]);
683 - expect(console.error.calls.all().map(c => c.args)).toEqual([
684 + expect(console.error.mock.calls).toEqual([
685 [
686 // Reported because we're in a browser click event:
687 expect.objectContaining({
@@ -695,14 +696,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
696
697 // Check next render doesn't throw.
698 windowOnError.mockReset();
698 - console.error.calls.reset();
699 + console.error.mockReset();
700 act(() => {
701 ReactDOM.render(<NoError />, container);
702 });
703 expect(container.textContent).toBe('OK');
704 expect(windowOnError.mock.calls).toEqual([]);
705 if (__DEV__) {
705 - expect(console.error.calls.all().map(c => c.args)).toEqual([
706 + expect(console.error.mock.calls).toEqual([
707 [expect.stringContaining('ReactDOM.render is no longer supported')],
708 ]);
709 }
@@ -730,7 +731,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
731 }),
732 ],
733 ]);
733 - expect(console.error.calls.all().map(c => c.args)).toEqual([
734 + expect(console.error.mock.calls).toEqual([
735 [expect.stringContaining('ReactDOM.render is no longer supported')],
736 [
737 // Reported due to the guarded callback:
@@ -752,7 +753,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
753 // The top-level error was caught with try/catch, and there's no guarded callback,
754 // so in production we don't see an error event.
755 expect(windowOnError.mock.calls).toEqual([]);
755 - expect(console.error.calls.all().map(c => c.args)).toEqual([
756 + expect(console.error.mock.calls).toEqual([
757 [
758 // Reported by React with no extra message:
759 expect.objectContaining({
@@ -764,14 +765,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
765
766 // Check next render doesn't throw.
767 windowOnError.mockReset();
767 - console.error.calls.reset();
768 + console.error.mockReset();
769 act(() => {
770 ReactDOM.render(<NoError />, container);
771 });
772 expect(container.textContent).toBe('OK');
773 expect(windowOnError.mock.calls).toEqual([]);
774 if (__DEV__) {
774 - expect(console.error.calls.all().map(c => c.args)).toEqual([
775 + expect(console.error.mock.calls).toEqual([
776 [expect.stringContaining('ReactDOM.render is no longer supported')],
777 ]);
778 }
@@ -802,7 +803,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
803 }),
804 ],
805 ]);
805 - expect(console.error.calls.all().map(c => c.args)).toEqual([
806 + expect(console.error.mock.calls).toEqual([
807 [expect.stringContaining('ReactDOM.render is no longer supported')],
808 [
809 // Reported by jsdom due to the guarded callback:
@@ -824,7 +825,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
825 // The top-level error was caught with try/catch, and there's no guarded callback,
826 // so in production we don't see an error event.
827 expect(windowOnError.mock.calls).toEqual([]);
827 - expect(console.error.calls.all().map(c => c.args)).toEqual([
828 + expect(console.error.mock.calls).toEqual([
829 [
830 // Reported by React with no extra message:
831 expect.objectContaining({
@@ -836,14 +837,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
837
838 // Check next render doesn't throw.
839 windowOnError.mockReset();
839 - console.error.calls.reset();
840 + console.error.mockReset();
841 act(() => {
842 ReactDOM.render(<NoError />, container);
843 });
844 expect(container.textContent).toBe('OK');
845 expect(windowOnError.mock.calls).toEqual([]);
846 if (__DEV__) {
846 - expect(console.error.calls.all().map(c => c.args)).toEqual([
847 + expect(console.error.mock.calls).toEqual([
848 [expect.stringContaining('ReactDOM.render is no longer supported')],
849 ]);
850 }
@@ -874,7 +875,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
875 }),
876 ],
877 ]);
877 - expect(console.error.calls.all().map(c => c.args)).toEqual([
878 + expect(console.error.mock.calls).toEqual([
879 [expect.stringContaining('ReactDOM.render is no longer supported')],
880 [
881 // Reported due to the guarded callback:
@@ -896,7 +897,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
897 // The top-level error was caught with try/catch, and there's no guarded callback,
898 // so in production we don't see an error event.
899 expect(windowOnError.mock.calls).toEqual([]);
899 - expect(console.error.calls.all().map(c => c.args)).toEqual([
900 + expect(console.error.mock.calls).toEqual([
901 [
902 // Reported by React with no extra message:
903 expect.objectContaining({
@@ -908,14 +909,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
909
910 // Check next render doesn't throw.
911 windowOnError.mockReset();
911 - console.error.calls.reset();
912 + console.error.mockReset();
913 act(() => {
914 ReactDOM.render(<NoError />, container);
915 });
916 expect(container.textContent).toBe('OK');
917 expect(windowOnError.mock.calls).toEqual([]);
918 if (__DEV__) {
918 - expect(console.error.calls.all().map(c => c.args)).toEqual([
919 + expect(console.error.mock.calls).toEqual([
920 [expect.stringContaining('ReactDOM.render is no longer supported')],
921 ]);
922 }
@@ -949,7 +950,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
950 }),
951 ],
952 ]);
952 - expect(console.error.calls.all().map(c => c.args)).toEqual([
953 + expect(console.error.mock.calls).toEqual([
954 [expect.stringContaining('ReactDOM.render is no longer supported')],
955 [
956 // Reported by jsdom due to the guarded callback:
@@ -971,7 +972,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
972 // The top-level error was caught with try/catch, and there's no guarded callback,
973 // so in production we don't see an error event.
974 expect(windowOnError.mock.calls).toEqual([]);
974 - expect(console.error.calls.all().map(c => c.args)).toEqual([
975 + expect(console.error.mock.calls).toEqual([
976 [
977 // Reported by React with no extra message:
978 expect.objectContaining({
@@ -983,14 +984,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
984
985 // Check next render doesn't throw.
986 windowOnError.mockReset();
986 - console.error.calls.reset();
987 + console.error.mockReset();
988 act(() => {
989 ReactDOM.render(<NoError />, container);
990 });
991 expect(container.textContent).toBe('OK');
992 expect(windowOnError.mock.calls).toEqual([]);
993 if (__DEV__) {
993 - expect(console.error.calls.all().map(c => c.args)).toEqual([
994 + expect(console.error.mock.calls).toEqual([
995 [expect.stringContaining('ReactDOM.render is no longer supported')],
996 ]);
997 }
@@ -1021,7 +1022,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
1022 }),
1023 ],
1024 ]);
1024 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1025 + expect(console.error.mock.calls).toEqual([
1026 [expect.stringContaining('ReactDOM.render is no longer supported')],
1027 [
1028 // Reported due to the guarded callback:
@@ -1043,7 +1044,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
1044 // The top-level error was caught with try/catch, and there's no guarded callback,
1045 // so in production we don't see an error event.
1046 expect(windowOnError.mock.calls).toEqual([]);
1046 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1047 + expect(console.error.mock.calls).toEqual([
1048 [
1049 // Reported by React with no extra message:
1050 expect.objectContaining({
@@ -1055,14 +1056,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
1056
1057 // Check next render doesn't throw.
1058 windowOnError.mockReset();
1058 - console.error.calls.reset();
1059 + console.error.mockReset();
1060 act(() => {
1061 ReactDOM.render(<NoError />, container);
1062 });
1063 expect(container.textContent).toBe('OK');
1064 expect(windowOnError.mock.calls).toEqual([]);
1065 if (__DEV__) {
1065 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1066 + expect(console.error.mock.calls).toEqual([
1067 [expect.stringContaining('ReactDOM.render is no longer supported')],
1068 ]);
1069 }
@@ -1096,7 +1097,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
1097 }),
1098 ],
1099 ]);
1099 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1100 + expect(console.error.mock.calls).toEqual([
1101 [expect.stringContaining('ReactDOM.render is no longer supported')],
1102 [
1103 // Reported by jsdom due to the guarded callback:
@@ -1118,7 +1119,7 @@ describe('ReactDOMConsoleErrorReporting', () => {
1119 // The top-level error was caught with try/catch, and there's no guarded callback,
1120 // so in production we don't see an error event.
1121 expect(windowOnError.mock.calls).toEqual([]);
1121 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1122 + expect(console.error.mock.calls).toEqual([
1123 [
1124 // Reported by React with no extra message:
1125 expect.objectContaining({
@@ -1130,14 +1131,14 @@ describe('ReactDOMConsoleErrorReporting', () => {
1131
1132 // Check next render doesn't throw.
1133 windowOnError.mockReset();
1133 - console.error.calls.reset();
1134 + console.error.mockReset();
1135 act(() => {
1136 ReactDOM.render(<NoError />, container);
1137 });
1138 expect(container.textContent).toBe('OK');
1139 expect(windowOnError.mock.calls).toEqual([]);
1140 if (__DEV__) {
1140 - expect(console.error.calls.all().map(c => c.args)).toEqual([
1141 + expect(console.error.mock.calls).toEqual([
1142 [expect.stringContaining('ReactDOM.render is no longer supported')],
1143 ]);
1144 }
packages/react-dom/src/__tests__/ReactDOMFiber-test.js
+5 -4
@@ -24,6 +24,7 @@ describe('ReactDOMFiber', () => {
24 afterEach(() => {
25 document.body.removeChild(container);
26 container = null;
27 + jest.restoreAllMocks();
28 });
29
30 it('should render strings as children', () => {
@@ -1154,11 +1155,11 @@ describe('ReactDOMFiber', () => {
1155 expect(ops).toEqual(['A']);
1156
1157 if (__DEV__) {
1157 - expect(console.error.calls.count()).toBe(2);
1158 - expect(console.error.calls.argsFor(0)[0]).toMatch(
1158 + expect(console.error).toHaveBeenCalledTimes(2);
1159 + expect(console.error.mock.calls[0][0]).toMatch(
1160 'ReactDOM.render is no longer supported in React 18',
1161 );
1161 - expect(console.error.calls.argsFor(1)[0]).toMatch(
1162 + expect(console.error.mock.calls[1][0]).toMatch(
1163 'ReactDOM.render is no longer supported in React 18',
1164 );
1165 }
@@ -1257,7 +1258,7 @@ describe('ReactDOMFiber', () => {
1258 let actualDocument;
1259 let textNode;
1260
1260 - spyOnDevAndProd(iframeContainer, 'appendChild').and.callFake(node => {
1261 + spyOnDevAndProd(iframeContainer, 'appendChild').mockImplementation(node => {
1262 actualDocument = node.ownerDocument;
1263 textNode = node;
1264 });
packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js
+6 -2
@@ -63,6 +63,10 @@ describe('ReactDOMFizzShellHydration', () => {
63 });
64 });
65
66 + afterEach(() => {
67 + jest.restoreAllMocks();
68 + });
69 +
70 async function serverAct(callback) {
71 await callback();
72 // Await one turn around the event loop.
@@ -286,7 +290,7 @@ describe('ReactDOMFizzShellHydration', () => {
290 });
291
292 test('TODO: A large component stack causes SSR to stack overflow', async () => {
289 - spyOnDevAndProd(console, 'error');
293 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
294
295 function NestedComponent({depth}: {depth: number}) {
296 if (depth <= 0) {
@@ -302,7 +306,7 @@ describe('ReactDOMFizzShellHydration', () => {
306 );
307 });
308 expect(console.error).toHaveBeenCalledTimes(1);
305 - expect(console.error.calls.argsFor(0)[0].toString()).toBe(
309 + expect(console.error.mock.calls[0][0].toString()).toBe(
310 'RangeError: Maximum call stack size exceeded',
311 );
312 });
packages/react-dom/src/__tests__/ReactDOMInput-test.js
+12 -4
@@ -48,6 +48,7 @@ describe('ReactDOMInput', () => {
48
49 afterEach(() => {
50 document.body.removeChild(container);
51 + jest.restoreAllMocks();
52 });
53
54 it('should warn for controlled value of 0 with missing onChange', () => {
@@ -1670,7 +1671,9 @@ describe('ReactDOMInput', () => {
1671 it('sets type, step, min, max before value always', () => {
1672 const log = [];
1673 const originalCreateElement = document.createElement;
1673 - spyOnDevAndProd(document, 'createElement').and.callFake(function (type) {
1674 + spyOnDevAndProd(document, 'createElement').mockImplementation(function (
1675 + type,
1676 + ) {
1677 const el = originalCreateElement.apply(this, arguments);
1678 let value = '';
1679
@@ -1684,7 +1687,7 @@ describe('ReactDOMInput', () => {
1687 log.push('set property value');
1688 },
1689 });
1687 - spyOnDevAndProd(el, 'setAttribute').and.callFake(function (name) {
1690 + spyOnDevAndProd(el, 'setAttribute').mockImplementation(function (name) {
1691 log.push('set attribute ' + name);
1692 });
1693 }
@@ -1743,7 +1746,9 @@ describe('ReactDOMInput', () => {
1746
1747 const log = [];
1748 const originalCreateElement = document.createElement;
1746 - spyOnDevAndProd(document, 'createElement').and.callFake(function (type) {
1749 + spyOnDevAndProd(document, 'createElement').mockImplementation(function (
1750 + type,
1751 + ) {
1752 const el = originalCreateElement.apply(this, arguments);
1753 const getDefaultValue = Object.getOwnPropertyDescriptor(
1754 HTMLInputElement.prototype,
@@ -1780,7 +1785,10 @@ describe('ReactDOMInput', () => {
1785 setValue.call(this, val);
1786 },
1787 });
1783 - spyOnDevAndProd(el, 'setAttribute').and.callFake(function (name, val) {
1788 + spyOnDevAndProd(el, 'setAttribute').mockImplementation(function (
1789 + name,
1790 + val,
1791 + ) {
1792 log.push(`node.setAttribute(${strify(name)}, ${strify(val)})`);
1793 });
1794 }
packages/react-dom/src/__tests__/ReactDOMTextarea-test.js
+7 -1
@@ -42,6 +42,10 @@ describe('ReactDOMTextarea', () => {
42 };
43 });
44
45 + afterEach(() => {
46 + jest.restoreAllMocks();
47 + });
48 +
49 it('should allow setting `defaultValue`', () => {
50 const container = document.createElement('div');
51 const node = renderTextarea(<textarea defaultValue="giraffe" />, container);
@@ -133,7 +137,9 @@ describe('ReactDOMTextarea', () => {
137
138 let counter = 0;
139 const originalCreateElement = document.createElement;
136 - spyOnDevAndProd(document, 'createElement').and.callFake(function (type) {
140 + spyOnDevAndProd(document, 'createElement').mockImplementation(function (
141 + type,
142 + ) {
143 const el = originalCreateElement.apply(this, arguments);
144 let value = '';
145 if (type === 'textarea') {
packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js
+2 -2
@@ -796,10 +796,10 @@ describe('ReactErrorBoundaries', () => {
796 );
797 if (__DEV__) {
798 expect(console.error).toHaveBeenCalledTimes(2);
799 - expect(console.error.calls.argsFor(0)[0]).toContain(
799 + expect(console.error.mock.calls[0][0]).toContain(
800 'ReactDOM.render is no longer supported',
801 );
802 - expect(console.error.calls.argsFor(1)[0]).toContain(
802 + expect(console.error.mock.calls[1][0]).toContain(
803 'The above error occurred in the <BrokenRender> component:',
804 );
805 }
packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js
+6 -2
@@ -584,6 +584,10 @@ describe('ReactLegacyErrorBoundaries', () => {
584 };
585 });
586
587 + afterEach(() => {
588 + jest.restoreAllMocks();
589 + });
590 +
591 it('does not swallow exceptions on mounting without boundaries', () => {
592 let container = document.createElement('div');
593 expect(() => {
@@ -677,10 +681,10 @@ describe('ReactLegacyErrorBoundaries', () => {
681 );
682 if (__DEV__) {
683 expect(console.error).toHaveBeenCalledTimes(2);
680 - expect(console.error.calls.argsFor(0)[0]).toContain(
684 + expect(console.error.mock.calls[0][0]).toContain(
685 'ReactDOM.render is no longer supported',
686 );
683 - expect(console.error.calls.argsFor(1)[0]).toContain(
687 + expect(console.error.mock.calls[1][0]).toContain(
688 'The above error occurred in the <BrokenRender> component:',
689 );
690 }
packages/react-dom/src/__tests__/ReactLegacyRootWarnings-test.js
+6 -2
@@ -9,6 +9,10 @@ describe('ReactDOMRoot', () => {
9 ReactDOM = require('react-dom');
10 });
11
12 + afterEach(() => {
13 + jest.restoreAllMocks();
14 + });
15 +
16 test('deprecation warning for ReactDOM.render', () => {
17 spyOnDev(console, 'error');
18
@@ -16,7 +20,7 @@ describe('ReactDOMRoot', () => {
20 expect(container.textContent).toEqual('Hi');
21 if (__DEV__) {
22 expect(console.error).toHaveBeenCalledTimes(1);
19 - expect(console.error.calls.argsFor(0)[0]).toContain(
23 + expect(console.error.mock.calls[0][0]).toContain(
24 'ReactDOM.render is no longer supported',
25 );
26 }
@@ -30,7 +34,7 @@ describe('ReactDOMRoot', () => {
34 expect(container.textContent).toEqual('Hi');
35 if (__DEV__) {
36 expect(console.error).toHaveBeenCalledTimes(1);
33 - expect(console.error.calls.argsFor(0)[0]).toContain(
37 + expect(console.error.mock.calls[0][0]).toContain(
38 'ReactDOM.hydrate is no longer supported',
39 );
40 }
packages/react-dom/src/__tests__/ReactTestUtils-test.js
+2 -2
@@ -333,7 +333,7 @@ describe('ReactTestUtils', () => {
333 e.persist();
334 },
335 };
336 - spyOnDevAndProd(obj, 'handler').and.callThrough();
336 + spyOnDevAndProd(obj, 'handler');
337 const container = document.createElement('div');
338 const node = ReactDOM.render(
339 <input type="text" onChange={obj.handler} />,
@@ -369,7 +369,7 @@ describe('ReactTestUtils', () => {
369 e.persist();
370 },
371 };
372 - spyOnDevAndProd(obj, 'handler').and.callThrough();
372 + spyOnDevAndProd(obj, 'handler');
373 const container = document.createElement('div');
374 const instance = ReactDOM.render(
375 <SomeComponent handleChange={obj.handler} />,
packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js
+10 -6
@@ -28,6 +28,10 @@ function sleep(period) {
28 }
29
30 describe('ReactTestUtils.act()', () => {
31 + afterEach(() => {
32 + jest.restoreAllMocks();
33 + });
34 +
35 // first we run all the tests with concurrent mode
36 if (__EXPERIMENTAL__) {
37 let concurrentRoot = null;
@@ -488,13 +492,13 @@ function runActTests(label, render, unmount, rerender) {
492
493 // @gate __DEV__
494 it('warns if you do not await an act call', async () => {
491 - spyOnDevAndProd(console, 'error');
495 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
496 act(async () => {});
497 // it's annoying that we have to wait a tick before this warning comes in
498 await sleep(0);
499 if (__DEV__) {
496 - expect(console.error.calls.count()).toEqual(1);
497 - expect(console.error.calls.argsFor(0)[0]).toMatch(
500 + expect(console.error).toHaveBeenCalledTimes(1);
501 + expect(console.error.mock.calls[0][0]).toMatch(
502 'You called act(async () => ...) without await.',
503 );
504 }
@@ -502,7 +506,7 @@ function runActTests(label, render, unmount, rerender) {
506
507 // @gate __DEV__
508 it('warns if you try to interleave multiple act calls', async () => {
505 - spyOnDevAndProd(console, 'error');
509 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
510
511 await Promise.all([
512 act(async () => {
@@ -516,10 +520,10 @@ function runActTests(label, render, unmount, rerender) {
520 await sleep(150);
521 if (__DEV__) {
522 expect(console.error).toHaveBeenCalledTimes(2);
519 - expect(console.error.calls.argsFor(0)[0]).toMatch(
523 + expect(console.error.mock.calls[0][0]).toMatch(
524 'You seem to have overlapping act() calls',
525 );
522 - expect(console.error.calls.argsFor(1)[0]).toMatch(
526 + expect(console.error.mock.calls[1][0]).toMatch(
527 'You seem to have overlapping act() calls',
528 );
529 }
packages/react-dom/src/__tests__/ReactUpdates-test.js
+1 -1
@@ -1706,7 +1706,7 @@ describe('ReactUpdates', () => {
1706
1707 it('prevents infinite update loop triggered by synchronous updates in useEffect', () => {
1708 // Ignore flushSync warning
1709 - spyOnDev(console, 'error');
1709 + spyOnDev(console, 'error').mockImplementation(() => {});
1710
1711 function NonTerminating() {
1712 const [step, setStep] = React.useState(0);
packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js
+10 -6
@@ -67,19 +67,23 @@ module.exports = function (initModules) {
67 // performs fn asynchronously and expects count errors logged to console.error.
68 // will fail the test if the count of errors logged is not equal to count.
69 async function expectErrors(fn, count) {
70 - if (console.error.calls && console.error.calls.reset) {
71 - console.error.calls.reset();
70 + if (console.error.mockClear) {
71 + console.error.mockClear();
72 } else {
73 // TODO: Rewrite tests that use this helper to enumerate expected errors.
74 // This will enable the helper to use the .toErrorDev() matcher instead of spying.
75 - spyOnDev(console, 'error');
75 + spyOnDev(console, 'error').mockImplementation(() => {});
76 }
77
78 const result = await fn();
79 - if (console.error.calls && console.error.calls.count() !== 0) {
79 + if (
80 + console.error.mock &&
81 + console.error.mock.calls &&
82 + console.error.mock.calls.length !== 0
83 + ) {
84 const filteredWarnings = [];
81 - for (let i = 0; i < console.error.calls.count(); i++) {
82 - const args = console.error.calls.argsFor(i);
85 + for (let i = 0; i < console.error.mock.calls.length; i++) {
86 + const args = console.error.mock.calls[i];
87 const [format, ...rest] = args;
88 if (!shouldIgnoreConsoleError(format, rest)) {
89 filteredWarnings.push(args);
packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js
+3 -3
@@ -33,14 +33,14 @@ describe('DebugTracing', () => {
33
34 const groups = [];
35
36 - spyOnDevAndProd(console, 'log').and.callFake(message => {
36 + spyOnDevAndProd(console, 'log').mockImplementation(message => {
37 logs.push(`log: ${message.replace(/%c/g, '')}`);
38 });
39 - spyOnDevAndProd(console, 'group').and.callFake(message => {
39 + spyOnDevAndProd(console, 'group').mockImplementation(message => {
40 logs.push(`group: ${message.replace(/%c/g, '')}`);
41 groups.push(message);
42 });
43 - spyOnDevAndProd(console, 'groupEnd').and.callFake(() => {
43 + spyOnDevAndProd(console, 'groupEnd').mockImplementation(() => {
44 const message = groups.pop();
45 logs.push(`groupEnd: ${message.replace(/%c/g, '')}`);
46 });
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+2 -2
@@ -1724,7 +1724,7 @@ describe('ReactHooks', () => {
1724 // Regression test for #14674
1725 it('does not swallow original error when updating another component in render phase', async () => {
1726 const {useState} = React;
1727 - spyOnDev(console, 'error');
1727 + spyOnDev(console, 'error').mockImplementation(() => {});
1728
1729 let _setState;
1730 function A() {
@@ -1754,7 +1754,7 @@ describe('ReactHooks', () => {
1754
1755 if (__DEV__) {
1756 expect(console.error).toHaveBeenCalledTimes(2);
1757 - expect(console.error.calls.argsFor(0)[0]).toContain(
1757 + expect(console.error.mock.calls[0][0]).toContain(
1758 'Warning: Cannot update a component (`%s`) while rendering ' +
1759 'a different component (`%s`).',
1760 );
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+11 -7
@@ -29,6 +29,10 @@ describe('ReactIncrementalErrorHandling', () => {
29 act = require('jest-react').act;
30 });
31
32 + afterEach(() => {
33 + jest.restoreAllMocks();
34 + });
35 +
36 function normalizeCodeLocInfo(str) {
37 return (
38 str &&
@@ -1520,8 +1524,8 @@ describe('ReactIncrementalErrorHandling', () => {
1524 });
1525
1526 it('error boundaries capture non-errors', () => {
1523 - spyOnProd(console, 'error');
1524 - spyOnDev(console, 'error');
1527 + spyOnProd(console, 'error').mockImplementation(() => {});
1528 + spyOnDev(console, 'error').mockImplementation(() => {});
1529
1530 class ErrorBoundary extends React.Component {
1531 state = {error: null};
@@ -1583,12 +1587,12 @@ describe('ReactIncrementalErrorHandling', () => {
1587
1588 if (__DEV__) {
1589 expect(console.error).toHaveBeenCalledTimes(1);
1586 - expect(console.error.calls.argsFor(0)[0]).toContain(
1590 + expect(console.error.mock.calls[0][0]).toContain(
1591 'The above error occurred in the <BadRender> component:',
1592 );
1593 } else {
1594 expect(console.error).toHaveBeenCalledTimes(1);
1591 - expect(console.error.calls.argsFor(0)[0]).toBe(notAnError);
1595 + expect(console.error.mock.calls[0][0]).toBe(notAnError);
1596 }
1597 });
1598
@@ -1950,7 +1954,7 @@ describe('ReactIncrementalErrorHandling', () => {
1954 // point to prevent an infinite loop in the case where there is (by
1955 // accident) a render phase triggered from userspace.
1956
1953 - spyOnDev(console, 'error');
1957 + spyOnDev(console, 'error').mockImplementation(() => {});
1958
1959 let numberOfThrows = 0;
1960
@@ -1990,10 +1994,10 @@ describe('ReactIncrementalErrorHandling', () => {
1994
1995 if (__DEV__) {
1996 expect(console.error).toHaveBeenCalledTimes(2);
1993 - expect(console.error.calls.argsFor(0)[0]).toContain(
1997 + expect(console.error.mock.calls[0][0]).toContain(
1998 'Cannot update a component (`%s`) while rendering a different component',
1999 );
1996 - expect(console.error.calls.argsFor(1)[0]).toContain(
2000 + expect(console.error.mock.calls[1][0]).toContain(
2001 'The above error occurred in the <App> component',
2002 );
2003 }
packages/react-reconciler/src/__tests__/ReactIsomorphicAct-test.js
+9 -5
@@ -34,6 +34,10 @@ describe('isomorphic act()', () => {
34 global.IS_REACT_ACT_ENVIRONMENT = true;
35 });
36
37 + afterEach(() => {
38 + jest.restoreAllMocks();
39 + });
40 +
41 // @gate __DEV__
42 test('bypasses queueMicrotask', async () => {
43 const root = ReactNoop.createRoot();
@@ -208,7 +212,7 @@ describe('isomorphic act()', () => {
212 return use(promise);
213 }
214
211 - spyOnDev(console, 'error');
215 + spyOnDev(console, 'error').mockImplementation(() => {});
216 const root = ReactNoop.createRoot();
217 act(() => {
218 startTransition(() => {
@@ -229,8 +233,8 @@ describe('isomorphic act()', () => {
233 await null;
234 await null;
235
232 - expect(console.error.calls.count()).toBe(1);
233 - expect(console.error.calls.argsFor(0)[0]).toContain(
236 + expect(console.error).toHaveBeenCalledTimes(1);
237 + expect(console.error.mock.calls[0][0]).toContain(
238 'Warning: A component suspended inside an `act` scope, but the `act` ' +
239 'call was not awaited. When testing React components that ' +
240 'depend on asynchronous data, you must await the result:\n\n' +
@@ -260,7 +264,7 @@ describe('isomorphic act()', () => {
264 return 'Async';
265 }
266
263 - spyOnDev(console, 'error');
267 + spyOnDev(console, 'error').mockImplementation(() => {});
268 const root = ReactNoop.createRoot();
269 act(() => {
270 startTransition(() => {
@@ -282,7 +286,7 @@ describe('isomorphic act()', () => {
286 await null;
287 await null;
288
285 - expect(console.error.calls.count()).toBe(0);
289 + expect(console.error).toHaveBeenCalledTimes(0);
290
291 // Finish loading the data
292 await act(async () => {
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+2 -2
@@ -161,7 +161,7 @@ describe('ReactLazy', () => {
161 });
162
163 it('does not support arbitrary promises, only module objects', async () => {
164 - spyOnDev(console, 'error');
164 + spyOnDev(console, 'error').mockImplementation(() => {});
165
166 const LazyText = lazy(async () => Text);
167
@@ -181,7 +181,7 @@ describe('ReactLazy', () => {
181 expect(Scheduler).toFlushAndThrow('Element type is invalid');
182 if (__DEV__) {
183 expect(console.error).toHaveBeenCalledTimes(3);
184 - expect(console.error.calls.argsFor(0)[0]).toContain(
184 + expect(console.error.mock.calls[0][0]).toContain(
185 'Expected the result of a dynamic import() call',
186 );
187 }
packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+8 -4
@@ -26,6 +26,10 @@ describe('ReactNewContext', () => {
26 gen = require('random-seed');
27 });
28
29 + afterEach(() => {
30 + jest.restoreAllMocks();
31 + });
32 +
33 function Text(props) {
34 Scheduler.unstable_yieldValue(props.text);
35 return <span prop={props.text} />;
@@ -860,7 +864,7 @@ describe('ReactNewContext', () => {
864 });
865
866 it('warns if multiple renderers concurrently render the same context', () => {
863 - spyOnDev(console, 'error');
867 + spyOnDev(console, 'error').mockImplementation(() => {});
868 const Context = React.createContext(0);
869
870 function Foo(props) {
@@ -898,7 +902,7 @@ describe('ReactNewContext', () => {
902 expect(Scheduler).toFlushAndYield(['Foo', 'Foo']);
903
904 if (__DEV__) {
901 - expect(console.error.calls.argsFor(0)[0]).toContain(
905 + expect(console.error.mock.calls[0][0]).toContain(
906 'Detected multiple renderers concurrently rendering the same ' +
907 'context provider. This is currently unsupported',
908 );
@@ -1047,12 +1051,12 @@ describe('ReactNewContext', () => {
1051
1052 describe('Context.Consumer', () => {
1053 it('warns if child is not a function', () => {
1050 - spyOnDev(console, 'error');
1054 + spyOnDev(console, 'error').mockImplementation(() => {});
1055 const Context = React.createContext(0);
1056 ReactNoop.render(<Context.Consumer />);
1057 expect(Scheduler).toFlushAndThrow('is not a function');
1058 if (__DEV__) {
1055 - expect(console.error.calls.argsFor(0)[0]).toContain(
1059 + expect(console.error.mock.calls[0][0]).toContain(
1060 'A context consumer was rendered with multiple children, or a child ' +
1061 "that isn't a function",
1062 );
packages/react-reconciler/src/__tests__/ReactThenable-test.js
+3 -3
@@ -505,7 +505,7 @@ describe('ReactThenable', () => {
505 }
506 }
507
508 - spyOnDev(console, 'error');
508 + spyOnDev(console, 'error').mockImplementation(() => {});
509 function App() {
510 return (
511 <Suspense fallback={<Text text="Loading..." />}>
@@ -522,8 +522,8 @@ describe('ReactThenable', () => {
522 });
523
524 if (__DEV__) {
525 - expect(console.error.calls.count()).toBe(1);
526 - expect(console.error.calls.argsFor(0)[0]).toContain(
525 + expect(console.error).toHaveBeenCalledTimes(1);
526 + expect(console.error.mock.calls[0][0]).toContain(
527 'Warning: `use` was called from inside a try/catch block. This is not ' +
528 'allowed and can lead to unexpected behavior. To handle errors ' +
529 'triggered by `use`, wrap your component in a error boundary.',
packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+4 -4
@@ -1904,7 +1904,7 @@ describe('useMutableSource', () => {
1904 // Get a new copy of ReactNoop.
1905 loadModules();
1906
1907 - spyOnDev(console, 'error');
1907 + spyOnDev(console, 'error').mockImplementation(() => {});
1908
1909 // Use the mutablesource again but with a different renderer.
1910 ReactNoop.render(
@@ -1917,7 +1917,7 @@ describe('useMutableSource', () => {
1917 );
1918 expect(Scheduler).toFlushAndYieldThrough(['c:one']);
1919
1920 - expect(console.error.calls.argsFor(0)[0]).toContain(
1920 + expect(console.error.mock.calls[0][0]).toContain(
1921 'Detected multiple renderers concurrently rendering the ' +
1922 'same mutable source. This is currently unsupported.',
1923 );
@@ -1985,7 +1985,7 @@ describe('useMutableSource', () => {
1985 // Get a new copy of ReactNoop.
1986 loadModules();
1987
1988 - spyOnDev(console, 'error');
1988 + spyOnDev(console, 'error').mockImplementation(() => {});
1989
1990 // Mutate before the new render reads from the source.
1991 source.value = 'two';
@@ -2001,7 +2001,7 @@ describe('useMutableSource', () => {
2001 );
2002 expect(Scheduler).toFlushAndYieldThrough(['c:two']);
2003
2004 - expect(console.error.calls.argsFor(0)[0]).toContain(
2004 + expect(console.error.mock.calls[0][0]).toContain(
2005 'Detected multiple renderers concurrently rendering the ' +
2006 'same mutable source. This is currently unsupported.',
2007 );
packages/react/src/__tests__/ReactClassEquivalence-test.js
+17 -10
@@ -29,21 +29,28 @@ function runJest(testFile) {
29 const cwd = process.cwd();
30 const extension = process.platform === 'win32' ? '.cmd' : '';
31 const command = process.env.npm_lifecycle_event;
32 + const defaultReporter = '--reporters=default';
33 + const equivalenceReporter =
34 + '--reporters=<rootDir>/scripts/jest/spec-equivalence-reporter/equivalenceReporter.js';
35 if (!command.startsWith('test')) {
36 throw new Error(
37 'Expected this test to run as a result of one of test commands.',
38 );
39 }
37 - const result = spawnSync('yarn' + extension, [command, testFile], {
38 - cwd,
39 - env: Object.assign({}, process.env, {
40 - REACT_CLASS_EQUIVALENCE_TEST: 'true',
41 - // Remove these so that the test file is not filtered out by the mechanism
42 - // we use to parallelize tests in CI
43 - CIRCLE_NODE_TOTAL: '',
44 - CIRCLE_NODE_INDEX: '',
45 - }),
46 - });
40 + const result = spawnSync(
41 + 'yarn' + extension,
42 + [command, testFile, defaultReporter, equivalenceReporter],
43 + {
44 + cwd,
45 + env: Object.assign({}, process.env, {
46 + REACT_CLASS_EQUIVALENCE_TEST: 'true',
47 + // Remove these so that the test file is not filtered out by the mechanism
48 + // we use to parallelize tests in CI
49 + CIRCLE_NODE_TOTAL: '',
50 + CIRCLE_NODE_INDEX: '',
51 + }),
52 + },
53 + );
54
55 if (result.error) {
56 throw result.error;
packages/react/src/__tests__/ReactStrictMode-test.js
+4
@@ -982,6 +982,10 @@ describe('context legacy', () => {
982 PropTypes = require('prop-types');
983 });
984
985 + afterEach(() => {
986 + jest.restoreAllMocks();
987 + });
988 +
989 it('should warn if the legacy context API have been used in strict mode', () => {
990 class LegacyContextProvider extends React.Component {
991 getChildContext() {
packages/scheduler/src/__tests__/SchedulerProfiling-test.js
+3 -3
@@ -481,14 +481,14 @@ Task 1 [Normal] │ █████████
481 it('automatically stops profiling and warns if event log gets too big', async () => {
482 Scheduler.unstable_Profiling.startLoggingProfilingEvents();
483
484 - spyOnDevAndProd(console, 'error');
484 + spyOnDevAndProd(console, 'error').mockImplementation(() => {});
485
486 // Increase infinite loop guard limit
487 const originalMaxIterations = global.__MAX_ITERATIONS__;
488 global.__MAX_ITERATIONS__ = 120000;
489
490 let taskId = 1;
491 - while (console.error.calls.count() === 0) {
491 + while (console.error.mock.calls.length === 0) {
492 taskId++;
493 const task = scheduleCallback(NormalPriority, () => {});
494 cancelCallback(task);
@@ -496,7 +496,7 @@ Task 1 [Normal] │ █████████
496 }
497
498 expect(console.error).toHaveBeenCalledTimes(1);
499 - expect(console.error.calls.argsFor(0)[0]).toBe(
499 + expect(console.error.mock.calls[0][0]).toBe(
500 "Scheduler Profiling: Event log exceeded maximum size. Don't forget " +
501 'to call `stopLoggingProfilingEvents()`.',
502 );
packages/shared/__tests__/describeComponentFrame-test.js
+4 -2
@@ -97,12 +97,14 @@ describe('Component stack trace displaying', () => {
97 });
98 if (__DEV__) {
99 let i = 0;
100 - expect(console.error.calls.count()).toBe(Object.keys(fileNames).length);
100 + expect(console.error).toHaveBeenCalledTimes(
101 + Object.keys(fileNames).length,
102 + );
103 for (const fileName in fileNames) {
104 if (!fileNames.hasOwnProperty(fileName)) {
105 continue;
106 }
105 - const args = console.error.calls.argsFor(i);
107 + const args = console.error.mock.calls[i];
108 const stack = args[args.length - 1];
109 const expected = fileNames[fileName];
110 expect(stack).toContain(`at ${expected}:`);
scripts/jest/config.base.js
+1 -1
@@ -30,5 +30,5 @@ module.exports = {
30
31 testEnvironment: 'jsdom',
32
33 - testRunner: 'jasmine2',
33 + testRunner: 'jest-circus/runner',
34 };
scripts/jest/setupTests.js
+11 -15
@@ -10,16 +10,11 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
10 // require that instead.
11 require('./spec-equivalence-reporter/setupTests.js');
12 } else {
13 - const env = jasmine.getEnv();
13 const errorMap = require('../error-codes/codes.json');
14
16 - // TODO: Stop using spyOn in all the test since that seem deprecated.
17 - // This is a legacy upgrade path strategy from:
18 - // https://github.com/facebook/jest/blob/v20.0.4/packages/jest-matchers/src/spyMatchers.js#L160
19 - const isSpy = spy => spy.calls && typeof spy.calls.count === 'function';
20 -
21 - const spyOn = global.spyOn;
22 - const noop = function () {};
15 + // By default, jest.spyOn also calls the spied method.
16 + const spyOn = jest.spyOn;
17 + const noop = jest.fn;
18
19 // Spying on console methods in production builds can mask errors.
20 // This is why we added an explicit spyOnDev() helper.
@@ -55,10 +50,10 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
50 // global variable. The global lets us detect an infinite loop even if
51 // the actual error object ends up being caught and ignored. An infinite
52 // loop must always fail the test!
58 - env.beforeEach(() => {
53 + beforeEach(() => {
54 global.infiniteLoopError = null;
55 });
61 - env.afterEach(() => {
56 + afterEach(() => {
57 const error = global.infiniteLoopError;
58 global.infiniteLoopError = null;
59 if (error) {
@@ -97,7 +92,10 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
92 expectedMatcher,
93 unexpectedConsoleCallStacks
94 ) => {
100 - if (console[methodName] !== mockMethod && !isSpy(console[methodName])) {
95 + if (
96 + console[methodName] !== mockMethod &&
97 + !jest.isMockFunction(console[methodName])
98 + ) {
99 throw new Error(
100 `Test did not tear down console.${methodName} mock properly.`
101 );
@@ -157,8 +155,8 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
155 unexpectedWarnCallStacks.length = 0;
156 };
157
160 - env.beforeEach(resetAllUnexpectedConsoleCalls);
161 - env.afterEach(flushAllUnexpectedConsoleCalls);
158 + beforeEach(resetAllUnexpectedConsoleCalls);
159 + afterEach(flushAllUnexpectedConsoleCalls);
160
161 if (process.env.NODE_ENV === 'production') {
162 // In production, we strip error messages and turn them into codes.
@@ -309,6 +307,4 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
307 const flags = getTestFlags();
308 return fn(flags);
309 };
312 -
313 - require('jasmine-check').install();
310 }
scripts/jest/spec-equivalence-reporter/equivalenceReporter.js new
+20
@@ -0,0 +1,20 @@
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 +'use strict';
9 +
10 +class EquivalenceReporter {
11 + onTestCaseResult(test, testCaseResult) {
12 + console.log(
13 + `EQUIVALENCE: ${testCaseResult.title}, ` +
14 + `status: ${testCaseResult.status}, ` +
15 + `numExpectations: ${testCaseResult.numPassingAsserts}`
16 + );
17 + }
18 +}
19 +
20 +module.exports = EquivalenceReporter;
scripts/jest/spec-equivalence-reporter/setupTests.js
+1 -22
@@ -7,16 +7,7 @@
7
8 'use strict';
9
10 -const expect = global.expect;
11 -
12 -let numExpectations = 0;
13 -
14 -global.expect = function () {
15 - numExpectations += 1;
16 - return expect.apply(this, arguments);
17 -};
18 -
19 -const spyOn = global.spyOn;
10 +const spyOn = jest.spyOn;
11
12 // Spying on console methods in production builds can mask errors.
13 // This is why we added an explicit spyOnDev() helper.
@@ -50,15 +41,3 @@ expect.extend({
41 ...require('../matchers/toThrow'),
42 ...require('../matchers/toWarnDev'),
43 });
53 -
54 -beforeEach(() => (numExpectations = 0));
55 -
56 -jasmine.currentEnv_.addReporter({
57 - specDone: spec => {
58 - console.log(
59 - `EQUIVALENCE: ${spec.description}, ` +
60 - `status: ${spec.status}, ` +
61 - `numExpectations: ${numExpectations}`
62 - );
63 - },
64 -});
scripts/jest/typescript/jest.d.ts
-5
@@ -1,4 +1,3 @@
1 -declare var jasmine: any;
1 declare var __DEV__: boolean;
2 declare var __TEST__: boolean;
3 declare var __EXTENSION__: boolean;
@@ -71,9 +70,5 @@ interface MockFunction {
70 mockReturnValueOnce(value: any): MockFunction
71 }
72
74 -// Allow importing jasmine-check
75 -declare module 'jasmine-check' {
76 - export function install(global?: any): void;
77 -}
73 declare var check: any;
74 declare var gen: any;
yarn.lock
-35
@@ -10277,13 +10277,6 @@ isurl@^1.0.0-alpha5:
10277 has-to-string-tag-x "^1.2.0"
10278 is-object "^1.0.1"
10279
10280 -jasmine-check@^1.0.0-rc.0:
10281 - version "1.0.0-rc.0"
10282 - resolved "https://registry.yarnpkg.com/jasmine-check/-/jasmine-check-1.0.0-rc.0.tgz#117728c150078ecf211986c5f164275b71e937a4"
10283 - integrity sha512-V11aKvbAAEN34vVMRQVqylq3j8kw1Hmkf8JOVLYPcVpQX1jZ5pQPTYwbSnjMEjuRp5XQnI0qOqd2yosJoH7Vzw==
10284 - dependencies:
10285 - testcheck "^1.0.0-rc"
10286 -
10280 jed@1.1.1:
10281 version "1.1.1"
10282 resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"
@@ -10469,29 +10462,6 @@ jest-haste-map@^29.4.1:
10462 optionalDependencies:
10463 fsevents "^2.3.2"
10464
10472 -jest-jasmine2@^29.4.1:
10473 - version "29.4.1"
10474 - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-29.4.1.tgz#67fbf2a729889ea390a8aa70ba3582e9d6c32603"
10475 - integrity sha512-fuwfsso6Kc7eGjNCWfWQgW4lcJwdkbfnVx6KQSw2a6a2VBOcxUSn/q8lAwblvJc6hYB7XhGfSVLDw2mvjYDZ0A==
10476 - dependencies:
10477 - "@jest/environment" "^29.4.1"
10478 - "@jest/expect" "^29.4.1"
10479 - "@jest/source-map" "^29.2.0"
10480 - "@jest/test-result" "^29.4.1"
10481 - "@jest/types" "^29.4.1"
10482 - "@types/node" "*"
10483 - chalk "^4.0.0"
10484 - co "^4.6.0"
10485 - is-generator-fn "^2.0.0"
10486 - jest-each "^29.4.1"
10487 - jest-matcher-utils "^29.4.1"
10488 - jest-message-util "^29.4.1"
10489 - jest-runtime "^29.4.1"
10490 - jest-snapshot "^29.4.1"
10491 - jest-util "^29.4.1"
10492 - p-limit "^3.1.0"
10493 - pretty-format "^29.4.1"
10494 -
10465 jest-leak-detector@^29.4.1:
10466 version "29.4.1"
10467 resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz#632186c546e084da2b490b7496fee1a1c9929637"
@@ -16039,11 +16009,6 @@ test-exclude@^6.0.0:
16009 glob "^7.1.4"
16010 minimatch "^3.0.4"
16011
16042 -testcheck@^1.0.0-rc:
16043 - version "1.0.0-rc.2"
16044 - resolved "https://registry.yarnpkg.com/testcheck/-/testcheck-1.0.0-rc.2.tgz#11356a25b84575efe0b0857451e85b5fa74ee4e4"
16045 - integrity sha512-lY0PM4ypOuf3WenJkx/C8+LeLPucHnnRAOtHRQkm8K6pG170tYw0xmxyVjrejJ2bpHWHn5EUkoC+qhnhFAUcvg==
16046 -
16012 text-table@^0.2.0:
16013 version "0.2.0"
16014 resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"