@samitouri / QOS-React-2 / commits / 8e25ed20bd

Unify noop and test renderer assertion APIs (#14952)

* Throw in tests if work is done before emptying log Test renderer already does this. Makes it harder to miss unexpected behavior by forcing you to assert on every logged value. * Convert ReactNoop tests to use jest matchers The matchers warn if work is flushed while the log is empty. This is the pattern we already follow for test renderer. I've used the same APIs as test renderer, so it should be easy to switch between the two.

Andrew Clark committed Feb 25, 2019 at 19:01 UTC 8e25ed20bd27d126f670d04680db85209f779056
30 files changed +1072 -1004
packages/create-subscription/src/__tests__/createSubscription-test.internal.js
+28 -28
@@ -65,16 +65,16 @@ describe('createSubscription', () => {
65 );
66
67 // Updates while subscribed should re-render the child component
68 - expect(ReactNoop.flush()).toEqual(['default']);
68 + expect(ReactNoop).toFlushAndYield(['default']);
69 observable.next(123);
70 - expect(ReactNoop.flush()).toEqual([123]);
70 + expect(ReactNoop).toFlushAndYield([123]);
71 observable.next('abc');
72 - expect(ReactNoop.flush()).toEqual(['abc']);
72 + expect(ReactNoop).toFlushAndYield(['abc']);
73
74 // Unmounting the subscriber should remove listeners
75 ReactNoop.render(<div />);
76 observable.next(456);
77 - expect(ReactNoop.flush()).toEqual([]);
77 + expect(ReactNoop).toFlushAndYield([]);
78 });
79
80 it('should support observable types like RxJS ReplaySubject', () => {
@@ -102,13 +102,13 @@ describe('createSubscription', () => {
102 const observable = createReplaySubject('initial');
103
104 ReactNoop.render(<Subscription source={observable}>{render}</Subscription>);
105 - expect(ReactNoop.flush()).toEqual(['initial']);
105 + expect(ReactNoop).toFlushAndYield(['initial']);
106 observable.next('updated');
107 - expect(ReactNoop.flush()).toEqual(['updated']);
107 + expect(ReactNoop).toFlushAndYield(['updated']);
108
109 // Unsetting the subscriber prop should reset subscribed values
110 ReactNoop.render(<Subscription>{render}</Subscription>);
111 - expect(ReactNoop.flush()).toEqual(['default']);
111 + expect(ReactNoop).toFlushAndYield(['default']);
112 });
113
114 describe('Promises', () => {
@@ -141,19 +141,19 @@ describe('createSubscription', () => {
141
142 // Test a promise that resolves after render
143 ReactNoop.render(<Subscription source={promiseA}>{render}</Subscription>);
144 - expect(ReactNoop.flush()).toEqual(['loading']);
144 + expect(ReactNoop).toFlushAndYield(['loading']);
145 resolveA(true);
146 await promiseA;
147 - expect(ReactNoop.flush()).toEqual(['finished']);
147 + expect(ReactNoop).toFlushAndYield(['finished']);
148
149 // Test a promise that resolves before render
150 // Note that this will require an extra render anyway,
151 // Because there is no way to synchronously get a Promise's value
152 rejectB(false);
153 ReactNoop.render(<Subscription source={promiseB}>{render}</Subscription>);
154 - expect(ReactNoop.flush()).toEqual(['loading']);
154 + expect(ReactNoop).toFlushAndYield(['loading']);
155 await promiseB.catch(() => true);
156 - expect(ReactNoop.flush()).toEqual(['failed']);
156 + expect(ReactNoop).toFlushAndYield(['failed']);
157 });
158
159 it('should still work if unsubscription is managed incorrectly', async () => {
@@ -177,9 +177,9 @@ describe('createSubscription', () => {
177
178 // Subscribe first to Promise A then Promise B
179 ReactNoop.render(<Subscription source={promiseA}>{render}</Subscription>);
180 - expect(ReactNoop.flush()).toEqual(['default']);
180 + expect(ReactNoop).toFlushAndYield(['default']);
181 ReactNoop.render(<Subscription source={promiseB}>{render}</Subscription>);
182 - expect(ReactNoop.flush()).toEqual(['default']);
182 + expect(ReactNoop).toFlushAndYield(['default']);
183
184 // Resolve both Promises
185 resolveB(123);
@@ -187,7 +187,7 @@ describe('createSubscription', () => {
187 await Promise.all([promiseA, promiseB]);
188
189 // Ensure that only Promise B causes an update
190 - expect(ReactNoop.flush()).toEqual([123]);
190 + expect(ReactNoop).toFlushAndYield([123]);
191 });
192
193 it('should not call setState for a Promise that resolves after unmount', async () => {
@@ -211,11 +211,11 @@ describe('createSubscription', () => {
211 });
212
213 ReactNoop.render(<Subscription source={promise}>{render}</Subscription>);
214 - expect(ReactNoop.flush()).toEqual(['rendered']);
214 + expect(ReactNoop).toFlushAndYield(['rendered']);
215
216 // Unmount
217 ReactNoop.render(null);
218 - ReactNoop.flush();
218 + expect(ReactNoop).toFlushWithoutYielding();
219
220 // Resolve Promise should not trigger a setState warning
221 resolvePromise(true);
@@ -245,21 +245,21 @@ describe('createSubscription', () => {
245 );
246
247 // Updates while subscribed should re-render the child component
248 - expect(ReactNoop.flush()).toEqual(['a-0']);
248 + expect(ReactNoop).toFlushAndYield(['a-0']);
249
250 // Unsetting the subscriber prop should reset subscribed values
251 ReactNoop.render(
252 <Subscription source={observableB}>{render}</Subscription>,
253 );
254 - expect(ReactNoop.flush()).toEqual(['b-0']);
254 + expect(ReactNoop).toFlushAndYield(['b-0']);
255
256 // Updates to the old subscribable should not re-render the child component
257 observableA.next('a-1');
258 - expect(ReactNoop.flush()).toEqual([]);
258 + expect(ReactNoop).toFlushAndYield([]);
259
260 // Updates to the bew subscribable should re-render the child component
261 observableB.next('b-1');
262 - expect(ReactNoop.flush()).toEqual(['b-1']);
262 + expect(ReactNoop).toFlushAndYield(['b-1']);
263 });
264
265 it('should ignore values emitted by a new subscribable until the commit phase', () => {
@@ -315,12 +315,12 @@ describe('createSubscription', () => {
315 const observableB = createBehaviorSubject('b-0');
316
317 ReactNoop.render(<Parent observed={observableA} />);
318 - expect(ReactNoop.flush()).toEqual(['Subscriber: a-0', 'Child: a-0']);
318 + expect(ReactNoop).toFlushAndYield(['Subscriber: a-0', 'Child: a-0']);
319 expect(log).toEqual(['Parent.componentDidMount']);
320
321 // Start React update, but don't finish
322 ReactNoop.render(<Parent observed={observableB} />);
323 - ReactNoop.flushThrough(['Subscriber: b-0']);
323 + expect(ReactNoop).toFlushAndYieldThrough(['Subscriber: b-0']);
324 expect(log).toEqual(['Parent.componentDidMount']);
325
326 // Emit some updates from the uncommitted subscribable
@@ -335,7 +335,7 @@ describe('createSubscription', () => {
335 // We expect the last emitted update to be rendered (because of the commit phase value check)
336 // But the intermediate ones should be ignored,
337 // And the final rendered output should be the higher-priority observable.
338 - expect(ReactNoop.flush()).toEqual([
338 + expect(ReactNoop).toFlushAndYield([
339 'Child: b-0',
340 'Subscriber: b-3',
341 'Child: b-3',
@@ -402,12 +402,12 @@ describe('createSubscription', () => {
402 const observableB = createBehaviorSubject('b-0');
403
404 ReactNoop.render(<Parent observed={observableA} />);
405 - expect(ReactNoop.flush()).toEqual(['Subscriber: a-0', 'Child: a-0']);
405 + expect(ReactNoop).toFlushAndYield(['Subscriber: a-0', 'Child: a-0']);
406 expect(log).toEqual(['Parent.componentDidMount']);
407
408 // Start React update, but don't finish
409 ReactNoop.render(<Parent observed={observableB} />);
410 - ReactNoop.flushThrough(['Subscriber: b-0']);
410 + expect(ReactNoop).toFlushAndYieldThrough(['Subscriber: b-0']);
411 expect(log).toEqual(['Parent.componentDidMount']);
412
413 // Emit some updates from the old subscribable
@@ -420,7 +420,7 @@ describe('createSubscription', () => {
420 // Flush everything and ensure that the correct subscribable is used
421 // We expect the new subscribable to finish rendering,
422 // But then the updated values from the old subscribable should be used.
423 - expect(ReactNoop.flush()).toEqual([
423 + expect(ReactNoop).toFlushAndYield([
424 'Child: b-0',
425 'Subscriber: a-2',
426 'Child: a-2',
@@ -433,7 +433,7 @@ describe('createSubscription', () => {
433
434 // Updates from the new subscribable should be ignored.
435 observableB.next('b-1');
436 - expect(ReactNoop.flush()).toEqual([]);
436 + expect(ReactNoop).toFlushAndYield([]);
437 expect(log).toEqual([
438 'Parent.componentDidMount',
439 'Parent.componentDidUpdate',
@@ -479,7 +479,7 @@ describe('createSubscription', () => {
479 <Subscription source={observable}>{value => null}</Subscription>,
480 );
481
482 - expect(ReactNoop.flush).toThrow(
482 + expect(ReactNoop).toFlushAndThrow(
483 'A subscription must return an unsubscribe function.',
484 );
485 });
packages/react-art/src/__tests__/ReactART-test.js
+2 -2
@@ -385,7 +385,7 @@ describe('ReactART', () => {
385 </CurrentRendererContext.Provider>,
386 );
387
388 - ReactNoop.flushThrough(['A']);
388 + expect(ReactNoop).toFlushAndYieldThrough(['A']);
389
390 ReactDOM.render(
391 <Surface>
@@ -400,7 +400,7 @@ describe('ReactART', () => {
400 expect(ops).toEqual([null, 'ART']);
401
402 ops = [];
403 - expect(ReactNoop.flush()).toEqual(['B', 'C']);
403 + expect(ReactNoop).toFlushAndYield(['B', 'C']);
404
405 expect(ops).toEqual(['Test']);
406 });
packages/react-noop-renderer/src/createReactNoop.js
+51 -92
@@ -534,55 +534,71 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
534 const roots = new Map();
535 const DEFAULT_ROOT_ID = '<default>';
536
537 - let yieldedValues = null;
538 -
539 - let didYield;
540 - let unitsRemaining;
537 + let yieldedValues: Array<mixed> = [];
538 + let didStop: boolean = false;
539 + let expectedNumberOfYields: number = -1;
540
541 function shouldYield() {
543 - // Check if we already yielded
544 - if (didYield || yieldedValues !== null) {
545 - return true;
546 - }
547 -
548 - // If there are no remaining units of work, and we haven't timed out, then
549 - // we should yield.
542 if (
551 - unitsRemaining-- <= 0 &&
543 + expectedNumberOfYields !== -1 &&
544 + yieldedValues.length >= expectedNumberOfYields &&
545 (scheduledCallbackTimeout === -1 ||
546 elapsedTimeInMs < scheduledCallbackTimeout)
547 ) {
555 - didYield = true;
548 + // We yielded at least as many values as expected. Stop rendering.
549 + didStop = true;
550 return true;
551 }
558 -
559 - // Otherwise, keep working.
552 + // Keep rendering.
553 return false;
554 }
555
563 - function* flushUnitsOfWork(n: number): Generator<Array<mixed>, void, void> {
564 - unitsRemaining = n;
565 - didYield = false;
556 + function flushAll(): Array<mixed> {
557 + yieldedValues = [];
558 + while (scheduledCallback !== null) {
559 + const cb = scheduledCallback;
560 + scheduledCallback = null;
561 + const didTimeout =
562 + scheduledCallbackTimeout !== -1 &&
563 + scheduledCallbackTimeout < elapsedTimeInMs;
564 + cb(didTimeout);
565 + }
566 + const values = yieldedValues;
567 + yieldedValues = [];
568 + return values;
569 + }
570 +
571 + function flushNumberOfYields(count: number): Array<mixed> {
572 + expectedNumberOfYields = count;
573 + didStop = false;
574 + yieldedValues = [];
575 try {
567 - while (!didYield && scheduledCallback !== null) {
568 - let cb = scheduledCallback;
576 + while (scheduledCallback !== null && !didStop) {
577 + const cb = scheduledCallback;
578 scheduledCallback = null;
579 const didTimeout =
580 scheduledCallbackTimeout !== -1 &&
581 scheduledCallbackTimeout < elapsedTimeInMs;
582 cb(didTimeout);
574 - if (yieldedValues !== null) {
575 - const values = yieldedValues;
576 - yieldedValues = null;
577 - yield values;
578 - }
583 }
584 + return yieldedValues;
585 } finally {
581 - unitsRemaining = -1;
582 - didYield = false;
586 + expectedNumberOfYields = -1;
587 + didStop = false;
588 + yieldedValues = [];
589 }
590 }
591
592 + function yieldValue(value: mixed): void {
593 + yieldedValues.push(value);
594 + }
595 +
596 + function clearYields(): Array<mixed> {
597 + const values = yieldedValues;
598 + yieldedValues = [];
599 + return values;
600 + }
601 +
602 function childToJSX(child, text) {
603 if (text !== null) {
604 return text;
@@ -747,53 +763,14 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
763 return NoopRenderer.findHostInstance(component);
764 },
765
750 - flush(): Array<mixed> {
751 - let values = yieldedValues || [];
752 - yieldedValues = null;
753 - // eslint-disable-next-line no-for-of-loops/no-for-of-loops
754 - for (const value of flushUnitsOfWork(Infinity)) {
755 - values.push(...value);
756 - }
757 - return values;
758 - },
759 -
766 // TODO: Should only be used via a Jest plugin (like we do with the
767 // test renderer).
762 - unstable_flushNumberOfYields(n: number): Array<mixed> {
763 - let values = yieldedValues || [];
764 - yieldedValues = null;
765 - // eslint-disable-next-line no-for-of-loops/no-for-of-loops
766 - for (const value of flushUnitsOfWork(Infinity)) {
767 - values.push(...value);
768 - if (values.length >= n) {
769 - break;
770 - }
771 - }
772 - return values;
773 - },
774 -
775 - flushThrough(expected: Array<mixed>): void {
776 - let actual = [];
777 - if (expected.length !== 0) {
778 - // eslint-disable-next-line no-for-of-loops/no-for-of-loops
779 - for (const value of flushUnitsOfWork(Infinity)) {
780 - actual.push(...value);
781 - if (actual.length >= expected.length) {
782 - break;
783 - }
784 - }
785 - }
786 - expect(actual).toEqual(expected);
787 - },
768 + unstable_flushWithoutYielding: flushAll,
769 + unstable_flushNumberOfYields: flushNumberOfYields,
770 + unstable_clearYields: clearYields,
771
772 flushNextYield(): Array<mixed> {
790 - let actual = null;
791 - // eslint-disable-next-line no-for-of-loops/no-for-of-loops
792 - for (const value of flushUnitsOfWork(Infinity)) {
793 - actual = value;
794 - break;
795 - }
796 - return actual !== null ? actual : [];
773 + return flushNumberOfYields(1);
774 },
775
776 flushWithHostCounters(
@@ -811,7 +788,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
788 hostUpdateCounter = 0;
789 hostCloneCounter = 0;
790 try {
814 - ReactNoop.flush();
791 + flushAll();
792 return useMutation
793 ? {
794 hostDiffCounter,
@@ -838,28 +815,10 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
815 },
816
817 flushExpired(): Array<mixed> {
841 - let values = yieldedValues || [];
842 - yieldedValues = null;
843 - // eslint-disable-next-line no-for-of-loops/no-for-of-loops
844 - for (const value of flushUnitsOfWork(0)) {
845 - values.push(...value);
846 - }
847 - return values;
848 - },
849 -
850 - yield(value: mixed) {
851 - if (yieldedValues === null) {
852 - yieldedValues = [value];
853 - } else {
854 - yieldedValues.push(value);
855 - }
818 + return flushNumberOfYields(0);
819 },
820
858 - clearYields() {
859 - const values = yieldedValues;
860 - yieldedValues = null;
861 - return values;
862 - },
821 + yield: yieldValue,
822
823 hasScheduledCallback() {
824 return !!scheduledCallback;
@@ -1038,7 +997,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
997 _next: null,
998 };
999 root.firstBatch = batch;
1041 - const actual = ReactNoop.flush();
1000 + const actual = flushAll();
1001 expect(actual).toEqual(expectedFlush);
1002 return (expectedCommit: Array<mixed>) => {
1003 batch._defer = false;
packages/react-reconciler/src/__tests__/ReactExpiration-test.internal.js
+15 -9
@@ -73,7 +73,7 @@ describe('ReactExpiration', () => {
73 ReactNoop.render(<Text text="B" />);
74 // The updates should flush in separate batches, since sufficient time
75 // passed in between them *and* they occurred in separate events.
76 - expect(ReactNoop.flush()).toEqual([
76 + expect(ReactNoop).toFlushAndYield([
77 'A [render]',
78 'A [commit]',
79 'B [render]',
@@ -88,13 +88,13 @@ describe('ReactExpiration', () => {
88 // haven't entered an idle callback, the scheduler must assume that we're
89 // inside the same event.
90 ReactNoop.advanceTime(2000);
91 - expect(ReactNoop.clearYields()).toEqual(null);
91 + expect(ReactNoop).toHaveYielded([]);
92 expect(ReactNoop.getChildren()).toEqual([span('B')]);
93 // Schedule another update.
94 ReactNoop.render(<Text text="B" />);
95 // The updates should flush in the same batch, since as far as the scheduler
96 // knows, they may have occurred inside the same event.
97 - expect(ReactNoop.flush()).toEqual(['B [render]', 'B [commit]']);
97 + expect(ReactNoop).toFlushAndYield(['B [render]', 'B [commit]']);
98 });
99
100 it(
@@ -127,7 +127,7 @@ describe('ReactExpiration', () => {
127 ReactNoop.render(<Text text="B" />);
128 // The updates should flush in separate batches, since sufficient time
129 // passed in between them *and* they occurred in separate events.
130 - expect(ReactNoop.flush()).toEqual([
130 + expect(ReactNoop).toFlushAndYield([
131 'A [render]',
132 'A [commit]',
133 'B [render]',
@@ -142,7 +142,7 @@ describe('ReactExpiration', () => {
142 // haven't entered an idle callback, the scheduler must assume that we're
143 // inside the same event.
144 ReactNoop.advanceTime(2000);
145 - expect(ReactNoop.clearYields()).toEqual(null);
145 + expect(ReactNoop).toHaveYielded([]);
146 expect(ReactNoop.getChildren()).toEqual([span('B')]);
147
148 // Perform some synchronous work. Again, the scheduler must assume we're
@@ -156,7 +156,7 @@ describe('ReactExpiration', () => {
156 ReactNoop.render(<Text text="B" />);
157 // The updates should flush in the same batch, since as far as the scheduler
158 // knows, they may have occurred inside the same event.
159 - expect(ReactNoop.flush()).toEqual(['B [render]', 'B [commit]']);
159 + expect(ReactNoop).toFlushAndYield(['B [render]', 'B [commit]']);
160 },
161 );
162
@@ -191,7 +191,7 @@ describe('ReactExpiration', () => {
191
192 // Initial mount
193 ReactNoop.render(<App />);
194 - expect(ReactNoop.flush()).toEqual([
194 + expect(ReactNoop).toFlushAndYield([
195 'initial [A] [render]',
196 'initial [B] [render]',
197 'initial [C] [render]',
@@ -204,12 +204,18 @@ describe('ReactExpiration', () => {
204
205 // Partial update
206 subscribers.forEach(s => s.setState({text: '1'}));
207 - ReactNoop.flushThrough(['1 [A] [render]', '1 [B] [render]']);
207 + expect(ReactNoop).toFlushAndYieldThrough([
208 + '1 [A] [render]',
209 + '1 [B] [render]',
210 + ]);
211
212 // Before the update can finish, update again. Even though no time has
213 // advanced, this update should be given a different expiration time than
214 // the currently rendering one. So, C and D should render with 1, not 2.
215 subscribers.forEach(s => s.setState({text: '2'}));
213 - ReactNoop.flushThrough(['1 [C] [render]', '1 [D] [render]']);
216 + expect(ReactNoop).toFlushAndYieldThrough([
217 + '1 [C] [render]',
218 + '1 [D] [render]',
219 + ]);
220 });
221 });
packages/react-reconciler/src/__tests__/ReactFragment-test.js
+52 -52
@@ -43,7 +43,7 @@ describe('ReactFragment', () => {
43 );
44
45 ReactNoop.render(element);
46 - ReactNoop.flush();
46 + expect(ReactNoop).toFlushWithoutYielding();
47
48 expect(ReactNoop.getChildren()).toEqual([span()]);
49 });
@@ -52,7 +52,7 @@ describe('ReactFragment', () => {
52 const element = <React.Fragment />;
53
54 ReactNoop.render(element);
55 - ReactNoop.flush();
55 + expect(ReactNoop).toFlushWithoutYielding();
56
57 expect(ReactNoop.getChildren()).toEqual([]);
58 });
@@ -65,7 +65,7 @@ describe('ReactFragment', () => {
65 );
66
67 ReactNoop.render(element);
68 - ReactNoop.flush();
68 + expect(ReactNoop).toFlushWithoutYielding();
69
70 expect(ReactNoop.getChildren()).toEqual([text('hello '), span()]);
71 });
@@ -78,7 +78,7 @@ describe('ReactFragment', () => {
78 );
79
80 ReactNoop.render(element);
81 - ReactNoop.flush();
81 + expect(ReactNoop).toFlushWithoutYielding();
82
83 expect(ReactNoop.getChildren()).toEqual([span(), span()]);
84 });
@@ -108,16 +108,16 @@ describe('ReactFragment', () => {
108 }
109
110 ReactNoop.render(<Foo condition={true} />);
111 - ReactNoop.flush();
111 + expect(ReactNoop).toFlushWithoutYielding();
112
113 ReactNoop.render(<Foo condition={false} />);
114 - ReactNoop.flush();
114 + expect(ReactNoop).toFlushWithoutYielding();
115
116 expect(ops).toEqual(['Update Stateful']);
117 expect(ReactNoop.getChildren()).toEqual([div(), div()]);
118
119 ReactNoop.render(<Foo condition={true} />);
120 - ReactNoop.flush();
120 + expect(ReactNoop).toFlushWithoutYielding();
121
122 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
123 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -149,16 +149,16 @@ describe('ReactFragment', () => {
149 }
150
151 ReactNoop.render(<Foo condition={true} />);
152 - ReactNoop.flush();
152 + expect(ReactNoop).toFlushWithoutYielding();
153
154 ReactNoop.render(<Foo condition={false} />);
155 - ReactNoop.flush();
155 + expect(ReactNoop).toFlushWithoutYielding();
156
157 expect(ops).toEqual(['Update Stateful']);
158 expect(ReactNoop.getChildren()).toEqual([div()]);
159
160 ReactNoop.render(<Foo condition={true} />);
161 - ReactNoop.flush();
161 + expect(ReactNoop).toFlushWithoutYielding();
162
163 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
164 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -199,16 +199,16 @@ describe('ReactFragment', () => {
199 }
200
201 ReactNoop.render(<Foo condition={true} />);
202 - ReactNoop.flush();
202 + expect(ReactNoop).toFlushWithoutYielding();
203
204 ReactNoop.render(<Foo condition={false} />);
205 - ReactNoop.flush();
205 + expect(ReactNoop).toFlushWithoutYielding();
206
207 expect(ops).toEqual(['Update Stateful']);
208 expect(ReactNoop.getChildren()).toEqual([div(), div()]);
209
210 ReactNoop.render(<Foo condition={true} />);
211 - ReactNoop.flush();
211 + expect(ReactNoop).toFlushWithoutYielding();
212
213 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
214 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -242,16 +242,16 @@ describe('ReactFragment', () => {
242 }
243
244 ReactNoop.render(<Foo condition={true} />);
245 - ReactNoop.flush();
245 + expect(ReactNoop).toFlushWithoutYielding();
246
247 ReactNoop.render(<Foo condition={false} />);
248 - ReactNoop.flush();
248 + expect(ReactNoop).toFlushWithoutYielding();
249
250 expect(ops).toEqual([]);
251 expect(ReactNoop.getChildren()).toEqual([div()]);
252
253 ReactNoop.render(<Foo condition={true} />);
254 - ReactNoop.flush();
254 + expect(ReactNoop).toFlushWithoutYielding();
255
256 expect(ops).toEqual([]);
257 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -283,16 +283,16 @@ describe('ReactFragment', () => {
283 }
284
285 ReactNoop.render(<Foo condition={true} />);
286 - ReactNoop.flush();
286 + expect(ReactNoop).toFlushWithoutYielding();
287
288 ReactNoop.render(<Foo condition={false} />);
289 - ReactNoop.flush();
289 + expect(ReactNoop).toFlushWithoutYielding();
290
291 expect(ops).toEqual([]);
292 expect(ReactNoop.getChildren()).toEqual([div()]);
293
294 ReactNoop.render(<Foo condition={true} />);
295 - ReactNoop.flush();
295 + expect(ReactNoop).toFlushWithoutYielding();
296
297 expect(ops).toEqual([]);
298 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -325,16 +325,16 @@ describe('ReactFragment', () => {
325 }
326
327 ReactNoop.render(<Foo condition={true} />);
328 - ReactNoop.flush();
328 + expect(ReactNoop).toFlushWithoutYielding();
329
330 ReactNoop.render(<Foo condition={false} />);
331 - ReactNoop.flush();
331 + expect(ReactNoop).toFlushWithoutYielding();
332
333 expect(ops).toEqual([]);
334 expect(ReactNoop.getChildren()).toEqual([div(), div()]);
335
336 ReactNoop.render(<Foo condition={true} />);
337 - ReactNoop.flush();
337 + expect(ReactNoop).toFlushWithoutYielding();
338
339 expect(ops).toEqual([]);
340 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -364,16 +364,16 @@ describe('ReactFragment', () => {
364 }
365
366 ReactNoop.render(<Foo condition={true} />);
367 - ReactNoop.flush();
367 + expect(ReactNoop).toFlushWithoutYielding();
368
369 ReactNoop.render(<Foo condition={false} />);
370 - ReactNoop.flush();
370 + expect(ReactNoop).toFlushWithoutYielding();
371
372 expect(ops).toEqual(['Update Stateful']);
373 expect(ReactNoop.getChildren()).toEqual([div()]);
374
375 ReactNoop.render(<Foo condition={true} />);
376 - ReactNoop.flush();
376 + expect(ReactNoop).toFlushWithoutYielding();
377
378 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
379 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -403,16 +403,16 @@ describe('ReactFragment', () => {
403 }
404
405 ReactNoop.render(<Foo condition={true} />);
406 - ReactNoop.flush();
406 + expect(ReactNoop).toFlushWithoutYielding();
407
408 ReactNoop.render(<Foo condition={false} />);
409 - ReactNoop.flush();
409 + expect(ReactNoop).toFlushWithoutYielding();
410
411 expect(ops).toEqual(['Update Stateful']);
412 expect(ReactNoop.getChildren()).toEqual([div()]);
413
414 ReactNoop.render(<Foo condition={true} />);
415 - ReactNoop.flush();
415 + expect(ReactNoop).toFlushWithoutYielding();
416
417 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
418 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -444,16 +444,16 @@ describe('ReactFragment', () => {
444 }
445
446 ReactNoop.render(<Foo condition={true} />);
447 - ReactNoop.flush();
447 + expect(ReactNoop).toFlushWithoutYielding();
448
449 ReactNoop.render(<Foo condition={false} />);
450 - ReactNoop.flush();
450 + expect(ReactNoop).toFlushWithoutYielding();
451
452 expect(ops).toEqual([]);
453 expect(ReactNoop.getChildren()).toEqual([div()]);
454
455 ReactNoop.render(<Foo condition={true} />);
456 - ReactNoop.flush();
456 + expect(ReactNoop).toFlushWithoutYielding();
457
458 expect(ops).toEqual([]);
459 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -481,16 +481,16 @@ describe('ReactFragment', () => {
481 }
482
483 ReactNoop.render(<Foo condition={true} />);
484 - ReactNoop.flush();
484 + expect(ReactNoop).toFlushWithoutYielding();
485
486 ReactNoop.render(<Foo condition={false} />);
487 - ReactNoop.flush();
487 + expect(ReactNoop).toFlushWithoutYielding();
488
489 expect(ops).toEqual([]);
490 expect(ReactNoop.getChildren()).toEqual([div()]);
491
492 ReactNoop.render(<Foo condition={true} />);
493 - ReactNoop.flush();
493 + expect(ReactNoop).toFlushWithoutYielding();
494
495 expect(ops).toEqual([]);
496 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -522,16 +522,16 @@ describe('ReactFragment', () => {
522 }
523
524 ReactNoop.render(<Foo condition={true} />);
525 - ReactNoop.flush();
525 + expect(ReactNoop).toFlushWithoutYielding();
526
527 ReactNoop.render(<Foo condition={false} />);
528 - ReactNoop.flush();
528 + expect(ReactNoop).toFlushWithoutYielding();
529
530 expect(ops).toEqual(['Update Stateful']);
531 expect(ReactNoop.getChildren()).toEqual([div()]);
532
533 ReactNoop.render(<Foo condition={true} />);
534 - ReactNoop.flush();
534 + expect(ReactNoop).toFlushWithoutYielding();
535
536 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
537 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -564,16 +564,16 @@ describe('ReactFragment', () => {
564 }
565
566 ReactNoop.render(<Foo condition={true} />);
567 - ReactNoop.flush();
567 + expect(ReactNoop).toFlushWithoutYielding();
568
569 ReactNoop.render(<Foo condition={false} />);
570 - ReactNoop.flush();
570 + expect(ReactNoop).toFlushWithoutYielding();
571
572 expect(ops).toEqual([]);
573 expect(ReactNoop.getChildren()).toEqual([div(), span()]);
574
575 ReactNoop.render(<Foo condition={true} />);
576 - ReactNoop.flush();
576 + expect(ReactNoop).toFlushWithoutYielding();
577
578 expect(ops).toEqual([]);
579 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -605,16 +605,16 @@ describe('ReactFragment', () => {
605 }
606
607 ReactNoop.render(<Foo condition={true} />);
608 - ReactNoop.flush();
608 + expect(ReactNoop).toFlushWithoutYielding();
609
610 ReactNoop.render(<Foo condition={false} />);
611 - ReactNoop.flush();
611 + expect(ReactNoop).toFlushWithoutYielding();
612
613 expect(ops).toEqual([]);
614 expect(ReactNoop.getChildren()).toEqual([div()]);
615
616 ReactNoop.render(<Foo condition={true} />);
617 - ReactNoop.flush();
617 + expect(ReactNoop).toFlushWithoutYielding();
618
619 expect(ops).toEqual([]);
620 expect(ReactNoop.getChildren()).toEqual([div()]);
@@ -658,16 +658,16 @@ describe('ReactFragment', () => {
658 }
659
660 ReactNoop.render(<Foo condition={true} />);
661 - ReactNoop.flush();
661 + expect(ReactNoop).toFlushWithoutYielding();
662
663 ReactNoop.render(<Foo condition={false} />);
664 - ReactNoop.flush();
664 + expect(ReactNoop).toFlushWithoutYielding();
665
666 expect(ops).toEqual(['Update Stateful']);
667 expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
668
669 ReactNoop.render(<Foo condition={true} />);
670 - ReactNoop.flush();
670 + expect(ReactNoop).toFlushWithoutYielding();
671
672 expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
673 expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
@@ -705,10 +705,10 @@ describe('ReactFragment', () => {
705 }
706
707 ReactNoop.render(<Foo condition={true} />);
708 - ReactNoop.flush();
708 + expect(ReactNoop).toFlushWithoutYielding();
709
710 ReactNoop.render(<Foo condition={false} />);
711 - expect(ReactNoop.flush).toWarnDev(
711 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
712 'Each child in a list should have a unique "key" prop.',
713 );
714
@@ -716,7 +716,7 @@ describe('ReactFragment', () => {
716 expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
717
718 ReactNoop.render(<Foo condition={true} />);
719 - ReactNoop.flush();
719 + expect(ReactNoop).toFlushWithoutYielding();
720
721 expect(ops).toEqual([]);
722 expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
@@ -752,12 +752,12 @@ describe('ReactFragment', () => {
752 }
753
754 ReactNoop.render(<Foo condition={true} />);
755 - expect(ReactNoop.flush).toWarnDev(
755 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
756 'Each child in a list should have a unique "key" prop.',
757 );
758
759 ReactNoop.render(<Foo condition={false} />);
760 - expect(ReactNoop.flush).toWarnDev(
760 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
761 'Each child in a list should have a unique "key" prop.',
762 );
763
@@ -765,7 +765,7 @@ describe('ReactFragment', () => {
765 expect(ReactNoop.getChildren()).toEqual([span(), div()]);
766
767 ReactNoop.render(<Foo condition={true} />);
768 - expect(ReactNoop.flush).toWarnDev(
768 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
769 'Each child in a list should have a unique "key" prop.',
770 );
771
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js
+175 -176
@@ -74,7 +74,7 @@ describe('ReactHooksWithNoopRenderer', () => {
74 // Initial mount
75 const counter = React.createRef(null);
76 ReactNoop.render(<Counter label="Count" ref={counter} />);
77 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
77 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
78 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
79
80 // Schedule some updates
@@ -84,17 +84,17 @@ describe('ReactHooksWithNoopRenderer', () => {
84 });
85
86 // Partially flush without committing
87 - ReactNoop.flushThrough(['Count: 11']);
87 + expect(ReactNoop).toFlushAndYieldThrough(['Count: 11']);
88 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
89
90 // Interrupt with a high priority update
91 ReactNoop.flushSync(() => {
92 ReactNoop.render(<Counter label="Total" />);
93 });
94 - expect(ReactNoop.clearYields()).toEqual(['Total: 0']);
94 + expect(ReactNoop).toHaveYielded(['Total: 0']);
95
96 // Resume rendering
97 - ReactNoop.flush();
97 + expect(ReactNoop).toFlushAndYield(['Total: 11']);
98 expect(ReactNoop.getChildren()).toEqual([span('Total: 11')]);
99 });
100
@@ -107,7 +107,7 @@ describe('ReactHooksWithNoopRenderer', () => {
107 }
108 ReactNoop.render(<BadCounter />);
109
110 - expect(() => ReactNoop.flush()).toThrow(
110 + expect(ReactNoop).toFlushAndThrow(
111 'Hooks can only be called inside the body of a function component.',
112 );
113
@@ -117,7 +117,7 @@ describe('ReactHooksWithNoopRenderer', () => {
117 return <Text text={count} />;
118 }
119 ReactNoop.render(<GoodCounter initialCount={10} />);
120 - expect(ReactNoop.flush()).toEqual([10]);
120 + expect(ReactNoop).toFlushAndYield([10]);
121 });
122
123 it('throws inside module-style components', () => {
@@ -130,7 +130,7 @@ describe('ReactHooksWithNoopRenderer', () => {
130 };
131 }
132 ReactNoop.render(<Counter />);
133 - expect(() => ReactNoop.flush()).toThrow(
133 + expect(ReactNoop).toFlushAndThrow(
134 'Hooks can only be called inside the body of a function component.',
135 );
136
@@ -140,7 +140,7 @@ describe('ReactHooksWithNoopRenderer', () => {
140 return <Text text={count} />;
141 }
142 ReactNoop.render(<GoodCounter initialCount={10} />);
143 - expect(ReactNoop.flush()).toEqual([10]);
143 + expect(ReactNoop).toFlushAndYield([10]);
144 });
145
146 it('throws when called outside the render phase', () => {
@@ -159,15 +159,15 @@ describe('ReactHooksWithNoopRenderer', () => {
159 Counter = forwardRef(Counter);
160 const counter = React.createRef(null);
161 ReactNoop.render(<Counter ref={counter} />);
162 - ReactNoop.flush();
162 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
163 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
164
165 act(() => counter.current.updateCount(1));
166 - ReactNoop.flush();
166 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
167 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
168
169 act(() => counter.current.updateCount(count => count + 10));
170 - ReactNoop.flush();
170 + expect(ReactNoop).toFlushAndYield(['Count: 11']);
171 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
172 });
173
@@ -183,11 +183,11 @@ describe('ReactHooksWithNoopRenderer', () => {
183 Counter = forwardRef(Counter);
184 const counter = React.createRef(null);
185 ReactNoop.render(<Counter initialState={42} ref={counter} />);
186 - expect(ReactNoop.flush()).toEqual(['getInitialState', 'Count: 42']);
186 + expect(ReactNoop).toFlushAndYield(['getInitialState', 'Count: 42']);
187 expect(ReactNoop.getChildren()).toEqual([span('Count: 42')]);
188
189 act(() => counter.current.updateCount(7));
190 - expect(ReactNoop.flush()).toEqual(['Count: 7']);
190 + expect(ReactNoop).toFlushAndYield(['Count: 7']);
191 expect(ReactNoop.getChildren()).toEqual([span('Count: 7')]);
192 });
193
@@ -201,14 +201,14 @@ describe('ReactHooksWithNoopRenderer', () => {
201 Counter = forwardRef(Counter);
202 const counter = React.createRef(null);
203 ReactNoop.render(<Counter ref={counter} />);
204 - ReactNoop.flush();
204 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
205 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
206
207 act(() => counter.current.updateCount(7));
208 - expect(ReactNoop.flush()).toEqual(['Count: 7']);
208 + expect(ReactNoop).toFlushAndYield(['Count: 7']);
209
210 act(() => counter.current.updateLabel('Total'));
211 - expect(ReactNoop.flush()).toEqual(['Total: 7']);
211 + expect(ReactNoop).toFlushAndYield(['Total: 7']);
212 });
213
214 it('returns the same updater function every time', () => {
@@ -219,15 +219,15 @@ describe('ReactHooksWithNoopRenderer', () => {
219 return <Text text={'Count: ' + count} />;
220 }
221 ReactNoop.render(<Counter />);
222 - ReactNoop.flush();
222 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
223 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
224
225 act(() => updaters[0](1));
226 - ReactNoop.flush();
226 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
227 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
228
229 act(() => updaters[0](count => count + 10));
230 - ReactNoop.flush();
230 + expect(ReactNoop).toFlushAndYield(['Count: 11']);
231 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
232
233 expect(updaters).toEqual([updaters[0], updaters[0], updaters[0]]);
@@ -242,9 +242,9 @@ describe('ReactHooksWithNoopRenderer', () => {
242 }
243
244 ReactNoop.render(<Counter />);
245 - ReactNoop.flush();
245 + expect(ReactNoop).toFlushWithoutYielding();
246 ReactNoop.render(null);
247 - ReactNoop.flush();
247 + expect(ReactNoop).toFlushWithoutYielding();
248 expect(() => act(() => _updateCount(1))).toWarnDev(
249 "Warning: Can't perform a React state update on an unmounted " +
250 'component. This is a no-op, but it indicates a memory leak in your ' +
@@ -264,15 +264,15 @@ describe('ReactHooksWithNoopRenderer', () => {
264 Counter = memo(Counter);
265
266 ReactNoop.render(<Counter />);
267 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
267 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
268 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
269
270 ReactNoop.render(<Counter />);
271 - expect(ReactNoop.flush()).toEqual([]);
271 + expect(ReactNoop).toFlushAndYield([]);
272 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
273
274 act(() => _updateCount(1));
275 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
275 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
276 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
277 });
278 });
@@ -293,27 +293,27 @@ describe('ReactHooksWithNoopRenderer', () => {
293 }
294
295 ReactNoop.render(<ScrollView row={1} />);
296 - ReactNoop.flush();
296 + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']);
297 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
298
299 ReactNoop.render(<ScrollView row={5} />);
300 - ReactNoop.flush();
300 + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']);
301 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
302
303 ReactNoop.render(<ScrollView row={5} />);
304 - ReactNoop.flush();
304 + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']);
305 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
306
307 ReactNoop.render(<ScrollView row={10} />);
308 - ReactNoop.flush();
308 + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']);
309 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
310
311 ReactNoop.render(<ScrollView row={2} />);
312 - ReactNoop.flush();
312 + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']);
313 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
314
315 ReactNoop.render(<ScrollView row={2} />);
316 - ReactNoop.flush();
316 + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']);
317 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
318 });
319
@@ -328,7 +328,7 @@ describe('ReactHooksWithNoopRenderer', () => {
328 }
329
330 ReactNoop.render(<Counter />);
331 - expect(ReactNoop.flush()).toEqual([
331 + expect(ReactNoop).toFlushAndYield([
332 'Render: 0',
333 'Render: 1',
334 'Render: 2',
@@ -351,7 +351,7 @@ describe('ReactHooksWithNoopRenderer', () => {
351 }
352
353 ReactNoop.render(<Counter />);
354 - expect(ReactNoop.flush()).toEqual([
354 + expect(ReactNoop).toFlushAndYield([
355 // Should increase by three each time
356 'Render: 0',
357 'Render: 3',
@@ -371,7 +371,7 @@ describe('ReactHooksWithNoopRenderer', () => {
371 return <Text text={count} />;
372 }
373 ReactNoop.render(<Counter />);
374 - expect(() => ReactNoop.flush()).toThrow(
374 + expect(ReactNoop).toFlushAndThrow(
375 'Too many re-renders. React limits the number of renders to prevent ' +
376 'an infinite loop.',
377 );
@@ -391,7 +391,7 @@ describe('ReactHooksWithNoopRenderer', () => {
391 }
392
393 ReactNoop.render(<Counter />);
394 - expect(ReactNoop.flush()).toEqual([
394 + expect(ReactNoop).toFlushAndYield([
395 'Render: 0',
396 'Render: 1',
397 'Render: 2',
@@ -441,7 +441,7 @@ describe('ReactHooksWithNoopRenderer', () => {
441 Counter = forwardRef(Counter);
442 const counter = React.createRef(null);
443 ReactNoop.render(<Counter ref={counter} />);
444 - expect(ReactNoop.flush()).toEqual([
444 + expect(ReactNoop).toFlushAndYield([
445 // The count should increase by alternating amounts of 10 and 1
446 // until we reach 21.
447 'Render: 0',
@@ -458,7 +458,7 @@ describe('ReactHooksWithNoopRenderer', () => {
458 counter.current.dispatch('reset');
459 });
460 ReactNoop.render(<Counter ref={counter} />);
461 - expect(ReactNoop.flush()).toEqual([
461 + expect(ReactNoop).toFlushAndYield([
462 'Render: 0',
463 'Render: 1',
464 'Render: 11',
@@ -494,11 +494,11 @@ describe('ReactHooksWithNoopRenderer', () => {
494 Counter = forwardRef(Counter);
495 const counter = React.createRef(null);
496 ReactNoop.render(<Counter ref={counter} />);
497 - ReactNoop.flush();
497 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
498 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
499
500 act(() => counter.current.dispatch(INCREMENT));
501 - ReactNoop.flush();
501 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
502 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
503 act(() => {
504 counter.current.dispatch(DECREMENT);
@@ -506,7 +506,7 @@ describe('ReactHooksWithNoopRenderer', () => {
506 counter.current.dispatch(DECREMENT);
507 });
508
509 - ReactNoop.flush();
509 + expect(ReactNoop).toFlushAndYield(['Count: -2']);
510 expect(ReactNoop.getChildren()).toEqual([span('Count: -2')]);
511 });
512
@@ -536,11 +536,11 @@ describe('ReactHooksWithNoopRenderer', () => {
536 Counter = forwardRef(Counter);
537 const counter = React.createRef(null);
538 ReactNoop.render(<Counter initialCount={10} ref={counter} />);
539 - expect(ReactNoop.flush()).toEqual(['Init', 'Count: 10']);
539 + expect(ReactNoop).toFlushAndYield(['Init', 'Count: 10']);
540 expect(ReactNoop.getChildren()).toEqual([span('Count: 10')]);
541
542 act(() => counter.current.dispatch(INCREMENT));
543 - expect(ReactNoop.flush()).toEqual(['Count: 11']);
543 + expect(ReactNoop).toFlushAndYield(['Count: 11']);
544 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
545
546 act(() => {
@@ -549,7 +549,7 @@ describe('ReactHooksWithNoopRenderer', () => {
549 counter.current.dispatch(DECREMENT);
550 });
551
552 - expect(ReactNoop.flush()).toEqual(['Count: 8']);
552 + expect(ReactNoop).toFlushAndYield(['Count: 8']);
553 expect(ReactNoop.getChildren()).toEqual([span('Count: 8')]);
554 });
555
@@ -571,7 +571,7 @@ describe('ReactHooksWithNoopRenderer', () => {
571 const counter = React.createRef(null);
572 ReactNoop.render(<Counter ref={counter} />);
573
574 - ReactNoop.flush();
574 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
575 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
576
577 act(() => {
@@ -583,9 +583,10 @@ describe('ReactHooksWithNoopRenderer', () => {
583 ReactNoop.flushSync(() => {
584 counter.current.dispatch(INCREMENT);
585 });
586 + expect(ReactNoop).toHaveYielded(['Count: 1']);
587 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
588
588 - ReactNoop.flush();
589 + expect(ReactNoop).toFlushAndYield(['Count: 4']);
590 expect(ReactNoop.getChildren()).toEqual([span('Count: 4')]);
591 });
592 });
@@ -599,17 +600,17 @@ describe('ReactHooksWithNoopRenderer', () => {
600 return <Text text={'Count: ' + props.count} />;
601 }
602 ReactNoop.render(<Counter count={0} />);
602 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
603 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
604 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
605 ReactNoop.flushPassiveEffects();
605 - expect(ReactNoop.clearYields()).toEqual(['Did commit [0]']);
606 + expect(ReactNoop).toHaveYielded(['Did commit [0]']);
607
608 ReactNoop.render(<Counter count={1} />);
608 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
609 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
610 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
611 // Effects are deferred until after the commit
612 ReactNoop.flushPassiveEffects();
612 - expect(ReactNoop.clearYields()).toEqual(['Did commit [1]']);
613 + expect(ReactNoop).toHaveYielded(['Did commit [1]']);
614 });
615
616 it('flushes passive effects even with sibling deletions', () => {
@@ -627,7 +628,7 @@ describe('ReactHooksWithNoopRenderer', () => {
628 }
629 let passive = <PassiveEffect key="p" />;
630 ReactNoop.render([<LayoutEffect key="l" />, passive]);
630 - expect(ReactNoop.flush()).toEqual(['Layout', 'Passive', 'Layout effect']);
631 + expect(ReactNoop).toFlushAndYield(['Layout', 'Passive', 'Layout effect']);
632 expect(ReactNoop.getChildren()).toEqual([
633 span('Layout'),
634 span('Passive'),
@@ -636,12 +637,13 @@ describe('ReactHooksWithNoopRenderer', () => {
637 // Destroying the first child shouldn't prevent the passive effect from
638 // being executed
639 ReactNoop.render([passive]);
639 - expect(ReactNoop.flush()).toEqual(['Passive effect']);
640 + expect(ReactNoop).toHaveYielded(['Passive effect']);
641 + expect(ReactNoop).toFlushAndYield([]);
642 expect(ReactNoop.getChildren()).toEqual([span('Passive')]);
643
644 // (No effects are left to flush.)
645 ReactNoop.flushPassiveEffects();
644 - expect(ReactNoop.clearYields()).toEqual(null);
646 + expect(ReactNoop).toHaveYielded([]);
647 });
648
649 it('flushes passive effects even if siblings schedule an update', () => {
@@ -666,7 +668,7 @@ describe('ReactHooksWithNoopRenderer', () => {
668 ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);
669
670 act(() => {
669 - expect(ReactNoop.flush()).toEqual([
671 + expect(ReactNoop).toFlushAndYield([
672 'Passive',
673 'Layout',
674 'Layout effect 0',
@@ -698,7 +700,7 @@ describe('ReactHooksWithNoopRenderer', () => {
700 return <Text text="Layout" />;
701 }
702 ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);
701 - expect(ReactNoop.flush()).toEqual([
703 + expect(ReactNoop).toFlushAndYield([
704 'Passive',
705 'Layout',
706 'Layout effect',
@@ -732,20 +734,20 @@ describe('ReactHooksWithNoopRenderer', () => {
734 return <Text text={props.count} />;
735 }
736 ReactNoop.render(<Counter count={0} />);
735 - expect(ReactNoop.flush()).toEqual([0]);
737 + expect(ReactNoop).toFlushAndYield([0]);
738 expect(ReactNoop.getChildren()).toEqual([span(0)]);
739
740 // Before the effects have a chance to flush, schedule another update
741 ReactNoop.render(<Counter count={1} />);
740 - expect(ReactNoop.flush()).toEqual([
742 + expect(ReactNoop).toHaveYielded([
743 // The previous effect flushes before the reconciliation
744 'Committed state when effect was fired: 0',
743 - 1,
745 ]);
746 + expect(ReactNoop).toFlushAndYield([1]);
747 expect(ReactNoop.getChildren()).toEqual([span(1)]);
748
749 ReactNoop.flushPassiveEffects();
748 - expect(ReactNoop.clearYields()).toEqual([
750 + expect(ReactNoop).toHaveYielded([
751 'Committed state when effect was fired: 1',
752 ]);
753 },
@@ -764,18 +766,18 @@ describe('ReactHooksWithNoopRenderer', () => {
766 return <Text text={'Count: ' + count} />;
767 }
768 ReactNoop.render(<Counter count={0} />);
767 - expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
769 + expect(ReactNoop).toFlushAndYield(['Count: (empty)']);
770 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
771 ReactNoop.flushPassiveEffects();
770 - expect(ReactNoop.clearYields()).toEqual(['Schedule update [0]']);
771 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
772 + expect(ReactNoop).toHaveYielded(['Schedule update [0]']);
773 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
774
775 ReactNoop.render(<Counter count={1} />);
774 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
776 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
777 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
778 ReactNoop.flushPassiveEffects();
777 - expect(ReactNoop.clearYields()).toEqual(['Schedule update [1]']);
778 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
779 + expect(ReactNoop).toHaveYielded(['Schedule update [1]']);
780 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
781 });
782
783 it('updates have async priority even if effects are flushed early', () => {
@@ -791,22 +793,24 @@ describe('ReactHooksWithNoopRenderer', () => {
793 return <Text text={'Count: ' + count} />;
794 }
795 ReactNoop.render(<Counter count={0} />);
794 - expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
796 + expect(ReactNoop).toFlushAndYield(['Count: (empty)']);
797 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
798
799 // Rendering again should flush the previous commit's effects
800 ReactNoop.render(<Counter count={1} />);
799 - ReactNoop.flushThrough(['Schedule update [0]', 'Count: 0']);
801 + expect(ReactNoop).toHaveYielded(['Schedule update [0]']);
802 + expect(ReactNoop).toFlushAndYieldThrough(['Count: 0']);
803 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
804
805 ReactNoop.batchedUpdates(() => {
803 - expect(ReactNoop.flush()).toEqual([]);
806 + expect(ReactNoop).toFlushAndYield([]);
807 });
808
809 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
810
811 ReactNoop.flushPassiveEffects();
809 - expect(ReactNoop.flush()).toEqual(['Schedule update [1]', 'Count: 1']);
812 + expect(ReactNoop).toHaveYielded(['Schedule update [1]']);
813 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
814 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
815 });
816
@@ -823,13 +827,14 @@ describe('ReactHooksWithNoopRenderer', () => {
827 }
828
829 ReactNoop.render(<Counter count={0} />);
826 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
830 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
831 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
832
833 // Enqueuing this update forces the passive effect to be flushed --
834 // updateCount(1) happens first, so 2 wins.
835 act(() => _updateCount(2));
832 - expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']);
836 + expect(ReactNoop).toHaveYielded(['Will set count to 1']);
837 + expect(ReactNoop).toFlushAndYield(['Count: 2']);
838 expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
839 });
840
@@ -867,7 +872,7 @@ describe('ReactHooksWithNoopRenderer', () => {
872 ReactNoop.render(<Counter count={0} />);
873 },
874 );
870 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
875 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
876 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
877
878 expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(0);
@@ -875,7 +880,8 @@ describe('ReactHooksWithNoopRenderer', () => {
880 // Enqueuing this update forces the passive effect to be flushed --
881 // updateCount(1) happens first, so 2 wins.
882 act(() => _updateCount(2));
878 - expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']);
883 + expect(ReactNoop).toHaveYielded(['Will set count to 1']);
884 + expect(ReactNoop).toFlushAndYield(['Count: 2']);
885 expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);
886
887 expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);
@@ -905,13 +911,13 @@ describe('ReactHooksWithNoopRenderer', () => {
911 }
912 ReactNoop.renderLegacySyncRoot(<Counter count={0} />);
913 // Even in sync mode, effects are deferred until after paint
908 - expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
914 + expect(ReactNoop).toHaveYielded(['Count: (empty)']);
915 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
916 // Now fire the effects
917 ReactNoop.flushPassiveEffects();
918 // There were multiple updates, but there should only be a
919 // single render
914 - expect(ReactNoop.clearYields()).toEqual(['Count: 0']);
920 + expect(ReactNoop).toHaveYielded(['Count: 0']);
921 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
922 },
923 );
@@ -931,7 +937,7 @@ describe('ReactHooksWithNoopRenderer', () => {
937 return <Text text={'Count: ' + count} />;
938 }
939 ReactNoop.render(<Counter count={0} />);
934 - expect(ReactNoop.flush()).toEqual(['Count: (empty)']);
940 + expect(ReactNoop).toFlushAndYield(['Count: (empty)']);
941 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
942
943 expect(() => {
@@ -950,19 +956,16 @@ describe('ReactHooksWithNoopRenderer', () => {
956 return <Text text={'Count: ' + props.count} />;
957 }
958 ReactNoop.render(<Counter count={0} />);
953 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
959 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
960 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
961 ReactNoop.flushPassiveEffects();
956 - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
962 + expect(ReactNoop).toHaveYielded(['Did create [0]']);
963
964 ReactNoop.render(<Counter count={1} />);
959 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
965 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
966 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
967 ReactNoop.flushPassiveEffects();
962 - expect(ReactNoop.clearYields()).toEqual([
963 - 'Did destroy [0]',
964 - 'Did create [1]',
965 - ]);
968 + expect(ReactNoop).toHaveYielded(['Did destroy [0]', 'Did create [1]']);
969 });
970
971 it('unmounts on deletion', () => {
@@ -976,13 +979,13 @@ describe('ReactHooksWithNoopRenderer', () => {
979 return <Text text={'Count: ' + props.count} />;
980 }
981 ReactNoop.render(<Counter count={0} />);
979 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
982 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
983 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
984 ReactNoop.flushPassiveEffects();
982 - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
985 + expect(ReactNoop).toHaveYielded(['Did create [0]']);
986
987 ReactNoop.render(null);
985 - expect(ReactNoop.flush()).toEqual(['Did destroy [0]']);
988 + expect(ReactNoop).toFlushAndYield(['Did destroy [0]']);
989 expect(ReactNoop.getChildren()).toEqual([]);
990 });
991
@@ -997,19 +1000,19 @@ describe('ReactHooksWithNoopRenderer', () => {
1000 return <Text text={'Count: ' + props.count} />;
1001 }
1002 ReactNoop.render(<Counter count={0} />);
1000 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1003 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1004 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1005 ReactNoop.flushPassiveEffects();
1003 - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);
1006 + expect(ReactNoop).toHaveYielded(['Did create [0]']);
1007
1008 ReactNoop.render(<Counter count={1} />);
1006 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1009 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1010 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1011 ReactNoop.flushPassiveEffects();
1009 - expect(ReactNoop.clearYields()).toEqual(null);
1012 + expect(ReactNoop).toHaveYielded([]);
1013
1014 ReactNoop.render(null);
1012 - expect(ReactNoop.flush()).toEqual(['Did destroy [0]']);
1015 + expect(ReactNoop).toFlushAndYield(['Did destroy [0]']);
1016 expect(ReactNoop.getChildren()).toEqual([]);
1017 });
1018
@@ -1025,19 +1028,19 @@ describe('ReactHooksWithNoopRenderer', () => {
1028 return <Text text={'Count: ' + props.count} />;
1029 }
1030 ReactNoop.render(<Counter count={0} />);
1028 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1031 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1032 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1033 ReactNoop.flushPassiveEffects();
1031 - expect(ReactNoop.clearYields()).toEqual(['Did create']);
1034 + expect(ReactNoop).toHaveYielded(['Did create']);
1035
1036 ReactNoop.render(<Counter count={1} />);
1034 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1037 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1038 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1039 ReactNoop.flushPassiveEffects();
1037 - expect(ReactNoop.clearYields()).toEqual(['Did destroy', 'Did create']);
1040 + expect(ReactNoop).toHaveYielded(['Did destroy', 'Did create']);
1041
1042 ReactNoop.render(null);
1040 - expect(ReactNoop.flush()).toEqual(['Did destroy']);
1043 + expect(ReactNoop).toFlushAndYield(['Did destroy']);
1044 expect(ReactNoop.getChildren()).toEqual([]);
1045 });
1046
@@ -1056,34 +1059,34 @@ describe('ReactHooksWithNoopRenderer', () => {
1059 return <Text text={text} />;
1060 }
1061 ReactNoop.render(<Counter label="Count" count={0} />);
1059 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1062 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1063 ReactNoop.flushPassiveEffects();
1061 - expect(ReactNoop.clearYields()).toEqual(['Did create [Count: 0]']);
1064 + expect(ReactNoop).toHaveYielded(['Did create [Count: 0]']);
1065 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1066
1067 ReactNoop.render(<Counter label="Count" count={1} />);
1068 // Count changed
1066 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1069 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1070 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1071 ReactNoop.flushPassiveEffects();
1069 - expect(ReactNoop.clearYields()).toEqual([
1072 + expect(ReactNoop).toHaveYielded([
1073 'Did destroy [Count: 0]',
1074 'Did create [Count: 1]',
1075 ]);
1076
1077 ReactNoop.render(<Counter label="Count" count={1} />);
1078 // Nothing changed, so no effect should have fired
1076 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1079 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1080 ReactNoop.flushPassiveEffects();
1078 - expect(ReactNoop.clearYields()).toEqual(null);
1081 + expect(ReactNoop).toHaveYielded([]);
1082 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1083
1084 ReactNoop.render(<Counter label="Total" count={1} />);
1085 // Label changed
1083 - expect(ReactNoop.flush()).toEqual(['Total: 1']);
1086 + expect(ReactNoop).toFlushAndYield(['Total: 1']);
1087 expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);
1088 ReactNoop.flushPassiveEffects();
1086 - expect(ReactNoop.clearYields()).toEqual([
1089 + expect(ReactNoop).toHaveYielded([
1090 'Did destroy [Count: 1]',
1091 'Did create [Total: 1]',
1092 ]);
@@ -1100,22 +1103,16 @@ describe('ReactHooksWithNoopRenderer', () => {
1103 return <Text text={'Count: ' + props.count} />;
1104 }
1105 ReactNoop.render(<Counter count={0} />);
1103 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1106 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1107 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1108 ReactNoop.flushPassiveEffects();
1106 - expect(ReactNoop.clearYields()).toEqual([
1107 - 'Did commit 1 [0]',
1108 - 'Did commit 2 [0]',
1109 - ]);
1109 + expect(ReactNoop).toHaveYielded(['Did commit 1 [0]', 'Did commit 2 [0]']);
1110
1111 ReactNoop.render(<Counter count={1} />);
1112 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1112 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1113 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1114 ReactNoop.flushPassiveEffects();
1115 - expect(ReactNoop.clearYields()).toEqual([
1116 - 'Did commit 1 [1]',
1117 - 'Did commit 2 [1]',
1118 - ]);
1115 + expect(ReactNoop).toHaveYielded(['Did commit 1 [1]', 'Did commit 2 [1]']);
1116 });
1117
1118 it('unmounts all previous effects before creating any new ones', () => {
@@ -1135,16 +1132,16 @@ describe('ReactHooksWithNoopRenderer', () => {
1132 return <Text text={'Count: ' + props.count} />;
1133 }
1134 ReactNoop.render(<Counter count={0} />);
1138 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1135 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1136 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1137 ReactNoop.flushPassiveEffects();
1141 - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1138 + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1139
1140 ReactNoop.render(<Counter count={1} />);
1144 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1141 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1142 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1143 ReactNoop.flushPassiveEffects();
1147 - expect(ReactNoop.clearYields()).toEqual([
1144 + expect(ReactNoop).toHaveYielded([
1145 'Unmount A [0]',
1146 'Unmount B [0]',
1147 'Mount A [1]',
@@ -1172,10 +1169,10 @@ describe('ReactHooksWithNoopRenderer', () => {
1169 return <Text text={'Count: ' + props.count} />;
1170 }
1171 ReactNoop.render(<Counter count={0} />);
1175 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1172 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1173 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1174 expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1178 - expect(ReactNoop.clearYields()).toEqual([
1175 + expect(ReactNoop).toHaveYielded([
1176 'Mount A [0]',
1177 'Oops!',
1178 // Clean up effect A. There's no effect B to clean-up, because it
@@ -1206,17 +1203,17 @@ describe('ReactHooksWithNoopRenderer', () => {
1203 return <Text text={'Count: ' + props.count} />;
1204 }
1205 ReactNoop.render(<Counter count={0} />);
1209 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1206 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1207 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1208 ReactNoop.flushPassiveEffects();
1212 - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1209 + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1210
1211 // This update will trigger an errror
1212 ReactNoop.render(<Counter count={1} />);
1216 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1213 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1214 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1215 expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1219 - expect(ReactNoop.clearYields()).toEqual([
1216 + expect(ReactNoop).toHaveYielded([
1217 'Unmount A [0]',
1218 'Unmount B [0]',
1219 'Mount A [1]',
@@ -1248,17 +1245,17 @@ describe('ReactHooksWithNoopRenderer', () => {
1245 return <Text text={'Count: ' + props.count} />;
1246 }
1247 ReactNoop.render(<Counter count={0} />);
1251 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
1248 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1249 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1250 ReactNoop.flushPassiveEffects();
1254 - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);
1251 + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
1252
1253 // This update will trigger an errror
1254 ReactNoop.render(<Counter count={1} />);
1258 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
1255 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1256 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1257 expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
1261 - expect(ReactNoop.clearYields()).toEqual([
1258 + expect(ReactNoop).toHaveYielded([
1259 'Oops!',
1260 // B unmounts even though an error was thrown in the previous effect
1261 'Unmount B [0]',
@@ -1277,15 +1274,15 @@ describe('ReactHooksWithNoopRenderer', () => {
1274 Counter = memo(Counter);
1275
1276 ReactNoop.render(<Counter count={0} />);
1280 - expect(ReactNoop.flush()).toEqual(['Count: 0', 'Mount: 0']);
1277 + expect(ReactNoop).toFlushAndYield(['Count: 0', 'Mount: 0']);
1278 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1279
1280 ReactNoop.render(<Counter count={1} />);
1284 - expect(ReactNoop.flush()).toEqual(['Count: 1', 'Unmount: 0', 'Mount: 1']);
1281 + expect(ReactNoop).toFlushAndYield(['Count: 1', 'Unmount: 0', 'Mount: 1']);
1282 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1283
1284 ReactNoop.render(null);
1288 - expect(ReactNoop.flush()).toEqual(['Unmount: 1']);
1285 + expect(ReactNoop).toFlushAndYield(['Unmount: 1']);
1286 expect(ReactNoop.getChildren()).toEqual([]);
1287 });
1288 });
@@ -1293,7 +1290,9 @@ describe('ReactHooksWithNoopRenderer', () => {
1290 describe('useLayoutEffect', () => {
1291 it('fires layout effects after the host has been mutated', () => {
1292 function getCommittedText() {
1293 + const yields = ReactNoop.unstable_clearYields();
1294 const children = ReactNoop.getChildren();
1295 + ReactNoop.yield(yields);
1296 if (children === null) {
1297 return null;
1298 }
@@ -1308,11 +1307,11 @@ describe('ReactHooksWithNoopRenderer', () => {
1307 }
1308
1309 ReactNoop.render(<Counter count={0} />);
1311 - expect(ReactNoop.flush()).toEqual([0, 'Current: 0']);
1310 + expect(ReactNoop).toFlushAndYield([[0], 'Current: 0']);
1311 expect(ReactNoop.getChildren()).toEqual([span(0)]);
1312
1313 ReactNoop.render(<Counter count={1} />);
1315 - expect(ReactNoop.flush()).toEqual([1, 'Current: 1']);
1314 + expect(ReactNoop).toFlushAndYield([[1], 'Current: 1']);
1315 expect(ReactNoop.getChildren()).toEqual([span(1)]);
1316 });
1317
@@ -1340,19 +1339,19 @@ describe('ReactHooksWithNoopRenderer', () => {
1339 }
1340
1341 ReactNoop.render(<Counter count={0} />);
1343 - expect(ReactNoop.flush()).toEqual(['Mount layout [current: 0]']);
1342 + expect(ReactNoop).toFlushAndYield(['Mount layout [current: 0]']);
1343 expect(committedText).toEqual('0');
1344
1345 ReactNoop.render(<Counter count={1} />);
1347 - expect(ReactNoop.flush()).toEqual([
1348 - 'Mount normal [current: 0]',
1346 + expect(ReactNoop).toHaveYielded(['Mount normal [current: 0]']);
1347 + expect(ReactNoop).toFlushAndYield([
1348 'Unmount layout [current: 0]',
1349 'Mount layout [current: 1]',
1350 ]);
1351 expect(committedText).toEqual('1');
1352
1353 ReactNoop.flushPassiveEffects();
1355 - expect(ReactNoop.clearYields()).toEqual([
1354 + expect(ReactNoop).toHaveYielded([
1355 'Unmount normal [current: 1]',
1356 'Mount normal [current: 1]',
1357 ]);
@@ -1385,14 +1384,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1384
1385 const button = React.createRef(null);
1386 ReactNoop.render(<Counter incrementBy={1} />);
1388 - expect(ReactNoop.flush()).toEqual(['Increment', 'Count: 0']);
1387 + expect(ReactNoop).toFlushAndYield(['Increment', 'Count: 0']);
1388 expect(ReactNoop.getChildren()).toEqual([
1389 span('Increment'),
1390 span('Count: 0'),
1391 ]);
1392
1393 act(button.current.increment);
1395 - expect(ReactNoop.flush()).toEqual([
1394 + expect(ReactNoop).toFlushAndYield([
1395 // Button should not re-render, because its props haven't changed
1396 // 'Increment',
1397 'Count: 1',
@@ -1404,7 +1403,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1403
1404 // Increase the increment amount
1405 ReactNoop.render(<Counter incrementBy={10} />);
1407 - expect(ReactNoop.flush()).toEqual([
1406 + expect(ReactNoop).toFlushAndYield([
1407 // Inputs did change this time
1408 'Increment',
1409 'Count: 1',
@@ -1416,7 +1415,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1415
1416 // Callback should have updated
1417 act(button.current.increment);
1419 - expect(ReactNoop.flush()).toEqual(['Count: 11']);
1418 + expect(ReactNoop).toFlushAndYield(['Count: 11']);
1419 expect(ReactNoop.getChildren()).toEqual([
1420 span('Increment'),
1421 span('Count: 11'),
@@ -1439,19 +1438,19 @@ describe('ReactHooksWithNoopRenderer', () => {
1438 }
1439
1440 ReactNoop.render(<CapitalizedText text="hello" />);
1442 - expect(ReactNoop.flush()).toEqual(["Capitalize 'hello'", 'HELLO']);
1441 + expect(ReactNoop).toFlushAndYield(["Capitalize 'hello'", 'HELLO']);
1442 expect(ReactNoop.getChildren()).toEqual([span('HELLO')]);
1443
1444 ReactNoop.render(<CapitalizedText text="hi" />);
1446 - expect(ReactNoop.flush()).toEqual(["Capitalize 'hi'", 'HI']);
1445 + expect(ReactNoop).toFlushAndYield(["Capitalize 'hi'", 'HI']);
1446 expect(ReactNoop.getChildren()).toEqual([span('HI')]);
1447
1448 ReactNoop.render(<CapitalizedText text="hi" />);
1450 - expect(ReactNoop.flush()).toEqual(['HI']);
1449 + expect(ReactNoop).toFlushAndYield(['HI']);
1450 expect(ReactNoop.getChildren()).toEqual([span('HI')]);
1451
1452 ReactNoop.render(<CapitalizedText text="goodbye" />);
1454 - expect(ReactNoop.flush()).toEqual(["Capitalize 'goodbye'", 'GOODBYE']);
1453 + expect(ReactNoop).toFlushAndYield(["Capitalize 'goodbye'", 'GOODBYE']);
1454 expect(ReactNoop.getChildren()).toEqual([span('GOODBYE')]);
1455 });
1456
@@ -1472,16 +1471,16 @@ describe('ReactHooksWithNoopRenderer', () => {
1471 }
1472
1473 ReactNoop.render(<LazyCompute compute={computeA} />);
1475 - expect(ReactNoop.flush()).toEqual(['compute A', 'A']);
1474 + expect(ReactNoop).toFlushAndYield(['compute A', 'A']);
1475
1476 ReactNoop.render(<LazyCompute compute={computeA} />);
1478 - expect(ReactNoop.flush()).toEqual(['compute A', 'A']);
1477 + expect(ReactNoop).toFlushAndYield(['compute A', 'A']);
1478
1479 ReactNoop.render(<LazyCompute compute={computeA} />);
1481 - expect(ReactNoop.flush()).toEqual(['compute A', 'A']);
1480 + expect(ReactNoop).toFlushAndYield(['compute A', 'A']);
1481
1482 ReactNoop.render(<LazyCompute compute={computeB} />);
1484 - expect(ReactNoop.flush()).toEqual(['compute B', 'B']);
1483 + expect(ReactNoop).toFlushAndYield(['compute B', 'B']);
1484 });
1485
1486 it('should not invoke memoized function during re-renders unless inputs change', () => {
@@ -1502,13 +1501,13 @@ describe('ReactHooksWithNoopRenderer', () => {
1501 }
1502
1503 ReactNoop.render(<LazyCompute compute={compute} input="A" />);
1505 - expect(ReactNoop.flush()).toEqual(['compute A', 'A']);
1504 + expect(ReactNoop).toFlushAndYield(['compute A', 'A']);
1505
1506 ReactNoop.render(<LazyCompute compute={compute} input="A" />);
1508 - expect(ReactNoop.flush()).toEqual(['A']);
1507 + expect(ReactNoop).toFlushAndYield(['A']);
1508
1509 ReactNoop.render(<LazyCompute compute={compute} input="B" />);
1511 - expect(ReactNoop.flush()).toEqual(['compute B', 'B']);
1510 + expect(ReactNoop).toFlushAndYield(['compute B', 'B']);
1511 });
1512 });
1513
@@ -1546,17 +1545,17 @@ describe('ReactHooksWithNoopRenderer', () => {
1545 }
1546
1547 ReactNoop.render(<App />);
1549 - expect(ReactNoop.flush()).toEqual([]);
1548 + expect(ReactNoop).toFlushAndYield([]);
1549
1550 ping(1);
1551 ping(2);
1552 ping(3);
1553
1555 - expect(ReactNoop.flush()).toEqual([]);
1554 + expect(ReactNoop).toHaveYielded([]);
1555
1556 jest.advanceTimersByTime(100);
1557
1559 - expect(ReactNoop.flush()).toEqual(['ping: 3']);
1558 + expect(ReactNoop).toHaveYielded(['ping: 3']);
1559
1560 ping(4);
1561 jest.advanceTimersByTime(20);
@@ -1564,10 +1563,10 @@ describe('ReactHooksWithNoopRenderer', () => {
1563 ping(6);
1564 jest.advanceTimersByTime(80);
1565
1567 - expect(ReactNoop.flush()).toEqual([]);
1566 + expect(ReactNoop).toHaveYielded([]);
1567
1568 jest.advanceTimersByTime(20);
1570 - expect(ReactNoop.flush()).toEqual(['ping: 6']);
1569 + expect(ReactNoop).toHaveYielded(['ping: 6']);
1570 });
1571
1572 it('should return the same ref during re-renders', () => {
@@ -1588,10 +1587,10 @@ describe('ReactHooksWithNoopRenderer', () => {
1587 }
1588
1589 ReactNoop.render(<Counter />);
1591 - expect(ReactNoop.flush()).toEqual(['val']);
1590 + expect(ReactNoop).toFlushAndYield(['val']);
1591
1592 ReactNoop.render(<Counter />);
1594 - expect(ReactNoop.flush()).toEqual(['val']);
1593 + expect(ReactNoop).toFlushAndYield(['val']);
1594 });
1595 });
1596
@@ -1612,14 +1611,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1611 Counter = forwardRef(Counter);
1612 const counter = React.createRef(null);
1613 ReactNoop.render(<Counter ref={counter} />);
1615 - ReactNoop.flush();
1614 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1615 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1616 expect(counter.current.count).toBe(0);
1617
1618 act(() => {
1619 counter.current.dispatch(INCREMENT);
1620 });
1622 - ReactNoop.flush();
1621 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1622 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1623 // Intentionally not updated because of [] deps:
1624 expect(counter.current.count).toBe(0);
@@ -1642,14 +1641,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1641 Counter = forwardRef(Counter);
1642 const counter = React.createRef(null);
1643 ReactNoop.render(<Counter ref={counter} />);
1645 - ReactNoop.flush();
1644 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1645 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1646 expect(counter.current.count).toBe(0);
1647
1648 act(() => {
1649 counter.current.dispatch(INCREMENT);
1650 });
1652 - ReactNoop.flush();
1651 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1652 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1653 expect(counter.current.count).toBe(1);
1654 });
@@ -1678,7 +1677,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1677 Counter = forwardRef(Counter);
1678 const counter = React.createRef(null);
1679 ReactNoop.render(<Counter ref={counter} />);
1681 - ReactNoop.flush();
1680 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
1681 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
1682 expect(counter.current.count).toBe(0);
1683 expect(totalRefUpdates).toBe(1);
@@ -1686,14 +1685,14 @@ describe('ReactHooksWithNoopRenderer', () => {
1685 act(() => {
1686 counter.current.dispatch(INCREMENT);
1687 });
1689 - ReactNoop.flush();
1688 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1689 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1690 expect(counter.current.count).toBe(1);
1691 expect(totalRefUpdates).toBe(2);
1692
1693 // Update that doesn't change the ref dependencies
1694 ReactNoop.render(<Counter ref={counter} />);
1696 - ReactNoop.flush();
1695 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
1696 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
1697 expect(counter.current.count).toBe(1);
1698 expect(totalRefUpdates).toBe(2); // Should not increase since last time
@@ -1723,7 +1722,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1722 }
1723
1724 ReactNoop.render(<App loadC={false} />);
1726 - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: [not loaded]']);
1725 + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0, C: [not loaded]']);
1726 expect(ReactNoop.getChildren()).toEqual([
1727 span('A: 0, B: 0, C: [not loaded]'),
1728 ]);
@@ -1733,21 +1732,21 @@ describe('ReactHooksWithNoopRenderer', () => {
1732 updateB(3);
1733 });
1734
1736 - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: [not loaded]']);
1735 + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: [not loaded]']);
1736 expect(ReactNoop.getChildren()).toEqual([
1737 span('A: 2, B: 3, C: [not loaded]'),
1738 ]);
1739
1740 ReactNoop.render(<App loadC={true} />);
1741 expect(() => {
1743 - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 0']);
1742 + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 0']);
1743 }).toThrow('Rendered more hooks than during the previous render');
1744
1745 // Uncomment if/when we support this again
1746 // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 0')]);
1747
1748 // updateC(4);
1750 - // expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']);
1749 + // expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 4']);
1750 // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);
1751 });
1752
@@ -1775,17 +1774,17 @@ describe('ReactHooksWithNoopRenderer', () => {
1774 }
1775
1776 ReactNoop.render(<App loadC={true} />);
1778 - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: 0']);
1777 + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0, C: 0']);
1778 expect(ReactNoop.getChildren()).toEqual([span('A: 0, B: 0, C: 0')]);
1779 act(() => {
1780 updateA(2);
1781 updateB(3);
1782 updateC(4);
1783 });
1785 - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']);
1784 + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 4']);
1785 expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);
1786 ReactNoop.render(<App loadC={false} />);
1788 - expect(() => ReactNoop.flush()).toThrow(
1787 + expect(ReactNoop).toFlushAndThrow(
1788 'Rendered fewer hooks than expected. This may be caused by an ' +
1789 'accidental early return statement.',
1790 );
@@ -1813,21 +1812,21 @@ describe('ReactHooksWithNoopRenderer', () => {
1812 }
1813
1814 ReactNoop.render(<App showMore={false} />);
1816 - expect(ReactNoop.flush()).toEqual([]);
1815 + expect(ReactNoop).toFlushAndYield([]);
1816 ReactNoop.flushPassiveEffects();
1818 - expect(ReactNoop.clearYields()).toEqual(['Mount A']);
1817 + expect(ReactNoop).toHaveYielded(['Mount A']);
1818
1819 ReactNoop.render(<App showMore={true} />);
1820 expect(() => {
1822 - expect(ReactNoop.flush()).toEqual([]);
1821 + expect(ReactNoop).toFlushAndYield([]);
1822 }).toThrow('Rendered more hooks than during the previous render');
1823
1824 // Uncomment if/when we support this again
1825 // ReactNoop.flushPassiveEffects();
1827 - // expect(ReactNoop.clearYields()).toEqual(['Mount B']);
1826 + // expect(ReactNoop).toHaveYielded(['Mount B']);
1827
1828 // ReactNoop.render(<App showMore={false} />);
1830 - // expect(() => ReactNoop.flush()).toThrow(
1829 + // expect(ReactNoop).toFlushAndThrow(
1830 // 'Rendered fewer hooks than expected. This may be caused by an ' +
1831 // 'accidental early return statement.',
1832 // );
packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js
+101 -101
@@ -35,7 +35,7 @@ describe('ReactIncremental', () => {
35 }
36
37 ReactNoop.render(<Foo />);
38 - ReactNoop.flush();
38 + expect(ReactNoop).toFlushWithoutYielding();
39 });
40
41 it('should render a simple component, in steps if needed', () => {
@@ -58,7 +58,7 @@ describe('ReactIncremental', () => {
58 expect(ReactNoop.flushNextYield()).toEqual(['Foo']);
59
60 // Do the rest of the work.
61 - expect(ReactNoop.flush()).toEqual(['Bar', 'Bar', 'callback']);
61 + expect(ReactNoop).toFlushAndYield(['Bar', 'Bar', 'callback']);
62 });
63
64 it('updates a previous render', () => {
@@ -96,7 +96,7 @@ describe('ReactIncremental', () => {
96 ReactNoop.render(<Foo text="foo" />, () =>
97 ops.push('renderCallbackCalled'),
98 );
99 - ReactNoop.flush();
99 + expect(ReactNoop).toFlushWithoutYielding();
100
101 expect(ops).toEqual([
102 'Foo',
@@ -114,7 +114,7 @@ describe('ReactIncremental', () => {
114 ReactNoop.render(<Foo text="bar" />, () =>
115 ops.push('secondRenderCallbackCalled'),
116 );
117 - ReactNoop.flush();
117 + expect(ReactNoop).toFlushWithoutYielding();
118
119 // TODO: Test bail out of host components. This is currently unobservable.
120
@@ -146,21 +146,21 @@ describe('ReactIncremental', () => {
146
147 // Init
148 ReactNoop.render(<Foo text="foo" />);
149 - ReactNoop.flush();
149 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar']);
150
151 ReactNoop.render(<Foo text="bar" />);
152 // Flush part of the work
153 - ReactNoop.flushThrough(['Foo', 'Bar']);
153 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']);
154
155 // This will abort the previous work and restart
156 ReactNoop.flushSync(() => ReactNoop.render(null));
157 ReactNoop.render(<Foo text="baz" />);
158
159 // Flush part of the new work
160 - ReactNoop.flushThrough(['Foo', 'Bar']);
160 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']);
161
162 // Flush the rest of the work which now includes the low priority
163 - expect(ReactNoop.flush()).toEqual(['Bar']);
163 + expect(ReactNoop).toFlushAndYield(['Bar']);
164 });
165
166 it('should call callbacks even if updates are aborted', () => {
@@ -186,7 +186,7 @@ describe('ReactIncremental', () => {
186 }
187
188 ReactNoop.render(<Foo />);
189 - ReactNoop.flush();
189 + expect(ReactNoop).toFlushWithoutYielding();
190
191 inst.setState(
192 () => {
@@ -197,7 +197,7 @@ describe('ReactIncremental', () => {
197 );
198
199 // Flush part of the work
200 - ReactNoop.flushThrough(['setState1']);
200 + expect(ReactNoop).toFlushAndYieldThrough(['setState1']);
201
202 // This will abort the previous work and restart
203 ReactNoop.flushSync(() => ReactNoop.render(<Foo />));
@@ -210,7 +210,7 @@ describe('ReactIncremental', () => {
210 );
211
212 // Flush the rest of the work which now includes the low priority
213 - expect(ReactNoop.flush()).toEqual([
213 + expect(ReactNoop).toFlushAndYield([
214 'setState1',
215 'setState2',
216 'callback1',
@@ -248,7 +248,7 @@ describe('ReactIncremental', () => {
248
249 // Init
250 ReactNoop.render(<Foo text="foo" />);
251 - expect(ReactNoop.flush()).toEqual([
251 + expect(ReactNoop).toFlushAndYield([
252 'Foo',
253 'Bar',
254 'Bar',
@@ -259,9 +259,9 @@ describe('ReactIncremental', () => {
259 // Render part of the work. This should be enough to flush everything except
260 // the middle which has lower priority.
261 ReactNoop.render(<Foo text="bar" />);
262 - ReactNoop.flushThrough(['Foo', 'Bar', 'Bar']);
262 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar', 'Bar']);
263 // Flush only the remaining work
264 - expect(ReactNoop.flush()).toEqual(['Middle', 'Middle']);
264 + expect(ReactNoop).toFlushAndYield(['Middle', 'Middle']);
265 });
266
267 it('can deprioritize a tree from without dropping work', () => {
@@ -297,7 +297,7 @@ describe('ReactIncremental', () => {
297 ReactNoop.flushSync(() => {
298 ReactNoop.render(<Foo text="foo" />);
299 });
300 - ReactNoop.flush();
300 + expect(ReactNoop).toFlushWithoutYielding();
301 expect(ops).toEqual(['Foo', 'Bar', 'Bar', 'Middle', 'Middle']);
302
303 ops = [];
@@ -312,7 +312,7 @@ describe('ReactIncremental', () => {
312
313 // The hidden content was deprioritized from high to low priority. A low
314 // priority callback should have been scheduled. Flush it now.
315 - ReactNoop.flush();
315 + expect(ReactNoop).toFlushWithoutYielding();
316 expect(ops).toEqual(['Middle', 'Middle']);
317 });
318
@@ -375,7 +375,7 @@ describe('ReactIncremental', () => {
375 ops = [];
376
377 // Flush the rest to make sure that the bailout didn't block this work.
378 - ReactNoop.flush();
378 + expect(ReactNoop).toFlushWithoutYielding();
379 expect(ops).toEqual(['Middle']);
380 });
381
@@ -455,7 +455,7 @@ describe('ReactIncremental', () => {
455 // as a single batch. Therefore, it is correct that Middle should be in the
456 // middle. If it occurs after the two "Bar" components then it was flushed
457 // after them which is not correct.
458 - ReactNoop.flush();
458 + expect(ReactNoop).toFlushWithoutYielding();
459 expect(ops).toEqual(['Bar', 'Middle', 'Bar']);
460
461 ops = [];
@@ -473,7 +473,7 @@ describe('ReactIncremental', () => {
473 // it. If the priority levels aren't down-prioritized correctly this may
474 // abort rendering of the down-prioritized content.
475 ReactNoop.render(<Foo text="bar" />);
476 - ReactNoop.flush();
476 + expect(ReactNoop).toFlushWithoutYielding();
477 expect(ops).toEqual(['Foo', 'Bar', 'Bar']);
478 });
479
@@ -514,7 +514,7 @@ describe('ReactIncremental', () => {
514 foo.setState({value: 'bar'});
515
516 ops = [];
517 - ReactNoop.flush();
517 + expect(ReactNoop).toFlushWithoutYielding();
518 expect(ops).toEqual(['Foo', 'Bar']);
519 });
520
@@ -577,7 +577,7 @@ describe('ReactIncremental', () => {
577 foo.setState({value: 'bar'});
578
579 ops = [];
580 - ReactNoop.flush();
580 + expect(ReactNoop).toFlushWithoutYielding();
581 expect(constructorCount).toEqual(1);
582 expect(ops).toEqual([
583 'componentWillMount: foo',
@@ -639,7 +639,7 @@ describe('ReactIncremental', () => {
639 // Interrupt the rendering with a quick update. This should not touch the
640 // middle content.
641 ReactNoop.render(<Foo text="foo" text2="bar" step={0} />);
642 - ReactNoop.flush();
642 + expect(ReactNoop).toFlushWithoutYielding();
643
644 // We've now rendered the entire tree but we didn't have to redo the work
645 // done by the first Middle and Bar already.
@@ -674,7 +674,7 @@ describe('ReactIncremental', () => {
674 // Since we did nothing to the middle subtree during the interruption,
675 // we should be able to reuse the reconciliation work that we already did
676 // without restarting.
677 - ReactNoop.flush();
677 + expect(ReactNoop).toFlushWithoutYielding();
678 expect(ops).toEqual(['Middle']);
679 });
680
@@ -727,7 +727,7 @@ describe('ReactIncremental', () => {
727 }
728
729 ReactNoop.render(<Parent />);
730 - ReactNoop.flush();
730 + expect(ReactNoop).toFlushWithoutYielding();
731 ops = [];
732
733 // Begin working on a low priority update to Child, but stop before
@@ -747,7 +747,7 @@ describe('ReactIncremental', () => {
747 // Continue the low pri work. The work on Child and GrandChild was memoized
748 // so they should not be worked on again.
749 ops = [];
750 - ReactNoop.flush();
750 + expect(ReactNoop).toFlushWithoutYielding();
751 expect(ops).toEqual([
752 // No Child
753 // No Grandchild
@@ -803,7 +803,7 @@ describe('ReactIncremental', () => {
803
804 // Init
805 ReactNoop.render(<Foo text="foo" step={0} />);
806 - ReactNoop.flush();
806 + expect(ReactNoop).toFlushWithoutYielding();
807
808 expect(ops).toEqual(['Foo', 'Bar', 'Content', 'Middle', 'Bar', 'Middle']);
809
@@ -836,7 +836,7 @@ describe('ReactIncremental', () => {
836 // Since we did nothing to the middle subtree during the interruption,
837 // we should be able to reuse the reconciliation work that we already did
838 // without restarting.
839 - ReactNoop.flush();
839 + expect(ReactNoop).toFlushWithoutYielding();
840 expect(ops).toEqual(['Middle']);
841 });
842
@@ -857,16 +857,16 @@ describe('ReactIncremental', () => {
857 }
858
859 ReactNoop.render(<Foo step={1} />);
860 - ReactNoop.flush();
860 + expect(ReactNoop).toFlushWithoutYielding();
861
862 ops = [];
863 ReactNoop.render(<Foo step={2} />);
864 - ReactNoop.flush();
864 + expect(ReactNoop).toFlushWithoutYielding();
865 expect(ops).toEqual(['shouldComponentUpdate: false']);
866
867 ops = [];
868 ReactNoop.render(<Foo step={3} />);
869 - ReactNoop.flush();
869 + expect(ReactNoop).toFlushWithoutYielding();
870 expect(ops).toEqual([
871 // If the memoized props were not updated during last bail out, sCU will
872 // keep returning false.
@@ -897,10 +897,10 @@ describe('ReactIncremental', () => {
897 }
898
899 ReactNoop.render(<Foo />);
900 - ReactNoop.flush();
900 + expect(ReactNoop).toFlushWithoutYielding();
901 expect(instance.state).toEqual({a: 'a'});
902 instance.setState({b: 'b'});
903 - ReactNoop.flush();
903 + expect(ReactNoop).toFlushWithoutYielding();
904 expect(instance.state).toEqual({a: 'a', b: 'b'});
905 });
906
@@ -926,12 +926,12 @@ describe('ReactIncremental', () => {
926 }
927
928 ReactNoop.render(<Foo />);
929 - ReactNoop.flush();
929 + expect(ReactNoop).toFlushWithoutYielding();
930 // Call setState multiple times before flushing
931 instance.setState({b: 'b'});
932 instance.setState({c: 'c'});
933 instance.setState({d: 'd'});
934 - ReactNoop.flush();
934 + expect(ReactNoop).toFlushWithoutYielding();
935 expect(instance.state).toEqual({a: 'a', b: 'b', c: 'c', d: 'd'});
936 });
937
@@ -961,15 +961,15 @@ describe('ReactIncremental', () => {
961 }
962
963 ReactNoop.render(<Foo multiplier={2} />);
964 - ReactNoop.flush();
964 + expect(ReactNoop).toFlushWithoutYielding();
965 expect(instance.state.num).toEqual(1);
966 instance.setState(updater);
967 - ReactNoop.flush();
967 + expect(ReactNoop).toFlushWithoutYielding();
968 expect(instance.state.num).toEqual(2);
969
970 instance.setState(updater);
971 ReactNoop.render(<Foo multiplier={3} />);
972 - ReactNoop.flush();
972 + expect(ReactNoop).toFlushWithoutYielding();
973 expect(instance.state.num).toEqual(6);
974 });
975
@@ -1003,10 +1003,10 @@ describe('ReactIncremental', () => {
1003 }
1004
1005 ReactNoop.render(<Foo multiplier={2} />);
1006 - ReactNoop.flush();
1006 + expect(ReactNoop).toFlushWithoutYielding();
1007 instance.setState(updater);
1008 instance.setState(updater, callback);
1009 - ReactNoop.flush();
1009 + expect(ReactNoop).toFlushWithoutYielding();
1010 expect(instance.state.num).toEqual(4);
1011 expect(instance.state.called).toEqual(true);
1012 });
@@ -1030,11 +1030,11 @@ describe('ReactIncremental', () => {
1030 }
1031
1032 ReactNoop.render(<Foo />);
1033 - ReactNoop.flush();
1033 + expect(ReactNoop).toFlushWithoutYielding();
1034 instance.setState({b: 'b'});
1035 instance.setState({c: 'c'});
1036 instance.updater.enqueueReplaceState(instance, {d: 'd'});
1037 - ReactNoop.flush();
1037 + expect(ReactNoop).toFlushWithoutYielding();
1038 expect(instance.state).toEqual({d: 'd'});
1039 });
1040
@@ -1071,10 +1071,10 @@ describe('ReactIncremental', () => {
1071 }
1072
1073 ReactNoop.render(<Foo />);
1074 - ReactNoop.flush();
1074 + expect(ReactNoop).toFlushWithoutYielding();
1075 expect(ops).toEqual(['Foo', 'Bar', 'Baz']);
1076 instance.forceUpdate();
1077 - ReactNoop.flush();
1077 + expect(ReactNoop).toFlushWithoutYielding();
1078 expect(ops).toEqual(['Foo', 'Bar', 'Baz', 'Bar', 'Baz']);
1079 });
1080
@@ -1091,14 +1091,14 @@ describe('ReactIncremental', () => {
1091
1092 const foo = React.createRef(null);
1093 ReactNoop.render(<Foo ref={foo} b={0} />);
1094 - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0']);
1094 + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0']);
1095
1096 a = 1;
1097 foo.current.forceUpdate();
1098 - expect(ReactNoop.flush()).toEqual(['A: 1, B: 0']);
1098 + expect(ReactNoop).toFlushAndYield(['A: 1, B: 0']);
1099
1100 ReactNoop.render(<Foo ref={foo} b={0} />);
1101 - expect(ReactNoop.flush()).toEqual([]);
1101 + expect(ReactNoop).toFlushAndYield([]);
1102 });
1103
1104 xit('can call sCU while resuming a partly mounted component', () => {
@@ -1193,7 +1193,7 @@ describe('ReactIncremental', () => {
1193 <Baz />
1194 </div>,
1195 );
1196 - ReactNoop.flush();
1196 + expect(ReactNoop).toFlushWithoutYielding();
1197
1198 ops = [];
1199
@@ -1214,7 +1214,7 @@ describe('ReactIncremental', () => {
1214
1215 ops = [];
1216
1217 - ReactNoop.flush();
1217 + expect(ReactNoop).toFlushWithoutYielding();
1218 expect(ops).toEqual(['Bar:A-1', 'Baz']);
1219 });
1220
@@ -1263,7 +1263,7 @@ describe('ReactIncremental', () => {
1263 ops = [];
1264
1265 ReactNoop.render(<App x={1} />);
1266 - ReactNoop.flush();
1266 + expect(ReactNoop).toFlushWithoutYielding();
1267
1268 expect(ops).toEqual([
1269 'App',
@@ -1311,7 +1311,7 @@ describe('ReactIncremental', () => {
1311
1312 ops = [];
1313 ReactNoop.render(<App x={1} />);
1314 - ReactNoop.flush();
1314 + expect(ReactNoop).toFlushWithoutYielding();
1315
1316 expect(ops).toEqual([
1317 'App',
@@ -1366,7 +1366,7 @@ describe('ReactIncremental', () => {
1366 }
1367
1368 ReactNoop.render(<App x={0} />);
1369 - ReactNoop.flush();
1369 + expect(ReactNoop).toFlushWithoutYielding();
1370
1371 expect(ops).toEqual([
1372 'App',
@@ -1394,7 +1394,7 @@ describe('ReactIncremental', () => {
1394 ops = [];
1395
1396 ReactNoop.render(<App x={2} />);
1397 - ReactNoop.flush();
1397 + expect(ReactNoop).toFlushWithoutYielding();
1398
1399 expect(ops).toEqual([
1400 'App',
@@ -1432,7 +1432,7 @@ describe('ReactIncremental', () => {
1432 }
1433
1434 ReactNoop.render(<LifeCycle />);
1435 - ReactNoop.flush();
1435 + expect(ReactNoop).toFlushWithoutYielding();
1436
1437 expect(ops).toEqual(['getDerivedStateFromProps', 'render']);
1438 expect(instance.state).toEqual({foo: 'foo'});
@@ -1440,7 +1440,7 @@ describe('ReactIncremental', () => {
1440 ops = [];
1441
1442 instance.changeState();
1443 - ReactNoop.flush();
1443 + expect(ReactNoop).toFlushWithoutYielding();
1444
1445 expect(ops).toEqual([
1446 'getDerivedStateFromProps',
@@ -1472,7 +1472,7 @@ describe('ReactIncremental', () => {
1472
1473 const child = React.createRef(null);
1474 ReactNoop.render(<Parent />);
1475 - expect(ReactNoop.flush()).toEqual([
1475 + expect(ReactNoop).toFlushAndYield([
1476 'getDerivedStateFromProps',
1477 'Parent',
1478 'Child',
@@ -1480,7 +1480,7 @@ describe('ReactIncremental', () => {
1480
1481 // Schedule an update on the child. The parent should not re-render.
1482 child.current.setState({});
1483 - expect(ReactNoop.flush()).toEqual(['Child']);
1483 + expect(ReactNoop).toFlushAndYield(['Child']);
1484 });
1485
1486 xit('does not call componentWillReceiveProps for state-only updates', () => {
@@ -1553,7 +1553,7 @@ describe('ReactIncremental', () => {
1553 }
1554
1555 ReactNoop.render(<App y={0} />);
1556 - ReactNoop.flush();
1556 + expect(ReactNoop).toFlushWithoutYielding();
1557
1558 expect(ops).toEqual([
1559 'App',
@@ -1584,7 +1584,7 @@ describe('ReactIncremental', () => {
1584 // LifeCycle
1585 instances[1].tick();
1586
1587 - ReactNoop.flush();
1587 + expect(ReactNoop).toFlushWithoutYielding();
1588
1589 expect(ops).toEqual([
1590 // no componentWillReceiveProps
@@ -1617,7 +1617,7 @@ describe('ReactIncremental', () => {
1617 // Next we will update LifeCycle directly but not with new props.
1618 instances[1].tick();
1619
1620 - ReactNoop.flush();
1620 + expect(ReactNoop).toFlushWithoutYielding();
1621
1622 expect(ops).toEqual([
1623 // This should not trigger another componentWillReceiveProps because
@@ -1672,7 +1672,7 @@ describe('ReactIncremental', () => {
1672 }
1673
1674 ReactNoop.render(<App x={0} />);
1675 - ReactNoop.flush();
1675 + expect(ReactNoop).toFlushWithoutYielding();
1676
1677 expect(ops).toEqual([
1678 'componentWillMount',
@@ -1685,7 +1685,7 @@ describe('ReactIncremental', () => {
1685
1686 // Update to same props
1687 ReactNoop.render(<App x={0} />);
1688 - ReactNoop.flush();
1688 + expect(ReactNoop).toFlushWithoutYielding();
1689
1690 expect(ops).toEqual([
1691 'componentWillReceiveProps',
@@ -1715,7 +1715,7 @@ describe('ReactIncremental', () => {
1715
1716 // ...but we'll interrupt it to rerender the same props.
1717 ReactNoop.render(<App x={1} />);
1718 - ReactNoop.flush();
1718 + expect(ReactNoop).toFlushWithoutYielding();
1719
1720 // We can bail out this time, but we must call componentDidUpdate.
1721 expect(ops).toEqual([
@@ -1741,7 +1741,7 @@ describe('ReactIncremental', () => {
1741 }
1742
1743 ReactNoop.render(<Foo />);
1744 - ReactNoop.flush();
1744 + expect(ReactNoop).toFlushWithoutYielding();
1745 ops = [];
1746
1747 ReactNoop.flushSync(() => {
@@ -1783,7 +1783,7 @@ describe('ReactIncremental', () => {
1783 }
1784
1785 ReactNoop.render(<Foo />);
1786 - ReactNoop.flush();
1786 + expect(ReactNoop).toFlushWithoutYielding();
1787 ops = [];
1788
1789 function updater({n}) {
@@ -1798,7 +1798,7 @@ describe('ReactIncremental', () => {
1798 instance.setState(updater, () => ops.push('third callback'));
1799
1800 expect(() => {
1801 - ReactNoop.flush();
1801 + expect(ReactNoop).toFlushWithoutYielding();
1802 }).toThrow('callback error');
1803
1804 // The third callback isn't called because the second one throws
@@ -1897,7 +1897,7 @@ describe('ReactIncremental', () => {
1897 </Intl>,
1898 );
1899 expect(() =>
1900 - expect(ReactNoop.flush()).toEqual([
1900 + expect(ReactNoop).toFlushAndYield([
1901 'Intl {}',
1902 'ShowLocale {"locale":"fr"}',
1903 'ShowBoth {"locale":"fr"}',
@@ -1916,7 +1916,7 @@ describe('ReactIncremental', () => {
1916 </div>
1917 </Intl>,
1918 );
1919 - expect(ReactNoop.flush()).toEqual([
1919 + expect(ReactNoop).toFlushAndYield([
1920 'Intl {}',
1921 'ShowLocale {"locale":"de"}',
1922 'ShowBoth {"locale":"de"}',
@@ -1930,7 +1930,7 @@ describe('ReactIncremental', () => {
1930 </div>
1931 </Intl>,
1932 );
1933 - ReactNoop.flushThrough(['Intl {}']);
1933 + expect(ReactNoop).toFlushAndYieldThrough(['Intl {}']);
1934
1935 ReactNoop.render(
1936 <Intl locale="en">
@@ -1942,7 +1942,7 @@ describe('ReactIncremental', () => {
1942 </Intl>,
1943 );
1944 expect(() =>
1945 - expect(ReactNoop.flush()).toEqual([
1945 + expect(ReactNoop).toFlushAndYield([
1946 'ShowLocale {"locale":"sv"}',
1947 'ShowBoth {"locale":"sv"}',
1948 'Intl {}',
@@ -1986,7 +1986,7 @@ describe('ReactIncremental', () => {
1986 }
1987
1988 ReactNoop.render(<Recurse />);
1989 - expect(ReactNoop.flush).toWarnDev(
1989 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1990 'Legacy context API has been detected within a strict-mode tree: \n\n' +
1991 'Please update the following components: Recurse',
1992 {withoutStack: true},
@@ -2023,7 +2023,7 @@ describe('ReactIncremental', () => {
2023 };
2024
2025 ReactNoop.render(<Recurse />);
2026 - expect(ReactNoop.flush).toWarnDev(
2026 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2027 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2028 'Please update the following components: Recurse',
2029 {withoutStack: true},
@@ -2074,14 +2074,14 @@ describe('ReactIncremental', () => {
2074 <ShowLocale />
2075 </Intl>,
2076 );
2077 - ReactNoop.flushThrough([
2077 + expect(ReactNoop).toFlushAndYieldThrough([
2078 'Intl {}',
2079 'ShowLocale {"locale":"fr"}',
2080 'ShowLocale {"locale":"fr"}',
2081 ]);
2082
2083 expect(() =>
2084 - expect(ReactNoop.flush()).toEqual([
2084 + expect(ReactNoop).toFlushAndYield([
2085 'ShowLocale {"locale":"fr"}',
2086 'Intl {}',
2087 'ShowLocale {"locale":"ru"}',
@@ -2165,7 +2165,7 @@ describe('ReactIncremental', () => {
2165 </IndirectionFn>
2166 </Intl>,
2167 );
2168 - expect(ReactNoop.flush).toWarnDev(
2168 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2169 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2170 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2171 {withoutStack: true},
@@ -2181,7 +2181,7 @@ describe('ReactIncremental', () => {
2181
2182 ops.length = 0;
2183 statefulInst.setState({x: 1});
2184 - ReactNoop.flush();
2184 + expect(ReactNoop).toFlushWithoutYielding();
2185 // All work has been memoized because setState()
2186 // happened below the context and could not have affected it.
2187 expect(ops).toEqual([]);
@@ -2257,7 +2257,7 @@ describe('ReactIncremental', () => {
2257 </IndirectionFn>
2258 </Stateful>,
2259 );
2260 - expect(ReactNoop.flush).toWarnDev(
2260 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2261 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2262 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn',
2263 {withoutStack: true},
@@ -2273,7 +2273,7 @@ describe('ReactIncremental', () => {
2273
2274 ops.length = 0;
2275 statefulInst.setState({locale: 'gr'});
2276 - ReactNoop.flush();
2276 + expect(ReactNoop).toFlushWithoutYielding();
2277 expect(ops).toEqual([
2278 // Intl is below setState() so it might have been
2279 // affected by it. Therefore we re-render and recompute
@@ -2326,7 +2326,7 @@ describe('ReactIncremental', () => {
2326
2327 // Init
2328 ReactNoop.render(<Root />);
2329 - expect(ReactNoop.flush).toWarnDev(
2329 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2330 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2331 'Please update the following components: Child',
2332 {withoutStack: true},
@@ -2334,7 +2334,7 @@ describe('ReactIncremental', () => {
2334
2335 // Trigger an update in the middle of the tree
2336 instance.setState({});
2337 - ReactNoop.flush();
2337 + expect(ReactNoop).toFlushWithoutYielding();
2338 });
2339
2340 it('maintains the correct context when unwinding due to an error in render', () => {
@@ -2376,7 +2376,7 @@ describe('ReactIncremental', () => {
2376
2377 // Init
2378 ReactNoop.render(<Root />);
2379 - expect(ReactNoop.flush).toWarnDev(
2379 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2380 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2381 'Please update the following components: ContextProvider',
2382 {withoutStack: true},
@@ -2387,7 +2387,7 @@ describe('ReactIncremental', () => {
2387 instance.setState({
2388 throwError: true,
2389 });
2390 - expect(ReactNoop.flush).toWarnDev(
2390 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2391 'Error boundaries should implement getDerivedStateFromError()',
2392 {withoutStack: true},
2393 );
@@ -2425,7 +2425,7 @@ describe('ReactIncremental', () => {
2425 }
2426
2427 ReactNoop.render(<MyComponent />);
2428 - expect(ReactNoop.flush).toWarnDev(
2428 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2429 [
2430 'componentWillReceiveProps: Please update the following components ' +
2431 'to use static getDerivedStateFromProps instead: MyComponent',
@@ -2496,7 +2496,7 @@ describe('ReactIncremental', () => {
2496 // Initial render of the entire tree.
2497 // Renders: Root, Middle, FirstChild, SecondChild
2498 ReactNoop.render(<Root>A</Root>);
2499 - ReactNoop.flush();
2499 + expect(ReactNoop).toFlushWithoutYielding();
2500
2501 expect(renderCounter).toBe(1);
2502
@@ -2518,7 +2518,7 @@ describe('ReactIncremental', () => {
2518 // The in-progress child content will bailout.
2519 // Renders: Root, Middle, FirstChild, SecondChild
2520 ReactNoop.render(<Root>B</Root>);
2521 - ReactNoop.flush();
2521 + expect(ReactNoop).toFlushWithoutYielding();
2522
2523 // At this point the higher priority render has completed.
2524 // Since FirstChild props didn't change, sCU returned false.
@@ -2575,14 +2575,14 @@ describe('ReactIncremental', () => {
2575 </TopContextProvider>,
2576 );
2577
2578 - expect(ReactNoop.flush).toWarnDev(
2578 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2579 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2580 'Please update the following components: Child, TopContextProvider',
2581 {withoutStack: true},
2582 );
2583 expect(rendered).toEqual(['count:0']);
2584 instance.updateCount();
2585 - ReactNoop.flush();
2585 + expect(ReactNoop).toFlushWithoutYielding();
2586 expect(rendered).toEqual(['count:0', 'count:1']);
2587 });
2588
@@ -2637,14 +2637,14 @@ describe('ReactIncremental', () => {
2637 </TopContextProvider>,
2638 );
2639
2640 - expect(ReactNoop.flush).toWarnDev(
2640 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2641 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2642 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2643 {withoutStack: true},
2644 );
2645 expect(rendered).toEqual(['count:0']);
2646 instance.updateCount();
2647 - ReactNoop.flush();
2647 + expect(ReactNoop).toFlushWithoutYielding();
2648 expect(rendered).toEqual(['count:0', 'count:1']);
2649 });
2650
@@ -2708,14 +2708,14 @@ describe('ReactIncremental', () => {
2708 </TopContextProvider>,
2709 );
2710
2711 - expect(ReactNoop.flush).toWarnDev(
2711 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2712 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2713 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2714 {withoutStack: true},
2715 );
2716 expect(rendered).toEqual(['count:0']);
2717 instance.updateCount();
2718 - ReactNoop.flush();
2718 + expect(ReactNoop).toFlushWithoutYielding();
2719 expect(rendered).toEqual(['count:0']);
2720 });
2721
@@ -2789,17 +2789,17 @@ describe('ReactIncremental', () => {
2789 </TopContextProvider>,
2790 );
2791
2792 - expect(ReactNoop.flush).toWarnDev(
2792 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
2793 'Legacy context API has been detected within a strict-mode tree: \n\n' +
2794 'Please update the following components: Child, MiddleContextProvider, TopContextProvider',
2795 {withoutStack: true},
2796 );
2797 expect(rendered).toEqual(['count:0, name:brian']);
2798 topInstance.updateCount();
2799 - ReactNoop.flush();
2799 + expect(ReactNoop).toFlushWithoutYielding();
2800 expect(rendered).toEqual(['count:0, name:brian']);
2801 middleInstance.updateName('not brian');
2802 - ReactNoop.flush();
2802 + expect(ReactNoop).toFlushWithoutYielding();
2803 expect(rendered).toEqual([
2804 'count:0, name:brian',
2805 'count:1, name:not brian',
@@ -2818,12 +2818,12 @@ describe('ReactIncremental', () => {
2818 }
2819
2820 ReactNoop.render(<Parent step={1} />);
2821 - ReactNoop.flushThrough(['Parent: 1']);
2821 + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']);
2822
2823 // Interrupt at same priority
2824 ReactNoop.render(<Parent step={2} />);
2825
2826 - expect(ReactNoop.flush()).toEqual(['Child: 1', 'Parent: 2', 'Child: 2']);
2826 + expect(ReactNoop).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
2827 });
2828
2829 it('does not interrupt for update at lower priority', () => {
@@ -2838,13 +2838,13 @@ describe('ReactIncremental', () => {
2838 }
2839
2840 ReactNoop.render(<Parent step={1} />);
2841 - ReactNoop.flushThrough(['Parent: 1']);
2841 + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']);
2842
2843 // Interrupt at lower priority
2844 ReactNoop.expire(2000);
2845 ReactNoop.render(<Parent step={2} />);
2846
2847 - expect(ReactNoop.flush()).toEqual(['Child: 1', 'Parent: 2', 'Child: 2']);
2847 + expect(ReactNoop).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
2848 });
2849
2850 it('does interrupt for update at higher priority', () => {
@@ -2859,15 +2859,15 @@ describe('ReactIncremental', () => {
2859 }
2860
2861 ReactNoop.render(<Parent step={1} />);
2862 - ReactNoop.flushThrough(['Parent: 1']);
2862 + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']);
2863
2864 // Interrupt at higher priority
2865 expect(
2866 ReactNoop.flushSync(() => ReactNoop.render(<Parent step={2} />)),
2867 ).toEqual(['Parent: 2', 'Child: 2']);
2868 - ReactNoop.clearYields();
2868 + expect(ReactNoop).toHaveYielded(['Parent: 2', 'Child: 2']);
2869
2870 - expect(ReactNoop.flush()).toEqual([]);
2870 + expect(ReactNoop).toFlushAndYield([]);
2871 });
2872
2873 // We don't currently use fibers as keys. Re-enable this test if we
@@ -2889,7 +2889,7 @@ describe('ReactIncremental', () => {
2889 }
2890 }
2891 ReactNoop.render(<Boundary />);
2892 - ReactNoop.flush();
2892 + expect(ReactNoop).toFlushWithoutYielding();
2893 }
2894
2895 // First, verify that this code path normally receives Fibers as keys,
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+60 -58
@@ -86,7 +86,7 @@ describe('ReactIncrementalErrorHandling', () => {
86 );
87
88 // Start rendering asynchronously
89 - ReactNoop.flushThrough([
89 + expect(ReactNoop).toFlushAndYieldThrough([
90 'ErrorBoundary (try)',
91 'Indirection',
92 'Indirection',
@@ -96,9 +96,9 @@ describe('ReactIncrementalErrorHandling', () => {
96 ]);
97
98 // Still rendering async...
99 - ReactNoop.flushThrough(['Indirection']);
99 + expect(ReactNoop).toFlushAndYieldThrough(['Indirection']);
100
101 - ReactNoop.flushThrough([
101 + expect(ReactNoop).toFlushAndYieldThrough([
102 'Indirection',
103
104 // Call getDerivedStateFromError and re-render the error boundary, this
@@ -179,7 +179,7 @@ describe('ReactIncrementalErrorHandling', () => {
179 );
180
181 // Start rendering asynchronously
182 - ReactNoop.flushThrough([
182 + expect(ReactNoop).toFlushAndYieldThrough([
183 'ErrorBoundary (try)',
184 'Indirection',
185 'Indirection',
@@ -189,9 +189,9 @@ describe('ReactIncrementalErrorHandling', () => {
189 ]);
190
191 // Still rendering async...
192 - ReactNoop.flushThrough(['Indirection']);
192 + expect(ReactNoop).toFlushAndYieldThrough(['Indirection']);
193
194 - ReactNoop.flushThrough([
194 + expect(ReactNoop).toFlushAndYieldThrough([
195 'Indirection',
196 // Now that the tree is complete, and there's no remaining work, React
197 // reverts to sync mode to retry one more time before handling the error.
@@ -230,7 +230,7 @@ describe('ReactIncrementalErrorHandling', () => {
230 ReactNoop.expire(2000);
231 ReactNoop.render(<App isBroken={false} />, onCommit);
232
233 - expect(ReactNoop.flush()).toEqual([
233 + expect(ReactNoop).toFlushAndYield([
234 // The first render fails. But because there's a lower priority pending
235 // update, it doesn't throw.
236 'error',
@@ -270,7 +270,7 @@ describe('ReactIncrementalErrorHandling', () => {
270 // Initial mount
271 const parent = React.createRef(null);
272 ReactNoop.render(<Parent ref={parent} childIsBroken={false} />);
273 - expect(ReactNoop.flush()).toEqual(['Child']);
273 + expect(ReactNoop).toFlushAndYield(['Child']);
274 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
275
276 // Schedule a low priority update to hide the child
@@ -281,7 +281,7 @@ describe('ReactIncrementalErrorHandling', () => {
281 ReactNoop.flushSync(() => {
282 ReactNoop.render(<Parent ref={parent} childIsBroken={true} />);
283 });
284 - expect(ReactNoop.clearYields()).toEqual([
284 + expect(ReactNoop).toHaveYielded([
285 // First the sync update triggers an error
286 'Error!',
287 // Because there's a pending low priority update, we restart at the
@@ -321,10 +321,10 @@ describe('ReactIncrementalErrorHandling', () => {
321 ReactNoop.render(<Parent />, () => ReactNoop.yield('commit'));
322
323 // Render the bad component asynchronously
324 - ReactNoop.flushThrough(['Parent', 'BadRender']);
324 + expect(ReactNoop).toFlushAndYieldThrough(['Parent', 'BadRender']);
325
326 // Finish the rest of the async work
327 - ReactNoop.flushThrough(['Sibling']);
327 + expect(ReactNoop).toFlushAndYieldThrough(['Sibling']);
328
329 // React retries once, synchronously, before throwing.
330 ops = [];
@@ -371,7 +371,7 @@ describe('ReactIncrementalErrorHandling', () => {
371 </ErrorBoundary>,
372 );
373
374 - expect(ReactNoop.flush()).toEqual([
374 + expect(ReactNoop).toFlushAndYield([
375 'ErrorBoundary',
376 'BadMount',
377 'BadMount',
@@ -408,7 +408,7 @@ describe('ReactIncrementalErrorHandling', () => {
408 <BrokenRender />
409 </ErrorBoundary>,
410 );
411 - ReactNoop.flush();
411 + expect(ReactNoop).toFlushWithoutYielding();
412 expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
413 });
414
@@ -442,10 +442,10 @@ describe('ReactIncrementalErrorHandling', () => {
442 </ErrorBoundary>,
443 );
444
445 - ReactNoop.flushThrough(['ErrorBoundary render success']);
445 + expect(ReactNoop).toFlushAndYieldThrough(['ErrorBoundary render success']);
446 expect(ReactNoop.getChildren()).toEqual([]);
447
448 - expect(ReactNoop.flush()).toEqual([
448 + expect(ReactNoop).toFlushAndYield([
449 'BrokenRender',
450 // React retries one more time
451 'ErrorBoundary render success',
@@ -570,7 +570,7 @@ describe('ReactIncrementalErrorHandling', () => {
570 );
571
572 expect(() => {
573 - ReactNoop.flush();
573 + expect(ReactNoop).toFlushWithoutYielding();
574 }).toThrow('Hello');
575 expect(ops).toEqual([
576 'RethrowErrorBoundary render',
@@ -609,12 +609,14 @@ describe('ReactIncrementalErrorHandling', () => {
609 </RethrowErrorBoundary>,
610 );
611
612 - ReactNoop.flushThrough(['RethrowErrorBoundary render']);
612 + expect(ReactNoop).toFlushAndYieldThrough(['RethrowErrorBoundary render']);
613
614 expect(() => {
615 - ReactNoop.flush();
615 + expect(ReactNoop).toFlushWithoutYielding();
616 }).toThrow('Hello');
617 - expect(ReactNoop.clearYields()).toEqual([
617 + expect(ReactNoop).toHaveYielded([
618 + 'BrokenRender',
619 +
620 // React retries one more time
621 'RethrowErrorBoundary render',
622 'BrokenRender',
@@ -709,7 +711,7 @@ describe('ReactIncrementalErrorHandling', () => {
711 throw new Error('Hello');
712 });
713 }).toThrow('Hello');
712 - ReactNoop.flush();
714 + expect(ReactNoop).toFlushWithoutYielding();
715 expect(ReactNoop.getChildren()).toEqual([span('a:3')]);
716 });
717
@@ -726,7 +728,7 @@ describe('ReactIncrementalErrorHandling', () => {
728 });
729 });
730 }).toThrow('Hello');
729 - ReactNoop.flush();
731 + expect(ReactNoop).toFlushWithoutYielding();
732 expect(ReactNoop.getChildren()).toEqual([span('a:5')]);
733 });
734
@@ -759,7 +761,7 @@ describe('ReactIncrementalErrorHandling', () => {
761
762 ReactNoop.render(<BrokenRender />);
763 expect(() => {
762 - ReactNoop.flush();
764 + expect(ReactNoop).toFlushWithoutYielding();
765 }).toThrow('Hello');
766 expect(ops).toEqual([
767 'BrokenRender',
@@ -769,7 +771,7 @@ describe('ReactIncrementalErrorHandling', () => {
771 ]);
772 ops = [];
773 ReactNoop.render(<Foo />);
772 - ReactNoop.flush();
774 + expect(ReactNoop).toFlushWithoutYielding();
775 expect(ops).toEqual(['Foo']);
776 });
777
@@ -790,12 +792,12 @@ describe('ReactIncrementalErrorHandling', () => {
792 }
793
794 ReactNoop.render(<BrokenRender throw={false} />);
793 - ReactNoop.flush();
795 + expect(ReactNoop).toFlushWithoutYielding();
796 ops = [];
797
798 expect(() => {
799 ReactNoop.render(<BrokenRender throw={true} />);
798 - ReactNoop.flush();
800 + expect(ReactNoop).toFlushWithoutYielding();
801 }).toThrow('Hello');
802 expect(ops).toEqual([
803 'BrokenRender',
@@ -806,7 +808,7 @@ describe('ReactIncrementalErrorHandling', () => {
808
809 ops = [];
810 ReactNoop.render(<Foo />);
809 - ReactNoop.flush();
811 + expect(ReactNoop).toFlushWithoutYielding();
812 expect(ops).toEqual(['Foo']);
813 });
814
@@ -828,16 +830,16 @@ describe('ReactIncrementalErrorHandling', () => {
830 }
831
832 ReactNoop.render(<BrokenComponentWillUnmount />);
831 - ReactNoop.flush();
833 + expect(ReactNoop).toFlushWithoutYielding();
834
835 expect(() => {
836 ReactNoop.render(<div />);
835 - ReactNoop.flush();
837 + expect(ReactNoop).toFlushWithoutYielding();
838 }).toThrow('Hello');
839
840 ops = [];
841 ReactNoop.render(<Foo />);
840 - ReactNoop.flush();
842 + expect(ReactNoop).toFlushWithoutYielding();
843 expect(ops).toEqual(['Foo']);
844 });
845
@@ -871,9 +873,9 @@ describe('ReactIncrementalErrorHandling', () => {
873 }
874
875 ReactNoop.render(<Parent />);
874 - ReactNoop.flush();
876 + expect(ReactNoop).toFlushWithoutYielding();
877 ReactNoop.render(null);
876 - expect(ReactNoop.flush()).toEqual([
878 + expect(ReactNoop).toFlushAndYield([
879 // Parent unmounts before the error is thrown.
880 'Parent componentWillUnmount',
881 'ThrowsOnUnmount componentWillUnmount',
@@ -910,7 +912,7 @@ describe('ReactIncrementalErrorHandling', () => {
912 }
913
914 ReactNoop.render(<Parent />);
913 - ReactNoop.flush();
915 + expect(ReactNoop).toFlushWithoutYielding();
916
917 ReactNoop.flushSync(() => {
918 ReactNoop.render(<Parent />);
@@ -944,7 +946,7 @@ describe('ReactIncrementalErrorHandling', () => {
946 'a',
947 );
948 ReactNoop.renderToRootWithID(<span prop="b:1" />, 'b');
947 - ReactNoop.flush();
949 + expect(ReactNoop).toFlushWithoutYielding();
950 expect(ReactNoop.getChildren('a')).toEqual([
951 span('Caught an error: Hello.'),
952 ]);
@@ -958,14 +960,14 @@ describe('ReactIncrementalErrorHandling', () => {
960
961 ReactNoop.renderToRootWithID(<BrokenRender />, 'a');
962 expect(() => {
961 - ReactNoop.flush();
963 + expect(ReactNoop).toFlushWithoutYielding();
964 }).toThrow('Hello');
965 expect(ReactNoop.getChildren('a')).toEqual([]);
966
967 ReactNoop.renderToRootWithID(<BrokenRender />, 'a');
968 ReactNoop.renderToRootWithID(<span prop="b:2" />, 'b');
969 expect(() => {
968 - ReactNoop.flush();
970 + expect(ReactNoop).toFlushWithoutYielding();
971 }).toThrow('Hello');
972
973 expect(ReactNoop.getChildren('a')).toEqual([]);
@@ -974,7 +976,7 @@ describe('ReactIncrementalErrorHandling', () => {
976 ReactNoop.renderToRootWithID(<span prop="a:3" />, 'a');
977 ReactNoop.renderToRootWithID(<BrokenRender />, 'b');
978 expect(() => {
977 - ReactNoop.flush();
979 + expect(ReactNoop).toFlushWithoutYielding();
980 }).toThrow('Hello');
981 expect(ReactNoop.getChildren('a')).toEqual([span('a:3')]);
982 expect(ReactNoop.getChildren('b')).toEqual([]);
@@ -983,7 +985,7 @@ describe('ReactIncrementalErrorHandling', () => {
985 ReactNoop.renderToRootWithID(<BrokenRender />, 'b');
986 ReactNoop.renderToRootWithID(<span prop="c:4" />, 'c');
987 expect(() => {
986 - ReactNoop.flush();
988 + expect(ReactNoop).toFlushWithoutYielding();
989 }).toThrow('Hello');
990 expect(ReactNoop.getChildren('a')).toEqual([span('a:4')]);
991 expect(ReactNoop.getChildren('b')).toEqual([]);
@@ -995,7 +997,7 @@ describe('ReactIncrementalErrorHandling', () => {
997 ReactNoop.renderToRootWithID(<span prop="d:5" />, 'd');
998 ReactNoop.renderToRootWithID(<BrokenRender />, 'e');
999 expect(() => {
998 - ReactNoop.flush();
1000 + expect(ReactNoop).toFlushWithoutYielding();
1001 }).toThrow('Hello');
1002 expect(ReactNoop.getChildren('a')).toEqual([span('a:5')]);
1003 expect(ReactNoop.getChildren('b')).toEqual([span('b:5')]);
@@ -1010,7 +1012,7 @@ describe('ReactIncrementalErrorHandling', () => {
1012 ReactNoop.renderToRootWithID(<BrokenRender />, 'e');
1013 ReactNoop.renderToRootWithID(<span prop="f:6" />, 'f');
1014 expect(() => {
1013 - ReactNoop.flush();
1015 + expect(ReactNoop).toFlushWithoutYielding();
1016 }).toThrow('Hello');
1017 expect(ReactNoop.getChildren('a')).toEqual([]);
1018 expect(ReactNoop.getChildren('b')).toEqual([span('b:6')]);
@@ -1025,7 +1027,7 @@ describe('ReactIncrementalErrorHandling', () => {
1027 ReactNoop.unmountRootWithID('d');
1028 ReactNoop.unmountRootWithID('e');
1029 ReactNoop.unmountRootWithID('f');
1028 - ReactNoop.flush();
1030 + expect(ReactNoop).toFlushWithoutYielding();
1031 expect(ReactNoop.getChildren('a')).toEqual(null);
1032 expect(ReactNoop.getChildren('b')).toEqual(null);
1033 expect(ReactNoop.getChildren('c')).toEqual(null);
@@ -1086,7 +1088,7 @@ describe('ReactIncrementalErrorHandling', () => {
1088 <Connector />
1089 </Provider>,
1090 );
1089 - expect(ReactNoop.flush).toWarnDev(
1091 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1092 'Legacy context API has been detected within a strict-mode tree: \n\n' +
1093 'Please update the following components: Connector, Provider',
1094 {withoutStack: true},
@@ -1119,7 +1121,7 @@ describe('ReactIncrementalErrorHandling', () => {
1121 <BrokenRender />
1122 </ErrorBoundary>,
1123 );
1122 - expect(ReactNoop.flush).toWarnDev([
1124 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([
1125 'Warning: React.createElement: type is invalid -- expected a string',
1126 // React retries once on error
1127 'Warning: React.createElement: type is invalid -- expected a string',
@@ -1161,14 +1163,14 @@ describe('ReactIncrementalErrorHandling', () => {
1163 <BrokenRender fail={false} />
1164 </ErrorBoundary>,
1165 );
1164 - ReactNoop.flush();
1166 + expect(ReactNoop).toFlushWithoutYielding();
1167
1168 ReactNoop.render(
1169 <ErrorBoundary>
1170 <BrokenRender fail={true} />
1171 </ErrorBoundary>,
1172 );
1171 - expect(ReactNoop.flush).toWarnDev([
1173 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([
1174 'Warning: React.createElement: type is invalid -- expected a string',
1175 // React retries once on error
1176 'Warning: React.createElement: type is invalid -- expected a string',
@@ -1192,7 +1194,7 @@ describe('ReactIncrementalErrorHandling', () => {
1194 'Warning: React.createElement: type is invalid -- expected a string',
1195 {withoutStack: true},
1196 );
1195 - expect(ReactNoop.flush).toThrowError(
1197 + expect(ReactNoop).toFlushAndThrow(
1198 'Element type is invalid: expected a string (for built-in components) or ' +
1199 'a class/function (for composite components) but got: undefined.' +
1200 (__DEV__
@@ -1202,7 +1204,7 @@ describe('ReactIncrementalErrorHandling', () => {
1204 );
1205
1206 ReactNoop.render(<span prop="hi" />);
1205 - ReactNoop.flush();
1207 + expect(ReactNoop).toFlushWithoutYielding();
1208 expect(ReactNoop.getChildren()).toEqual([span('hi')]);
1209 });
1210
@@ -1241,11 +1243,11 @@ describe('ReactIncrementalErrorHandling', () => {
1243 </Parent>
1244 </Parent>,
1245 );
1244 - ReactNoop.flush();
1246 + expect(ReactNoop).toFlushWithoutYielding();
1247
1248 inst.setState({fail: true});
1249 expect(() => {
1248 - ReactNoop.flush();
1250 + expect(ReactNoop).toFlushWithoutYielding();
1251 }).toThrowError('Hello.');
1252
1253 expect(ops).toEqual([
@@ -1283,7 +1285,7 @@ describe('ReactIncrementalErrorHandling', () => {
1285 }
1286
1287 ReactNoop.render(<Foo />);
1286 - ReactNoop.flush();
1288 + expect(ReactNoop).toFlushWithoutYielding();
1289 expect(ops).toEqual(['barRef attach']);
1290 expect(ReactNoop.getChildren()).toEqual([div(span('Bar'))]);
1291
@@ -1291,7 +1293,7 @@ describe('ReactIncrementalErrorHandling', () => {
1293
1294 // Unmount
1295 ReactNoop.render(<Foo hide={true} />);
1294 - expect(() => ReactNoop.flush()).toThrow('Detach error');
1296 + expect(ReactNoop).toFlushAndThrow('Detach error');
1297 expect(ops).toEqual([
1298 'barRef detach',
1299 // Bar should unmount even though its ref threw an error while detaching
@@ -1303,14 +1305,14 @@ describe('ReactIncrementalErrorHandling', () => {
1305
1306 it('handles error thrown by host config while working on failed root', () => {
1307 ReactNoop.render(<errorInBeginPhase />);
1306 - expect(() => ReactNoop.flush()).toThrow('Error in host config.');
1308 + expect(ReactNoop).toFlushAndThrow('Error in host config.');
1309 });
1310
1311 it('handles error thrown by top-level callback', () => {
1312 ReactNoop.render(<div />, () => {
1313 throw new Error('Error!');
1314 });
1313 - expect(() => ReactNoop.flush()).toThrow('Error!');
1315 + expect(ReactNoop).toFlushAndThrow('Error!');
1316 });
1317
1318 it('error boundaries capture non-errors', () => {
@@ -1357,7 +1359,7 @@ describe('ReactIncrementalErrorHandling', () => {
1359 </Indirection>
1360 </ErrorBoundary>,
1361 );
1360 - ReactNoop.flush();
1362 + expect(ReactNoop).toFlushWithoutYielding();
1363
1364 expect(ops).toEqual([
1365 'ErrorBoundary (try)',
@@ -1428,7 +1430,7 @@ describe('ReactIncrementalErrorHandling', () => {
1430 </ErrorBoundary>,
1431 );
1432
1431 - expect(ReactNoop.flush()).toEqual([
1433 + expect(ReactNoop).toFlushAndYield([
1434 'ErrorBoundary (try)',
1435 'throw',
1436 // Continue rendering siblings after BadRender throws
@@ -1478,7 +1480,7 @@ describe('ReactIncrementalErrorHandling', () => {
1480 }
1481
1482 ReactNoop.render(<Parent step={1} />);
1481 - ReactNoop.flushThrough([
1483 + expect(ReactNoop).toFlushAndYieldThrough([
1484 'render',
1485 'throw',
1486 'render',
@@ -1520,7 +1522,7 @@ describe('ReactIncrementalErrorHandling', () => {
1522 <BrokenRender />
1523 </ErrorBoundary>,
1524 );
1523 - ReactNoop.flush();
1525 + expect(ReactNoop).toFlushAndYield(['render error message']);
1526 expect(ReactNoop.getChildren()).toEqual([
1527 span(
1528 'Caught an error:\n' +
@@ -1556,7 +1558,7 @@ describe('ReactIncrementalErrorHandling', () => {
1558 <BrokenRender />
1559 </ErrorBoundary>,
1560 );
1559 - ReactNoop.flush();
1561 + expect(ReactNoop).toFlushWithoutYielding();
1562 expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello')]);
1563 });
1564
@@ -1580,7 +1582,7 @@ describe('ReactIncrementalErrorHandling', () => {
1582
1583 ReactNoop.render(<Provider />);
1584 expect(() => {
1583 - expect(() => ReactNoop.flush()).toThrow('Oops!');
1585 + expect(ReactNoop).toFlushAndThrow('Oops!');
1586 }).toWarnDev(
1587 'Legacy context API has been detected within a strict-mode tree: \n\n' +
1588 'Please update the following components: Provider',
packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js
+4 -4
@@ -50,7 +50,7 @@ describe('ReactIncrementalErrorLogging', () => {
50 </span>
51 </div>,
52 );
53 - expect(() => ReactNoop.flush()).toThrowError('constructor error');
53 + expect(ReactNoop).toFlushAndThrow('constructor error');
54 expect(console.error).toHaveBeenCalledTimes(1);
55 expect(console.error).toHaveBeenCalledWith(
56 __DEV__
@@ -86,7 +86,7 @@ describe('ReactIncrementalErrorLogging', () => {
86 </span>
87 </div>,
88 );
89 - expect(() => ReactNoop.flush()).toThrowError('componentDidMount error');
89 + expect(ReactNoop).toFlushAndThrow('componentDidMount error');
90 expect(console.error).toHaveBeenCalledTimes(1);
91 expect(console.error).toHaveBeenCalledWith(
92 __DEV__
@@ -125,7 +125,7 @@ describe('ReactIncrementalErrorLogging', () => {
125 </span>
126 </div>,
127 );
128 - expect(() => ReactNoop.flush()).toThrow('render error');
128 + expect(ReactNoop).toFlushAndThrow('render error');
129 expect(logCapturedErrorCalls.length).toBe(1);
130 expect(logCapturedErrorCalls[0]).toEqual(
131 __DEV__
@@ -181,7 +181,7 @@ describe('ReactIncrementalErrorLogging', () => {
181 <Foo />
182 </ErrorBoundary>,
183 );
184 - expect(ReactNoop.flush()).toEqual(
184 + expect(ReactNoop).toFlushAndYield(
185 [
186 'render: 0',
187 __DEV__ && 'render: 0', // replay
packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js
+2 -2
@@ -22,7 +22,7 @@ describe('ReactIncrementalErrorReplay', () => {
22
23 it('should fail gracefully on error in the host environment', () => {
24 ReactNoop.render(<errorInBeginPhase />);
25 - expect(() => ReactNoop.flush()).toThrow('Error in host config.');
25 + expect(ReactNoop).toFlushAndThrow('Error in host config.');
26 });
27
28 it("should ignore error if it doesn't throw on retry", () => {
@@ -43,6 +43,6 @@ describe('ReactIncrementalErrorReplay', () => {
43 }
44 }
45 ReactNoop.render(<App />);
46 - expect(() => ReactNoop.flush()).not.toThrow();
46 + expect(ReactNoop).toFlushWithoutYielding();
47 });
48 });
packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+32 -31
@@ -144,7 +144,7 @@ describe('ReactDebugFiberPerf', () => {
144 </Parent>,
145 );
146 addComment('Mount');
147 - ReactNoop.flush();
147 + expect(ReactNoop).toFlushWithoutYielding();
148
149 ReactNoop.render(
150 <Parent>
@@ -152,11 +152,11 @@ describe('ReactDebugFiberPerf', () => {
152 </Parent>,
153 );
154 addComment('Update');
155 - ReactNoop.flush();
155 + expect(ReactNoop).toFlushWithoutYielding();
156
157 ReactNoop.render(null);
158 addComment('Unmount');
159 - ReactNoop.flush();
159 + expect(ReactNoop).toFlushWithoutYielding();
160
161 expect(getFlameChart()).toMatchSnapshot();
162 });
@@ -182,7 +182,7 @@ describe('ReactDebugFiberPerf', () => {
182 </Parent>,
183 );
184 addComment('Mount');
185 - ReactNoop.flush();
185 + expect(ReactNoop).toFlushWithoutYielding();
186
187 expect(getFlameChart()).toMatchSnapshot();
188 });
@@ -200,7 +200,7 @@ describe('ReactDebugFiberPerf', () => {
200 </React.unstable_Profiler>,
201 );
202 addComment('Mount');
203 - ReactNoop.flush();
203 + expect(ReactNoop).toFlushWithoutYielding();
204
205 expect(getFlameChart()).toMatchSnapshot();
206 });
@@ -216,7 +216,7 @@ describe('ReactDebugFiberPerf', () => {
216 </Provider>,
217 );
218 addComment('Mount');
219 - ReactNoop.flush();
219 + expect(ReactNoop).toFlushWithoutYielding();
220
221 expect(getFlameChart()).toMatchSnapshot();
222 });
@@ -248,13 +248,13 @@ describe('ReactDebugFiberPerf', () => {
248 </Parent>
249 </Parent>,
250 );
251 - ReactNoop.flush();
251 + expect(ReactNoop).toFlushWithoutYielding();
252 resetFlamechart();
253
254 a.setState({});
255 b.setState({});
256 addComment('Should include just A and B, no Parents');
257 - ReactNoop.flush();
257 + expect(ReactNoop).toFlushWithoutYielding();
258 expect(getFlameChart()).toMatchSnapshot();
259 });
260
@@ -274,7 +274,7 @@ describe('ReactDebugFiberPerf', () => {
274 </Parent>,
275 );
276 addComment('Should print a warning');
277 - ReactNoop.flush();
277 + expect(ReactNoop).toFlushWithoutYielding();
278 expect(getFlameChart()).toMatchSnapshot();
279 });
280
@@ -283,7 +283,7 @@ describe('ReactDebugFiberPerf', () => {
283 componentDidMount() {
284 ReactNoop.renderToRootWithID(<Child />, 'b');
285 addComment('Scheduling another root from componentDidMount');
286 - ReactNoop.flush();
286 + expect(ReactNoop).toFlushWithoutYielding();
287 }
288 render() {
289 return <div>{this.props.children}</div>;
@@ -292,7 +292,7 @@ describe('ReactDebugFiberPerf', () => {
292
293 ReactNoop.renderToRootWithID(<Cascading />, 'a');
294 addComment('Rendering the first root');
295 - ReactNoop.flush();
295 + expect(ReactNoop).toFlushWithoutYielding();
296 expect(getFlameChart()).toMatchSnapshot();
297 });
298
@@ -315,7 +315,7 @@ describe('ReactDebugFiberPerf', () => {
315 </Parent>,
316 );
317 addComment('Should not print a warning');
318 - expect(ReactNoop.flush).toWarnDev(
318 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
319 [
320 'componentWillMount: Please update the following components ' +
321 'to use componentDidMount instead: NotCascading' +
@@ -330,7 +330,7 @@ describe('ReactDebugFiberPerf', () => {
330 </Parent>,
331 );
332 addComment('Should not print a warning');
333 - ReactNoop.flush();
333 + expect(ReactNoop).toFlushWithoutYielding();
334 expect(getFlameChart()).toMatchSnapshot();
335 });
336
@@ -357,7 +357,7 @@ describe('ReactDebugFiberPerf', () => {
357 }
358 ReactNoop.render(<AllLifecycles />);
359 addComment('Mount');
360 - expect(ReactNoop.flush).toWarnDev(
360 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
361 [
362 'componentWillMount: Please update the following components ' +
363 'to use componentDidMount instead: AllLifecycles' +
@@ -372,10 +372,10 @@ describe('ReactDebugFiberPerf', () => {
372 );
373 ReactNoop.render(<AllLifecycles />);
374 addComment('Update');
375 - ReactNoop.flush();
375 + expect(ReactNoop).toFlushWithoutYielding();
376 ReactNoop.render(null);
377 addComment('Unmount');
378 - ReactNoop.flush();
378 + expect(ReactNoop).toFlushWithoutYielding();
379 expect(getFlameChart()).toMatchSnapshot();
380 });
381
@@ -391,7 +391,7 @@ describe('ReactDebugFiberPerf', () => {
391 );
392 });
393 addComment('Flush the child');
394 - ReactNoop.flush();
394 + expect(ReactNoop).toFlushWithoutYielding();
395 expect(getFlameChart()).toMatchSnapshot();
396 });
397
@@ -431,9 +431,9 @@ describe('ReactDebugFiberPerf', () => {
431 </Parent>,
432 );
433 addComment('Start rendering through B');
434 - ReactNoop.flushThrough(['A', 'B']);
434 + expect(ReactNoop).toFlushAndYieldThrough(['A', 'B']);
435 addComment('Complete the rest');
436 - ReactNoop.flush();
436 + expect(ReactNoop).toFlushAndYield(['C']);
437 expect(getFlameChart()).toMatchSnapshot();
438 });
439
@@ -449,7 +449,7 @@ describe('ReactDebugFiberPerf', () => {
449 );
450 try {
451 addComment('Will fatal');
452 - ReactNoop.flush();
452 + expect(ReactNoop).toFlushWithoutYielding();
453 } catch (err) {
454 expect(err.message).toBe('Game over');
455 }
@@ -459,7 +459,7 @@ describe('ReactDebugFiberPerf', () => {
459 </Parent>,
460 );
461 addComment('Will reconcile from a clean state');
462 - ReactNoop.flush();
462 + expect(ReactNoop).toFlushWithoutYielding();
463 expect(getFlameChart()).toMatchSnapshot();
464 });
465
@@ -495,7 +495,7 @@ describe('ReactDebugFiberPerf', () => {
495 </Parent>,
496 );
497 addComment('Stop on Baddie and restart from Boundary');
498 - ReactNoop.flush();
498 + expect(ReactNoop).toFlushWithoutYielding();
499 expect(getFlameChart()).toMatchSnapshot();
500 });
501
@@ -526,7 +526,7 @@ describe('ReactDebugFiberPerf', () => {
526 <B />
527 </Parent>,
528 );
529 - ReactNoop.flush();
529 + expect(ReactNoop).toFlushWithoutYielding();
530 resetFlamechart();
531
532 ReactNoop.render(
@@ -538,7 +538,7 @@ describe('ReactDebugFiberPerf', () => {
538 </Parent>,
539 );
540 addComment('The commit phase should mention A and B just once');
541 - ReactNoop.flush();
541 + expect(ReactNoop).toFlushWithoutYielding();
542 ReactNoop.render(
543 <Parent>
544 <A />
@@ -549,7 +549,7 @@ describe('ReactDebugFiberPerf', () => {
549 );
550 addComment("Because of deduplication, we don't know B was cascading,");
551 addComment('but we should still see the warning for the commit phase.');
552 - ReactNoop.flush();
552 + expect(ReactNoop).toFlushWithoutYielding();
553 expect(getFlameChart()).toMatchSnapshot();
554 });
555
@@ -562,7 +562,7 @@ describe('ReactDebugFiberPerf', () => {
562 {ReactNoop.createPortal(<Child />, portalContainer, null)}
563 </Parent>,
564 );
565 - ReactNoop.flush();
565 + expect(ReactNoop).toFlushWithoutYielding();
566 expect(getFlameChart()).toMatchSnapshot();
567 });
568
@@ -575,7 +575,7 @@ describe('ReactDebugFiberPerf', () => {
575 <MemoFoo />
576 </Parent>,
577 );
578 - ReactNoop.flush();
578 + expect(ReactNoop).toFlushWithoutYielding();
579 expect(getFlameChart()).toMatchSnapshot();
580 });
581
@@ -603,7 +603,7 @@ describe('ReactDebugFiberPerf', () => {
603 </React.Suspense>
604 </Parent>,
605 );
606 - ReactNoop.flush();
606 + expect(ReactNoop).toFlushWithoutYielding();
607 expect(getFlameChart()).toMatchSnapshot();
608
609 resolve(
@@ -621,7 +621,7 @@ describe('ReactDebugFiberPerf', () => {
621 </React.Suspense>
622 </Parent>,
623 );
624 - ReactNoop.flush();
624 + expect(ReactNoop).toFlushWithoutYielding();
625 expect(getFlameChart()).toMatchSnapshot();
626 });
627
@@ -652,7 +652,8 @@ describe('ReactDebugFiberPerf', () => {
652 ReactNoop.flushSync(() => {
653 ReactNoop.render(<Foo />);
654 });
655 - ReactNoop.flush();
655 + expect(ReactNoop).toHaveYielded(['Foo']);
656 + expect(ReactNoop).toFlushWithoutYielding();
657 expect(getFlameChart()).toMatchSnapshot();
658 });
659
@@ -663,7 +664,7 @@ describe('ReactDebugFiberPerf', () => {
664
665 ReactNoop.render(<Foo />);
666 ReactNoop.expire(6000);
666 - ReactNoop.flush();
667 + expect(ReactNoop).toFlushWithoutYielding();
668 expect(getFlameChart()).toMatchSnapshot();
669 });
670 });
packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js
+30 -18
@@ -23,6 +23,17 @@ describe('ReactIncrementalReflection', () => {
23 ReactNoop = require('react-noop-renderer');
24 });
25
26 + function div(...children) {
27 + children = children.map(
28 + c => (typeof c === 'string' ? {text: c, hidden: false} : c),
29 + );
30 + return {type: 'div', children, prop: undefined, hidden: false};
31 + }
32 +
33 + function span(prop) {
34 + return {type: 'span', children: [], prop, hidden: false};
35 + }
36 +
37 it('handles isMounted even when the initial render is deferred', () => {
38 const instances = [];
39
@@ -51,13 +62,13 @@ describe('ReactIncrementalReflection', () => {
62 ReactNoop.render(<Foo />);
63
64 // Render part way through but don't yet commit the updates.
54 - ReactNoop.flushThrough(['componentWillMount: false']);
65 + expect(ReactNoop).toFlushAndYieldThrough(['componentWillMount: false']);
66
67 expect(instances[0]._isMounted()).toBe(false);
68
69 // Render the rest and commit the updates.
70 expect(() =>
60 - expect(ReactNoop.flush()).toEqual(['componentDidMount: true']),
71 + expect(ReactNoop).toFlushAndYield(['componentDidMount: true']),
72 ).toWarnDev(
73 'componentWillMount: Please update the following components ' +
74 'to use componentDidMount instead: Component',
@@ -96,7 +107,7 @@ describe('ReactIncrementalReflection', () => {
107 }
108
109 ReactNoop.render(<Foo mount={true} />);
99 - expect(() => expect(ReactNoop.flush()).toEqual(['Component'])).toWarnDev(
110 + expect(() => expect(ReactNoop).toFlushAndYield(['Component'])).toWarnDev(
111 'componentWillMount: Please update the following components ' +
112 'to use componentDidMount instead: Component',
113 {withoutStack: true},
@@ -107,12 +118,12 @@ describe('ReactIncrementalReflection', () => {
118 ReactNoop.render(<Foo mount={false} />);
119 // Render part way through but don't yet commit the updates so it is not
120 // fully unmounted yet.
110 - ReactNoop.flushThrough(['Other']);
121 + expect(ReactNoop).toFlushAndYieldThrough(['Other']);
122
123 expect(instances[0]._isMounted()).toBe(true);
124
125 // Finish flushing the unmount.
115 - expect(ReactNoop.flush()).toEqual(['componentWillUnmount: true']);
126 + expect(ReactNoop).toFlushAndYield(['componentWillUnmount: true']);
127
128 expect(instances[0]._isMounted()).toBe(false);
129 });
@@ -174,7 +185,7 @@ describe('ReactIncrementalReflection', () => {
185
186 ReactNoop.render(<Foo step={0} />);
187 // Flush past Component but don't complete rendering everything yet.
177 - ReactNoop.flushThrough([
188 + expect(ReactNoop).toFlushAndYieldThrough([
189 ['componentWillMount', null],
190 'render',
191 'render sibling',
@@ -186,9 +197,7 @@ describe('ReactIncrementalReflection', () => {
197 expect(findInstance(classInstance)).toBe(null);
198
199 expect(() =>
189 - expect(ReactNoop.flush()).toEqual([
190 - ['componentDidMount', classInstance.span],
191 - ]),
200 + expect(ReactNoop).toFlushAndYield([['componentDidMount', span()]]),
201 ).toWarnDev(
202 'componentWillMount: Please update the following components ' +
203 'to use componentDidMount instead: Component' +
@@ -205,7 +214,7 @@ describe('ReactIncrementalReflection', () => {
214 // Flush next step which will cause an update but not yet render a new host
215 // node.
216 ReactNoop.render(<Foo step={1} />);
208 - expect(ReactNoop.flush()).toEqual([
217 + expect(ReactNoop).toFlushAndYield([
218 ['componentWillUpdate', hostSpan],
219 'render',
220 'render sibling',
@@ -217,7 +226,7 @@ describe('ReactIncrementalReflection', () => {
226 // The next step will render a new host node but won't get committed yet.
227 // We expect this to mutate the original Fiber.
228 ReactNoop.render(<Foo step={2} />);
220 - ReactNoop.flushThrough([
229 + expect(ReactNoop).toFlushAndYieldThrough([
230 ['componentWillUpdate', hostSpan],
231 'render',
232 'render sibling',
@@ -227,9 +236,7 @@ describe('ReactIncrementalReflection', () => {
236 expect(ReactNoop.findInstance(classInstance)).toBe(hostSpan);
237
238 // When we finally flush the tree it will get committed.
230 - expect(ReactNoop.flush()).toEqual([
231 - ['componentDidUpdate', classInstance.div],
232 - ]);
239 + expect(ReactNoop).toFlushAndYield([['componentDidUpdate', div()]]);
240
241 const hostDiv = classInstance.div;
242 expect(hostDiv).toBeDefined();
@@ -240,7 +247,7 @@ describe('ReactIncrementalReflection', () => {
247
248 // Render to null but don't commit it yet.
249 ReactNoop.render(<Foo step={3} />);
243 - ReactNoop.flushThrough([
250 + expect(ReactNoop).toFlushAndYieldThrough([
251 ['componentWillUpdate', hostDiv],
252 'render',
253 'render sibling',
@@ -249,17 +256,22 @@ describe('ReactIncrementalReflection', () => {
256 // This should still be the host div since the deletion is not committed.
257 expect(ReactNoop.findInstance(classInstance)).toBe(hostDiv);
258
252 - expect(ReactNoop.flush()).toEqual([['componentDidUpdate', null]]);
259 + expect(ReactNoop).toFlushAndYield([['componentDidUpdate', null]]);
260
261 // This should still be the host div since the deletion is not committed.
262 expect(ReactNoop.findInstance(classInstance)).toBe(null);
263
264 // Render a div again
265 ReactNoop.render(<Foo step={4} />);
259 - ReactNoop.flush();
266 + expect(ReactNoop).toFlushAndYield([
267 + ['componentWillUpdate', null],
268 + 'render',
269 + 'render sibling',
270 + ['componentDidUpdate', div()],
271 + ]);
272
273 // Unmount the component.
274 ReactNoop.render([]);
263 - expect(ReactNoop.flush()).toEqual([['componentWillUnmount', hostDiv]]);
275 + expect(ReactNoop).toFlushAndYield([['componentWillUnmount', hostDiv]]);
276 });
277 });
packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js
+45 -39
@@ -31,8 +31,8 @@ describe('ReactIncrementalScheduling', () => {
31 ReactNoop.render(<span prop="1" />);
32 expect(ReactNoop.getChildren()).toEqual([]);
33
34 - ReactNoop.flush();
35 - expect(ReactNoop.getChildren()).toEqual([span('1')]);
34 + expect(ReactNoop).toFlushWithoutYielding();
35 + expect(ReactNoop).toMatchRenderedOutput(<span prop="1" />);
36 });
37
38 it('searches for work on other roots once the current root completes', () => {
@@ -40,7 +40,7 @@ describe('ReactIncrementalScheduling', () => {
40 ReactNoop.renderToRootWithID(<span prop="b:1" />, 'b');
41 ReactNoop.renderToRootWithID(<span prop="c:1" />, 'c');
42
43 - ReactNoop.flush();
43 + expect(ReactNoop).toFlushWithoutYielding();
44
45 expect(ReactNoop.getChildren('a')).toEqual([span('a:1')]);
46 expect(ReactNoop.getChildren('b')).toEqual([span('b:1')]);
@@ -50,8 +50,8 @@ describe('ReactIncrementalScheduling', () => {
50 it('schedules top-level updates in order of priority', () => {
51 // Initial render.
52 ReactNoop.render(<span prop={1} />);
53 - ReactNoop.flush();
54 - expect(ReactNoop.getChildren()).toEqual([span(1)]);
53 + expect(ReactNoop).toFlushWithoutYielding();
54 + expect(ReactNoop).toMatchRenderedOutput(<span prop={1} />);
55
56 ReactNoop.batchedUpdates(() => {
57 ReactNoop.render(<span prop={5} />);
@@ -62,27 +62,27 @@ describe('ReactIncrementalScheduling', () => {
62 });
63 });
64 // The sync updates flush first.
65 - expect(ReactNoop.getChildren()).toEqual([span(4)]);
65 + expect(ReactNoop).toMatchRenderedOutput(<span prop={4} />);
66
67 // The terminal value should be the last update that was scheduled,
68 // regardless of priority. In this case, that's the last sync update.
69 - ReactNoop.flush();
70 - expect(ReactNoop.getChildren()).toEqual([span(4)]);
69 + expect(ReactNoop).toFlushWithoutYielding();
70 + expect(ReactNoop).toMatchRenderedOutput(<span prop={4} />);
71 });
72
73 it('schedules top-level updates with same priority in order of insertion', () => {
74 // Initial render.
75 ReactNoop.render(<span prop={1} />);
76 - ReactNoop.flush();
77 - expect(ReactNoop.getChildren()).toEqual([span(1)]);
76 + expect(ReactNoop).toFlushWithoutYielding();
77 + expect(ReactNoop).toMatchRenderedOutput(<span prop={1} />);
78
79 ReactNoop.render(<span prop={2} />);
80 ReactNoop.render(<span prop={3} />);
81 ReactNoop.render(<span prop={4} />);
82 ReactNoop.render(<span prop={5} />);
83
84 - ReactNoop.flush();
85 - expect(ReactNoop.getChildren()).toEqual([span(5)]);
84 + expect(ReactNoop).toFlushWithoutYielding();
85 + expect(ReactNoop).toMatchRenderedOutput(<span prop={5} />);
86 });
87
88 it('works on deferred roots in the order they were scheduled', () => {
@@ -102,7 +102,7 @@ describe('ReactIncrementalScheduling', () => {
102 ReactNoop.renderToRootWithID(<Text text="b:1" />, 'b');
103 ReactNoop.renderToRootWithID(<Text text="c:1" />, 'c');
104 });
105 - ReactNoop.flush();
105 + expect(ReactNoop).toFlushAndYield(['a:1', 'b:1', 'c:1']);
106
107 expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1');
108 expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:1');
@@ -114,7 +114,7 @@ describe('ReactIncrementalScheduling', () => {
114 ReactNoop.renderToRootWithID(<Text text="b:2" />, 'b');
115 });
116 // Ensure it starts in the order it was scheduled
117 - ReactNoop.flushThrough(['c:2']);
117 + expect(ReactNoop).toFlushAndYieldThrough(['c:2']);
118
119 expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1');
120 expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:1');
@@ -124,12 +124,12 @@ describe('ReactIncrementalScheduling', () => {
124 ReactNoop.renderToRootWithID(<Text text="a:2" />, 'a');
125 });
126 // Keep performing work in the order it was scheduled
127 - ReactNoop.flushThrough(['b:2']);
127 + expect(ReactNoop).toFlushAndYieldThrough(['b:2']);
128 expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1');
129 expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:2');
130 expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2');
131
132 - ReactNoop.flushThrough(['a:2']);
132 + expect(ReactNoop).toFlushAndYieldThrough(['a:2']);
133 expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:2');
134 expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:2');
135 expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2');
@@ -175,7 +175,7 @@ describe('ReactIncrementalScheduling', () => {
175
176 ReactNoop.render(<Foo />);
177 // Render without committing
178 - ReactNoop.flushThrough(['render: 0']);
178 + expect(ReactNoop).toFlushAndYieldThrough(['render: 0']);
179
180 // Do one more unit of work to commit
181 expect(ReactNoop.flushNextYield()).toEqual([
@@ -188,7 +188,7 @@ describe('ReactIncrementalScheduling', () => {
188 ]);
189
190 instance.setState({tick: 2});
191 - ReactNoop.flushThrough(['render: 2']);
191 + expect(ReactNoop).toFlushAndYieldThrough(['render: 2']);
192 expect(ReactNoop.flushNextYield()).toEqual([
193 'componentDidUpdate: 2',
194 'componentDidUpdate (before setState): 2',
@@ -243,27 +243,31 @@ describe('ReactIncrementalScheduling', () => {
243 ReactNoop.render(<Foo />);
244 });
245 // The cDM update should not have flushed yet because it has async priority.
246 - expect(ReactNoop.getChildren()).toEqual([span(0)]);
246 + expect(ReactNoop).toHaveYielded([
247 + 'render: 0',
248 + 'componentDidMount (before setState): 0',
249 + 'componentDidMount (after setState): 0',
250 + ]);
251 + expect(ReactNoop).toMatchRenderedOutput(<span prop={0} />);
252
253 // Now flush the cDM update.
249 - ReactNoop.clearYields();
250 - expect(ReactNoop.flush()).toEqual(['render: 1', 'componentDidUpdate: 1']);
251 - expect(ReactNoop.getChildren()).toEqual([span(1)]);
254 + expect(ReactNoop).toFlushAndYield(['render: 1', 'componentDidUpdate: 1']);
255 + expect(ReactNoop).toMatchRenderedOutput(<span prop={1} />);
256
257 // Increment the tick to 2. This will trigger an update inside cDU. Flush
258 // the first update without flushing the second one.
259 instance.setState({tick: 2});
256 - ReactNoop.flushThrough([
260 + expect(ReactNoop).toFlushAndYieldThrough([
261 'render: 2',
262 'componentDidUpdate: 2',
263 'componentDidUpdate (before setState): 2',
264 'componentDidUpdate (after setState): 2',
265 ]);
262 - expect(ReactNoop.getChildren()).toEqual([span(2)]);
266 + expect(ReactNoop).toMatchRenderedOutput(<span prop={2} />);
267
268 // Now flush the cDU update.
265 - expect(ReactNoop.flush()).toEqual(['render: 3', 'componentDidUpdate: 3']);
266 - expect(ReactNoop.getChildren()).toEqual([span(3)]);
269 + expect(ReactNoop).toFlushAndYield(['render: 3', 'componentDidUpdate: 3']);
270 + expect(ReactNoop).toMatchRenderedOutput(<span prop={3} />);
271 });
272
273 it('performs Task work even after time runs out', () => {
@@ -286,13 +290,13 @@ describe('ReactIncrementalScheduling', () => {
290 ReactNoop.render(<Foo />);
291 // This should be just enough to complete all the work, but not enough to
292 // commit it.
289 - ReactNoop.flushThrough(['Foo']);
290 - expect(ReactNoop.getChildren()).toEqual([]);
293 + expect(ReactNoop).toFlushAndYieldThrough(['Foo']);
294 + expect(ReactNoop).toMatchRenderedOutput(null);
295
296 // Do one more unit of work.
297 ReactNoop.flushNextYield();
298 // The updates should all be flushed with Task priority
295 - expect(ReactNoop.getChildren()).toEqual([span(5)]);
299 + expect(ReactNoop).toMatchRenderedOutput(<span prop={5} />);
300 });
301
302 it('can opt-out of batching using unbatchedUpdates', () => {
@@ -305,16 +309,16 @@ describe('ReactIncrementalScheduling', () => {
309 // updates are not batched
310 ReactNoop.unbatchedUpdates(() => {
311 ReactNoop.render(<span prop={1} />);
308 - expect(ReactNoop.getChildren()).toEqual([span(1)]);
312 + expect(ReactNoop).toMatchRenderedOutput(<span prop={1} />);
313 ReactNoop.render(<span prop={2} />);
310 - expect(ReactNoop.getChildren()).toEqual([span(2)]);
314 + expect(ReactNoop).toMatchRenderedOutput(<span prop={2} />);
315 });
316
317 ReactNoop.render(<span prop={3} />);
314 - expect(ReactNoop.getChildren()).toEqual([span(2)]);
318 + expect(ReactNoop).toMatchRenderedOutput(<span prop={2} />);
319 });
320 // Remaining update is now flushed
317 - expect(ReactNoop.getChildren()).toEqual([span(3)]);
321 + expect(ReactNoop).toMatchRenderedOutput(<span prop={3} />);
322 });
323
324 it('nested updates are always deferred, even inside unbatchedUpdates', () => {
@@ -331,7 +335,7 @@ describe('ReactIncrementalScheduling', () => {
335 // in unbatchedUpdates.
336 this.setState({step: 2});
337 });
334 - expect(ReactNoop.getChildren()).toEqual([span(1)]);
338 + expect(ReactNoop).toMatchRenderedOutput(<span prop={1} />);
339 }
340 }
341 render() {
@@ -341,13 +345,13 @@ describe('ReactIncrementalScheduling', () => {
345 }
346 }
347 ReactNoop.render(<Foo />);
344 - ReactNoop.flush();
345 - expect(ReactNoop.getChildren()).toEqual([span(0)]);
348 + expect(ReactNoop).toFlushWithoutYielding();
349 + expect(ReactNoop).toMatchRenderedOutput(<span prop={0} />);
350
351 ReactNoop.flushSync(() => {
352 instance.setState({step: 1});
353 });
350 - expect(ReactNoop.getChildren()).toEqual([span(2)]);
354 + expect(ReactNoop).toMatchRenderedOutput(<span prop={2} />);
355
356 expect(ops).toEqual([
357 'render: 0',
@@ -376,14 +380,16 @@ describe('ReactIncrementalScheduling', () => {
380 }
381
382 ReactNoop.render(<Foo step={1} />);
379 - expect(ReactNoop.flush).toWarnDev(
383 + expect(() => {
384 + expect(ReactNoop).toFlushWithoutYielding();
385 + }).toWarnDev(
386 'componentWillReceiveProps: Please update the following components ' +
387 'to use static getDerivedStateFromProps instead: Foo',
388 {withoutStack: true},
389 );
390
391 ReactNoop.render(<Foo step={2} />);
386 - expect(ReactNoop.flush()).toEqual([
392 + expect(ReactNoop).toFlushAndYield([
393 'has callback before setState: false',
394 'has callback after setState: false',
395 ]);
packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js
+61 -61
@@ -53,11 +53,11 @@ describe('ReactIncrementalSideEffects', () => {
53 }
54
55 ReactNoop.render(<Foo text="Hello" />);
56 - ReactNoop.flush();
56 + expect(ReactNoop).toFlushWithoutYielding();
57 expect(ReactNoop.getChildren()).toEqual([div(span())]);
58
59 ReactNoop.render(<Foo text="World" />);
60 - ReactNoop.flush();
60 + expect(ReactNoop).toFlushWithoutYielding();
61 expect(ReactNoop.getChildren()).toEqual([div(span(), span())]);
62 });
63
@@ -81,17 +81,17 @@ describe('ReactIncrementalSideEffects', () => {
81 }
82
83 ReactNoop.render(<Foo text="Hello" />);
84 - ReactNoop.flush();
84 + expect(ReactNoop).toFlushWithoutYielding();
85 expect(ReactNoop.getChildren()).toEqual([div(span(), span('test'))]);
86
87 ReactNoop.render(<Foo text="World" />);
88 - ReactNoop.flush();
88 + expect(ReactNoop).toFlushWithoutYielding();
89 expect(ReactNoop.getChildren()).toEqual([
90 div(span(), span(), div(), span('test')),
91 ]);
92
93 ReactNoop.render(<Foo text="Hi" />);
94 - ReactNoop.flush();
94 + expect(ReactNoop).toFlushWithoutYielding();
95 expect(ReactNoop.getChildren()).toEqual([
96 div(span(), div(), span(), span('test')),
97 ]);
@@ -114,11 +114,11 @@ describe('ReactIncrementalSideEffects', () => {
114 }
115
116 ReactNoop.render(<Foo text="Hello" />);
117 - ReactNoop.flush();
117 + expect(ReactNoop).toFlushWithoutYielding();
118 expect(ReactNoop.getChildren()).toEqual([div('Hello')]);
119
120 ReactNoop.render(<Foo text="World" />);
121 - ReactNoop.flush();
121 + expect(ReactNoop).toFlushWithoutYielding();
122 expect(ReactNoop.getChildren()).toEqual([div('World', 'World', '!')]);
123 });
124
@@ -138,13 +138,13 @@ describe('ReactIncrementalSideEffects', () => {
138 }
139
140 ReactNoop.render(<Foo show={true} />);
141 - ReactNoop.flush();
141 + expect(ReactNoop).toFlushWithoutYielding();
142 expect(ReactNoop.getChildren()).toEqual([
143 div(div(), span('Hello'), 'World'),
144 ]);
145
146 ReactNoop.render(<Foo show={false} />);
147 - ReactNoop.flush();
147 + expect(ReactNoop).toFlushWithoutYielding();
148 expect(ReactNoop.getChildren()).toEqual([div()]);
149 });
150
@@ -180,23 +180,23 @@ describe('ReactIncrementalSideEffects', () => {
180 }
181
182 ReactNoop.render(<Foo useClass={true} />);
183 - ReactNoop.flush();
183 + expect(ReactNoop).toFlushWithoutYielding();
184 expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]);
185
186 expect(unmounted).toBe(false);
187
188 ReactNoop.render(<Foo useFunction={true} />);
189 - ReactNoop.flush();
189 + expect(ReactNoop).toFlushWithoutYielding();
190 expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]);
191
192 expect(unmounted).toBe(true);
193
194 ReactNoop.render(<Foo useText={true} />);
195 - ReactNoop.flush();
195 + expect(ReactNoop).toFlushWithoutYielding();
196 expect(ReactNoop.getChildren()).toEqual([div('Text', 'Trail')]);
197
198 ReactNoop.render(<Foo />);
199 - ReactNoop.flush();
199 + expect(ReactNoop).toFlushWithoutYielding();
200 expect(ReactNoop.getChildren()).toEqual([div('Trail')]);
201 });
202
@@ -230,19 +230,19 @@ describe('ReactIncrementalSideEffects', () => {
230 }
231
232 ReactNoop.render(<Foo useClass={true} />);
233 - ReactNoop.flush();
233 + expect(ReactNoop).toFlushWithoutYielding();
234 expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]);
235
236 expect(unmounted).toBe(false);
237
238 ReactNoop.render(<Foo useFunction={true} />);
239 - ReactNoop.flush();
239 + expect(ReactNoop).toFlushWithoutYielding();
240 expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]);
241
242 expect(unmounted).toBe(true);
243
244 ReactNoop.render(<Foo />);
245 - ReactNoop.flush();
245 + expect(ReactNoop).toFlushWithoutYielding();
246 expect(ReactNoop.getChildren()).toEqual([div('Trail')]);
247 });
248
@@ -267,7 +267,7 @@ describe('ReactIncrementalSideEffects', () => {
267 <Foo show={true} />
268 </div>,
269 );
270 - ReactNoop.flush();
270 + expect(ReactNoop).toFlushWithoutYielding();
271 expect(ReactNoop.getChildren()).toEqual([div()]);
272 expect(ReactNoop.getChildren('portalContainer')).toEqual([
273 div(),
@@ -280,7 +280,7 @@ describe('ReactIncrementalSideEffects', () => {
280 <Foo show={false} />
281 </div>,
282 );
283 - ReactNoop.flush();
283 + expect(ReactNoop).toFlushWithoutYielding();
284 expect(ReactNoop.getChildren()).toEqual([div()]);
285 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
286
@@ -289,7 +289,7 @@ describe('ReactIncrementalSideEffects', () => {
289 <Foo show={true} />
290 </div>,
291 );
292 - ReactNoop.flush();
292 + expect(ReactNoop).toFlushWithoutYielding();
293 expect(ReactNoop.getChildren()).toEqual([div()]);
294 expect(ReactNoop.getChildren('portalContainer')).toEqual([
295 div(),
@@ -298,17 +298,17 @@ describe('ReactIncrementalSideEffects', () => {
298 ]);
299
300 ReactNoop.render(null);
301 - ReactNoop.flush();
301 + expect(ReactNoop).toFlushWithoutYielding();
302 expect(ReactNoop.getChildren()).toEqual([]);
303 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
304
305 ReactNoop.render(<Foo show={false} />);
306 - ReactNoop.flush();
306 + expect(ReactNoop).toFlushWithoutYielding();
307 expect(ReactNoop.getChildren()).toEqual([]);
308 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
309
310 ReactNoop.render(<Foo show={true} />);
311 - ReactNoop.flush();
311 + expect(ReactNoop).toFlushWithoutYielding();
312 expect(ReactNoop.getChildren()).toEqual([]);
313 expect(ReactNoop.getChildren('portalContainer')).toEqual([
314 div(),
@@ -317,7 +317,7 @@ describe('ReactIncrementalSideEffects', () => {
317 ]);
318
319 ReactNoop.render(null);
320 - ReactNoop.flush();
320 + expect(ReactNoop).toFlushWithoutYielding();
321 expect(ReactNoop.getChildren()).toEqual([]);
322 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
323 });
@@ -343,7 +343,7 @@ describe('ReactIncrementalSideEffects', () => {
343 <Foo />
344 </div>,
345 );
346 - ReactNoop.flush();
346 + expect(ReactNoop).toFlushWithoutYielding();
347 expect(ReactNoop.getChildren()).toEqual([div()]);
348 expect(ReactNoop.getChildren('portalContainer')).toEqual([
349 div(),
@@ -352,12 +352,12 @@ describe('ReactIncrementalSideEffects', () => {
352 ]);
353
354 ReactNoop.render(null);
355 - ReactNoop.flush();
355 + expect(ReactNoop).toFlushWithoutYielding();
356 expect(ReactNoop.getChildren()).toEqual([]);
357 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
358
359 ReactNoop.render(<Foo />);
360 - ReactNoop.flush();
360 + expect(ReactNoop).toFlushWithoutYielding();
361 expect(ReactNoop.getChildren()).toEqual([]);
362 expect(ReactNoop.getChildren('portalContainer')).toEqual([
363 div(),
@@ -366,7 +366,7 @@ describe('ReactIncrementalSideEffects', () => {
366 ]);
367
368 ReactNoop.render(null);
369 - ReactNoop.flush();
369 + expect(ReactNoop).toFlushWithoutYielding();
370 expect(ReactNoop.getChildren()).toEqual([]);
371 expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
372 });
@@ -391,7 +391,7 @@ describe('ReactIncrementalSideEffects', () => {
391 }
392
393 ReactNoop.render(<Foo text="Hello" />);
394 - ReactNoop.flush();
394 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar', 'Bar']);
395 expect(ReactNoop.getChildren()).toEqual([
396 div(div(span('Hello'), span('Hello')), span('Yo')),
397 ]);
@@ -399,7 +399,7 @@ describe('ReactIncrementalSideEffects', () => {
399 ReactNoop.render(<Foo text="World" />);
400
401 // Flush some of the work without committing
402 - ReactNoop.flushThrough(['Foo', 'Bar']);
402 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']);
403 expect(ReactNoop.getChildren()).toEqual([
404 div(div(span('Hello'), span('Hello')), span('Yo')),
405 ]);
@@ -423,7 +423,7 @@ describe('ReactIncrementalSideEffects', () => {
423 }
424
425 ReactNoop.render(<Foo text="foo" />);
426 - ReactNoop.flush();
426 + expect(ReactNoop).toFlushAndYield(['Foo', 'Middle']);
427
428 expect(ReactNoop.getChildrenAsJSX()).toEqual(
429 <div>
@@ -434,7 +434,7 @@ describe('ReactIncrementalSideEffects', () => {
434 );
435
436 ReactNoop.render(<Foo text="bar" />, () => ReactNoop.yield('commit'));
437 - ReactNoop.flushThrough(['Foo', 'commit']);
437 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'commit']);
438 expect(ReactNoop.getChildrenAsJSX()).toEqual(
439 <div>
440 <div hidden={true}>
@@ -443,7 +443,7 @@ describe('ReactIncrementalSideEffects', () => {
443 </div>,
444 );
445
446 - ReactNoop.flush();
446 + expect(ReactNoop).toFlushAndYield(['Middle']);
447 expect(ReactNoop.getChildrenAsJSX()).toEqual(
448 <div>
449 <div hidden={true}>
@@ -484,7 +484,7 @@ describe('ReactIncrementalSideEffects', () => {
484
485 // Init
486 ReactNoop.render(<Foo text="foo" step={0} />);
487 - ReactNoop.flush();
487 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar']);
488
489 expect(ReactNoop.getChildrenAsJSX()).toEqual(
490 <div hidden={true}>
@@ -500,7 +500,7 @@ describe('ReactIncrementalSideEffects', () => {
500 ReactNoop.render(<Foo text="bar" step={1} />, () =>
501 ReactNoop.yield('commit'),
502 );
503 - ReactNoop.flushThrough(['Foo', 'commit', 'Bar']);
503 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'commit', 'Bar']);
504
505 // The tree remains unchanged.
506 expect(ReactNoop.getChildrenAsJSX()).toEqual(
@@ -516,7 +516,7 @@ describe('ReactIncrementalSideEffects', () => {
516 // render some higher priority work. The middle content will bailout so
517 // it remains untouched which means that it should reuse it next time.
518 ReactNoop.render(<Foo text="foo" step={1} />);
519 - ReactNoop.flush();
519 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar']);
520
521 // Since we did nothing to the middle subtree during the interruption,
522 // we should be able to reuse the reconciliation work that we already did
@@ -569,7 +569,7 @@ describe('ReactIncrementalSideEffects', () => {
569
570 // Init
571 ReactNoop.render(<Foo text="foo" step={0} />);
572 - ReactNoop.flush();
572 + expect(ReactNoop).toFlushAndYield(['Foo', 'Content', 'Bar', 'Bar']);
573
574 expect(ReactNoop.getChildrenAsJSX()).toEqual(
575 <div hidden={true}>
@@ -583,7 +583,7 @@ describe('ReactIncrementalSideEffects', () => {
583 // Make a quick update which will schedule low priority work to
584 // update the middle content.
585 ReactNoop.render(<Foo text="bar" step={1} />);
586 - ReactNoop.flushThrough(['Foo', 'Content', 'Bar']);
586 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Content', 'Bar']);
587
588 // The tree remains unchanged.
589 expect(ReactNoop.getChildrenAsJSX()).toEqual(
@@ -599,7 +599,7 @@ describe('ReactIncrementalSideEffects', () => {
599 // render some higher priority work. The middle content will bailout so
600 // it remains untouched which means that it should reuse it next time.
601 ReactNoop.render(<Foo text="foo" step={1} />);
602 - ReactNoop.flush();
602 + expect(ReactNoop).toFlushAndYield(['Foo', 'Content', 'Bar', 'Bar']);
603
604 // Since we did nothing to the middle subtree during the interruption,
605 // we should be able to reuse the reconciliation work that we already did
@@ -622,7 +622,7 @@ describe('ReactIncrementalSideEffects', () => {
622 }
623 ReactNoop.render(<Foo step={1} />);
624 // This should be just enough to complete the tree without committing it
625 - ReactNoop.flushThrough(['Foo']);
625 + expect(ReactNoop).toFlushAndYieldThrough(['Foo']);
626 expect(ReactNoop.getChildrenAsJSX()).toEqual(null);
627 // To confirm, perform one more unit of work. The tree should now
628 // be flushed.
@@ -631,7 +631,7 @@ describe('ReactIncrementalSideEffects', () => {
631
632 ReactNoop.render(<Foo step={2} />);
633 // This should be just enough to complete the tree without committing it
634 - ReactNoop.flushThrough(['Foo']);
634 + expect(ReactNoop).toFlushAndYieldThrough(['Foo']);
635 expect(ReactNoop.getChildrenAsJSX()).toEqual(<span prop={1} />);
636 // This time, before we commit the tree, we update the root component with
637 // new props
@@ -643,7 +643,7 @@ describe('ReactIncrementalSideEffects', () => {
643 expect(ReactNoop.getChildrenAsJSX()).toEqual(<span prop={2} />);
644 // If we flush the rest of the work, we should get another commit that
645 // renders 3. If it renders 2 again, that means an update was dropped.
646 - ReactNoop.flush();
646 + expect(ReactNoop).toFlushWithoutYielding();
647 expect(ReactNoop.getChildrenAsJSX()).toEqual(<span prop={3} />);
648 });
649
@@ -657,7 +657,7 @@ describe('ReactIncrementalSideEffects', () => {
657 }
658
659 ReactNoop.render(<Foo />);
660 - ReactNoop.flush();
660 + expect(ReactNoop).toFlushWithoutYielding();
661 expect(ReactNoop.getChildrenAsJSX()).toEqual(
662 <div hidden={true}>
663 <span prop={1} />
@@ -723,7 +723,7 @@ describe('ReactIncrementalSideEffects', () => {
723 ),
724 ]);
725 ReactNoop.render(<Foo tick={3} idx={1} />);
726 - ReactNoop.flush();
726 + expect(ReactNoop).toFlushWithoutYielding();
727 expect(ReactNoop.getChildren()).toEqual([
728 div(
729 span(3),
@@ -800,7 +800,7 @@ describe('ReactIncrementalSideEffects', () => {
800 expect(ops).toEqual(['Foo']);
801 ops = [];
802
803 - ReactNoop.flush();
803 + expect(ReactNoop).toFlushWithoutYielding();
804 expect(ReactNoop.getChildren()).toEqual([
805 div(
806 span(1),
@@ -867,7 +867,7 @@ describe('ReactIncrementalSideEffects', () => {
867
868 // We should now be able to reuse some of the work we've already done
869 // and replay those side-effects.
870 - ReactNoop.flush();
870 + expect(ReactNoop).toFlushWithoutYielding();
871 expect(ReactNoop.getChildren()).toEqual([
872 div(
873 span(3),
@@ -917,7 +917,7 @@ describe('ReactIncrementalSideEffects', () => {
917 );
918 }
919 ReactNoop.render(<Foo tick={0} idx={0} />);
920 - expect(ReactNoop.flush()).toEqual(['Foo', 'Bar', 'Bar', 'Bar']);
920 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar', 'Bar']);
921 expect(ReactNoop.getChildrenAsJSX()).toEqual(
922 <div>
923 <span prop={0} />
@@ -930,7 +930,7 @@ describe('ReactIncrementalSideEffects', () => {
930 );
931
932 ReactNoop.render(<Foo tick={1} idx={1} />);
933 - ReactNoop.flushThrough(['Foo', 'Bar', 'Bar']);
933 + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar', 'Bar']);
934 expect(ReactNoop.getChildrenAsJSX()).toEqual(
935 <div>
936 {/* Updated */}
@@ -948,7 +948,7 @@ describe('ReactIncrementalSideEffects', () => {
948 // This should not be enough time to render the content of all the hidden
949 // items. Including the set state since that is deprioritized.
950 // ReactNoop.flushDeferredPri(35);
951 - ReactNoop.flushThrough(['Bar']);
951 + expect(ReactNoop).toFlushAndYieldThrough(['Bar']);
952 expect(ReactNoop.getChildrenAsJSX()).toEqual(
953 <div>
954 {/* Updated */}
@@ -964,7 +964,7 @@ describe('ReactIncrementalSideEffects', () => {
964
965 // However, once we render fully, we will have enough time to finish it all
966 // at once.
967 - expect(ReactNoop.flush()).toEqual(['Bar', 'Bar', 'Bar']);
967 + expect(ReactNoop).toFlushAndYield(['Bar', 'Bar', 'Bar']);
968 expect(ReactNoop.getChildrenAsJSX()).toEqual(
969 <div>
970 <span prop={1} />
@@ -995,14 +995,14 @@ describe('ReactIncrementalSideEffects', () => {
995 }
996
997 ReactNoop.render(<Foo />);
998 - ReactNoop.flush();
998 + expect(ReactNoop).toFlushWithoutYielding();
999 expect(ReactNoop.getChildren()).toEqual([span('foo')]);
1000 let called = false;
1001 instance.setState({text: 'bar'}, () => {
1002 expect(ReactNoop.getChildren()).toEqual([span('bar')]);
1003 called = true;
1004 });
1005 - ReactNoop.flush();
1005 + expect(ReactNoop).toFlushWithoutYielding();
1006 expect(called).toBe(true);
1007 });
1008
@@ -1023,13 +1023,13 @@ describe('ReactIncrementalSideEffects', () => {
1023 }
1024
1025 ReactNoop.render(<Foo />);
1026 - ReactNoop.flush();
1026 + expect(ReactNoop).toFlushWithoutYielding();
1027 expect(ReactNoop.getChildren()).toEqual([span('foo')]);
1028 let called = false;
1029 instance.setState({}, () => {
1030 called = true;
1031 });
1032 - ReactNoop.flush();
1032 + expect(ReactNoop).toFlushWithoutYielding();
1033 expect(called).toBe(true);
1034 });
1035
@@ -1077,11 +1077,11 @@ describe('ReactIncrementalSideEffects', () => {
1077 }
1078
1079 ReactNoop.render(<Foo show={true} />);
1080 - ReactNoop.flush();
1080 + expect(ReactNoop).toFlushWithoutYielding();
1081 expect(ops).toEqual([]);
1082
1083 ReactNoop.render(<Foo show={false} />);
1084 - ReactNoop.flush();
1084 + expect(ReactNoop).toFlushWithoutYielding();
1085 expect(ops).toEqual([
1086 'A',
1087 'Wrapper',
@@ -1140,7 +1140,7 @@ describe('ReactIncrementalSideEffects', () => {
1140 }
1141
1142 ReactNoop.render(<Foo />);
1143 - ReactNoop.flush();
1143 + expect(ReactNoop).toFlushWithoutYielding();
1144 expect(ops).toEqual([
1145 'mount:A',
1146 'mount:B',
@@ -1156,7 +1156,7 @@ describe('ReactIncrementalSideEffects', () => {
1156 ops = [];
1157
1158 ReactNoop.render(<Foo />);
1159 - ReactNoop.flush();
1159 + expect(ReactNoop).toFlushWithoutYielding();
1160 expect(ops).toEqual([
1161 'update:A',
1162 'update:B',
@@ -1197,7 +1197,7 @@ describe('ReactIncrementalSideEffects', () => {
1197 }
1198
1199 ReactNoop.render(<Foo show={true} />);
1200 - expect(ReactNoop.flush).toWarnDev(
1200 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1201 'Warning: Function components cannot be given refs. ' +
1202 'Attempts to access this ref will fail. ' +
1203 'Did you mean to use React.forwardRef()?\n\n' +
@@ -1217,7 +1217,7 @@ describe('ReactIncrementalSideEffects', () => {
1217
1218 // Refs that switch function instances get reinvoked
1219 ReactNoop.render(<Foo show={true} />);
1220 - ReactNoop.flush();
1220 + expect(ReactNoop).toFlushWithoutYielding();
1221 expect(ops).toEqual([
1222 // detach all refs that switched handlers first.
1223 null,
@@ -1230,7 +1230,7 @@ describe('ReactIncrementalSideEffects', () => {
1230 ops = [];
1231
1232 ReactNoop.render(<Foo show={false} />);
1233 - ReactNoop.flush();
1233 + expect(ReactNoop).toFlushWithoutYielding();
1234 expect(ops).toEqual([
1235 // unmount
1236 null,
@@ -1261,7 +1261,7 @@ describe('ReactIncrementalSideEffects', () => {
1261 }
1262
1263 ReactNoop.render(<Foo />);
1264 - expect(ReactNoop.flush).toWarnDev(
1264 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1265 'Warning: A string ref, "bar", has been found within a strict mode tree.',
1266 );
1267
packages/react-reconciler/src/__tests__/ReactIncrementalTriangle-test.internal.js
+3 -3
@@ -306,7 +306,7 @@ describe('ReactIncrementalTriangle', () => {
306 } else {
307 ReactNoop.render(<App remainingDepth={MAX_DEPTH} key={keyCounter++} />);
308 }
309 - ReactNoop.flush();
309 + ReactNoop.unstable_flushWithoutYielding();
310 assertConsistentTree();
311 return appInstance;
312 }
@@ -388,7 +388,7 @@ describe('ReactIncrementalTriangle', () => {
388 ReactNoop.unstable_flushNumberOfYields(action.unitsOfWork);
389 break;
390 case FLUSH_ALL:
391 - ReactNoop.flush();
391 + ReactNoop.unstable_flushWithoutYielding();
392 break;
393 case STEP:
394 ReactNoop.deferredUpdates(() => {
@@ -430,7 +430,7 @@ describe('ReactIncrementalTriangle', () => {
430 assertConsistentTree(activeLeafIndices);
431 }
432 // Flush remaining work
433 - ReactNoop.flush();
433 + ReactNoop.unstable_flushWithoutYielding();
434 assertConsistentTree(activeLeafIndices, expectedCounterAtEnd);
435 }
436
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.internal.js
+24 -24
@@ -48,9 +48,9 @@ describe('ReactIncrementalUpdates', () => {
48 }
49
50 ReactNoop.render(<Foo />);
51 - ReactNoop.flushThrough(['commit']);
51 + expect(ReactNoop).toFlushAndYieldThrough(['commit']);
52 expect(state).toEqual({a: 'a'});
53 - ReactNoop.flush();
53 + expect(ReactNoop).toFlushWithoutYielding();
54 expect(state).toEqual({a: 'a', b: 'b', c: 'c'});
55 });
56
@@ -71,7 +71,7 @@ describe('ReactIncrementalUpdates', () => {
71 }
72
73 ReactNoop.render(<Foo />);
74 - ReactNoop.flush();
74 + expect(ReactNoop).toFlushWithoutYielding();
75 expect(state).toEqual({a: 'a', b: 'b', c: 'c'});
76 });
77
@@ -94,7 +94,7 @@ describe('ReactIncrementalUpdates', () => {
94 }
95
96 ReactNoop.render(<Foo />);
97 - ReactNoop.flush();
97 + expect(ReactNoop).toFlushWithoutYielding();
98
99 ReactNoop.flushSync(() => {
100 ReactNoop.deferredUpdates(() => {
@@ -121,7 +121,7 @@ describe('ReactIncrementalUpdates', () => {
121
122 ops = [];
123
124 - ReactNoop.flush();
124 + expect(ReactNoop).toFlushWithoutYielding();
125 // Now the rest of the updates are flushed, including the replaceState.
126 expect(instance.state).toEqual({c: 'c', d: 'd'});
127 expect(ops).toEqual(['render', 'componentDidUpdate']);
@@ -144,7 +144,7 @@ describe('ReactIncrementalUpdates', () => {
144 }
145
146 ReactNoop.render(<Foo />);
147 - ReactNoop.flush();
147 + expect(ReactNoop).toFlushWithoutYielding();
148
149 function createUpdate(letter) {
150 return () => {
@@ -161,7 +161,7 @@ describe('ReactIncrementalUpdates', () => {
161 instance.setState(createUpdate('c'));
162
163 // Begin the updates but don't flush them yet
164 - ReactNoop.flushThrough(['a', 'b', 'c']);
164 + expect(ReactNoop).toFlushAndYieldThrough(['a', 'b', 'c']);
165 expect(ReactNoop.getChildren()).toEqual([span('')]);
166
167 // Schedule some more updates at different priorities
@@ -173,13 +173,13 @@ describe('ReactIncrementalUpdates', () => {
173 instance.setState(createUpdate('g'));
174
175 // The sync updates should have flushed, but not the async ones
176 + expect(ReactNoop).toHaveYielded(['e', 'f']);
177 expect(ReactNoop.getChildren()).toEqual([span('ef')]);
178
179 // Now flush the remaining work. Even though e and f were already processed,
180 // they should be processed again, to ensure that the terminal state
181 // is deterministic.
181 - ReactNoop.clearYields();
182 - expect(ReactNoop.flush()).toEqual([
182 + expect(ReactNoop).toFlushAndYield([
183 'a',
184 'b',
185 'c',
@@ -215,7 +215,7 @@ describe('ReactIncrementalUpdates', () => {
215 }
216
217 ReactNoop.render(<Foo />);
218 - ReactNoop.flush();
218 + expect(ReactNoop).toFlushWithoutYielding();
219
220 function createUpdate(letter) {
221 return () => {
@@ -232,7 +232,7 @@ describe('ReactIncrementalUpdates', () => {
232 instance.setState(createUpdate('c'));
233
234 // Begin the updates but don't flush them yet
235 - ReactNoop.flushThrough(['a', 'b', 'c']);
235 + expect(ReactNoop).toFlushAndYieldThrough(['a', 'b', 'c']);
236 expect(ReactNoop.getChildren()).toEqual([span('')]);
237
238 // Schedule some more updates at different priorities{
@@ -247,13 +247,13 @@ describe('ReactIncrementalUpdates', () => {
247
248 // The sync updates should have flushed, but not the async ones. Update d
249 // was dropped and replaced by e.
250 + expect(ReactNoop).toHaveYielded(['e', 'f']);
251 expect(ReactNoop.getChildren()).toEqual([span('f')]);
252
253 // Now flush the remaining work. Even though e and f were already processed,
254 // they should be processed again, to ensure that the terminal state
255 // is deterministic.
255 - ReactNoop.clearYields();
256 - expect(ReactNoop.flush()).toEqual([
256 + expect(ReactNoop).toFlushAndYield([
257 'a',
258 'b',
259 'c',
@@ -282,7 +282,7 @@ describe('ReactIncrementalUpdates', () => {
282 }
283 }
284 ReactNoop.render(<Foo />);
285 - ReactNoop.flush();
285 + expect(ReactNoop).toFlushWithoutYielding();
286
287 instance.setState({a: 'a'});
288 instance.setState({b: 'b'});
@@ -291,7 +291,7 @@ describe('ReactIncrementalUpdates', () => {
291 instance.updater.enqueueReplaceState(instance, previousState => ({
292 previousState,
293 }));
294 - ReactNoop.flush();
294 + expect(ReactNoop).toFlushWithoutYielding();
295 expect(instance.state).toEqual({previousState: {a: 'a', b: 'b'}});
296 });
297
@@ -315,7 +315,7 @@ describe('ReactIncrementalUpdates', () => {
315 }
316
317 ReactNoop.render(<Foo />);
318 - ReactNoop.flush();
318 + expect(ReactNoop).toFlushWithoutYielding();
319 expect(ops).toEqual([
320 'render',
321 'did mount',
@@ -343,7 +343,7 @@ describe('ReactIncrementalUpdates', () => {
343 }
344 }
345 ReactNoop.render(<Foo />);
346 - expect(ReactNoop.flush).toWarnDev(
346 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
347 'componentWillReceiveProps: Please update the following components ' +
348 'to use static getDerivedStateFromProps instead: Foo',
349 {withoutStack: true},
@@ -374,7 +374,7 @@ describe('ReactIncrementalUpdates', () => {
374 }
375
376 ReactNoop.render(<Foo />);
377 - ReactNoop.flush();
377 + expect(ReactNoop).toFlushWithoutYielding();
378
379 instance.setState(function a() {
380 ops.push('setState updater');
@@ -382,7 +382,7 @@ describe('ReactIncrementalUpdates', () => {
382 return {a: 'a'};
383 });
384
385 - expect(ReactNoop.flush).toWarnDev(
385 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
386 'An update (setState, replaceState, or forceUpdate) was scheduled ' +
387 'from inside an update function. Update functions should be pure, ' +
388 'with zero side-effects. Consider using componentDidUpdate or a ' +
@@ -404,7 +404,7 @@ describe('ReactIncrementalUpdates', () => {
404 this.setState({a: 'a'});
405 return {b: 'b'};
406 });
407 - ReactNoop.flush();
407 + expect(ReactNoop).toFlushWithoutYielding();
408 });
409
410 it('getDerivedStateFromProps should update base state of updateQueue (based on product bug)', () => {
@@ -483,7 +483,7 @@ describe('ReactIncrementalUpdates', () => {
483 ReactNoop.render(<Foo prop="hello" />);
484
485 // There should be a separate render and commit for each update
486 - expect(ReactNoop.flush()).toEqual([
486 + expect(ReactNoop).toFlushAndYield([
487 'Render: ',
488 'Commit: ',
489 'Render: he',
@@ -512,7 +512,7 @@ describe('ReactIncrementalUpdates', () => {
512 jest.advanceTimersByTime(10000);
513
514 // All the updates should render and commit in a single batch.
515 - expect(ReactNoop.flush()).toEqual(['Render: goodbye', 'Commit: goodbye']);
515 + expect(ReactNoop).toFlushAndYield(['Render: goodbye', 'Commit: goodbye']);
516 expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
517 });
518
@@ -552,7 +552,7 @@ describe('ReactIncrementalUpdates', () => {
552 ReactNoop.renderToRootWithID(<Foo prop="hello" />, 'b');
553
554 // There should be a separate render and commit for each update
555 - expect(ReactNoop.flush()).toEqual([
555 + expect(ReactNoop).toFlushAndYield([
556 'Render: ',
557 'Commit: ',
558 'Render: ',
@@ -594,7 +594,7 @@ describe('ReactIncrementalUpdates', () => {
594 jest.advanceTimersByTime(10000);
595
596 // All the updates should render and commit in a single batch.
597 - expect(ReactNoop.flush()).toEqual([
597 + expect(ReactNoop).toFlushAndYield([
598 'Render: goodbye',
599 'Commit: goodbye',
600 'Render: goodbye',
packages/react-reconciler/src/__tests__/ReactMemo-test.internal.js
+29 -29
@@ -54,7 +54,7 @@ describe('memo', () => {
54 return <App ref={() => {}} />;
55 }
56 ReactNoop.render(<Outer />);
57 - expect(ReactNoop.flush).toWarnDev([
57 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([
58 'Warning: Function components cannot be given refs. Attempts to access ' +
59 'this ref will fail.',
60 ]);
@@ -72,7 +72,7 @@ describe('memo', () => {
72 return <App ref={() => {}} />;
73 }
74 ReactNoop.render(<Outer />);
75 - expect(ReactNoop.flush).toWarnDev([
75 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([
76 'Warning: Function components cannot be given refs. Attempts to access ' +
77 'this ref will fail.',
78 ]);
@@ -106,9 +106,9 @@ describe('memo', () => {
106 <Counter count={0} />
107 </Suspense>,
108 );
109 - expect(ReactNoop.flush()).toEqual(['Loading...']);
109 + expect(ReactNoop).toFlushAndYield(['Loading...']);
110 await Promise.resolve();
111 - expect(ReactNoop.flush()).toEqual([0]);
111 + expect(ReactNoop).toFlushAndYield([0]);
112 expect(ReactNoop.getChildren()).toEqual([span(0)]);
113
114 // Should bail out because props have not changed
@@ -117,7 +117,7 @@ describe('memo', () => {
117 <Counter count={0} />
118 </Suspense>,
119 );
120 - expect(ReactNoop.flush()).toEqual([]);
120 + expect(ReactNoop).toFlushAndYield([]);
121 expect(ReactNoop.getChildren()).toEqual([span(0)]);
122
123 // Should update because count prop changed
@@ -126,7 +126,7 @@ describe('memo', () => {
126 <Counter count={1} />
127 </Suspense>,
128 );
129 - expect(ReactNoop.flush()).toEqual([1]);
129 + expect(ReactNoop).toFlushAndYield([1]);
130 expect(ReactNoop.getChildren()).toEqual([span(1)]);
131 });
132
@@ -161,19 +161,19 @@ describe('memo', () => {
161
162 const parent = React.createRef(null);
163 ReactNoop.render(<Parent ref={parent} />);
164 - expect(ReactNoop.flush()).toEqual(['Loading...']);
164 + expect(ReactNoop).toFlushAndYield(['Loading...']);
165 await Promise.resolve();
166 - expect(ReactNoop.flush()).toEqual(['Count: 0']);
166 + expect(ReactNoop).toFlushAndYield(['Count: 0']);
167 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
168
169 // Should bail out because props have not changed
170 ReactNoop.render(<Parent ref={parent} />);
171 - expect(ReactNoop.flush()).toEqual([]);
171 + expect(ReactNoop).toFlushAndYield([]);
172 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
173
174 // Should update because there was a context change
175 parent.current.setState({count: 1});
176 - expect(ReactNoop.flush()).toEqual(['Count: 1']);
176 + expect(ReactNoop).toFlushAndYield(['Count: 1']);
177 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
178 });
179
@@ -193,9 +193,9 @@ describe('memo', () => {
193 <Counter count={0} />
194 </Suspense>,
195 );
196 - expect(ReactNoop.flush()).toEqual(['Loading...']);
196 + expect(ReactNoop).toFlushAndYield(['Loading...']);
197 await Promise.resolve();
198 - expect(ReactNoop.flush()).toEqual([0]);
198 + expect(ReactNoop).toFlushAndYield([0]);
199 expect(ReactNoop.getChildren()).toEqual([span(0)]);
200
201 // Should bail out because props have not changed
@@ -204,7 +204,7 @@ describe('memo', () => {
204 <Counter count={0} />
205 </Suspense>,
206 );
207 - expect(ReactNoop.flush()).toEqual(['Old count: 0, New count: 0']);
207 + expect(ReactNoop).toFlushAndYield(['Old count: 0, New count: 0']);
208 expect(ReactNoop.getChildren()).toEqual([span(0)]);
209
210 // Should update because count prop changed
@@ -213,7 +213,7 @@ describe('memo', () => {
213 <Counter count={1} />
214 </Suspense>,
215 );
216 - expect(ReactNoop.flush()).toEqual(['Old count: 0, New count: 1', 1]);
216 + expect(ReactNoop).toFlushAndYield(['Old count: 0, New count: 1', 1]);
217 expect(ReactNoop.getChildren()).toEqual([span(1)]);
218 });
219
@@ -231,9 +231,9 @@ describe('memo', () => {
231 <Counter count={0} />
232 </Suspense>,
233 );
234 - expect(ReactNoop.flush()).toEqual(['Loading...']);
234 + expect(ReactNoop).toFlushAndYield(['Loading...']);
235 await Promise.resolve();
236 - expect(ReactNoop.flush()).toEqual(['0!']);
236 + expect(ReactNoop).toFlushAndYield(['0!']);
237 expect(ReactNoop.getChildren()).toEqual([span('0!')]);
238
239 // Should bail out because props have not changed
@@ -242,7 +242,7 @@ describe('memo', () => {
242 <Counter count={0} />
243 </Suspense>,
244 );
245 - expect(ReactNoop.flush()).toEqual([]);
245 + expect(ReactNoop).toFlushAndYield([]);
246 expect(ReactNoop.getChildren()).toEqual([span('0!')]);
247
248 // Should update because count prop changed
@@ -251,7 +251,7 @@ describe('memo', () => {
251 <Counter count={1} />
252 </Suspense>,
253 );
254 - expect(ReactNoop.flush()).toEqual(['1!']);
254 + expect(ReactNoop).toFlushAndYield(['1!']);
255 expect(ReactNoop.getChildren()).toEqual([span('1!')]);
256 });
257
@@ -284,9 +284,9 @@ describe('memo', () => {
284 <Counter e={5} />
285 </Suspense>,
286 );
287 - expect(ReactNoop.flush()).toEqual(['Loading...']);
287 + expect(ReactNoop).toFlushAndYield(['Loading...']);
288 await Promise.resolve();
289 - expect(ReactNoop.flush()).toEqual([15]);
289 + expect(ReactNoop).toFlushAndYield([15]);
290 expect(ReactNoop.getChildren()).toEqual([span(15)]);
291
292 // Should bail out because props have not changed
@@ -295,7 +295,7 @@ describe('memo', () => {
295 <Counter e={5} />
296 </Suspense>,
297 );
298 - expect(ReactNoop.flush()).toEqual([]);
298 + expect(ReactNoop).toFlushAndYield([]);
299 expect(ReactNoop.getChildren()).toEqual([span(15)]);
300
301 // Should update because count prop changed
@@ -304,7 +304,7 @@ describe('memo', () => {
304 <Counter e={10} />
305 </Suspense>,
306 );
307 - expect(ReactNoop.flush()).toEqual([20]);
307 + expect(ReactNoop).toFlushAndYield([20]);
308 expect(ReactNoop.getChildren()).toEqual([span(20)]);
309 });
310
@@ -334,7 +334,7 @@ describe('memo', () => {
334 // Mount
335 expect(() => {
336 ReactNoop.render(<Fn inner="2" />);
337 - ReactNoop.flush();
337 + expect(ReactNoop).toFlushWithoutYielding();
338 }).toWarnDev(
339 'Invalid prop `inner` of type `string` supplied to `FnInner`, expected `number`.',
340 );
@@ -342,7 +342,7 @@ describe('memo', () => {
342 // Update
343 expect(() => {
344 ReactNoop.render(<Fn inner={false} />);
345 - ReactNoop.flush();
345 + expect(ReactNoop).toFlushWithoutYielding();
346 }).toWarnDev(
347 'Invalid prop `inner` of type `boolean` supplied to `FnInner`, expected `number`.',
348 );
@@ -358,7 +358,7 @@ describe('memo', () => {
358 // Mount
359 expect(() => {
360 ReactNoop.render(<Fn outer="3" />);
361 - ReactNoop.flush();
361 + expect(ReactNoop).toFlushWithoutYielding();
362 }).toWarnDev(
363 // Outer props are checked in createElement
364 'Invalid prop `outer` of type `string` supplied to `FnInner`, expected `number`.',
@@ -367,7 +367,7 @@ describe('memo', () => {
367 // Update
368 expect(() => {
369 ReactNoop.render(<Fn outer={false} />);
370 - ReactNoop.flush();
370 + expect(ReactNoop).toFlushWithoutYielding();
371 }).toWarnDev(
372 // Outer props are checked in createElement
373 'Invalid prop `outer` of type `boolean` supplied to `FnInner`, expected `number`.',
@@ -389,12 +389,12 @@ describe('memo', () => {
389
390 // No warning expected because defaultProps satisfy both.
391 ReactNoop.render(<Outer />);
392 - ReactNoop.flush();
392 + expect(ReactNoop).toFlushWithoutYielding();
393
394 // Mount
395 expect(() => {
396 ReactNoop.render(<Outer inner="2" middle="3" outer="4" />);
397 - ReactNoop.flush();
397 + expect(ReactNoop).toFlushWithoutYielding();
398 }).toWarnDev([
399 'Invalid prop `outer` of type `string` supplied to `Inner`, expected `number`.',
400 'Invalid prop `middle` of type `string` supplied to `Inner`, expected `number`.',
@@ -406,7 +406,7 @@ describe('memo', () => {
406 ReactNoop.render(
407 <Outer inner={false} middle={false} outer={false} />,
408 );
409 - ReactNoop.flush();
409 + expect(ReactNoop).toFlushWithoutYielding();
410 }).toWarnDev([
411 'Invalid prop `outer` of type `boolean` supplied to `Inner`, expected `number`.',
412 'Invalid prop `middle` of type `boolean` supplied to `Inner`, expected `number`.',
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+73 -73
@@ -144,12 +144,12 @@ describe('ReactNewContext', () => {
144 }
145
146 ReactNoop.render(<App value={2} />);
147 - ReactNoop.flush();
147 + expect(ReactNoop).toFlushWithoutYielding();
148 expect(ReactNoop.getChildren()).toEqual([span('Result: 2')]);
149
150 // Update
151 ReactNoop.render(<App value={3} />);
152 - ReactNoop.flush();
152 + expect(ReactNoop).toFlushWithoutYielding();
153 expect(ReactNoop.getChildren()).toEqual([span('Result: 3')]);
154 });
155
@@ -202,7 +202,7 @@ describe('ReactNewContext', () => {
202 }
203
204 ReactNoop.render(<App value={2} />);
205 - expect(ReactNoop.flush()).toEqual([
205 + expect(ReactNoop).toFlushAndYield([
206 'App',
207 'Provider',
208 'Indirection',
@@ -214,7 +214,7 @@ describe('ReactNewContext', () => {
214
215 // Update
216 ReactNoop.render(<App value={3} />);
217 - expect(ReactNoop.flush()).toEqual([
217 + expect(ReactNoop).toFlushAndYield([
218 'App',
219 'Provider',
220 'Consumer render prop',
@@ -271,7 +271,7 @@ describe('ReactNewContext', () => {
271 }
272
273 ReactNoop.render(<App value={2} />);
274 - expect(ReactNoop.flush()).toEqual([
274 + expect(ReactNoop).toFlushAndYield([
275 'App',
276 'Provider',
277 'Indirection',
@@ -283,7 +283,7 @@ describe('ReactNewContext', () => {
283
284 // Update with the same context value
285 ReactNoop.render(<App value={2} />);
286 - expect(ReactNoop.flush()).toEqual([
286 + expect(ReactNoop).toFlushAndYield([
287 'App',
288 'Provider',
289 // Don't call render prop again
@@ -338,12 +338,12 @@ describe('ReactNewContext', () => {
338 }
339
340 ReactNoop.render(<App value={2} />);
341 - ReactNoop.flush();
341 + expect(ReactNoop).toFlushWithoutYielding();
342 expect(ReactNoop.getChildren()).toEqual([span('Result: 8')]);
343
344 // Update
345 ReactNoop.render(<App value={3} />);
346 - ReactNoop.flush();
346 + expect(ReactNoop).toFlushWithoutYielding();
347 expect(ReactNoop.getChildren()).toEqual([span('Result: 12')]);
348 });
349
@@ -382,7 +382,7 @@ describe('ReactNewContext', () => {
382 </BarConsumer>
383 </React.Fragment>,
384 );
385 - ReactNoop.flush();
385 + expect(ReactNoop).toFlushWithoutYielding();
386 });
387
388 it('multiple consumers in different branches', () => {
@@ -433,7 +433,7 @@ describe('ReactNewContext', () => {
433 }
434
435 ReactNoop.render(<App value={2} />);
436 - ReactNoop.flush();
436 + expect(ReactNoop).toFlushWithoutYielding();
437 expect(ReactNoop.getChildren()).toEqual([
438 span('Result: 4'),
439 span('Result: 2'),
@@ -441,7 +441,7 @@ describe('ReactNewContext', () => {
441
442 // Update
443 ReactNoop.render(<App value={3} />);
444 - ReactNoop.flush();
444 + expect(ReactNoop).toFlushWithoutYielding();
445 expect(ReactNoop.getChildren()).toEqual([
446 span('Result: 6'),
447 span('Result: 3'),
@@ -449,7 +449,7 @@ describe('ReactNewContext', () => {
449
450 // Another update
451 ReactNoop.render(<App value={4} />);
452 - ReactNoop.flush();
452 + expect(ReactNoop).toFlushWithoutYielding();
453 expect(ReactNoop.getChildren()).toEqual([
454 span('Result: 8'),
455 span('Result: 4'),
@@ -505,7 +505,7 @@ describe('ReactNewContext', () => {
505 }
506
507 ReactNoop.render(<App value={NaN} />);
508 - expect(ReactNoop.flush()).toEqual([
508 + expect(ReactNoop).toFlushAndYield([
509 'App',
510 'Provider',
511 'Indirection',
@@ -517,7 +517,7 @@ describe('ReactNewContext', () => {
517
518 // Update
519 ReactNoop.render(<App value={NaN} />);
520 - expect(ReactNoop.flush()).toEqual([
520 + expect(ReactNoop).toFlushAndYield([
521 'App',
522 'Provider',
523 // Consumer should not re-render again
@@ -571,7 +571,7 @@ describe('ReactNewContext', () => {
571 }
572
573 ReactNoop.render(<App value="A" />);
574 - ReactNoop.flush();
574 + expect(ReactNoop).toFlushWithoutYielding();
575 expect(ReactNoop.getChildren()).toEqual([
576 // The second provider should use the default value.
577 span('Result: Does not unwind'),
@@ -646,7 +646,7 @@ describe('ReactNewContext', () => {
646 }
647
648 ReactNoop.render(<App foo={1} bar={1} />);
649 - expect(ReactNoop.flush()).toEqual(['Foo', 'Bar']);
649 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar']);
650 expect(ReactNoop.getChildren()).toEqual([
651 span('Foo: 1'),
652 span('Bar: 1'),
@@ -654,7 +654,7 @@ describe('ReactNewContext', () => {
654
655 // Update only foo
656 ReactNoop.render(<App foo={2} bar={1} />);
657 - expect(ReactNoop.flush()).toEqual(['Foo']);
657 + expect(ReactNoop).toFlushAndYield(['Foo']);
658 expect(ReactNoop.getChildren()).toEqual([
659 span('Foo: 2'),
660 span('Bar: 1'),
@@ -662,7 +662,7 @@ describe('ReactNewContext', () => {
662
663 // Update only bar
664 ReactNoop.render(<App foo={2} bar={2} />);
665 - expect(ReactNoop.flush()).toEqual(['Bar']);
665 + expect(ReactNoop).toFlushAndYield(['Bar']);
666 expect(ReactNoop.getChildren()).toEqual([
667 span('Foo: 2'),
668 span('Bar: 2'),
@@ -670,7 +670,7 @@ describe('ReactNewContext', () => {
670
671 // Update both
672 ReactNoop.render(<App foo={3} bar={3} />);
673 - expect(ReactNoop.flush()).toEqual(['Foo', 'Bar']);
673 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar']);
674 expect(ReactNoop.getChildren()).toEqual([
675 span('Foo: 3'),
676 span('Bar: 3'),
@@ -763,7 +763,7 @@ describe('ReactNewContext', () => {
763 }
764
765 ReactNoop.render(<App foo={1} bar={1} />);
766 - expect(ReactNoop.flush()).toEqual(['Foo', 'Bar', 'Foo']);
766 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Foo']);
767 expect(ReactNoop.getChildren()).toEqual([
768 span('Foo: 1'),
769 span('Bar: 1'),
@@ -772,7 +772,7 @@ describe('ReactNewContext', () => {
772
773 // Update only foo
774 ReactNoop.render(<App foo={2} bar={1} />);
775 - expect(ReactNoop.flush()).toEqual(['Foo', 'Foo']);
775 + expect(ReactNoop).toFlushAndYield(['Foo', 'Foo']);
776 expect(ReactNoop.getChildren()).toEqual([
777 span('Foo: 2'),
778 span('Bar: 1'),
@@ -781,7 +781,7 @@ describe('ReactNewContext', () => {
781
782 // Update only bar
783 ReactNoop.render(<App foo={2} bar={2} />);
784 - expect(ReactNoop.flush()).toEqual(['Bar']);
784 + expect(ReactNoop).toFlushAndYield(['Bar']);
785 expect(ReactNoop.getChildren()).toEqual([
786 span('Foo: 2'),
787 span('Bar: 2'),
@@ -790,7 +790,7 @@ describe('ReactNewContext', () => {
790
791 // Update both
792 ReactNoop.render(<App foo={3} bar={3} />);
793 - expect(ReactNoop.flush()).toEqual(['Foo', 'Bar', 'Foo']);
793 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Foo']);
794 expect(ReactNoop.getChildren()).toEqual([
795 span('Foo: 3'),
796 span('Bar: 3'),
@@ -832,11 +832,11 @@ describe('ReactNewContext', () => {
832
833 // Initial mount
834 ReactNoop.render(<App value={1} />);
835 - expect(ReactNoop.flush()).toEqual(['Consumer render prop', 'Child']);
835 + expect(ReactNoop).toFlushAndYield(['Consumer render prop', 'Child']);
836 expect(ReactNoop.getChildren()).toEqual([span('Context: 1, Step: 0')]);
837
838 child.setState({step: 1});
839 - expect(ReactNoop.flush()).toEqual(['Child']);
839 + expect(ReactNoop).toFlushAndYield(['Child']);
840 expect(ReactNoop.getChildren()).toEqual([span('Context: 1, Step: 1')]);
841 });
842
@@ -885,7 +885,7 @@ describe('ReactNewContext', () => {
885
886 // Initial mount
887 ReactNoop.render(<App value={1} />);
888 - expect(ReactNoop.flush()).toEqual([
888 + expect(ReactNoop).toFlushAndYield([
889 'App',
890 'PureIndirection',
891 'ChildWithInlineRenderCallback',
@@ -897,12 +897,12 @@ describe('ReactNewContext', () => {
897
898 // Update (bailout)
899 ReactNoop.render(<App value={1} />);
900 - expect(ReactNoop.flush()).toEqual(['App']);
900 + expect(ReactNoop).toFlushAndYield(['App']);
901 expect(ReactNoop.getChildren()).toEqual([span(1), span(1)]);
902
903 // Update (no bailout)
904 ReactNoop.render(<App value={2} />);
905 - expect(ReactNoop.flush()).toEqual(['App', 'Consumer', 'Consumer']);
905 + expect(ReactNoop).toFlushAndYield(['App', 'Consumer', 'Consumer']);
906 expect(ReactNoop.getChildren()).toEqual([span(2), span(2)]);
907 });
908
@@ -921,7 +921,7 @@ describe('ReactNewContext', () => {
921 }
922
923 ReactNoop.render(<App theme="dark" />);
924 - expect(ReactNoop.flush()).toEqual(['dark']);
924 + expect(ReactNoop).toFlushAndYield(['dark']);
925 expect(ReactNoop.getChildrenAsJSX()).toEqual(
926 <div hidden={true}>
927 <span prop="dark" />
@@ -929,7 +929,7 @@ describe('ReactNewContext', () => {
929 );
930
931 ReactNoop.render(<App theme="light" />);
932 - expect(ReactNoop.flush()).toEqual(['light']);
932 + expect(ReactNoop).toFlushAndYield(['light']);
933 expect(ReactNoop.getChildrenAsJSX()).toEqual(
934 <div hidden={true}>
935 <span prop="light" />
@@ -968,11 +968,11 @@ describe('ReactNewContext', () => {
968 }
969
970 ReactNoop.render(<App reverse={false} />);
971 - ReactNoop.flush();
971 + expect(ReactNoop).toFlushWithoutYielding();
972 ReactNoop.render(<App reverse={true} />);
973 - ReactNoop.flush();
973 + expect(ReactNoop).toFlushWithoutYielding();
974 ReactNoop.render(<App reverse={false} />);
975 - ReactNoop.flush();
975 + expect(ReactNoop).toFlushWithoutYielding();
976 });
977
978 // This is a regression case for https://github.com/facebook/react/issues/12686
@@ -1025,14 +1025,14 @@ describe('ReactNewContext', () => {
1025 // Initial mount
1026 let inst;
1027 ReactNoop.render(<App ref={ref => (inst = ref)} />);
1028 - expect(ReactNoop.flush()).toEqual(['App']);
1028 + expect(ReactNoop).toFlushAndYield(['App']);
1029 expect(ReactNoop.getChildren()).toEqual([
1030 span('static 1'),
1031 span('static 2'),
1032 ]);
1033 // Update the first time
1034 inst.setState({step: 1});
1035 - expect(ReactNoop.flush()).toEqual(['App', 'Consumer']);
1035 + expect(ReactNoop).toFlushAndYield(['App', 'Consumer']);
1036 expect(ReactNoop.getChildren()).toEqual([
1037 span('static 1'),
1038 span('static 2'),
@@ -1040,7 +1040,7 @@ describe('ReactNewContext', () => {
1040 ]);
1041 // Update the second time
1042 inst.setState({step: 2});
1043 - expect(ReactNoop.flush()).toEqual(['App', 'Consumer']);
1043 + expect(ReactNoop).toFlushAndYield(['App', 'Consumer']);
1044 expect(ReactNoop.getChildren()).toEqual([
1045 span('static 1'),
1046 span('static 2'),
@@ -1062,11 +1062,11 @@ describe('ReactNewContext', () => {
1062 }
1063
1064 ReactNoop.render(<App value={1} />);
1065 - ReactNoop.flush();
1065 + expect(ReactNoop).toFlushWithoutYielding();
1066
1067 // Update
1068 ReactNoop.render(<App value={2} />);
1069 - expect(ReactNoop.flush).toWarnDev(
1069 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1070 'calculateChangedBits: Expected the return value to be a 31-bit ' +
1071 'integer. Instead received: 4294967295',
1072 );
@@ -1092,7 +1092,7 @@ describe('ReactNewContext', () => {
1092
1093 ReactNoop.render(<App value={1} />);
1094 // Render past the Provider, but don't commit yet
1095 - ReactNoop.flushThrough(['Foo']);
1095 + expect(ReactNoop).toFlushAndYieldThrough(['Foo']);
1096
1097 // Get a new copy of ReactNoop
1098 jest.resetModules();
@@ -1102,7 +1102,7 @@ describe('ReactNewContext', () => {
1102
1103 // Render the provider again using a different renderer
1104 ReactNoop.render(<App value={1} />);
1105 - ReactNoop.flush();
1105 + expect(ReactNoop).toFlushAndYield(['Foo', 'Foo']);
1106
1107 if (__DEV__) {
1108 expect(console.error.calls.argsFor(0)[0]).toContain(
@@ -1131,12 +1131,12 @@ describe('ReactNewContext', () => {
1131
1132 // Initial mount
1133 ReactNoop.render(<App value={1} />);
1134 - expect(ReactNoop.flush()).toEqual(['App', 'Child']);
1134 + expect(ReactNoop).toFlushAndYield(['App', 'Child']);
1135 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
1136
1137 // Update
1138 ReactNoop.render(<App value={1} />);
1139 - expect(ReactNoop.flush()).toEqual([
1139 + expect(ReactNoop).toFlushAndYield([
1140 'App',
1141 // Child does not re-render
1142 ]);
@@ -1191,7 +1191,7 @@ describe('ReactNewContext', () => {
1191 </LegacyProvider>,
1192 );
1193 expect(() => {
1194 - expect(ReactNoop.flush()).toEqual(['LegacyProvider', 'App', 'Child']);
1194 + expect(ReactNoop).toFlushAndYield(['LegacyProvider', 'App', 'Child']);
1195 }).toWarnDev(
1196 'Legacy context API has been detected within a strict-mode tree: \n\n' +
1197 'Please update the following components: LegacyProvider',
@@ -1201,17 +1201,17 @@ describe('ReactNewContext', () => {
1201
1202 // Update App with same value (should bail out)
1203 appRef.current.setState({value: 1});
1204 - expect(ReactNoop.flush()).toEqual(['App']);
1204 + expect(ReactNoop).toFlushAndYield(['App']);
1205 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
1206
1207 // Update LegacyProvider (should not bail out)
1208 legacyProviderRef.current.setState({value: 1});
1209 - expect(ReactNoop.flush()).toEqual(['LegacyProvider', 'App', 'Child']);
1209 + expect(ReactNoop).toFlushAndYield(['LegacyProvider', 'App', 'Child']);
1210 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
1211
1212 // Update App with same value (should bail out)
1213 appRef.current.setState({value: 1});
1214 - expect(ReactNoop.flush()).toEqual(['App']);
1214 + expect(ReactNoop).toFlushAndYield(['App']);
1215 expect(ReactNoop.getChildren()).toEqual([span('Child')]);
1216 });
1217 });
@@ -1221,7 +1221,7 @@ describe('ReactNewContext', () => {
1221 spyOnDev(console, 'error');
1222 const Context = React.createContext(0);
1223 ReactNoop.render(<Context.Consumer />);
1224 - expect(ReactNoop.flush).toThrow('render is not a function');
1224 + expect(ReactNoop).toFlushAndThrow('render is not a function');
1225 if (__DEV__) {
1226 expect(console.error.calls.argsFor(0)[0]).toContain(
1227 'A context consumer was rendered with multiple children, or a child ' +
@@ -1267,17 +1267,17 @@ describe('ReactNewContext', () => {
1267 }
1268
1269 ReactNoop.render(<App foo={1} bar={1} />);
1270 - expect(ReactNoop.flush()).toEqual(['Foo: 1, Bar: 1']);
1270 + expect(ReactNoop).toFlushAndYield(['Foo: 1, Bar: 1']);
1271 expect(ReactNoop.getChildren()).toEqual([span('Foo: 1, Bar: 1')]);
1272
1273 // Update foo
1274 ReactNoop.render(<App foo={2} bar={1} />);
1275 - expect(ReactNoop.flush()).toEqual(['Foo: 2, Bar: 1']);
1275 + expect(ReactNoop).toFlushAndYield(['Foo: 2, Bar: 1']);
1276 expect(ReactNoop.getChildren()).toEqual([span('Foo: 2, Bar: 1')]);
1277
1278 // Update bar
1279 ReactNoop.render(<App foo={2} bar={2} />);
1280 - expect(ReactNoop.flush()).toEqual(['Foo: 2, Bar: 2']);
1280 + expect(ReactNoop).toFlushAndYield(['Foo: 2, Bar: 2']);
1281 expect(ReactNoop.getChildren()).toEqual([span('Foo: 2, Bar: 2')]);
1282 });
1283
@@ -1313,12 +1313,12 @@ describe('ReactNewContext', () => {
1313 // Initial mount
1314 let inst;
1315 ReactNoop.render(<App value={1} ref={ref => (inst = ref)} />);
1316 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1316 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1317 expect(ReactNoop.getChildren()).toEqual([span('hello')]);
1318
1319 // Update
1320 inst.setState({text: 'goodbye'});
1321 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1321 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1322 expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
1323 });
1324 });
@@ -1384,7 +1384,7 @@ describe('ReactNewContext', () => {
1384 }
1385
1386 ReactNoop.render(<App foo={1} bar={1} baz={1} />);
1387 - expect(ReactNoop.flush()).toEqual(['Foo: 1, Bar: 1', 'Baz: 1']);
1387 + expect(ReactNoop).toFlushAndYield(['Foo: 1, Bar: 1', 'Baz: 1']);
1388 expect(ReactNoop.getChildren()).toEqual([
1389 span('Foo: 1, Bar: 1'),
1390 span('Baz: 1'),
@@ -1392,7 +1392,7 @@ describe('ReactNewContext', () => {
1392
1393 // Update only foo
1394 ReactNoop.render(<App foo={2} bar={1} baz={1} />);
1395 - expect(ReactNoop.flush()).toEqual(['Foo: 2, Bar: 1']);
1395 + expect(ReactNoop).toFlushAndYield(['Foo: 2, Bar: 1']);
1396 expect(ReactNoop.getChildren()).toEqual([
1397 span('Foo: 2, Bar: 1'),
1398 span('Baz: 1'),
@@ -1400,7 +1400,7 @@ describe('ReactNewContext', () => {
1400
1401 // Update only bar
1402 ReactNoop.render(<App foo={2} bar={2} baz={1} />);
1403 - expect(ReactNoop.flush()).toEqual(['Foo: 2, Bar: 2']);
1403 + expect(ReactNoop).toFlushAndYield(['Foo: 2, Bar: 2']);
1404 expect(ReactNoop.getChildren()).toEqual([
1405 span('Foo: 2, Bar: 2'),
1406 span('Baz: 1'),
@@ -1408,7 +1408,7 @@ describe('ReactNewContext', () => {
1408
1409 // Update only baz
1410 ReactNoop.render(<App foo={2} bar={2} baz={2} />);
1411 - expect(ReactNoop.flush()).toEqual(['Baz: 2']);
1411 + expect(ReactNoop).toFlushAndYield(['Baz: 2']);
1412 expect(ReactNoop.getChildren()).toEqual([
1413 span('Foo: 2, Bar: 2'),
1414 span('Baz: 2'),
@@ -1453,12 +1453,12 @@ describe('ReactNewContext', () => {
1453 // Initial mount
1454 let inst;
1455 ReactNoop.render(<App value={1} ref={ref => (inst = ref)} />);
1456 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1456 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1457 expect(ReactNoop.getChildren()).toEqual([span('hello')]);
1458
1459 // Update
1460 inst.setState({text: 'goodbye'});
1461 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1461 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1462 expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
1463 });
1464
@@ -1476,7 +1476,7 @@ describe('ReactNewContext', () => {
1476 }
1477
1478 ReactNoop.render(<Cls />);
1479 - expect(ReactNoop.flush).toWarnDev(
1479 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1480 [
1481 'Context can only be read while React is rendering',
1482 'Cannot update during an existing state transition',
@@ -1495,7 +1495,7 @@ describe('ReactNewContext', () => {
1495 return [Context].map(useContext);
1496 }
1497 ReactNoop.render(<Foo />);
1498 - expect(ReactNoop.flush).toWarnDev(
1498 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1499 'useContext() second argument is reserved for future ' +
1500 'use in React. Passing it is not supported. ' +
1501 'You passed: 0.\n\n' +
@@ -1513,7 +1513,7 @@ describe('ReactNewContext', () => {
1513 }
1514 }
1515 ReactNoop.render(<Foo />);
1516 - expect(ReactNoop.flush).toThrow(
1516 + expect(ReactNoop).toFlushAndThrow(
1517 'Hooks can only be called inside the body of a function component.',
1518 );
1519 });
@@ -1524,7 +1524,7 @@ describe('ReactNewContext', () => {
1524 return useContext(Context.Consumer);
1525 }
1526 ReactNoop.render(<Foo />);
1527 - expect(ReactNoop.flush).toWarnDev(
1527 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1528 'Calling useContext(Context.Consumer) is not supported, may cause bugs, ' +
1529 'and will be removed in a future major release. ' +
1530 'Did you mean to call useContext(Context) instead?',
@@ -1538,7 +1538,7 @@ describe('ReactNewContext', () => {
1538 return null;
1539 }
1540 ReactNoop.render(<Foo />);
1541 - expect(ReactNoop.flush).toWarnDev(
1541 + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev(
1542 'Calling useContext(Context.Provider) is not supported. ' +
1543 'Did you mean to call useContext(Context) instead?',
1544 );
@@ -1580,12 +1580,12 @@ describe('ReactNewContext', () => {
1580 // Initial mount
1581 let inst;
1582 ReactNoop.render(<App value={1} ref={ref => (inst = ref)} />);
1583 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1583 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1584 expect(ReactNoop.getChildren()).toEqual([span('hello')]);
1585
1586 // Update
1587 inst.setState({text: 'goodbye'});
1588 - expect(ReactNoop.flush()).toEqual(['App', 'App#renderConsumer']);
1588 + expect(ReactNoop).toFlushAndYield(['App', 'App#renderConsumer']);
1589 expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
1590 });
1591 });
@@ -1600,14 +1600,14 @@ describe('ReactNewContext', () => {
1600 <Context.Provider />
1601 </errorInCompletePhase>,
1602 );
1603 - expect(ReactNoop.flush).toThrow('Error in host config.');
1603 + expect(ReactNoop).toFlushAndThrow('Error in host config.');
1604
1605 ReactNoop.render(
1606 <Context.Provider value={10}>
1607 <Context.Consumer>{value => <span prop={value} />}</Context.Consumer>
1608 </Context.Provider>,
1609 );
1610 - ReactNoop.flush();
1610 + expect(ReactNoop).toFlushWithoutYielding();
1611 expect(ReactNoop.getChildren()).toEqual([span(10)]);
1612 });
1613
@@ -1769,7 +1769,7 @@ describe('ReactNewContext', () => {
1769 actions.forEach(action => {
1770 switch (action.type) {
1771 case FLUSH_ALL:
1772 - ReactNoop.flush();
1772 + ReactNoop.unstable_flushWithoutYielding();
1773 break;
1774 case FLUSH:
1775 ReactNoop.unstable_flushNumberOfYields(action.unitsOfWork);
@@ -1787,7 +1787,7 @@ describe('ReactNewContext', () => {
1787 assertConsistentTree();
1788 });
1789
1790 - ReactNoop.flush();
1790 + ReactNoop.unstable_flushWithoutYielding();
1791 assertConsistentTree(finalExpectedValues);
1792 }
1793
@@ -1839,7 +1839,7 @@ Context fuzz tester error! Copy and paste the following line into the test suite
1839
1840 expect(() => {
1841 ReactNoop.render(<Component />);
1842 - ReactNoop.flush();
1842 + expect(ReactNoop).toFlushWithoutYielding();
1843 }).toWarnDev(
1844 'Rendering <Context> directly is not supported and will be removed in ' +
1845 'a future major release. Did you mean to render <Context.Consumer> instead?',
@@ -1865,7 +1865,7 @@ Context fuzz tester error! Copy and paste the following line into the test suite
1865 }
1866
1867 ReactNoop.render(<Component />);
1868 - ReactNoop.flush();
1868 + expect(ReactNoop).toFlushWithoutYielding();
1869 });
1870
1871 it('should warn with an error message when using nested context consumers in DEV', () => {
@@ -1886,7 +1886,7 @@ Context fuzz tester error! Copy and paste the following line into the test suite
1886
1887 expect(() => {
1888 ReactNoop.render(<Component />);
1889 - ReactNoop.flush();
1889 + expect(ReactNoop).toFlushWithoutYielding();
1890 }).toWarnDev(
1891 'Rendering <Context.Consumer.Consumer> is not supported and will be removed in ' +
1892 'a future major release. Did you mean to render <Context.Consumer> instead?',
@@ -1910,7 +1910,7 @@ Context fuzz tester error! Copy and paste the following line into the test suite
1910
1911 expect(() => {
1912 ReactNoop.render(<Component />);
1913 - ReactNoop.flush();
1913 + expect(ReactNoop).toFlushWithoutYielding();
1914 }).toWarnDev(
1915 'Rendering <Context.Consumer.Provider> is not supported and will be removed in ' +
1916 'a future major release. Did you mean to render <Context.Provider> instead?',
packages/react-reconciler/src/__tests__/ReactPersistent-test.js
+9 -9
@@ -66,12 +66,12 @@ describe('ReactPersistent', () => {
66 }
67
68 render(<Foo text="Hello" />);
69 - ReactNoopPersistent.flush();
69 + expect(ReactNoopPersistent).toFlushWithoutYielding();
70 const originalChildren = getChildren();
71 expect(originalChildren).toEqual([div(span())]);
72
73 render(<Foo text="World" />);
74 - ReactNoopPersistent.flush();
74 + expect(ReactNoopPersistent).toFlushWithoutYielding();
75 const newChildren = getChildren();
76 expect(newChildren).toEqual([div(span(), span())]);
77
@@ -100,12 +100,12 @@ describe('ReactPersistent', () => {
100 }
101
102 render(<Foo text="Hello" />);
103 - ReactNoopPersistent.flush();
103 + expect(ReactNoopPersistent).toFlushWithoutYielding();
104 const originalChildren = getChildren();
105 expect(originalChildren).toEqual([div(span('Hello'))]);
106
107 render(<Foo text="World" />);
108 - ReactNoopPersistent.flush();
108 + expect(ReactNoopPersistent).toFlushWithoutYielding();
109 const newChildren = getChildren();
110 expect(newChildren).toEqual([div(span('Hello'), span('World'))]);
111
@@ -126,12 +126,12 @@ describe('ReactPersistent', () => {
126 }
127
128 render(<Foo text="Hello" />);
129 - ReactNoopPersistent.flush();
129 + expect(ReactNoopPersistent).toFlushWithoutYielding();
130 const originalChildren = getChildren();
131 expect(originalChildren).toEqual([div('Hello', span())]);
132
133 render(<Foo text="World" />);
134 - ReactNoopPersistent.flush();
134 + expect(ReactNoopPersistent).toFlushWithoutYielding();
135 const newChildren = getChildren();
136 expect(newChildren).toEqual([div('World', span())]);
137
@@ -167,7 +167,7 @@ describe('ReactPersistent', () => {
167 const portalContainer = {rootID: 'persistent-portal-test', children: []};
168 const emptyPortalChildSet = portalContainer.children;
169 render(<Parent>{createPortal(<Child />, portalContainer, null)}</Parent>);
170 - ReactNoopPersistent.flush();
170 + expect(ReactNoopPersistent).toFlushWithoutYielding();
171
172 expect(emptyPortalChildSet).toEqual([]);
173
@@ -181,7 +181,7 @@ describe('ReactPersistent', () => {
181 {createPortal(<Child>Hello {'World'}</Child>, portalContainer, null)}
182 </Parent>,
183 );
184 - ReactNoopPersistent.flush();
184 + expect(ReactNoopPersistent).toFlushWithoutYielding();
185
186 const newChildren = getChildren();
187 expect(newChildren).toEqual([div()]);
@@ -198,7 +198,7 @@ describe('ReactPersistent', () => {
198
199 // Deleting the Portal, should clear its children
200 render(<Parent />);
201 - ReactNoopPersistent.flush();
201 + expect(ReactNoopPersistent).toFlushWithoutYielding();
202
203 const clearedPortalChildren = portalContainer.children;
204 expect(clearedPortalChildren).toEqual([]);
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
+112 -110
@@ -106,7 +106,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
106 }
107
108 ReactNoop.render(<Foo />);
109 - expect(ReactNoop.flush()).toEqual([
109 + expect(ReactNoop).toFlushAndYield([
110 'Foo',
111 'Bar',
112 // A suspends
@@ -120,19 +120,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
120 // Flush some of the time
121 await advanceTimers(50);
122 // Still nothing...
123 - expect(ReactNoop.flush()).toEqual([]);
123 + expect(ReactNoop).toFlushWithoutYielding();
124 expect(ReactNoop.getChildren()).toEqual([]);
125
126 // Flush the promise completely
127 await advanceTimers(50);
128 // Renders successfully
129 - expect(ReactNoop.flush()).toEqual([
130 - 'Promise resolved [A]',
131 - 'Foo',
132 - 'Bar',
133 - 'A',
134 - 'B',
135 - ]);
129 + expect(ReactNoop).toHaveYielded(['Promise resolved [A]']);
130 + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'A', 'B']);
131 expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
132 });
133
@@ -148,7 +143,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
143 </Suspense>
144 </Fragment>,
145 );
151 - expect(ReactNoop.flush()).toEqual([
146 + expect(ReactNoop).toFlushAndYield([
147 'Suspend! [A]',
148 'Loading A...',
149 'Suspend! [B]',
@@ -160,7 +155,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
155 ReactNoop.expire(4000);
156 await advanceTimers(4000);
157
163 - expect(ReactNoop.flush()).toEqual([]);
158 + expect(ReactNoop).toFlushWithoutYielding();
159 expect(ReactNoop.getChildren()).toEqual([
160 span('Loading A...'),
161 span('Loading B...'),
@@ -172,7 +167,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
167 ReactNoop.expire(1000);
168 await advanceTimers(1000);
169
175 - expect(ReactNoop.flush()).toEqual(['Promise resolved [A]', 'A']);
170 + expect(ReactNoop).toHaveYielded(['Promise resolved [A]']);
171 + expect(ReactNoop).toFlushAndYield(['A']);
172 expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading B...')]);
173
174 // Advance time by enough that the second Suspense's promise resolves
@@ -180,7 +176,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
176 ReactNoop.expire(1000);
177 await advanceTimers(1000);
178
183 - expect(ReactNoop.flush()).toEqual(['Promise resolved [B]', 'B']);
179 + expect(ReactNoop).toHaveYielded(['Promise resolved [B]']);
180 + expect(ReactNoop).toFlushAndYield(['B']);
181 expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
182 });
183
@@ -194,7 +191,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
191 </Suspense>,
192 );
193 // B suspends. Continue rendering the remaining siblings.
197 - expect(ReactNoop.flush()).toEqual([
194 + expect(ReactNoop).toFlushAndYield([
195 'A',
196 'Suspend! [B]',
197 'C',
@@ -207,13 +204,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
204 // Wait for data to resolve
205 await advanceTimers(100);
206 // Renders successfully
210 - expect(ReactNoop.flush()).toEqual([
211 - 'Promise resolved [B]',
212 - 'A',
213 - 'B',
214 - 'C',
215 - 'D',
216 - ]);
207 + expect(ReactNoop).toHaveYielded(['Promise resolved [B]']);
208 + expect(ReactNoop).toFlushAndYield(['A', 'B', 'C', 'D']);
209 expect(ReactNoop.getChildren()).toEqual([
210 span('A'),
211 span('B'),
@@ -251,7 +243,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
243 }
244
245 ReactNoop.render(<App />);
254 - expect(ReactNoop.flush()).toEqual(['Suspend! [Result]', 'Loading...']);
246 + expect(ReactNoop).toFlushAndYield(['Suspend! [Result]', 'Loading...']);
247 expect(ReactNoop.getChildren()).toEqual([]);
248
249 textResourceShouldFail = true;
@@ -259,8 +251,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
251 await advanceTimers(1000);
252 textResourceShouldFail = false;
253
262 - expect(ReactNoop.flush()).toEqual([
263 - 'Promise rejected [Result]',
254 + expect(ReactNoop).toHaveYielded(['Promise rejected [Result]']);
255 +
256 + expect(ReactNoop).toFlushAndYield([
257 'Error! [Result]',
258
259 // React retries one more time
@@ -303,12 +296,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
296 }
297
298 ReactNoop.render(<App />);
306 - expect(ReactNoop.flush()).toEqual(['Suspend! [Result]', 'Loading...']);
299 + expect(ReactNoop).toFlushAndYield(['Suspend! [Result]', 'Loading...']);
300 expect(ReactNoop.getChildren()).toEqual([]);
301
302 ReactNoop.expire(2000);
303 await advanceTimers(2000);
311 - expect(ReactNoop.flush()).toEqual([]);
304 + expect(ReactNoop).toFlushWithoutYielding();
305 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
306
307 textResourceShouldFail = true;
@@ -316,8 +309,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
309 await advanceTimers(1000);
310 textResourceShouldFail = false;
311
319 - expect(ReactNoop.flush()).toEqual([
320 - 'Promise rejected [Result]',
312 + expect(ReactNoop).toHaveYielded(['Promise rejected [Result]']);
313 + expect(ReactNoop).toFlushAndYield([
314 'Error! [Result]',
315
316 // React retries one more time
@@ -344,14 +337,15 @@ describe('ReactSuspenseWithNoopRenderer', () => {
337
338 // Initial mount
339 ReactNoop.render(<App highPri="A" lowPri="1" />);
347 - ReactNoop.flush();
340 + expect(ReactNoop).toFlushAndYield(['A', 'Suspend! [1]', 'Loading...']);
341 await advanceTimers(0);
349 - ReactNoop.flush();
342 + expect(ReactNoop).toHaveYielded(['Promise resolved [1]']);
343 + expect(ReactNoop).toFlushAndYield(['A', '1']);
344 expect(ReactNoop.getChildren()).toEqual([span('A'), span('1')]);
345
346 // Update the low-pri text
347 ReactNoop.render(<App highPri="A" lowPri="2" />);
354 - expect(ReactNoop.flush()).toEqual([
348 + expect(ReactNoop).toFlushAndYield([
349 'A',
350 // Suspends
351 'Suspend! [2]',
@@ -363,12 +357,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
357 ReactNoop.flushSync(() => {
358 ReactNoop.render(<App highPri="B" lowPri="1" />);
359 });
366 - expect(ReactNoop.flush()).toEqual(['B', '1']);
360 + expect(ReactNoop).toHaveYielded(['B', '1']);
361 expect(ReactNoop.getChildren()).toEqual([span('B'), span('1')]);
362
363 // Unblock the low-pri text and finish
364 await advanceTimers(0);
371 - expect(ReactNoop.flush()).toEqual(['Promise resolved [2]']);
365 + expect(ReactNoop).toHaveYielded(['Promise resolved [2]']);
366 expect(ReactNoop.getChildren()).toEqual([span('B'), span('1')]);
367 });
368
@@ -383,17 +377,18 @@ describe('ReactSuspenseWithNoopRenderer', () => {
377 }
378
379 ReactNoop.render(<App showB={false} />);
386 - expect(ReactNoop.flush()).toEqual(['Suspend! [A]', 'Loading...']);
380 + expect(ReactNoop).toFlushAndYield(['Suspend! [A]', 'Loading...']);
381 expect(ReactNoop.getChildren()).toEqual([]);
382
383 // Advance React's virtual time by enough to fall into a new async bucket.
384 ReactNoop.expire(1200);
385 ReactNoop.render(<App showB={true} />);
392 - expect(ReactNoop.flush()).toEqual(['Suspend! [A]', 'B', 'Loading...']);
386 + expect(ReactNoop).toFlushAndYield(['Suspend! [A]', 'B', 'Loading...']);
387 expect(ReactNoop.getChildren()).toEqual([]);
388
389 await advanceTimers(0);
396 - expect(ReactNoop.flush()).toEqual(['Promise resolved [A]', 'A', 'B']);
390 + expect(ReactNoop).toHaveYielded(['Promise resolved [A]']);
391 + expect(ReactNoop).toFlushAndYield(['A', 'B']);
392 expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
393 });
394
@@ -418,7 +413,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
413 // Low pri
414 ReactNoop.render(<App hide={true} />);
415
421 - expect(ReactNoop.flush()).toEqual([
416 + expect(ReactNoop).toFlushAndYield([
417 // The first update suspends
418 'Suspend! [Async]',
419 // but we have another pending update that we can work on
@@ -437,7 +432,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
432 </Fragment>,
433 );
434
440 - expect(ReactNoop.flush()).toEqual([
435 + expect(ReactNoop).toFlushAndYield([
436 // The async child suspends
437 'Suspend! [Async]',
438 // Render the placeholder
@@ -460,7 +455,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
455
456 // Once the promise resolves, we render the suspended view
457 await advanceTimers(10000);
463 - expect(ReactNoop.flush()).toEqual(['Promise resolved [Async]', 'Async']);
458 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
459 + expect(ReactNoop).toFlushAndYield(['Async']);
460 expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
461 });
462
@@ -481,7 +477,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
477 </Fragment>,
478 );
479
484 - expect(ReactNoop.flush()).toEqual([
480 + expect(ReactNoop).toFlushAndYield([
481 'Sync',
482 // The async content suspends
483 'Suspend! [Outer content]',
@@ -496,7 +492,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
492 // We should see the outer loading placeholder.
493 ReactNoop.expire(1500);
494 await advanceTimers(1500);
499 - expect(ReactNoop.flush()).toEqual([]);
495 + expect(ReactNoop).toFlushWithoutYielding();
496 expect(ReactNoop.getChildren()).toEqual([
497 span('Sync'),
498 span('Loading outer...'),
@@ -509,8 +505,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
505 // timed out at 1.5 seconds. So, 2 seconds have elapsed since the
506 // placeholder timed out. That means we still haven't reached the 2.5 second
507 // threshold of the inner placeholder.
512 - expect(ReactNoop.flush()).toEqual([
513 - 'Promise resolved [Outer content]',
508 + expect(ReactNoop).toHaveYielded(['Promise resolved [Outer content]']);
509 + expect(ReactNoop).toFlushAndYield([
510 'Outer content',
511 'Suspend! [Inner content]',
512 'Loading inner...',
@@ -535,10 +531,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
531 // Finally, flush the inner promise. We should see the complete screen.
532 ReactNoop.expire(1000);
533 await advanceTimers(1000);
538 - expect(ReactNoop.flush()).toEqual([
539 - 'Promise resolved [Inner content]',
540 - 'Inner content',
541 - ]);
534 + expect(ReactNoop).toHaveYielded(['Promise resolved [Inner content]']);
535 + expect(ReactNoop).toFlushAndYield(['Inner content']);
536 expect(ReactNoop.getChildren()).toEqual([
537 span('Sync'),
538 span('Outer content'),
@@ -558,7 +552,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
552 </Fragment>,
553 ),
554 );
561 - expect(ReactNoop.clearYields()).toEqual([
555 + expect(ReactNoop).toHaveYielded([
556 // The async child suspends
557 'Suspend! [Async]',
558 // We immediately render the fallback UI
@@ -571,7 +565,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
565
566 // Once the promise resolves, we render the suspended view
567 await advanceTimers(0);
574 - expect(ReactNoop.flush()).toEqual(['Promise resolved [Async]', 'Async']);
568 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
569 + expect(ReactNoop).toFlushAndYield(['Async']);
570 expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
571 });
572
@@ -588,7 +583,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
583 </Fragment>,
584 ),
585 );
591 - expect(ReactNoop.clearYields()).toEqual([
586 + expect(ReactNoop).toHaveYielded([
587 'Suspend! [Async]',
588 'Suspend! [Loading (inner)...]',
589 'Sync',
@@ -608,7 +603,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
603 </Fragment>,
604 );
605
611 - expect(ReactNoop.flush()).toEqual([
606 + expect(ReactNoop).toFlushAndYield([
607 // The async child suspends
608 'Suspend! [Async]',
609 'Loading...',
@@ -623,12 +618,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
618 // expiration time.
619 ReactNoop.expire(2000);
620 await advanceTimers(2000);
626 - expect(ReactNoop.flush()).toEqual([]);
621 + expect(ReactNoop).toFlushWithoutYielding();
622 expect(ReactNoop.getChildren()).toEqual([span('Loading...'), span('Sync')]);
623
624 // Once the promise resolves, we render the suspended view
625 await advanceTimers(1000);
631 - expect(ReactNoop.flush()).toEqual(['Promise resolved [Async]', 'Async']);
626 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
627 + expect(ReactNoop).toFlushAndYield(['Async']);
628 expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
629 });
630
@@ -643,8 +639,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
639 expect(ReactNoop.expire(1500)).toEqual([]);
640 // Before we have a chance to flush, the promise resolves.
641 await advanceTimers(2000);
646 - expect(ReactNoop.clearYields()).toEqual(['Promise resolved [Async]']);
647 - expect(ReactNoop.flush()).toEqual(['Async']);
642 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
643 + expect(ReactNoop).toFlushAndYield(['Async']);
644 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
645 });
646
@@ -672,12 +668,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
668
669 await advanceTimers(100);
670
675 - expect(ReactNoop.flush()).toEqual([
671 + expect(ReactNoop).toHaveYielded([
672 'Promise resolved [A]',
673 'Promise resolved [B]',
678 - 'A',
679 - 'B',
674 ]);
675 + expect(ReactNoop).toFlushAndYield(['A', 'B']);
676 expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
677 });
678
@@ -687,7 +682,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
682 <AsyncText text="Async" ms={100} />
683 </Suspense>,
684 );
690 - expect(ReactNoop.flush()).toEqual(['Suspend! [Async]', 'Loading...']);
685 + expect(ReactNoop).toFlushAndYield(['Suspend! [Async]', 'Loading...']);
686 expect(ReactNoop.getChildren()).toEqual([]);
687
688 // Advance time by an amount slightly smaller than what's necessary to
@@ -695,13 +690,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
690 await advanceTimers(99);
691
692 // Nothing has rendered yet
698 - expect(ReactNoop.flush()).toEqual([]);
693 + expect(ReactNoop).toFlushWithoutYielding();
694 expect(ReactNoop.getChildren()).toEqual([]);
695
696 // Resolve the promise
697 await advanceTimers(1);
698 // We can now resume rendering
704 - expect(ReactNoop.flush()).toEqual(['Promise resolved [Async]', 'Async']);
699 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
700 + expect(ReactNoop).toFlushAndYield(['Async']);
701 expect(ReactNoop.getChildren()).toEqual([span('Async')]);
702 });
703
@@ -721,20 +717,20 @@ describe('ReactSuspenseWithNoopRenderer', () => {
717 // Schedule an update
718 ReactNoop.render(<App text="A" />);
719 // The update should suspend.
724 - expect(ReactNoop.flush()).toEqual(['Suspend! [A]', 'Loading...']);
720 + expect(ReactNoop).toFlushAndYield(['Suspend! [A]', 'Loading...']);
721 expect(ReactNoop.getChildren()).toEqual([]);
722
723 // Advance time until right before it expires. This number may need to
724 // change if the default expiration for low priority updates is adjusted.
725 await advanceTimers(4999);
726 ReactNoop.expire(4999);
731 - expect(ReactNoop.flush()).toEqual([]);
727 + expect(ReactNoop).toFlushWithoutYielding();
728 expect(ReactNoop.getChildren()).toEqual([]);
729
730 // Schedule another low priority update.
731 ReactNoop.render(<App text="B" />);
732 // This update should also suspend.
737 - expect(ReactNoop.flush()).toEqual(['Suspend! [B]', 'Loading...']);
733 + expect(ReactNoop).toFlushAndYield(['Suspend! [B]', 'Loading...']);
734 expect(ReactNoop.getChildren()).toEqual([]);
735
736 // Schedule a high priority update. Its expiration time will fall between
@@ -742,15 +738,17 @@ describe('ReactSuspenseWithNoopRenderer', () => {
738 ReactNoop.interactiveUpdates(() => {
739 ReactNoop.render(<App text="C" />);
740 });
745 - expect(ReactNoop.flush()).toEqual(['C']);
741 + expect(ReactNoop).toFlushAndYield(['C']);
742 expect(ReactNoop.getChildren()).toEqual([span('C')]);
743
744 await advanceTimers(10000);
745 // Flush the remaining work.
750 - expect(ReactNoop.flush()).toEqual([
746 + expect(ReactNoop).toHaveYielded([
747 'Promise resolved [A]',
748 'Promise resolved [B]',
749 ]);
750 + // Nothing else to render.
751 + expect(ReactNoop).toFlushWithoutYielding();
752 expect(ReactNoop.getChildren()).toEqual([span('C')]);
753 });
754
@@ -785,7 +783,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
783 ReactNoop.advanceTime(10000);
784 jest.advanceTimersByTime(10000);
785
788 - expect(ReactNoop.flush()).toEqual([
786 + expect(ReactNoop).toFlushAndYield([
787 'Suspend! [goodbye]',
788 'Loading...',
789 'Commit: goodbye',
@@ -794,10 +792,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
792
793 ReactNoop.advanceTime(20000);
794 await advanceTimers(20000);
797 - expect(ReactNoop.clearYields()).toEqual(['Promise resolved [goodbye]']);
795 + expect(ReactNoop).toHaveYielded(['Promise resolved [goodbye]']);
796 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
797
800 - expect(ReactNoop.flush()).toEqual(['goodbye']);
798 + expect(ReactNoop).toFlushAndYield(['goodbye']);
799 expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
800 });
801
@@ -830,17 +828,17 @@ describe('ReactSuspenseWithNoopRenderer', () => {
828
829 it('works', async () => {
830 ReactNoop.render(<DebouncedText text="A" ms={1000} />);
833 - ReactNoop.flush();
831 + expect(ReactNoop).toFlushAndYield(['A']);
832 expect(ReactNoop.getChildren()).toEqual([]);
833
834 await advanceTimers(800);
835 ReactNoop.expire(800);
838 - ReactNoop.flush();
836 + expect(ReactNoop).toFlushWithoutYielding();
837 expect(ReactNoop.getChildren()).toEqual([]);
838
839 await advanceTimers(1000);
840 ReactNoop.expire(1000);
843 - ReactNoop.flush();
841 + expect(ReactNoop).toFlushWithoutYielding();
842 expect(ReactNoop.getChildren()).toEqual([span('A')]);
843 });
844 });
@@ -857,17 +855,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
855
856 // Times out immediately, ignoring the specified threshold.
857 ReactNoop.renderLegacySyncRoot(<App />);
860 - expect(ReactNoop.clearYields()).toEqual([
861 - 'Suspend! [Result]',
862 - 'Loading...',
863 - ]);
858 + expect(ReactNoop).toHaveYielded(['Suspend! [Result]', 'Loading...']);
859 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
860
861 + ReactNoop.expire(100);
862 await advanceTimers(100);
867 - expect(ReactNoop.expire(100)).toEqual([
868 - 'Promise resolved [Result]',
869 - 'Result',
870 - ]);
863 + expect(ReactNoop).toHaveYielded(['Promise resolved [Result]', 'Result']);
864
865 expect(ReactNoop.getChildren()).toEqual([span('Result')]);
866 });
@@ -905,7 +898,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
898 // Initial mount. This is synchronous, because the root is sync.
899 ReactNoop.renderLegacySyncRoot(<App />);
900 await advanceTimers(100);
908 - expect(ReactNoop.clearYields()).toEqual([
901 + expect(ReactNoop).toHaveYielded([
902 'Suspend! [Step: 1]',
903 'Sibling',
904 'Loading (1)',
@@ -914,7 +907,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
907 'Promise resolved [Step: 1]',
908 'Step: 1',
909 ]);
917 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
910 + expect(ReactNoop).toMatchRenderedOutput(
911 <React.Fragment>
912 <span prop="Step: 1" />
913 <span prop="Sibling" />
@@ -928,13 +921,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
921
922 // Suspend during an async render.
923 expect(ReactNoop.flushNextYield()).toEqual(['Suspend! [Step: 2]']);
931 - expect(ReactNoop.flush()).toEqual([
924 + expect(ReactNoop).toFlushAndYield([
925 'Loading (1)',
926 'Loading (2)',
927 'Loading (3)',
928 'Update did commit',
929 ]);
937 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
930 + expect(ReactNoop).toMatchRenderedOutput(
931 <React.Fragment>
932 <span hidden={true} prop="Step: 1" />
933 <span hidden={true} prop="Sibling" />
@@ -945,11 +938,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
938 );
939
940 await advanceTimers(100);
948 - expect(ReactNoop.flush()).toEqual([
941 + expect(ReactNoop).toHaveYielded([
942 'Promise resolved [Step: 2]',
943 'Step: 2',
944 ]);
952 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
945 + expect(ReactNoop).toMatchRenderedOutput(
946 <React.Fragment>
947 <span prop="Step: 2" />
948 <span prop="Sibling" />
@@ -1008,7 +1001,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1001 ReactNoop.yield('Did mount'),
1002 );
1003 await advanceTimers(100);
1011 - expect(ReactNoop.clearYields()).toEqual([
1004 + expect(ReactNoop).toHaveYielded([
1005 'Before',
1006 'Suspend! [Async: 1]',
1007 'After',
@@ -1020,7 +1013,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1013 'Promise resolved [Async: 1]',
1014 'Async: 1',
1015 ]);
1023 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1016 + expect(ReactNoop).toMatchRenderedOutput(
1017 <React.Fragment>
1018 <span prop="Before" />
1019 <span prop="Async: 1" />
@@ -1041,14 +1034,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1034 );
1035
1036 // Start rendering asynchronously
1044 - ReactNoop.flushThrough(['Before']);
1037 + expect(ReactNoop).toFlushAndYieldThrough(['Before']);
1038
1039 // Now render the next child, which suspends
1040 expect(ReactNoop.flushNextYield()).toEqual([
1041 // This child suspends
1042 'Suspend! [Async: 2]',
1043 ]);
1051 - expect(ReactNoop.flush()).toEqual([
1044 + expect(ReactNoop).toFlushAndYield([
1045 'After',
1046 'Loading...',
1047 'Before',
@@ -1057,7 +1050,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1050 'Update 1 did commit',
1051 'Update 2 did commit',
1052 ]);
1060 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1053 + expect(ReactNoop).toMatchRenderedOutput(
1054 <React.Fragment>
1055 <span hidden={true} prop="Before" />
1056 <span hidden={true} prop="Async: 1" />
@@ -1073,12 +1066,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1066 // When the placeholder is pinged, the boundary must be re-rendered
1067 // synchronously.
1068 await advanceTimers(100);
1076 - expect(ReactNoop.clearYields()).toEqual([
1069 + expect(ReactNoop).toHaveYielded([
1070 'Promise resolved [Async: 2]',
1071 'Async: 2',
1072 ]);
1073
1081 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1074 + expect(ReactNoop).toMatchRenderedOutput(
1075 <React.Fragment>
1076 <span prop="Before" />
1077 <span prop="Async: 2" />
@@ -1143,7 +1136,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1136 ReactNoop.yield('Did mount'),
1137 );
1138 await advanceTimers(100);
1146 - expect(ReactNoop.clearYields()).toEqual([
1139 + expect(ReactNoop).toHaveYielded([
1140 'Before',
1141 'Suspend! [Async: 1]',
1142 'After',
@@ -1155,7 +1148,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1148 'Promise resolved [Async: 1]',
1149 'Async: 1',
1150 ]);
1158 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1151 + expect(ReactNoop).toMatchRenderedOutput(
1152 <React.Fragment>
1153 <span prop="Before" />
1154 <span prop="Async: 1" />
@@ -1176,14 +1169,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1169 );
1170
1171 // Start rendering asynchronously
1179 - ReactNoop.flushThrough(['Before']);
1172 + expect(ReactNoop).toFlushAndYieldThrough(['Before']);
1173
1174 // Now render the next child, which suspends
1175 expect(ReactNoop.flushNextYield()).toEqual([
1176 // This child suspends
1177 'Suspend! [Async: 2]',
1178 ]);
1186 - expect(ReactNoop.flush()).toEqual([
1179 + expect(ReactNoop).toFlushAndYield([
1180 'After',
1181 'Loading...',
1182 'Before',
@@ -1192,7 +1185,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1185 'Update 1 did commit',
1186 'Update 2 did commit',
1187 ]);
1195 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1188 + expect(ReactNoop).toMatchRenderedOutput(
1189 <React.Fragment>
1190 <span hidden={true} prop="Before" />
1191 <span hidden={true} prop="Async: 1" />
@@ -1208,12 +1201,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1201 // When the placeholder is pinged, the boundary must be re-rendered
1202 // synchronously.
1203 await advanceTimers(100);
1211 - expect(ReactNoop.clearYields()).toEqual([
1204 + expect(ReactNoop).toHaveYielded([
1205 'Promise resolved [Async: 2]',
1206 'Async: 2',
1207 ]);
1208
1216 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1209 + expect(ReactNoop).toMatchRenderedOutput(
1210 <React.Fragment>
1211 <span prop="Before" />
1212 <span prop="Async: 2" />
@@ -1267,7 +1260,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1260 ReactNoop.renderLegacySyncRoot(<App />, () =>
1261 ReactNoop.yield('Commit root'),
1262 );
1270 - expect(ReactNoop.clearYields()).toEqual([
1263 + expect(ReactNoop).toHaveYielded([
1264 'A',
1265 'Suspend! [B]',
1266 'C',
@@ -1280,7 +1273,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1273 'Mount [Loading...]',
1274 'Commit root',
1275 ]);
1283 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1276 + expect(ReactNoop).toMatchRenderedOutput(
1277 <React.Fragment>
1278 <span hidden={true} prop="A" />
1279 <span hidden={true} prop="C" />
@@ -1289,10 +1282,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1282 </React.Fragment>,
1283 );
1284
1285 + ReactNoop.expire(1000);
1286 await advanceTimers(1000);
1293 - expect(ReactNoop.expire(1000)).toEqual(['Promise resolved [B]', 'B']);
1287 + expect(ReactNoop).toHaveYielded(['Promise resolved [B]', 'B']);
1288
1295 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1289 + expect(ReactNoop).toMatchRenderedOutput(
1290 <React.Fragment>
1291 <span prop="A" />
1292 <span prop="B" />
@@ -1334,7 +1328,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1328 </Suspense>,
1329 );
1330
1337 - expect(ReactNoop.clearYields()).toEqual([
1331 + expect(ReactNoop).toHaveYielded([
1332 'constructor',
1333 'Suspend! [Hi]',
1334 'Loading...',
@@ -1342,7 +1336,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1336 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
1337
1338 await advanceTimers(1000);
1345 - expect(ReactNoop.clearYields()).toEqual([
1339 + expect(ReactNoop).toHaveYielded([
1340 'Promise resolved [Hi]',
1341 'constructor',
1342 'Hi',
@@ -1377,8 +1371,16 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1371 }
1372
1373 ReactNoop.renderLegacySyncRoot(<Demo />);
1374 +
1375 + expect(ReactNoop).toHaveYielded([
1376 + 'Suspend! [Hi]',
1377 + 'Loading...',
1378 + // Re-render due to lifecycle update
1379 + 'Loading...',
1380 + ]);
1381 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
1382 await advanceTimers(100);
1383 + expect(ReactNoop).toHaveYielded(['Promise resolved [Hi]', 'Hi']);
1384 expect(ReactNoop.getChildren()).toEqual([span('Hi')]);
1385 });
1386
@@ -1409,7 +1411,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1411
1412 ReactNoop.renderLegacySyncRoot(<App middleText="B" />);
1413
1412 - expect(ReactNoop.clearYields()).toEqual([
1414 + expect(ReactNoop).toHaveYielded([
1415 'Suspend! [Hi]',
1416 'Loading...',
1417 // The child should have already been hidden
@@ -1418,7 +1420,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1420
1421 await advanceTimers(1000);
1422
1421 - expect(ReactNoop.clearYields()).toEqual(['Promise resolved [Hi]', 'Hi']);
1423 + expect(ReactNoop).toHaveYielded(['Promise resolved [Hi]', 'Hi']);
1424 });
1425 });
1426
@@ -1481,7 +1483,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1483 ReactNoop.renderLegacySyncRoot(<App />, () =>
1484 ReactNoop.yield('Commit root'),
1485 );
1484 - expect(ReactNoop.clearYields()).toEqual([
1486 + expect(ReactNoop).toHaveYielded([
1487 'A',
1488 'Suspend! [B]',
1489 'C',
@@ -1494,7 +1496,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1496 'Mount [Loading...]',
1497 'Commit root',
1498 ]);
1497 - expect(ReactNoop.getChildrenAsJSX()).toEqual(
1499 + expect(ReactNoop).toMatchRenderedOutput(
1500 <React.Fragment>
1501 <span hidden={true} prop="A" />
1502 <span hidden={true} prop="C" />
packages/react-reconciler/src/__tests__/ReactTopLevelFragment-test.js
+10 -10
@@ -27,7 +27,7 @@ describe('ReactTopLevelFragment', function() {
27 return [<div key="a">Hello</div>, <div key="b">World</div>];
28 }
29 ReactNoop.render(<Fragment />);
30 - ReactNoop.flush();
30 + expect(ReactNoop).toFlushWithoutYielding();
31 });
32
33 it('should preserve state when switching from a single child', function() {
@@ -48,14 +48,14 @@ describe('ReactTopLevelFragment', function() {
48 );
49 }
50 ReactNoop.render(<Fragment />);
51 - ReactNoop.flush();
51 + expect(ReactNoop).toFlushWithoutYielding();
52
53 const instanceA = instance;
54
55 expect(instanceA).not.toBe(null);
56
57 ReactNoop.render(<Fragment condition={true} />);
58 - ReactNoop.flush();
58 + expect(ReactNoop).toFlushWithoutYielding();
59
60 const instanceB = instance;
61
@@ -80,14 +80,14 @@ describe('ReactTopLevelFragment', function() {
80 );
81 }
82 ReactNoop.render(<Fragment />);
83 - ReactNoop.flush();
83 + expect(ReactNoop).toFlushWithoutYielding();
84
85 const instanceA = instance;
86
87 expect(instanceA).not.toBe(null);
88
89 ReactNoop.render(<Fragment condition={true} />);
90 - ReactNoop.flush();
90 + expect(ReactNoop).toFlushWithoutYielding();
91
92 const instanceB = instance;
93
@@ -110,21 +110,21 @@ describe('ReactTopLevelFragment', function() {
110 : [<div key="b">Hello</div>, <Stateful key="a" />];
111 }
112 ReactNoop.render(<Fragment />);
113 - ReactNoop.flush();
113 + expect(ReactNoop).toFlushWithoutYielding();
114
115 const instanceA = instance;
116
117 expect(instanceA).not.toBe(null);
118
119 ReactNoop.render(<Fragment condition={true} />);
120 - ReactNoop.flush();
120 + expect(ReactNoop).toFlushWithoutYielding();
121
122 const instanceB = instance;
123
124 expect(instanceB).toBe(instanceA);
125
126 ReactNoop.render(<Fragment condition={false} />);
127 - ReactNoop.flush();
127 + expect(ReactNoop).toFlushWithoutYielding();
128
129 const instanceC = instance;
130
@@ -147,14 +147,14 @@ describe('ReactTopLevelFragment', function() {
147 : [[<Stateful key="a" />, <div key="b">World</div>], <div key="c" />];
148 }
149 ReactNoop.render(<Fragment />);
150 - ReactNoop.flush();
150 + expect(ReactNoop).toFlushWithoutYielding();
151
152 const instanceA = instance;
153
154 expect(instanceA).not.toBe(null);
155
156 ReactNoop.render(<Fragment condition={true} />);
157 - ReactNoop.flush();
157 + expect(ReactNoop).toFlushWithoutYielding();
158
159 const instanceB = instance;
160
packages/react-reconciler/src/__tests__/ReactTopLevelText-test.js
+4 -4
@@ -25,14 +25,14 @@ describe('ReactTopLevelText', () => {
25 it('should render a component returning strings directly from render', () => {
26 const Text = ({value}) => value;
27 ReactNoop.render(<Text value="foo" />);
28 - ReactNoop.flush();
29 - expect(ReactNoop.getChildrenAsJSX()).toEqual('foo');
28 + expect(ReactNoop).toFlushWithoutYielding();
29 + expect(ReactNoop).toMatchRenderedOutput('foo');
30 });
31
32 it('should render a component returning numbers directly from render', () => {
33 const Text = ({value}) => value;
34 ReactNoop.render(<Text value={10} />);
35 - ReactNoop.flush();
36 - expect(ReactNoop.getChildrenAsJSX()).toEqual('10');
35 + expect(ReactNoop).toFlushWithoutYielding();
36 + expect(ReactNoop).toMatchRenderedOutput('10');
37 });
38 });
packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap
+1 -13
@@ -212,12 +212,6 @@ exports[`ReactDebugFiberPerf measures deferred work in chunks 1`] = `
212 "⚛ (Waiting for async callback... will force flush in 5250 ms)
213
214 // Start rendering through B
215 -⚛ (React Tree Reconciliation: Yielded)
216 - ⚛ Parent [mount]
217 - ⚛ A [mount]
218 -
219 -⚛ (Waiting for async callback... will force flush in 5250 ms)
220 -
215 ⚛ (React Tree Reconciliation: Yielded)
216 ⚛ Parent [mount]
217 ⚛ A [mount]
@@ -227,17 +221,11 @@ exports[`ReactDebugFiberPerf measures deferred work in chunks 1`] = `
221 ⚛ (Waiting for async callback... will force flush in 5250 ms)
222
223 // Complete the rest
230 -⚛ (React Tree Reconciliation: Yielded)
224 +⚛ (React Tree Reconciliation: Completed Root)
225 ⚛ Parent [mount]
226 ⚛ B [mount]
227 ⚛ Child [mount]
228 ⚛ C [mount]
235 -
236 -⚛ (Waiting for async callback... will force flush in 5250 ms)
237 -
238 -⚛ (React Tree Reconciliation: Completed Root)
239 - ⚛ Parent [mount]
240 - ⚛ C [mount]
229 ⚛ Child [mount]
230
231 ⚛ (Committing Changes)
packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js
+1 -1
@@ -1018,7 +1018,7 @@ describe('ReactTestRenderer', () => {
1018 </Context.Provider>
1019 );
1020 ReactNoop.render(<App />);
1021 - ReactNoop.flush();
1021 + expect(ReactNoop).toFlushWithoutYielding();
1022 ReactTestRenderer.create(<App />);
1023 });
1024
packages/react/src/__tests__/ReactProfiler-test.internal.js
+13 -11
@@ -1101,7 +1101,7 @@ describe('Profiler', () => {
1101 <errorInCompletePhase>hi</errorInCompletePhase>
1102 </React.unstable_Profiler>,
1103 );
1104 - expect(ReactNoop.flush).toThrow('Error in host config.');
1104 + expect(ReactNoop).toFlushAndThrow('Error in host config.');
1105
1106 // A similar case we've seen caused by an invariant in ReactDOM.
1107 // It didn't reproduce without a host component inside.
@@ -1112,7 +1112,7 @@ describe('Profiler', () => {
1112 </errorInCompletePhase>
1113 </React.unstable_Profiler>,
1114 );
1115 - expect(ReactNoop.flush).toThrow('Error in host config.');
1115 + expect(ReactNoop).toFlushAndThrow('Error in host config.');
1116
1117 // So long as the profiler timer's fiber stack is reset correctly,
1118 // Subsequent renders should not error.
@@ -1121,7 +1121,7 @@ describe('Profiler', () => {
1121 <span>hi</span>
1122 </React.unstable_Profiler>,
1123 );
1124 - ReactNoop.flush();
1124 + expect(ReactNoop).toFlushWithoutYielding();
1125 });
1126 });
1127 },
@@ -1242,7 +1242,7 @@ describe('Profiler', () => {
1242
1243 // Process some async work, but yield before committing it.
1244 ReactNoop.renderToRootWithID(<Parent duration={7} id="two" />, 'two');
1245 - ReactNoop.flushThrough(['Child:render:two']);
1245 + expect(ReactNoop).toFlushAndYieldThrough(['Child:render:two']);
1246
1247 ReactNoop.advanceTime(150);
1248
@@ -1254,7 +1254,11 @@ describe('Profiler', () => {
1254
1255 ReactNoop.advanceTime(200);
1256
1257 - ReactNoop.flush();
1257 + expect(ReactNoop).toHaveYielded(['Parent:componentDidMount:one']);
1258 + expect(ReactNoop).toFlushAndYield([
1259 + 'Child:render:two',
1260 + 'Parent:componentDidMount:two',
1261 + ]);
1262
1263 expect(ReactNoop.getRoot('two').current.actualDuration).toBe(14);
1264 });
@@ -2236,7 +2240,7 @@ describe('Profiler', () => {
2240 expect(getWorkForReactThreads(onWorkStarted)).toHaveLength(0);
2241 expect(getWorkForReactThreads(onWorkStopped)).toHaveLength(0);
2242
2239 - expect(ReactNoop.flush()).toEqual([
2243 + expect(ReactNoop).toFlushAndYield([
2244 'Suspend [Async]',
2245 'Text [Loading...]',
2246 'Text [Sync]',
@@ -2268,15 +2272,13 @@ describe('Profiler', () => {
2272
2273 // An unrelated update in the middle shouldn't affect things...
2274 monkey.current.forceUpdate();
2271 - expect(ReactNoop.flush()).toEqual(['Monkey']);
2275 + expect(ReactNoop).toFlushAndYield(['Monkey']);
2276 expect(onRender).toHaveBeenCalledTimes(2);
2277
2278 // Once the promise resolves, we render the suspended view
2279 await awaitableAdvanceTimers(10000);
2276 - expect(ReactNoop.flush()).toEqual([
2277 - 'Promise resolved [Async]',
2278 - 'AsyncText [Async]',
2279 - ]);
2280 + expect(ReactNoop).toHaveYielded(['Promise resolved [Async]']);
2281 + expect(ReactNoop).toFlushAndYield(['AsyncText [Async]']);
2282 expect(ReactNoop.getChildrenAsJSX()).toEqual('AsyncSync');
2283 expect(onRender).toHaveBeenCalledTimes(3);
2284
packages/react/src/__tests__/forwardRef-test.internal.js
+8 -8
@@ -40,7 +40,7 @@ describe('forwardRef', () => {
40 ));
41
42 ReactNoop.render(<RefForwardingComponent value={123} />);
43 - expect(ReactNoop.flush()).toEqual([123]);
43 + expect(ReactNoop).toFlushAndYield([123]);
44 });
45
46 it('should forward a ref for a single child', () => {
@@ -62,7 +62,7 @@ describe('forwardRef', () => {
62 const ref = React.createRef();
63
64 ReactNoop.render(<RefForwardingComponent ref={ref} value={123} />);
65 - expect(ReactNoop.flush()).toEqual([123]);
65 + expect(ReactNoop).toFlushAndYield([123]);
66 expect(ref.current instanceof Child).toBe(true);
67 });
68
@@ -91,7 +91,7 @@ describe('forwardRef', () => {
91 <div />
92 </div>,
93 );
94 - expect(ReactNoop.flush()).toEqual([123]);
94 + expect(ReactNoop).toFlushAndYield([123]);
95 expect(ref.current instanceof Child).toBe(true);
96 });
97
@@ -123,11 +123,11 @@ describe('forwardRef', () => {
123 };
124
125 ReactNoop.render(<RefForwardingComponent ref={setRef} value={123} />);
126 - expect(ReactNoop.flush()).toEqual([123]);
126 + expect(ReactNoop).toFlushAndYield([123]);
127 expect(ref instanceof Child).toBe(true);
128 expect(setRefCount).toBe(1);
129 ReactNoop.render(<RefForwardingComponent ref={setRef} value={456} />);
130 - expect(ReactNoop.flush()).toEqual([456]);
130 + expect(ReactNoop).toFlushAndYield([456]);
131 expect(ref instanceof Child).toBe(true);
132 expect(setRefCount).toBe(1);
133 });
@@ -172,7 +172,7 @@ describe('forwardRef', () => {
172 <RefForwardingComponent ref={ref} />
173 </ErrorBoundary>,
174 );
175 - expect(ReactNoop.flush()).toEqual([
175 + expect(ReactNoop).toFlushAndYield([
176 'ErrorBoundary.render: try',
177 'Wrapper',
178 'BadRender throw',
@@ -216,9 +216,9 @@ describe('forwardRef', () => {
216 }
217
218 ReactNoop.render(<App />);
219 - expect(ReactNoop.flush()).toEqual(['App', 'Forward', 'Middle', 'Inner']);
219 + expect(ReactNoop).toFlushAndYield(['App', 'Forward', 'Middle', 'Inner']);
220
221 inst.setState({});
222 - expect(ReactNoop.flush()).toEqual(['Inner']);
222 + expect(ReactNoop).toFlushAndYield(['Inner']);
223 });
224 });
packages/react/src/__tests__/forwardRef-test.js
+20 -20
@@ -38,11 +38,11 @@ describe('forwardRef', () => {
38 const ref = React.createRef();
39
40 ReactNoop.render(<RefForwardingComponent ref={ref} setRefOnDiv={true} />);
41 - ReactNoop.flush();
41 + expect(ReactNoop).toFlushWithoutYielding();
42 expect(ref.current.type).toBe('div');
43
44 ReactNoop.render(<RefForwardingComponent ref={ref} setRefOnDiv={false} />);
45 - ReactNoop.flush();
45 + expect(ReactNoop).toFlushWithoutYielding();
46 expect(ref.current.type).toBe('span');
47 });
48
@@ -52,7 +52,7 @@ describe('forwardRef', () => {
52 const ref = React.createRef();
53
54 ReactNoop.render(<RefForwardingComponent ref={ref} />);
55 - ReactNoop.flush();
55 + expect(ReactNoop).toFlushWithoutYielding();
56 expect(ref.current).toBe(null);
57 });
58
@@ -68,7 +68,7 @@ describe('forwardRef', () => {
68 <div />
69 </div>,
70 );
71 - ReactNoop.flush();
71 + expect(ReactNoop).toFlushWithoutYielding();
72 expect(ref.current).toBe(null);
73 });
74
@@ -101,14 +101,14 @@ describe('forwardRef', () => {
101 ReactNoop.render(
102 <RefForwardingComponent ref={ref} optional="foo" required="bar" />,
103 );
104 - ReactNoop.flush();
104 + expect(ReactNoop).toFlushWithoutYielding();
105 expect(ref.current.children).toEqual([
106 {text: 'foo', hidden: false},
107 {text: 'bar', hidden: false},
108 ]);
109
110 ReactNoop.render(<RefForwardingComponent ref={ref} required="foo" />);
111 - ReactNoop.flush();
111 + expect(ReactNoop).toFlushWithoutYielding();
112 expect(ref.current.children).toEqual([
113 {text: 'default', hidden: false},
114 {text: 'foo', hidden: false},
@@ -240,11 +240,11 @@ describe('forwardRef', () => {
240 const ref = React.createRef();
241
242 ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />);
243 - ReactNoop.flush();
243 + expect(ReactNoop).toFlushWithoutYielding();
244 expect(renderCount).toBe(1);
245
246 ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />);
247 - ReactNoop.flush();
247 + expect(ReactNoop).toFlushWithoutYielding();
248 expect(renderCount).toBe(2);
249 });
250
@@ -263,13 +263,13 @@ describe('forwardRef', () => {
263 const ref = React.createRef();
264
265 ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />);
266 - ReactNoop.flush();
266 + expect(ReactNoop).toFlushWithoutYielding();
267 expect(renderCount).toBe(1);
268
269 expect(ref.current.type).toBe('div');
270
271 ReactNoop.render(<RefForwardingComponent ref={ref} optional="foo" />);
272 - ReactNoop.flush();
272 + expect(ReactNoop).toFlushWithoutYielding();
273 expect(renderCount).toBe(1);
274
275 const differentRef = React.createRef();
@@ -277,14 +277,14 @@ describe('forwardRef', () => {
277 ReactNoop.render(
278 <RefForwardingComponent ref={differentRef} optional="foo" />,
279 );
280 - ReactNoop.flush();
280 + expect(ReactNoop).toFlushWithoutYielding();
281 expect(renderCount).toBe(2);
282
283 expect(ref.current).toBe(null);
284 expect(differentRef.current.type).toBe('div');
285
286 ReactNoop.render(<RefForwardingComponent ref={ref} optional="bar" />);
287 - ReactNoop.flush();
287 + expect(ReactNoop).toFlushWithoutYielding();
288 expect(renderCount).toBe(3);
289 });
290
@@ -304,19 +304,19 @@ describe('forwardRef', () => {
304 const ref = React.createRef();
305
306 ReactNoop.render(<RefForwardingComponent ref={ref} a="0" b="0" c="1" />);
307 - ReactNoop.flush();
307 + expect(ReactNoop).toFlushWithoutYielding();
308 expect(renderCount).toBe(1);
309
310 expect(ref.current.type).toBe('div');
311
312 // Changing either a or b rerenders
313 ReactNoop.render(<RefForwardingComponent ref={ref} a="0" b="1" c="1" />);
314 - ReactNoop.flush();
314 + expect(ReactNoop).toFlushWithoutYielding();
315 expect(renderCount).toBe(2);
316
317 // Changing c doesn't rerender
318 ReactNoop.render(<RefForwardingComponent ref={ref} a="0" b="1" c="2" />);
319 - ReactNoop.flush();
319 + expect(ReactNoop).toFlushWithoutYielding();
320 expect(renderCount).toBe(2);
321
322 const ComposedMemo = React.memo(
@@ -325,29 +325,29 @@ describe('forwardRef', () => {
325 );
326
327 ReactNoop.render(<ComposedMemo ref={ref} a="0" b="0" c="0" />);
328 - ReactNoop.flush();
328 + expect(ReactNoop).toFlushWithoutYielding();
329 expect(renderCount).toBe(3);
330
331 // Changing just b no longer updates
332 ReactNoop.render(<ComposedMemo ref={ref} a="0" b="1" c="0" />);
333 - ReactNoop.flush();
333 + expect(ReactNoop).toFlushWithoutYielding();
334 expect(renderCount).toBe(3);
335
336 // Changing just a and c updates
337 ReactNoop.render(<ComposedMemo ref={ref} a="2" b="2" c="2" />);
338 - ReactNoop.flush();
338 + expect(ReactNoop).toFlushWithoutYielding();
339 expect(renderCount).toBe(4);
340
341 // Changing just c does not update
342 ReactNoop.render(<ComposedMemo ref={ref} a="2" b="2" c="3" />);
343 - ReactNoop.flush();
343 + expect(ReactNoop).toFlushWithoutYielding();
344 expect(renderCount).toBe(4);
345
346 // Changing ref still rerenders
347 const differentRef = React.createRef();
348
349 ReactNoop.render(<ComposedMemo ref={differentRef} a="2" b="2" c="3" />);
350 - ReactNoop.flush();
350 + expect(ReactNoop).toFlushWithoutYielding();
351 expect(renderCount).toBe(5);
352
353 expect(ref.current).toBe(null);
scripts/jest/matchers/reactTestMatchers.js new
+105
@@ -0,0 +1,105 @@
1 +'use strict';
2 +
3 +const JestReact = require('jest-react');
4 +
5 +function captureAssertion(fn) {
6 + // Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
7 + // assertion; if it throws, we capture the error and return it, so the stack
8 + // trace presented to the user points to the original assertion in the
9 + // test file.
10 + try {
11 + fn();
12 + } catch (error) {
13 + return {
14 + pass: false,
15 + message: () => error.message,
16 + };
17 + }
18 + return {pass: true};
19 +}
20 +
21 +function isReactNoop(obj) {
22 + return typeof obj.hasScheduledCallback === 'function';
23 +}
24 +
25 +function assertYieldsWereCleared(ReactNoop) {
26 + const actualYields = ReactNoop.unstable_clearYields();
27 + if (actualYields.length !== 0) {
28 + throw new Error(
29 + 'Log of yielded values is not empty. ' +
30 + 'Call expect(ReactNoop).toHaveYielded(...) first.'
31 + );
32 + }
33 +}
34 +
35 +function toFlushAndYield(ReactNoop, expectedYields) {
36 + if (!isReactNoop(ReactNoop)) {
37 + return JestReact.unstable_toFlushAndYield(ReactNoop, expectedYields);
38 + }
39 + assertYieldsWereCleared(ReactNoop);
40 + const actualYields = ReactNoop.unstable_flushWithoutYielding();
41 + return captureAssertion(() => {
42 + expect(actualYields).toEqual(expectedYields);
43 + });
44 +}
45 +
46 +function toFlushAndYieldThrough(ReactNoop, expectedYields) {
47 + if (!isReactNoop(ReactNoop)) {
48 + return JestReact.unstable_toFlushAndYieldThrough(ReactNoop, expectedYields);
49 + }
50 + assertYieldsWereCleared(ReactNoop);
51 + const actualYields = ReactNoop.unstable_flushNumberOfYields(
52 + expectedYields.length
53 + );
54 + return captureAssertion(() => {
55 + expect(actualYields).toEqual(expectedYields);
56 + });
57 +}
58 +
59 +function toFlushWithoutYielding(ReactNoop) {
60 + if (!isReactNoop(ReactNoop)) {
61 + return JestReact.unstable_toFlushWithoutYielding(ReactNoop);
62 + }
63 + return toFlushAndYield(ReactNoop, []);
64 +}
65 +
66 +function toHaveYielded(ReactNoop, expectedYields) {
67 + if (!isReactNoop(ReactNoop)) {
68 + return JestReact.unstable_toHaveYielded(ReactNoop, expectedYields);
69 + }
70 + return captureAssertion(() => {
71 + const actualYields = ReactNoop.unstable_clearYields();
72 + expect(actualYields).toEqual(expectedYields);
73 + });
74 +}
75 +
76 +function toFlushAndThrow(ReactNoop, ...rest) {
77 + if (!isReactNoop(ReactNoop)) {
78 + return JestReact.unstable_toFlushAndThrow(ReactNoop, ...rest);
79 + }
80 + assertYieldsWereCleared(ReactNoop);
81 + return captureAssertion(() => {
82 + expect(() => {
83 + ReactNoop.unstable_flushWithoutYielding();
84 + }).toThrow(...rest);
85 + });
86 +}
87 +
88 +function toMatchRenderedOutput(ReactNoop, expectedJSX) {
89 + if (!isReactNoop(ReactNoop)) {
90 + return JestReact.unstable_toMatchRenderedOutput(ReactNoop, expectedJSX);
91 + }
92 + assertYieldsWereCleared(ReactNoop);
93 + return captureAssertion(() => {
94 + expect(ReactNoop.getChildrenAsJSX()).toEqual(expectedJSX);
95 + });
96 +}
97 +
98 +module.exports = {
99 + toFlushAndYield,
100 + toFlushAndYieldThrough,
101 + toFlushWithoutYielding,
102 + toHaveYielded,
103 + toFlushAndThrow,
104 + toMatchRenderedOutput,
105 +};
scripts/jest/setupTests.js
+1 -8
@@ -43,17 +43,10 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
43 global.spyOnDevAndProd = spyOn;
44 }
45
46 - const JestReact = require('jest-react');
46 expect.extend({
47 ...require('./matchers/interactionTracing'),
48 ...require('./matchers/toWarnDev'),
50 -
51 - toFlushWithoutYielding: JestReact.unstable_toFlushWithoutYielding,
52 - toFlushAndYield: JestReact.unstable_toFlushAndYield,
53 - toFlushAndYieldThrough: JestReact.unstable_toFlushAndYieldThrough,
54 - toHaveYielded: JestReact.unstable_toHaveYielded,
55 - toFlushAndThrow: JestReact.unstable_toFlushAndThrow,
56 - toMatchRenderedOutput: JestReact.unstable_toMatchRenderedOutput,
49 + ...require('./matchers/reactTestMatchers'),
50 });
51
52 require('jest-mock-scheduler');
scripts/jest/spec-equivalence-reporter/setupTests.js
+1 -8
@@ -45,17 +45,10 @@ global.spyOnProd = function(...args) {
45 }
46 };
47
48 -const JestReact = require('jest-react');
48 expect.extend({
49 ...require('../matchers/interactionTracing'),
50 ...require('../matchers/toWarnDev'),
52 -
53 - toFlushWithoutYielding: JestReact.unstable_toFlushWithoutYielding,
54 - toFlushAndYield: JestReact.unstable_toFlushAndYield,
55 - toFlushAndYieldThrough: JestReact.unstable_toFlushAndYieldThrough,
56 - toHaveYielded: JestReact.unstable_toHaveYielded,
57 - toFlushAndThrow: JestReact.unstable_toFlushAndThrow,
58 - toMatchRenderedOutput: JestReact.unstable_toMatchRenderedOutput,
51 + ...require('../matchers/reactTestMatchers'),
52 });
53
54 beforeEach(() => (numExpectations = 0));