Convert some tests to use assertConsoleErrorDev or just avoid mocking (#30307)
This is mainly so that I can rely on the helpers more for component stack testing.
Sebastian Markbåge committed
Jul 10, 2024 at 16:23 UTC
34dccefeb9302c1f4a39a7bde00eb8b1a6a36bdf
2 files changed
+226
-340
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+219
-330
@@ -1812,83 +1812,59 @@ describe('ReactDOMFizzServer', () => {
1812
);
1813
}
1814
1815
- // We can't use the toErrorDev helper here because this is an async act.
1816
- const originalConsoleError = console.error;
1817
- const mockError = jest.fn();
1818
- console.error = (...args) => {
1819
- mockError(...args.map(normalizeCodeLocInfo));
1820
- };
1821
-
1822
- try {
1823
- await act(() => {
1824
- const {pipe} = renderToPipeableStream(<A />);
1825
- pipe(writable);
1826
- });
1815
+ await act(() => {
1816
+ const {pipe} = renderToPipeableStream(<A />);
1817
+ pipe(writable);
1818
+ });
1819
1828
- expect(getVisibleChildren(container)).toEqual(
1829
- <div>
1830
- <incorrecttag>Loading</incorrecttag>
1831
- </div>,
1832
- );
1820
+ expect(getVisibleChildren(container)).toEqual(
1821
+ <div>
1822
+ <incorrecttag>Loading</incorrecttag>
1823
+ </div>,
1824
+ );
1825
1834
- if (__DEV__) {
1835
- expect(mockError).toHaveBeenCalledWith(
1836
- '<%s /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.%s',
1837
- 'inCorrectTag',
1838
- '\n' +
1839
- (gate(flags => flags.enableOwnerStacks)
1840
- ? ' in inCorrectTag (at **)\n' +
1841
- ' in C (at **)\n' +
1842
- ' in A (at **)'
1843
- : ' in inCorrectTag (at **)\n' +
1844
- ' in C (at **)\n' +
1845
- ' in Suspense (at **)\n' +
1846
- ' in div (at **)\n' +
1847
- ' in A (at **)'),
1848
- );
1849
- mockError.mockClear();
1850
- } else {
1851
- expect(mockError).not.toHaveBeenCalled();
1852
- }
1826
+ assertConsoleErrorDev([
1827
+ '<inCorrectTag /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.' +
1828
+ '\n' +
1829
+ (gate(flags => flags.enableOwnerStacks)
1830
+ ? ' in inCorrectTag (at **)\n' +
1831
+ ' in C (at **)\n' +
1832
+ ' in A (at **)'
1833
+ : ' in inCorrectTag (at **)\n' +
1834
+ ' in C (at **)\n' +
1835
+ ' in Suspense (at **)\n' +
1836
+ ' in div (at **)\n' +
1837
+ ' in A (at **)'),
1838
+ ]);
1839
1854
- await act(() => {
1855
- resolveText('Hello');
1856
- resolveText('World');
1857
- });
1840
+ await act(() => {
1841
+ resolveText('Hello');
1842
+ resolveText('World');
1843
+ });
1844
1859
- if (__DEV__) {
1860
- expect(mockError).toHaveBeenCalledWith(
1861
- 'Each child in a list should have a unique "key" prop.%s%s' +
1862
- ' See https://react.dev/link/warning-keys for more information.%s',
1863
- '\n\nCheck the render method of `B`.',
1864
- '',
1865
- '\n' +
1866
- (gate(flags => flags.enableOwnerStacks)
1867
- ? ' in span (at **)\n' +
1868
- ' in mapper (at **)\n' +
1869
- ' in B (at **)\n' +
1870
- ' in A (at **)'
1871
- : ' in span (at **)\n' +
1872
- ' in B (at **)\n' +
1873
- ' in Suspense (at **)\n' +
1874
- ' in div (at **)\n' +
1875
- ' in A (at **)'),
1876
- );
1877
- } else {
1878
- expect(mockError).not.toHaveBeenCalled();
1879
- }
1845
+ assertConsoleErrorDev([
1846
+ 'Each child in a list should have a unique "key" prop.\n\nCheck the render method of `B`.' +
1847
+ ' See https://react.dev/link/warning-keys for more information.\n' +
1848
+ (gate(flags => flags.enableOwnerStacks)
1849
+ ? ' in span (at **)\n' +
1850
+ ' in mapper (at **)\n' +
1851
+ ' in B (at **)\n' +
1852
+ ' in A (at **)'
1853
+ : ' in span (at **)\n' +
1854
+ ' in B (at **)\n' +
1855
+ ' in Suspense (at **)\n' +
1856
+ ' in div (at **)\n' +
1857
+ ' in A (at **)'),
1858
+ ]);
1859
1881
- expect(getVisibleChildren(container)).toEqual(
1860
+ expect(getVisibleChildren(container)).toEqual(
1861
+ <div>
1862
<div>
1883
- <div>
1884
- <span>Hello</span>
1885
- <span>World</span>
1886
- </div>
1887
- </div>,
1888
- );
1889
- } finally {
1890
- console.error = originalConsoleError;
1891
- }
1863
+ <span>Hello</span>
1864
+ <span>World</span>
1865
+ </div>
1866
+ </div>,
1867
+ );
1868
});
1869
1870
// @gate !disableLegacyContext
@@ -4683,12 +4659,6 @@ describe('ReactDOMFizzServer', () => {
4659
4660
// @gate favorSafetyOverHydrationPerf
4661
it('only warns once on hydration mismatch while within a suspense boundary', async () => {
4686
- const originalConsoleError = console.error;
4687
- const mockError = jest.fn();
4688
- console.error = (...args) => {
4689
- mockError(...args.map(normalizeCodeLocInfo));
4690
- };
4691
-
4662
const App = ({text}) => {
4663
return (
4664
<div>
@@ -4701,45 +4671,40 @@ describe('ReactDOMFizzServer', () => {
4671
);
4672
};
4673
4704
- try {
4705
- await act(() => {
4706
- const {pipe} = renderToPipeableStream(<App text="initial" />);
4707
- pipe(writable);
4708
- });
4674
+ await act(() => {
4675
+ const {pipe} = renderToPipeableStream(<App text="initial" />);
4676
+ pipe(writable);
4677
+ });
4678
4710
- expect(getVisibleChildren(container)).toEqual(
4711
- <div>
4712
- <h2>initial</h2>
4713
- <h2>initial</h2>
4714
- <h2>initial</h2>
4715
- </div>,
4716
- );
4679
+ expect(getVisibleChildren(container)).toEqual(
4680
+ <div>
4681
+ <h2>initial</h2>
4682
+ <h2>initial</h2>
4683
+ <h2>initial</h2>
4684
+ </div>,
4685
+ );
4686
4718
- ReactDOMClient.hydrateRoot(container, <App text="replaced" />, {
4719
- onRecoverableError(error) {
4720
- Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
4721
- if (error.cause) {
4722
- Scheduler.log('Cause: ' + normalizeError(error.cause.message));
4723
- }
4724
- },
4725
- });
4726
- await waitForAll([
4727
- "onRecoverableError: Hydration failed because the server rendered HTML didn't match the client.",
4728
- ]);
4687
+ ReactDOMClient.hydrateRoot(container, <App text="replaced" />, {
4688
+ onRecoverableError(error) {
4689
+ Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
4690
+ if (error.cause) {
4691
+ Scheduler.log('Cause: ' + normalizeError(error.cause.message));
4692
+ }
4693
+ },
4694
+ });
4695
+ await waitForAll([
4696
+ "onRecoverableError: Hydration failed because the server rendered HTML didn't match the client.",
4697
+ ]);
4698
4730
- expect(getVisibleChildren(container)).toEqual(
4731
- <div>
4732
- <h2>replaced</h2>
4733
- <h2>replaced</h2>
4734
- <h2>replaced</h2>
4735
- </div>,
4736
- );
4699
+ expect(getVisibleChildren(container)).toEqual(
4700
+ <div>
4701
+ <h2>replaced</h2>
4702
+ <h2>replaced</h2>
4703
+ <h2>replaced</h2>
4704
+ </div>,
4705
+ );
4706
4738
- await waitForAll([]);
4739
- expect(mockError.mock.calls.length).toBe(0);
4740
- } finally {
4741
- console.error = originalConsoleError;
4742
- }
4707
+ await waitForAll([]);
4708
});
4709
4710
it('supresses hydration warnings when an error occurs within a Suspense boundary', async () => {
@@ -4815,18 +4780,6 @@ describe('ReactDOMFizzServer', () => {
4780
});
4781
4782
it('does not log for errors after the first hydration error', async () => {
4818
- // We can't use the toErrorDev helper here because this is async.
4819
- const originalConsoleError = console.error;
4820
- const mockError = jest.fn();
4821
- console.error = (...args) => {
4822
- if (args.length > 1) {
4823
- if (typeof args[1] === 'object') {
4824
- mockError(args[0].split('\n')[0]);
4825
- return;
4826
- }
4827
- }
4828
- mockError(...args.map(normalizeCodeLocInfo));
4829
- };
4783
let isClient = false;
4784
4785
function ThrowWhenHydrating({children, message}) {
@@ -4864,69 +4817,50 @@ describe('ReactDOMFizzServer', () => {
4817
);
4818
};
4819
4867
- try {
4868
- await act(() => {
4869
- const {pipe} = renderToPipeableStream(<App />);
4870
- pipe(writable);
4871
- });
4820
+ await act(() => {
4821
+ const {pipe} = renderToPipeableStream(<App />);
4822
+ pipe(writable);
4823
+ });
4824
4873
- expect(getVisibleChildren(container)).toEqual(
4874
- <div>
4875
- <h1>one</h1>
4876
- <h2>two</h2>
4877
- <h3>three</h3>
4878
- </div>,
4879
- );
4825
+ expect(getVisibleChildren(container)).toEqual(
4826
+ <div>
4827
+ <h1>one</h1>
4828
+ <h2>two</h2>
4829
+ <h3>three</h3>
4830
+ </div>,
4831
+ );
4832
4881
- isClient = true;
4833
+ isClient = true;
4834
4883
- ReactDOMClient.hydrateRoot(container, <App />, {
4884
- onRecoverableError(error) {
4885
- Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
4886
- if (error.cause) {
4887
- Scheduler.log('Cause: ' + normalizeError(error.cause.message));
4888
- }
4889
- },
4890
- });
4891
- await waitForAll([
4892
- 'throwing: first error',
4835
+ ReactDOMClient.hydrateRoot(container, <App />, {
4836
+ onRecoverableError(error) {
4837
+ Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
4838
+ if (error.cause) {
4839
+ Scheduler.log('Cause: ' + normalizeError(error.cause.message));
4840
+ }
4841
+ },
4842
+ });
4843
+ await waitForAll([
4844
+ 'throwing: first error',
4845
4894
- // onRecoverableError because the UI recovered without surfacing the
4895
- // error to the user.
4896
- 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
4897
- 'Cause: first error',
4898
- ]);
4899
- expect(mockError.mock.calls).toEqual([]);
4900
- mockError.mockClear();
4846
+ // onRecoverableError because the UI recovered without surfacing the
4847
+ // error to the user.
4848
+ 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
4849
+ 'Cause: first error',
4850
+ ]);
4851
4902
- expect(getVisibleChildren(container)).toEqual(
4903
- <div>
4904
- <h1>one</h1>
4905
- <h2>two</h2>
4906
- <h3>three</h3>
4907
- </div>,
4908
- );
4852
+ expect(getVisibleChildren(container)).toEqual(
4853
+ <div>
4854
+ <h1>one</h1>
4855
+ <h2>two</h2>
4856
+ <h3>three</h3>
4857
+ </div>,
4858
+ );
4859
4910
- await waitForAll([]);
4911
- expect(mockError.mock.calls).toEqual([]);
4912
- } finally {
4913
- console.error = originalConsoleError;
4914
- }
4860
+ await waitForAll([]);
4861
});
4862
4863
it('does not log for errors after a preceding fiber suspends', async () => {
4918
- // We can't use the toErrorDev helper here because this is async.
4919
- const originalConsoleError = console.error;
4920
- const mockError = jest.fn();
4921
- console.error = (...args) => {
4922
- if (args.length > 1) {
4923
- if (typeof args[1] === 'object') {
4924
- mockError(args[0].split('\n')[0]);
4925
- return;
4926
- }
4927
- }
4928
- mockError(...args.map(normalizeCodeLocInfo));
4929
- };
4864
let isClient = false;
4865
let promise = null;
4866
let unsuspend = null;
@@ -4984,56 +4918,51 @@ describe('ReactDOMFizzServer', () => {
4918
);
4919
};
4920
4987
- try {
4988
- await act(() => {
4989
- const {pipe} = renderToPipeableStream(<App />);
4990
- pipe(writable);
4991
- });
4921
+ await act(() => {
4922
+ const {pipe} = renderToPipeableStream(<App />);
4923
+ pipe(writable);
4924
+ });
4925
4993
- expect(getVisibleChildren(container)).toEqual(
4994
- <div>
4995
- <h1>one</h1>
4996
- <h2>two</h2>
4997
- <h3>three</h3>
4998
- </div>,
4999
- );
4926
+ expect(getVisibleChildren(container)).toEqual(
4927
+ <div>
4928
+ <h1>one</h1>
4929
+ <h2>two</h2>
4930
+ <h3>three</h3>
4931
+ </div>,
4932
+ );
4933
5001
- isClient = true;
4934
+ isClient = true;
4935
5003
- ReactDOMClient.hydrateRoot(container, <App />, {
5004
- onRecoverableError(error) {
5005
- Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
5006
- if (error.cause) {
5007
- Scheduler.log('Cause: ' + normalizeError(error.cause.message));
5008
- }
5009
- },
5010
- });
5011
- await waitForAll(['suspending']);
5012
- expect(mockError.mock.calls).toEqual([]);
4936
+ ReactDOMClient.hydrateRoot(container, <App />, {
4937
+ onRecoverableError(error) {
4938
+ Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
4939
+ if (error.cause) {
4940
+ Scheduler.log('Cause: ' + normalizeError(error.cause.message));
4941
+ }
4942
+ },
4943
+ });
4944
+ await waitForAll(['suspending']);
4945
5014
- expect(getVisibleChildren(container)).toEqual(
5015
- <div>
5016
- <h1>one</h1>
5017
- <h2>two</h2>
5018
- <h3>three</h3>
5019
- </div>,
5020
- );
5021
- await unsuspend();
5022
- await waitForAll([
5023
- 'throwing: first error',
5024
- 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
5025
- 'Cause: first error',
5026
- ]);
5027
- expect(getVisibleChildren(container)).toEqual(
5028
- <div>
5029
- <h1>one</h1>
5030
- <h2>two</h2>
5031
- <h3>three</h3>
5032
- </div>,
5033
- );
5034
- } finally {
5035
- console.error = originalConsoleError;
5036
- }
4946
+ expect(getVisibleChildren(container)).toEqual(
4947
+ <div>
4948
+ <h1>one</h1>
4949
+ <h2>two</h2>
4950
+ <h3>three</h3>
4951
+ </div>,
4952
+ );
4953
+ await unsuspend();
4954
+ await waitForAll([
4955
+ 'throwing: first error',
4956
+ 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
4957
+ 'Cause: first error',
4958
+ ]);
4959
+ expect(getVisibleChildren(container)).toEqual(
4960
+ <div>
4961
+ <h1>one</h1>
4962
+ <h2>two</h2>
4963
+ <h3>three</h3>
4964
+ </div>,
4965
+ );
4966
});
4967
4968
it('(outdated behavior) suspending after erroring will cause errors previously queued to be silenced until the boundary resolves', async () => {
@@ -5042,18 +4971,6 @@ describe('ReactDOMFizzServer', () => {
4971
// stack and revert to client rendering. I've kept the test around just to
4972
// demonstrate what actually happens in this sequence of events.
4973
5045
- // We can't use the toErrorDev helper here because this is async.
5046
- const originalConsoleError = console.error;
5047
- const mockError = jest.fn();
5048
- console.error = (...args) => {
5049
- if (args.length > 1) {
5050
- if (typeof args[1] === 'object') {
5051
- mockError(args[0].split('\n')[0]);
5052
- return;
5053
- }
5054
- }
5055
- mockError(...args.map(normalizeCodeLocInfo));
5056
- };
4974
let isClient = false;
4975
let promise = null;
4976
let unsuspend = null;
@@ -5111,60 +5028,53 @@ describe('ReactDOMFizzServer', () => {
5028
);
5029
};
5030
5114
- try {
5115
- await act(() => {
5116
- const {pipe} = renderToPipeableStream(<App />);
5117
- pipe(writable);
5118
- });
5031
+ await act(() => {
5032
+ const {pipe} = renderToPipeableStream(<App />);
5033
+ pipe(writable);
5034
+ });
5035
5120
- expect(getVisibleChildren(container)).toEqual(
5121
- <div>
5122
- <h1>one</h1>
5123
- <h2>two</h2>
5124
- <h3>three</h3>
5125
- </div>,
5126
- );
5036
+ expect(getVisibleChildren(container)).toEqual(
5037
+ <div>
5038
+ <h1>one</h1>
5039
+ <h2>two</h2>
5040
+ <h3>three</h3>
5041
+ </div>,
5042
+ );
5043
5128
- isClient = true;
5044
+ isClient = true;
5045
5130
- ReactDOMClient.hydrateRoot(container, <App />, {
5131
- onRecoverableError(error) {
5132
- Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
5133
- if (error.cause) {
5134
- Scheduler.log('Cause: ' + normalizeError(error.cause.message));
5135
- }
5136
- },
5137
- });
5138
- await waitForAll([
5139
- 'throwing: first error',
5140
- 'suspending',
5141
- 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
5142
- 'Cause: first error',
5143
- ]);
5144
- expect(mockError.mock.calls).toEqual([]);
5145
- mockError.mockClear();
5046
+ ReactDOMClient.hydrateRoot(container, <App />, {
5047
+ onRecoverableError(error) {
5048
+ Scheduler.log('onRecoverableError: ' + normalizeError(error.message));
5049
+ if (error.cause) {
5050
+ Scheduler.log('Cause: ' + normalizeError(error.cause.message));
5051
+ }
5052
+ },
5053
+ });
5054
+ await waitForAll([
5055
+ 'throwing: first error',
5056
+ 'suspending',
5057
+ 'onRecoverableError: There was an error while hydrating but React was able to recover by instead client rendering from the nearest Suspense boundary.',
5058
+ 'Cause: first error',
5059
+ ]);
5060
5147
- expect(getVisibleChildren(container)).toEqual(
5148
- <div>
5149
- <h1>Loading...</h1>
5150
- </div>,
5151
- );
5152
- await clientAct(() => unsuspend());
5153
- // Since our client components only throw on the very first render there are no
5154
- // new throws in this pass
5155
- assertLog([]);
5156
- expect(mockError.mock.calls).toEqual([]);
5061
+ expect(getVisibleChildren(container)).toEqual(
5062
+ <div>
5063
+ <h1>Loading...</h1>
5064
+ </div>,
5065
+ );
5066
+ await clientAct(() => unsuspend());
5067
+ // Since our client components only throw on the very first render there are no
5068
+ // new throws in this pass
5069
+ assertLog([]);
5070
5158
- expect(getVisibleChildren(container)).toEqual(
5159
- <div>
5160
- <h1>one</h1>
5161
- <h2>two</h2>
5162
- <h3>three</h3>
5163
- </div>,
5164
- );
5165
- } finally {
5166
- console.error = originalConsoleError;
5167
- }
5071
+ expect(getVisibleChildren(container)).toEqual(
5072
+ <div>
5073
+ <h1>one</h1>
5074
+ <h2>two</h2>
5075
+ <h3>three</h3>
5076
+ </div>,
5077
+ );
5078
});
5079
5080
it('#24578 Hydration errors caused by a suspending component should not become recoverable when nested in an ancestor Suspense that is showing primary content', async () => {
@@ -6541,11 +6451,6 @@ describe('ReactDOMFizzServer', () => {
6451
function MyScript() {
6452
return 'bar();';
6453
}
6544
- const originalConsoleError = console.error;
6545
- const mockError = jest.fn();
6546
- console.error = (...args) => {
6547
- mockError(...args.map(normalizeCodeLocInfo));
6548
- };
6454
6455
function App() {
6456
return (
@@ -6563,47 +6468,31 @@ describe('ReactDOMFizzServer', () => {
6468
);
6469
}
6470
6566
- try {
6567
- await act(async () => {
6568
- const {pipe} = renderToPipeableStream(<App />);
6569
- pipe(writable);
6570
- });
6471
+ await act(async () => {
6472
+ const {pipe} = renderToPipeableStream(<App />);
6473
+ pipe(writable);
6474
+ });
6475
6572
- if (__DEV__) {
6573
- expect(mockError.mock.calls.length).toBe(3);
6574
- expect(mockError.mock.calls[0]).toEqual([
6575
- 'A script element was rendered with %s. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.%s',
6576
- 'a number for children',
6577
- componentStack(
6578
- gate(flags => flags.enableOwnerStacks)
6579
- ? ['script', 'App']
6580
- : ['script', 'body', 'html', 'App'],
6581
- ),
6582
- ]);
6583
- expect(mockError.mock.calls[1]).toEqual([
6584
- 'A script element was rendered with %s. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.%s',
6585
- 'an array for children',
6586
- componentStack(
6587
- gate(flags => flags.enableOwnerStacks)
6588
- ? ['script', 'App']
6589
- : ['script', 'body', 'html', 'App'],
6590
- ),
6591
- ]);
6592
- expect(mockError.mock.calls[2]).toEqual([
6593
- 'A script element was rendered with %s. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.%s',
6594
- 'something unexpected for children',
6595
- componentStack(
6596
- gate(flags => flags.enableOwnerStacks)
6597
- ? ['script', 'App']
6598
- : ['script', 'body', 'html', 'App'],
6599
- ),
6600
- ]);
6601
- } else {
6602
- expect(mockError.mock.calls.length).toBe(0);
6603
- }
6604
- } finally {
6605
- console.error = originalConsoleError;
6606
- }
6476
+ assertConsoleErrorDev([
6477
+ 'A script element was rendered with a number for children. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.' +
6478
+ componentStack(
6479
+ gate(flags => flags.enableOwnerStacks)
6480
+ ? ['script', 'App']
6481
+ : ['script', 'body', 'html', 'App'],
6482
+ ),
6483
+ 'A script element was rendered with an array for children. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.' +
6484
+ componentStack(
6485
+ gate(flags => flags.enableOwnerStacks)
6486
+ ? ['script', 'App']
6487
+ : ['script', 'body', 'html', 'App'],
6488
+ ),
6489
+ 'A script element was rendered with something unexpected for children. If script element has children it must be a single string. Consider using dangerouslySetInnerHTML or passing a plain string as children.' +
6490
+ componentStack(
6491
+ gate(flags => flags.enableOwnerStacks)
6492
+ ? ['script', 'App']
6493
+ : ['script', 'body', 'html', 'App'],
6494
+ ),
6495
+ ]);
6496
});
6497
6498
// @gate enablePostpone
packages/react-reconciler/src/__tests__/ReactFlushSync-test.js
+7
-10
@@ -7,6 +7,7 @@ let useState;
7
let useEffect;
8
let startTransition;
9
let assertLog;
10
+let assertConsoleErrorDev;
11
let waitForPaint;
12
13
// TODO: Migrate tests to React DOM instead of React Noop
@@ -26,6 +27,7 @@ describe('ReactFlushSync', () => {
27
28
const InternalTestUtils = require('internal-test-utils');
29
assertLog = InternalTestUtils.assertLog;
30
+ assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
31
waitForPaint = InternalTestUtils.waitForPaint;
32
});
33
@@ -77,8 +79,6 @@ describe('ReactFlushSync', () => {
79
}
80
81
it('changes priority of updates in useEffect', async () => {
80
- spyOnDev(console, 'error').mockImplementation(() => {});
81
-
82
function App() {
83
const [syncState, setSyncState] = useState(0);
84
const [state, setState] = useState(0);
@@ -107,18 +107,15 @@ describe('ReactFlushSync', () => {
107
// The remaining update is not sync
108
ReactDOM.flushSync();
109
assertLog([]);
110
+ assertConsoleErrorDev([
111
+ 'flushSync was called from inside a lifecycle method. React ' +
112
+ 'cannot flush when React is already rendering. Consider moving this ' +
113
+ 'call to a scheduler task or micro task.',
114
+ ]);
115
116
await waitForPaint([]);
117
});
118
expect(getVisibleChildren(container)).toEqual('1, 1');
114
-
115
- if (__DEV__) {
116
- expect(console.error.mock.calls[0][0]).toContain(
117
- 'flushSync was called from inside a lifecycle method. React ' +
118
- 'cannot flush when React is already rendering. Consider moving this ' +
119
- 'call to a scheduler task or micro task.%s',
120
- );
121
- }
119
});
120
121
it('supports nested flushSync with startTransition', async () => {