diff --git a/packages/create-subscription/src/__tests__/createSubscription-test.internal.js b/packages/create-subscription/src/__tests__/createSubscription-test.internal.js index cbbb34979a33c..39969ac4bd9d4 100644 --- a/packages/create-subscription/src/__tests__/createSubscription-test.internal.js +++ b/packages/create-subscription/src/__tests__/createSubscription-test.internal.js @@ -65,16 +65,16 @@ describe('createSubscription', () => { ); // Updates while subscribed should re-render the child component - expect(ReactNoop.flush()).toEqual(['default']); + expect(ReactNoop).toFlushAndYield(['default']); observable.next(123); - expect(ReactNoop.flush()).toEqual([123]); + expect(ReactNoop).toFlushAndYield([123]); observable.next('abc'); - expect(ReactNoop.flush()).toEqual(['abc']); + expect(ReactNoop).toFlushAndYield(['abc']); // Unmounting the subscriber should remove listeners ReactNoop.render(
); observable.next(456); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); }); it('should support observable types like RxJS ReplaySubject', () => { @@ -102,13 +102,13 @@ describe('createSubscription', () => { const observable = createReplaySubject('initial'); ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['initial']); + expect(ReactNoop).toFlushAndYield(['initial']); observable.next('updated'); - expect(ReactNoop.flush()).toEqual(['updated']); + expect(ReactNoop).toFlushAndYield(['updated']); // Unsetting the subscriber prop should reset subscribed values ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['default']); + expect(ReactNoop).toFlushAndYield(['default']); }); describe('Promises', () => { @@ -141,19 +141,19 @@ describe('createSubscription', () => { // Test a promise that resolves after render ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['loading']); + expect(ReactNoop).toFlushAndYield(['loading']); resolveA(true); await promiseA; - expect(ReactNoop.flush()).toEqual(['finished']); + expect(ReactNoop).toFlushAndYield(['finished']); // Test a promise that resolves before render // Note that this will require an extra render anyway, // Because there is no way to synchronously get a Promise's value rejectB(false); ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['loading']); + expect(ReactNoop).toFlushAndYield(['loading']); await promiseB.catch(() => true); - expect(ReactNoop.flush()).toEqual(['failed']); + expect(ReactNoop).toFlushAndYield(['failed']); }); it('should still work if unsubscription is managed incorrectly', async () => { @@ -177,9 +177,9 @@ describe('createSubscription', () => { // Subscribe first to Promise A then Promise B ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['default']); + expect(ReactNoop).toFlushAndYield(['default']); ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['default']); + expect(ReactNoop).toFlushAndYield(['default']); // Resolve both Promises resolveB(123); @@ -187,7 +187,7 @@ describe('createSubscription', () => { await Promise.all([promiseA, promiseB]); // Ensure that only Promise B causes an update - expect(ReactNoop.flush()).toEqual([123]); + expect(ReactNoop).toFlushAndYield([123]); }); it('should not call setState for a Promise that resolves after unmount', async () => { @@ -211,11 +211,11 @@ describe('createSubscription', () => { }); ReactNoop.render({render}); - expect(ReactNoop.flush()).toEqual(['rendered']); + expect(ReactNoop).toFlushAndYield(['rendered']); // Unmount ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // Resolve Promise should not trigger a setState warning resolvePromise(true); @@ -245,21 +245,21 @@ describe('createSubscription', () => { ); // Updates while subscribed should re-render the child component - expect(ReactNoop.flush()).toEqual(['a-0']); + expect(ReactNoop).toFlushAndYield(['a-0']); // Unsetting the subscriber prop should reset subscribed values ReactNoop.render( {render}, ); - expect(ReactNoop.flush()).toEqual(['b-0']); + expect(ReactNoop).toFlushAndYield(['b-0']); // Updates to the old subscribable should not re-render the child component observableA.next('a-1'); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); // Updates to the bew subscribable should re-render the child component observableB.next('b-1'); - expect(ReactNoop.flush()).toEqual(['b-1']); + expect(ReactNoop).toFlushAndYield(['b-1']); }); it('should ignore values emitted by a new subscribable until the commit phase', () => { @@ -315,12 +315,12 @@ describe('createSubscription', () => { const observableB = createBehaviorSubject('b-0'); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Subscriber: a-0', 'Child: a-0']); + expect(ReactNoop).toFlushAndYield(['Subscriber: a-0', 'Child: a-0']); expect(log).toEqual(['Parent.componentDidMount']); // Start React update, but don't finish ReactNoop.render(); - ReactNoop.flushThrough(['Subscriber: b-0']); + expect(ReactNoop).toFlushAndYieldThrough(['Subscriber: b-0']); expect(log).toEqual(['Parent.componentDidMount']); // Emit some updates from the uncommitted subscribable @@ -335,7 +335,7 @@ describe('createSubscription', () => { // We expect the last emitted update to be rendered (because of the commit phase value check) // But the intermediate ones should be ignored, // And the final rendered output should be the higher-priority observable. - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Child: b-0', 'Subscriber: b-3', 'Child: b-3', @@ -402,12 +402,12 @@ describe('createSubscription', () => { const observableB = createBehaviorSubject('b-0'); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Subscriber: a-0', 'Child: a-0']); + expect(ReactNoop).toFlushAndYield(['Subscriber: a-0', 'Child: a-0']); expect(log).toEqual(['Parent.componentDidMount']); // Start React update, but don't finish ReactNoop.render(); - ReactNoop.flushThrough(['Subscriber: b-0']); + expect(ReactNoop).toFlushAndYieldThrough(['Subscriber: b-0']); expect(log).toEqual(['Parent.componentDidMount']); // Emit some updates from the old subscribable @@ -420,7 +420,7 @@ describe('createSubscription', () => { // Flush everything and ensure that the correct subscribable is used // We expect the new subscribable to finish rendering, // But then the updated values from the old subscribable should be used. - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Child: b-0', 'Subscriber: a-2', 'Child: a-2', @@ -433,7 +433,7 @@ describe('createSubscription', () => { // Updates from the new subscribable should be ignored. observableB.next('b-1'); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); expect(log).toEqual([ 'Parent.componentDidMount', 'Parent.componentDidUpdate', @@ -479,7 +479,7 @@ describe('createSubscription', () => { {value => null}, ); - expect(ReactNoop.flush).toThrow( + expect(ReactNoop).toFlushAndThrow( 'A subscription must return an unsubscribe function.', ); }); diff --git a/packages/react-art/src/__tests__/ReactART-test.js b/packages/react-art/src/__tests__/ReactART-test.js index a9e0e7486fe06..f7115c556c0d5 100644 --- a/packages/react-art/src/__tests__/ReactART-test.js +++ b/packages/react-art/src/__tests__/ReactART-test.js @@ -385,7 +385,7 @@ describe('ReactART', () => { , ); - ReactNoop.flushThrough(['A']); + expect(ReactNoop).toFlushAndYieldThrough(['A']); ReactDOM.render( @@ -400,7 +400,7 @@ describe('ReactART', () => { expect(ops).toEqual([null, 'ART']); ops = []; - expect(ReactNoop.flush()).toEqual(['B', 'C']); + expect(ReactNoop).toFlushAndYield(['B', 'C']); expect(ops).toEqual(['Test']); }); diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 985493ea47132..714141ccd18c8 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -534,55 +534,71 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { const roots = new Map(); const DEFAULT_ROOT_ID = ''; - let yieldedValues = null; - - let didYield; - let unitsRemaining; + let yieldedValues: Array = []; + let didStop: boolean = false; + let expectedNumberOfYields: number = -1; function shouldYield() { - // Check if we already yielded - if (didYield || yieldedValues !== null) { - return true; - } - - // If there are no remaining units of work, and we haven't timed out, then - // we should yield. if ( - unitsRemaining-- <= 0 && + expectedNumberOfYields !== -1 && + yieldedValues.length >= expectedNumberOfYields && (scheduledCallbackTimeout === -1 || elapsedTimeInMs < scheduledCallbackTimeout) ) { - didYield = true; + // We yielded at least as many values as expected. Stop rendering. + didStop = true; return true; } - - // Otherwise, keep working. + // Keep rendering. return false; } - function* flushUnitsOfWork(n: number): Generator, void, void> { - unitsRemaining = n; - didYield = false; + function flushAll(): Array { + yieldedValues = []; + while (scheduledCallback !== null) { + const cb = scheduledCallback; + scheduledCallback = null; + const didTimeout = + scheduledCallbackTimeout !== -1 && + scheduledCallbackTimeout < elapsedTimeInMs; + cb(didTimeout); + } + const values = yieldedValues; + yieldedValues = []; + return values; + } + + function flushNumberOfYields(count: number): Array { + expectedNumberOfYields = count; + didStop = false; + yieldedValues = []; try { - while (!didYield && scheduledCallback !== null) { - let cb = scheduledCallback; + while (scheduledCallback !== null && !didStop) { + const cb = scheduledCallback; scheduledCallback = null; const didTimeout = scheduledCallbackTimeout !== -1 && scheduledCallbackTimeout < elapsedTimeInMs; cb(didTimeout); - if (yieldedValues !== null) { - const values = yieldedValues; - yieldedValues = null; - yield values; - } } + return yieldedValues; } finally { - unitsRemaining = -1; - didYield = false; + expectedNumberOfYields = -1; + didStop = false; + yieldedValues = []; } } + function yieldValue(value: mixed): void { + yieldedValues.push(value); + } + + function clearYields(): Array { + const values = yieldedValues; + yieldedValues = []; + return values; + } + function childToJSX(child, text) { if (text !== null) { return text; @@ -747,53 +763,14 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { return NoopRenderer.findHostInstance(component); }, - flush(): Array { - let values = yieldedValues || []; - yieldedValues = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const value of flushUnitsOfWork(Infinity)) { - values.push(...value); - } - return values; - }, - // TODO: Should only be used via a Jest plugin (like we do with the // test renderer). - unstable_flushNumberOfYields(n: number): Array { - let values = yieldedValues || []; - yieldedValues = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const value of flushUnitsOfWork(Infinity)) { - values.push(...value); - if (values.length >= n) { - break; - } - } - return values; - }, - - flushThrough(expected: Array): void { - let actual = []; - if (expected.length !== 0) { - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const value of flushUnitsOfWork(Infinity)) { - actual.push(...value); - if (actual.length >= expected.length) { - break; - } - } - } - expect(actual).toEqual(expected); - }, + unstable_flushWithoutYielding: flushAll, + unstable_flushNumberOfYields: flushNumberOfYields, + unstable_clearYields: clearYields, flushNextYield(): Array { - let actual = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const value of flushUnitsOfWork(Infinity)) { - actual = value; - break; - } - return actual !== null ? actual : []; + return flushNumberOfYields(1); }, flushWithHostCounters( @@ -811,7 +788,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { hostUpdateCounter = 0; hostCloneCounter = 0; try { - ReactNoop.flush(); + flushAll(); return useMutation ? { hostDiffCounter, @@ -838,28 +815,10 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { }, flushExpired(): Array { - let values = yieldedValues || []; - yieldedValues = null; - // eslint-disable-next-line no-for-of-loops/no-for-of-loops - for (const value of flushUnitsOfWork(0)) { - values.push(...value); - } - return values; - }, - - yield(value: mixed) { - if (yieldedValues === null) { - yieldedValues = [value]; - } else { - yieldedValues.push(value); - } + return flushNumberOfYields(0); }, - clearYields() { - const values = yieldedValues; - yieldedValues = null; - return values; - }, + yield: yieldValue, hasScheduledCallback() { return !!scheduledCallback; @@ -1038,7 +997,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { _next: null, }; root.firstBatch = batch; - const actual = ReactNoop.flush(); + const actual = flushAll(); expect(actual).toEqual(expectedFlush); return (expectedCommit: Array) => { batch._defer = false; diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.internal.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.internal.js index 65f06b6dc3f51..c397d01b34562 100644 --- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.internal.js @@ -73,7 +73,7 @@ describe('ReactExpiration', () => { ReactNoop.render(); // The updates should flush in separate batches, since sufficient time // passed in between them *and* they occurred in separate events. - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'A [render]', 'A [commit]', 'B [render]', @@ -88,13 +88,13 @@ describe('ReactExpiration', () => { // haven't entered an idle callback, the scheduler must assume that we're // inside the same event. ReactNoop.advanceTime(2000); - expect(ReactNoop.clearYields()).toEqual(null); + expect(ReactNoop).toHaveYielded([]); expect(ReactNoop.getChildren()).toEqual([span('B')]); // Schedule another update. ReactNoop.render(); // The updates should flush in the same batch, since as far as the scheduler // knows, they may have occurred inside the same event. - expect(ReactNoop.flush()).toEqual(['B [render]', 'B [commit]']); + expect(ReactNoop).toFlushAndYield(['B [render]', 'B [commit]']); }); it( @@ -127,7 +127,7 @@ describe('ReactExpiration', () => { ReactNoop.render(); // The updates should flush in separate batches, since sufficient time // passed in between them *and* they occurred in separate events. - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'A [render]', 'A [commit]', 'B [render]', @@ -142,7 +142,7 @@ describe('ReactExpiration', () => { // haven't entered an idle callback, the scheduler must assume that we're // inside the same event. ReactNoop.advanceTime(2000); - expect(ReactNoop.clearYields()).toEqual(null); + expect(ReactNoop).toHaveYielded([]); expect(ReactNoop.getChildren()).toEqual([span('B')]); // Perform some synchronous work. Again, the scheduler must assume we're @@ -156,7 +156,7 @@ describe('ReactExpiration', () => { ReactNoop.render(); // The updates should flush in the same batch, since as far as the scheduler // knows, they may have occurred inside the same event. - expect(ReactNoop.flush()).toEqual(['B [render]', 'B [commit]']); + expect(ReactNoop).toFlushAndYield(['B [render]', 'B [commit]']); }, ); @@ -191,7 +191,7 @@ describe('ReactExpiration', () => { // Initial mount ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'initial [A] [render]', 'initial [B] [render]', 'initial [C] [render]', @@ -204,12 +204,18 @@ describe('ReactExpiration', () => { // Partial update subscribers.forEach(s => s.setState({text: '1'})); - ReactNoop.flushThrough(['1 [A] [render]', '1 [B] [render]']); + expect(ReactNoop).toFlushAndYieldThrough([ + '1 [A] [render]', + '1 [B] [render]', + ]); // Before the update can finish, update again. Even though no time has // advanced, this update should be given a different expiration time than // the currently rendering one. So, C and D should render with 1, not 2. subscribers.forEach(s => s.setState({text: '2'})); - ReactNoop.flushThrough(['1 [C] [render]', '1 [D] [render]']); + expect(ReactNoop).toFlushAndYieldThrough([ + '1 [C] [render]', + '1 [D] [render]', + ]); }); }); diff --git a/packages/react-reconciler/src/__tests__/ReactFragment-test.js b/packages/react-reconciler/src/__tests__/ReactFragment-test.js index d6b8b41fc0f2a..c72b395eb27c3 100644 --- a/packages/react-reconciler/src/__tests__/ReactFragment-test.js +++ b/packages/react-reconciler/src/__tests__/ReactFragment-test.js @@ -43,7 +43,7 @@ describe('ReactFragment', () => { ); ReactNoop.render(element); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span()]); }); @@ -52,7 +52,7 @@ describe('ReactFragment', () => { const element = ; ReactNoop.render(element); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); }); @@ -65,7 +65,7 @@ describe('ReactFragment', () => { ); ReactNoop.render(element); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([text('hello '), span()]); }); @@ -78,7 +78,7 @@ describe('ReactFragment', () => { ); ReactNoop.render(element); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span(), span()]); }); @@ -108,16 +108,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div(), div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -149,16 +149,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -199,16 +199,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div(), div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -242,16 +242,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -283,16 +283,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -325,16 +325,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div(), div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -364,16 +364,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -403,16 +403,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -444,16 +444,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -481,16 +481,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -522,16 +522,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -564,16 +564,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div(), span()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -605,16 +605,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div()]); @@ -658,16 +658,16 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Update Stateful', 'Update Stateful']); expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]); @@ -705,10 +705,10 @@ describe('ReactFragment', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Each child in a list should have a unique "key" prop.', ); @@ -716,7 +716,7 @@ describe('ReactFragment', () => { expect(ReactNoop.getChildren()).toEqual([div(div(), span())]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([]); expect(ReactNoop.getChildren()).toEqual([div(div(), span())]); @@ -752,12 +752,12 @@ describe('ReactFragment', () => { } ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Each child in a list should have a unique "key" prop.', ); ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Each child in a list should have a unique "key" prop.', ); @@ -765,7 +765,7 @@ describe('ReactFragment', () => { expect(ReactNoop.getChildren()).toEqual([span(), div()]); ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Each child in a list should have a unique "key" prop.', ); diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js index bb8e033623f3e..adca4cbc6de8d 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js @@ -74,7 +74,7 @@ describe('ReactHooksWithNoopRenderer', () => { // Initial mount const counter = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); // Schedule some updates @@ -84,17 +84,17 @@ describe('ReactHooksWithNoopRenderer', () => { }); // Partially flush without committing - ReactNoop.flushThrough(['Count: 11']); + expect(ReactNoop).toFlushAndYieldThrough(['Count: 11']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); // Interrupt with a high priority update ReactNoop.flushSync(() => { ReactNoop.render(); }); - expect(ReactNoop.clearYields()).toEqual(['Total: 0']); + expect(ReactNoop).toHaveYielded(['Total: 0']); // Resume rendering - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Total: 11']); expect(ReactNoop.getChildren()).toEqual([span('Total: 11')]); }); @@ -107,7 +107,7 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow( + expect(ReactNoop).toFlushAndThrow( 'Hooks can only be called inside the body of a function component.', ); @@ -117,7 +117,7 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([10]); + expect(ReactNoop).toFlushAndYield([10]); }); it('throws inside module-style components', () => { @@ -130,7 +130,7 @@ describe('ReactHooksWithNoopRenderer', () => { }; } ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow( + expect(ReactNoop).toFlushAndThrow( 'Hooks can only be called inside the body of a function component.', ); @@ -140,7 +140,7 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([10]); + expect(ReactNoop).toFlushAndYield([10]); }); it('throws when called outside the render phase', () => { @@ -159,15 +159,15 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => counter.current.updateCount(1)); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); act(() => counter.current.updateCount(count => count + 10)); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 11']); expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]); }); @@ -183,11 +183,11 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['getInitialState', 'Count: 42']); + expect(ReactNoop).toFlushAndYield(['getInitialState', 'Count: 42']); expect(ReactNoop.getChildren()).toEqual([span('Count: 42')]); act(() => counter.current.updateCount(7)); - expect(ReactNoop.flush()).toEqual(['Count: 7']); + expect(ReactNoop).toFlushAndYield(['Count: 7']); expect(ReactNoop.getChildren()).toEqual([span('Count: 7')]); }); @@ -201,14 +201,14 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => counter.current.updateCount(7)); - expect(ReactNoop.flush()).toEqual(['Count: 7']); + expect(ReactNoop).toFlushAndYield(['Count: 7']); act(() => counter.current.updateLabel('Total')); - expect(ReactNoop.flush()).toEqual(['Total: 7']); + expect(ReactNoop).toFlushAndYield(['Total: 7']); }); it('returns the same updater function every time', () => { @@ -219,15 +219,15 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => updaters[0](1)); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); act(() => updaters[0](count => count + 10)); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 11']); expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]); expect(updaters).toEqual([updaters[0], updaters[0], updaters[0]]); @@ -242,9 +242,9 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(() => act(() => _updateCount(1))).toWarnDev( "Warning: Can't perform a React state update on an unmounted " + 'component. This is a no-op, but it indicates a memory leak in your ' + @@ -264,15 +264,15 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = memo(Counter); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => _updateCount(1)); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); }); }); @@ -293,27 +293,27 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: true']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Scrolling down: false']); expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]); }); @@ -328,7 +328,7 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Render: 0', 'Render: 1', 'Render: 2', @@ -351,7 +351,7 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // Should increase by three each time 'Render: 0', 'Render: 3', @@ -371,7 +371,7 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow( + expect(ReactNoop).toFlushAndThrow( 'Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.', ); @@ -391,7 +391,7 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Render: 0', 'Render: 1', 'Render: 2', @@ -441,7 +441,7 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // The count should increase by alternating amounts of 10 and 1 // until we reach 21. 'Render: 0', @@ -458,7 +458,7 @@ describe('ReactHooksWithNoopRenderer', () => { counter.current.dispatch('reset'); }); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Render: 0', 'Render: 1', 'Render: 11', @@ -494,11 +494,11 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => counter.current.dispatch(INCREMENT)); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); act(() => { counter.current.dispatch(DECREMENT); @@ -506,7 +506,7 @@ describe('ReactHooksWithNoopRenderer', () => { counter.current.dispatch(DECREMENT); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: -2']); expect(ReactNoop.getChildren()).toEqual([span('Count: -2')]); }); @@ -536,11 +536,11 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Init', 'Count: 10']); + expect(ReactNoop).toFlushAndYield(['Init', 'Count: 10']); expect(ReactNoop.getChildren()).toEqual([span('Count: 10')]); act(() => counter.current.dispatch(INCREMENT)); - expect(ReactNoop.flush()).toEqual(['Count: 11']); + expect(ReactNoop).toFlushAndYield(['Count: 11']); expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]); act(() => { @@ -549,7 +549,7 @@ describe('ReactHooksWithNoopRenderer', () => { counter.current.dispatch(DECREMENT); }); - expect(ReactNoop.flush()).toEqual(['Count: 8']); + expect(ReactNoop).toFlushAndYield(['Count: 8']); expect(ReactNoop.getChildren()).toEqual([span('Count: 8')]); }); @@ -571,7 +571,7 @@ describe('ReactHooksWithNoopRenderer', () => { const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); act(() => { @@ -583,9 +583,10 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.flushSync(() => { counter.current.dispatch(INCREMENT); }); + expect(ReactNoop).toHaveYielded(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 4']); expect(ReactNoop.getChildren()).toEqual([span('Count: 4')]); }); }); @@ -599,17 +600,17 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did commit [0]']); + expect(ReactNoop).toHaveYielded(['Did commit [0]']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); // Effects are deferred until after the commit ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did commit [1]']); + expect(ReactNoop).toHaveYielded(['Did commit [1]']); }); it('flushes passive effects even with sibling deletions', () => { @@ -627,7 +628,7 @@ describe('ReactHooksWithNoopRenderer', () => { } let passive = ; ReactNoop.render([, passive]); - expect(ReactNoop.flush()).toEqual(['Layout', 'Passive', 'Layout effect']); + expect(ReactNoop).toFlushAndYield(['Layout', 'Passive', 'Layout effect']); expect(ReactNoop.getChildren()).toEqual([ span('Layout'), span('Passive'), @@ -636,12 +637,13 @@ describe('ReactHooksWithNoopRenderer', () => { // Destroying the first child shouldn't prevent the passive effect from // being executed ReactNoop.render([passive]); - expect(ReactNoop.flush()).toEqual(['Passive effect']); + expect(ReactNoop).toHaveYielded(['Passive effect']); + expect(ReactNoop).toFlushAndYield([]); expect(ReactNoop.getChildren()).toEqual([span('Passive')]); // (No effects are left to flush.) ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(null); + expect(ReactNoop).toHaveYielded([]); }); it('flushes passive effects even if siblings schedule an update', () => { @@ -666,7 +668,7 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.render([, ]); act(() => { - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Passive', 'Layout', 'Layout effect 0', @@ -698,7 +700,7 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render([, ]); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Passive', 'Layout', 'Layout effect', @@ -732,20 +734,20 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([0]); + expect(ReactNoop).toFlushAndYield([0]); expect(ReactNoop.getChildren()).toEqual([span(0)]); // Before the effects have a chance to flush, schedule another update ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toHaveYielded([ // The previous effect flushes before the reconciliation 'Committed state when effect was fired: 0', - 1, ]); + expect(ReactNoop).toFlushAndYield([1]); expect(ReactNoop.getChildren()).toEqual([span(1)]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Committed state when effect was fired: 1', ]); }, @@ -764,18 +766,18 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: (empty)']); + expect(ReactNoop).toFlushAndYield(['Count: (empty)']); expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Schedule update [0]']); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toHaveYielded(['Schedule update [0]']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Schedule update [1]']); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toHaveYielded(['Schedule update [1]']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); }); it('updates have async priority even if effects are flushed early', () => { @@ -791,22 +793,24 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: (empty)']); + expect(ReactNoop).toFlushAndYield(['Count: (empty)']); expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]); // Rendering again should flush the previous commit's effects ReactNoop.render(); - ReactNoop.flushThrough(['Schedule update [0]', 'Count: 0']); + expect(ReactNoop).toHaveYielded(['Schedule update [0]']); + expect(ReactNoop).toFlushAndYieldThrough(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]); ReactNoop.batchedUpdates(() => { - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); }); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.flush()).toEqual(['Schedule update [1]', 'Count: 1']); + expect(ReactNoop).toHaveYielded(['Schedule update [1]']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); }); @@ -823,13 +827,14 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); // Enqueuing this update forces the passive effect to be flushed -- // updateCount(1) happens first, so 2 wins. act(() => _updateCount(2)); - expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']); + expect(ReactNoop).toHaveYielded(['Will set count to 1']); + expect(ReactNoop).toFlushAndYield(['Count: 2']); expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]); }); @@ -867,7 +872,7 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.render(); }, ); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(0); @@ -875,7 +880,8 @@ describe('ReactHooksWithNoopRenderer', () => { // Enqueuing this update forces the passive effect to be flushed -- // updateCount(1) happens first, so 2 wins. act(() => _updateCount(2)); - expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']); + expect(ReactNoop).toHaveYielded(['Will set count to 1']); + expect(ReactNoop).toFlushAndYield(['Count: 2']); expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]); expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1); @@ -905,13 +911,13 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.renderLegacySyncRoot(); // Even in sync mode, effects are deferred until after paint - expect(ReactNoop.flush()).toEqual(['Count: (empty)']); + expect(ReactNoop).toHaveYielded(['Count: (empty)']); expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]); // Now fire the effects ReactNoop.flushPassiveEffects(); // There were multiple updates, but there should only be a // single render - expect(ReactNoop.clearYields()).toEqual(['Count: 0']); + expect(ReactNoop).toHaveYielded(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); }, ); @@ -931,7 +937,7 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: (empty)']); + expect(ReactNoop).toFlushAndYield(['Count: (empty)']); expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]); expect(() => { @@ -950,19 +956,16 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']); + expect(ReactNoop).toHaveYielded(['Did create [0]']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ - 'Did destroy [0]', - 'Did create [1]', - ]); + expect(ReactNoop).toHaveYielded(['Did destroy [0]', 'Did create [1]']); }); it('unmounts on deletion', () => { @@ -976,13 +979,13 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']); + expect(ReactNoop).toHaveYielded(['Did create [0]']); ReactNoop.render(null); - expect(ReactNoop.flush()).toEqual(['Did destroy [0]']); + expect(ReactNoop).toFlushAndYield(['Did destroy [0]']); expect(ReactNoop.getChildren()).toEqual([]); }); @@ -997,19 +1000,19 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did create [0]']); + expect(ReactNoop).toHaveYielded(['Did create [0]']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(null); + expect(ReactNoop).toHaveYielded([]); ReactNoop.render(null); - expect(ReactNoop.flush()).toEqual(['Did destroy [0]']); + expect(ReactNoop).toFlushAndYield(['Did destroy [0]']); expect(ReactNoop.getChildren()).toEqual([]); }); @@ -1025,19 +1028,19 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did create']); + expect(ReactNoop).toHaveYielded(['Did create']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did destroy', 'Did create']); + expect(ReactNoop).toHaveYielded(['Did destroy', 'Did create']); ReactNoop.render(null); - expect(ReactNoop.flush()).toEqual(['Did destroy']); + expect(ReactNoop).toFlushAndYield(['Did destroy']); expect(ReactNoop.getChildren()).toEqual([]); }); @@ -1056,34 +1059,34 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Did create [Count: 0]']); + expect(ReactNoop).toHaveYielded(['Did create [Count: 0]']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.render(); // Count changed - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Did destroy [Count: 0]', 'Did create [Count: 1]', ]); ReactNoop.render(); // Nothing changed, so no effect should have fired - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(null); + expect(ReactNoop).toHaveYielded([]); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.render(); // Label changed - expect(ReactNoop.flush()).toEqual(['Total: 1']); + expect(ReactNoop).toFlushAndYield(['Total: 1']); expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Did destroy [Count: 1]', 'Did create [Total: 1]', ]); @@ -1100,22 +1103,16 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ - 'Did commit 1 [0]', - 'Did commit 2 [0]', - ]); + expect(ReactNoop).toHaveYielded(['Did commit 1 [0]', 'Did commit 2 [0]']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ - 'Did commit 1 [1]', - 'Did commit 2 [1]', - ]); + expect(ReactNoop).toHaveYielded(['Did commit 1 [1]', 'Did commit 2 [1]']); }); it('unmounts all previous effects before creating any new ones', () => { @@ -1135,16 +1132,16 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']); + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Unmount A [0]', 'Unmount B [0]', 'Mount A [1]', @@ -1172,10 +1169,10 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops'); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Mount A [0]', 'Oops!', // Clean up effect A. There's no effect B to clean-up, because it @@ -1206,17 +1203,17 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']); + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']); // This update will trigger an errror ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops'); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Unmount A [0]', 'Unmount B [0]', 'Mount A [1]', @@ -1248,17 +1245,17 @@ describe('ReactHooksWithNoopRenderer', () => { return ; } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']); + expect(ReactNoop).toHaveYielded(['Mount A [0]', 'Mount B [0]']); // This update will trigger an errror ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops'); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Oops!', // B unmounts even though an error was thrown in the previous effect 'Unmount B [0]', @@ -1277,15 +1274,15 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = memo(Counter); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 0', 'Mount: 0']); + expect(ReactNoop).toFlushAndYield(['Count: 0', 'Mount: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Count: 1', 'Unmount: 0', 'Mount: 1']); + expect(ReactNoop).toFlushAndYield(['Count: 1', 'Unmount: 0', 'Mount: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); ReactNoop.render(null); - expect(ReactNoop.flush()).toEqual(['Unmount: 1']); + expect(ReactNoop).toFlushAndYield(['Unmount: 1']); expect(ReactNoop.getChildren()).toEqual([]); }); }); @@ -1293,7 +1290,9 @@ describe('ReactHooksWithNoopRenderer', () => { describe('useLayoutEffect', () => { it('fires layout effects after the host has been mutated', () => { function getCommittedText() { + const yields = ReactNoop.unstable_clearYields(); const children = ReactNoop.getChildren(); + ReactNoop.yield(yields); if (children === null) { return null; } @@ -1308,11 +1307,11 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([0, 'Current: 0']); + expect(ReactNoop).toFlushAndYield([[0], 'Current: 0']); expect(ReactNoop.getChildren()).toEqual([span(0)]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([1, 'Current: 1']); + expect(ReactNoop).toFlushAndYield([[1], 'Current: 1']); expect(ReactNoop.getChildren()).toEqual([span(1)]); }); @@ -1340,19 +1339,19 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Mount layout [current: 0]']); + expect(ReactNoop).toFlushAndYield(['Mount layout [current: 0]']); expect(committedText).toEqual('0'); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ - 'Mount normal [current: 0]', + expect(ReactNoop).toHaveYielded(['Mount normal [current: 0]']); + expect(ReactNoop).toFlushAndYield([ 'Unmount layout [current: 0]', 'Mount layout [current: 1]', ]); expect(committedText).toEqual('1'); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ 'Unmount normal [current: 1]', 'Mount normal [current: 1]', ]); @@ -1385,14 +1384,14 @@ describe('ReactHooksWithNoopRenderer', () => { const button = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Increment', 'Count: 0']); + expect(ReactNoop).toFlushAndYield(['Increment', 'Count: 0']); expect(ReactNoop.getChildren()).toEqual([ span('Increment'), span('Count: 0'), ]); act(button.current.increment); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // Button should not re-render, because its props haven't changed // 'Increment', 'Count: 1', @@ -1404,7 +1403,7 @@ describe('ReactHooksWithNoopRenderer', () => { // Increase the increment amount ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // Inputs did change this time 'Increment', 'Count: 1', @@ -1416,7 +1415,7 @@ describe('ReactHooksWithNoopRenderer', () => { // Callback should have updated act(button.current.increment); - expect(ReactNoop.flush()).toEqual(['Count: 11']); + expect(ReactNoop).toFlushAndYield(['Count: 11']); expect(ReactNoop.getChildren()).toEqual([ span('Increment'), span('Count: 11'), @@ -1439,19 +1438,19 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(["Capitalize 'hello'", 'HELLO']); + expect(ReactNoop).toFlushAndYield(["Capitalize 'hello'", 'HELLO']); expect(ReactNoop.getChildren()).toEqual([span('HELLO')]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(["Capitalize 'hi'", 'HI']); + expect(ReactNoop).toFlushAndYield(["Capitalize 'hi'", 'HI']); expect(ReactNoop.getChildren()).toEqual([span('HI')]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['HI']); + expect(ReactNoop).toFlushAndYield(['HI']); expect(ReactNoop.getChildren()).toEqual([span('HI')]); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(["Capitalize 'goodbye'", 'GOODBYE']); + expect(ReactNoop).toFlushAndYield(["Capitalize 'goodbye'", 'GOODBYE']); expect(ReactNoop.getChildren()).toEqual([span('GOODBYE')]); }); @@ -1472,16 +1471,16 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute A', 'A']); + expect(ReactNoop).toFlushAndYield(['compute A', 'A']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute A', 'A']); + expect(ReactNoop).toFlushAndYield(['compute A', 'A']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute A', 'A']); + expect(ReactNoop).toFlushAndYield(['compute A', 'A']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute B', 'B']); + expect(ReactNoop).toFlushAndYield(['compute B', 'B']); }); it('should not invoke memoized function during re-renders unless inputs change', () => { @@ -1502,13 +1501,13 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute A', 'A']); + expect(ReactNoop).toFlushAndYield(['compute A', 'A']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['A']); + expect(ReactNoop).toFlushAndYield(['A']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['compute B', 'B']); + expect(ReactNoop).toFlushAndYield(['compute B', 'B']); }); }); @@ -1546,17 +1545,17 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); ping(1); ping(2); ping(3); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toHaveYielded([]); jest.advanceTimersByTime(100); - expect(ReactNoop.flush()).toEqual(['ping: 3']); + expect(ReactNoop).toHaveYielded(['ping: 3']); ping(4); jest.advanceTimersByTime(20); @@ -1564,10 +1563,10 @@ describe('ReactHooksWithNoopRenderer', () => { ping(6); jest.advanceTimersByTime(80); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toHaveYielded([]); jest.advanceTimersByTime(20); - expect(ReactNoop.flush()).toEqual(['ping: 6']); + expect(ReactNoop).toHaveYielded(['ping: 6']); }); it('should return the same ref during re-renders', () => { @@ -1588,10 +1587,10 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['val']); + expect(ReactNoop).toFlushAndYield(['val']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['val']); + expect(ReactNoop).toFlushAndYield(['val']); }); }); @@ -1612,14 +1611,14 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); expect(counter.current.count).toBe(0); act(() => { counter.current.dispatch(INCREMENT); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); // Intentionally not updated because of [] deps: expect(counter.current.count).toBe(0); @@ -1642,14 +1641,14 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); expect(counter.current.count).toBe(0); act(() => { counter.current.dispatch(INCREMENT); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); expect(counter.current.count).toBe(1); }); @@ -1678,7 +1677,7 @@ describe('ReactHooksWithNoopRenderer', () => { Counter = forwardRef(Counter); const counter = React.createRef(null); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 0']); expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]); expect(counter.current.count).toBe(0); expect(totalRefUpdates).toBe(1); @@ -1686,14 +1685,14 @@ describe('ReactHooksWithNoopRenderer', () => { act(() => { counter.current.dispatch(INCREMENT); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); expect(counter.current.count).toBe(1); expect(totalRefUpdates).toBe(2); // Update that doesn't change the ref dependencies ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Count: 1']); expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]); expect(counter.current.count).toBe(1); expect(totalRefUpdates).toBe(2); // Should not increase since last time @@ -1723,7 +1722,7 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: [not loaded]']); + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0, C: [not loaded]']); expect(ReactNoop.getChildren()).toEqual([ span('A: 0, B: 0, C: [not loaded]'), ]); @@ -1733,21 +1732,21 @@ describe('ReactHooksWithNoopRenderer', () => { updateB(3); }); - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: [not loaded]']); + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: [not loaded]']); expect(ReactNoop.getChildren()).toEqual([ span('A: 2, B: 3, C: [not loaded]'), ]); ReactNoop.render(); expect(() => { - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 0']); + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 0']); }).toThrow('Rendered more hooks than during the previous render'); // Uncomment if/when we support this again // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 0')]); // updateC(4); - // expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']); + // expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 4']); // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]); }); @@ -1775,17 +1774,17 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: 0']); + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0, C: 0']); expect(ReactNoop.getChildren()).toEqual([span('A: 0, B: 0, C: 0')]); act(() => { updateA(2); updateB(3); updateC(4); }); - expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']); + expect(ReactNoop).toFlushAndYield(['A: 2, B: 3, C: 4']); expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]); ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow( + expect(ReactNoop).toFlushAndThrow( 'Rendered fewer hooks than expected. This may be caused by an ' + 'accidental early return statement.', ); @@ -1813,21 +1812,21 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); ReactNoop.flushPassiveEffects(); - expect(ReactNoop.clearYields()).toEqual(['Mount A']); + expect(ReactNoop).toHaveYielded(['Mount A']); ReactNoop.render(); expect(() => { - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); }).toThrow('Rendered more hooks than during the previous render'); // Uncomment if/when we support this again // ReactNoop.flushPassiveEffects(); - // expect(ReactNoop.clearYields()).toEqual(['Mount B']); + // expect(ReactNoop).toHaveYielded(['Mount B']); // ReactNoop.render(); - // expect(() => ReactNoop.flush()).toThrow( + // expect(ReactNoop).toFlushAndThrow( // 'Rendered fewer hooks than expected. This may be caused by an ' + // 'accidental early return statement.', // ); diff --git a/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js index 1f65fc6ec3d90..1ae63e690e774 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncremental-test.internal.js @@ -35,7 +35,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }); it('should render a simple component, in steps if needed', () => { @@ -58,7 +58,7 @@ describe('ReactIncremental', () => { expect(ReactNoop.flushNextYield()).toEqual(['Foo']); // Do the rest of the work. - expect(ReactNoop.flush()).toEqual(['Bar', 'Bar', 'callback']); + expect(ReactNoop).toFlushAndYield(['Bar', 'Bar', 'callback']); }); it('updates a previous render', () => { @@ -96,7 +96,7 @@ describe('ReactIncremental', () => { ReactNoop.render(, () => ops.push('renderCallbackCalled'), ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'Foo', @@ -114,7 +114,7 @@ describe('ReactIncremental', () => { ReactNoop.render(, () => ops.push('secondRenderCallbackCalled'), ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // TODO: Test bail out of host components. This is currently unobservable. @@ -146,21 +146,21 @@ describe('ReactIncremental', () => { // Init ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar']); ReactNoop.render(); // Flush part of the work - ReactNoop.flushThrough(['Foo', 'Bar']); + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render(null)); ReactNoop.render(); // Flush part of the new work - ReactNoop.flushThrough(['Foo', 'Bar']); + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']); // Flush the rest of the work which now includes the low priority - expect(ReactNoop.flush()).toEqual(['Bar']); + expect(ReactNoop).toFlushAndYield(['Bar']); }); it('should call callbacks even if updates are aborted', () => { @@ -186,7 +186,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); inst.setState( () => { @@ -197,7 +197,7 @@ describe('ReactIncremental', () => { ); // Flush part of the work - ReactNoop.flushThrough(['setState1']); + expect(ReactNoop).toFlushAndYieldThrough(['setState1']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render()); @@ -210,7 +210,7 @@ describe('ReactIncremental', () => { ); // Flush the rest of the work which now includes the low priority - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'setState1', 'setState2', 'callback1', @@ -248,7 +248,7 @@ describe('ReactIncremental', () => { // Init ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Foo', 'Bar', 'Bar', @@ -259,9 +259,9 @@ describe('ReactIncremental', () => { // Render part of the work. This should be enough to flush everything except // the middle which has lower priority. ReactNoop.render(); - ReactNoop.flushThrough(['Foo', 'Bar', 'Bar']); + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar', 'Bar']); // Flush only the remaining work - expect(ReactNoop.flush()).toEqual(['Middle', 'Middle']); + expect(ReactNoop).toFlushAndYield(['Middle', 'Middle']); }); it('can deprioritize a tree from without dropping work', () => { @@ -297,7 +297,7 @@ describe('ReactIncremental', () => { ReactNoop.flushSync(() => { ReactNoop.render(); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar', 'Bar', 'Middle', 'Middle']); ops = []; @@ -312,7 +312,7 @@ describe('ReactIncremental', () => { // The hidden content was deprioritized from high to low priority. A low // priority callback should have been scheduled. Flush it now. - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Middle', 'Middle']); }); @@ -375,7 +375,7 @@ describe('ReactIncremental', () => { ops = []; // Flush the rest to make sure that the bailout didn't block this work. - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Middle']); }); @@ -455,7 +455,7 @@ describe('ReactIncremental', () => { // as a single batch. Therefore, it is correct that Middle should be in the // middle. If it occurs after the two "Bar" components then it was flushed // after them which is not correct. - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Bar', 'Middle', 'Bar']); ops = []; @@ -473,7 +473,7 @@ describe('ReactIncremental', () => { // it. If the priority levels aren't down-prioritized correctly this may // abort rendering of the down-prioritized content. ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar', 'Bar']); }); @@ -514,7 +514,7 @@ describe('ReactIncremental', () => { foo.setState({value: 'bar'}); ops = []; - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar']); }); @@ -577,7 +577,7 @@ describe('ReactIncremental', () => { foo.setState({value: 'bar'}); ops = []; - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(constructorCount).toEqual(1); expect(ops).toEqual([ 'componentWillMount: foo', @@ -639,7 +639,7 @@ describe('ReactIncremental', () => { // Interrupt the rendering with a quick update. This should not touch the // middle content. ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // We've now rendered the entire tree but we didn't have to redo the work // done by the first Middle and Bar already. @@ -674,7 +674,7 @@ describe('ReactIncremental', () => { // Since we did nothing to the middle subtree during the interruption, // we should be able to reuse the reconciliation work that we already did // without restarting. - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Middle']); }); @@ -727,7 +727,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; // Begin working on a low priority update to Child, but stop before @@ -747,7 +747,7 @@ describe('ReactIncremental', () => { // Continue the low pri work. The work on Child and GrandChild was memoized // so they should not be worked on again. ops = []; - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ // No Child // No Grandchild @@ -803,7 +803,7 @@ describe('ReactIncremental', () => { // Init ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar', 'Content', 'Middle', 'Bar', 'Middle']); @@ -836,7 +836,7 @@ describe('ReactIncremental', () => { // Since we did nothing to the middle subtree during the interruption, // we should be able to reuse the reconciliation work that we already did // without restarting. - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Middle']); }); @@ -857,16 +857,16 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['shouldComponentUpdate: false']); ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ // If the memoized props were not updated during last bail out, sCU will // keep returning false. @@ -897,10 +897,10 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state).toEqual({a: 'a'}); instance.setState({b: 'b'}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state).toEqual({a: 'a', b: 'b'}); }); @@ -926,12 +926,12 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // Call setState multiple times before flushing instance.setState({b: 'b'}); instance.setState({c: 'c'}); instance.setState({d: 'd'}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state).toEqual({a: 'a', b: 'b', c: 'c', d: 'd'}); }); @@ -961,15 +961,15 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state.num).toEqual(1); instance.setState(updater); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state.num).toEqual(2); instance.setState(updater); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state.num).toEqual(6); }); @@ -1003,10 +1003,10 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); instance.setState(updater); instance.setState(updater, callback); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state.num).toEqual(4); expect(instance.state.called).toEqual(true); }); @@ -1030,11 +1030,11 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); instance.setState({b: 'b'}); instance.setState({c: 'c'}); instance.updater.enqueueReplaceState(instance, {d: 'd'}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(instance.state).toEqual({d: 'd'}); }); @@ -1071,10 +1071,10 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar', 'Baz']); instance.forceUpdate(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo', 'Bar', 'Baz', 'Bar', 'Baz']); }); @@ -1091,14 +1091,14 @@ describe('ReactIncremental', () => { const foo = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['A: 0, B: 0']); + expect(ReactNoop).toFlushAndYield(['A: 0, B: 0']); a = 1; foo.current.forceUpdate(); - expect(ReactNoop.flush()).toEqual(['A: 1, B: 0']); + expect(ReactNoop).toFlushAndYield(['A: 1, B: 0']); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); }); xit('can call sCU while resuming a partly mounted component', () => { @@ -1193,7 +1193,7 @@ describe('ReactIncremental', () => {
, ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; @@ -1214,7 +1214,7 @@ describe('ReactIncremental', () => { ops = []; - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Bar:A-1', 'Baz']); }); @@ -1263,7 +1263,7 @@ describe('ReactIncremental', () => { ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'App', @@ -1311,7 +1311,7 @@ describe('ReactIncremental', () => { ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'App', @@ -1366,7 +1366,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'App', @@ -1394,7 +1394,7 @@ describe('ReactIncremental', () => { ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'App', @@ -1432,7 +1432,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['getDerivedStateFromProps', 'render']); expect(instance.state).toEqual({foo: 'foo'}); @@ -1440,7 +1440,7 @@ describe('ReactIncremental', () => { ops = []; instance.changeState(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'getDerivedStateFromProps', @@ -1472,7 +1472,7 @@ describe('ReactIncremental', () => { const child = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'getDerivedStateFromProps', 'Parent', 'Child', @@ -1480,7 +1480,7 @@ describe('ReactIncremental', () => { // Schedule an update on the child. The parent should not re-render. child.current.setState({}); - expect(ReactNoop.flush()).toEqual(['Child']); + expect(ReactNoop).toFlushAndYield(['Child']); }); xit('does not call componentWillReceiveProps for state-only updates', () => { @@ -1553,7 +1553,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'App', @@ -1584,7 +1584,7 @@ describe('ReactIncremental', () => { // LifeCycle instances[1].tick(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ // no componentWillReceiveProps @@ -1617,7 +1617,7 @@ describe('ReactIncremental', () => { // Next we will update LifeCycle directly but not with new props. instances[1].tick(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ // This should not trigger another componentWillReceiveProps because @@ -1672,7 +1672,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'componentWillMount', @@ -1685,7 +1685,7 @@ describe('ReactIncremental', () => { // Update to same props ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'componentWillReceiveProps', @@ -1715,7 +1715,7 @@ describe('ReactIncremental', () => { // ...but we'll interrupt it to rerender the same props. ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // We can bail out this time, but we must call componentDidUpdate. expect(ops).toEqual([ @@ -1741,7 +1741,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; ReactNoop.flushSync(() => { @@ -1783,7 +1783,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; function updater({n}) { @@ -1798,7 +1798,7 @@ describe('ReactIncremental', () => { instance.setState(updater, () => ops.push('third callback')); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('callback error'); // The third callback isn't called because the second one throws @@ -1897,7 +1897,7 @@ describe('ReactIncremental', () => { , ); expect(() => - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Intl {}', 'ShowLocale {"locale":"fr"}', 'ShowBoth {"locale":"fr"}', @@ -1916,7 +1916,7 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'Intl {}', 'ShowLocale {"locale":"de"}', 'ShowBoth {"locale":"de"}', @@ -1930,7 +1930,7 @@ describe('ReactIncremental', () => { , ); - ReactNoop.flushThrough(['Intl {}']); + expect(ReactNoop).toFlushAndYieldThrough(['Intl {}']); ReactNoop.render( @@ -1942,7 +1942,7 @@ describe('ReactIncremental', () => { , ); expect(() => - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'ShowLocale {"locale":"sv"}', 'ShowBoth {"locale":"sv"}', 'Intl {}', @@ -1986,7 +1986,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Recurse', {withoutStack: true}, @@ -2023,7 +2023,7 @@ describe('ReactIncremental', () => { }; ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Recurse', {withoutStack: true}, @@ -2074,14 +2074,14 @@ describe('ReactIncremental', () => { , ); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'Intl {}', 'ShowLocale {"locale":"fr"}', 'ShowLocale {"locale":"fr"}', ]); expect(() => - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'ShowLocale {"locale":"fr"}', 'Intl {}', 'ShowLocale {"locale":"ru"}', @@ -2165,7 +2165,7 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn', {withoutStack: true}, @@ -2181,7 +2181,7 @@ describe('ReactIncremental', () => { ops.length = 0; statefulInst.setState({x: 1}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // All work has been memoized because setState() // happened below the context and could not have affected it. expect(ops).toEqual([]); @@ -2257,7 +2257,7 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Intl, ShowLocaleClass, ShowLocaleFn', {withoutStack: true}, @@ -2273,7 +2273,7 @@ describe('ReactIncremental', () => { ops.length = 0; statefulInst.setState({locale: 'gr'}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ // Intl is below setState() so it might have been // affected by it. Therefore we re-render and recompute @@ -2326,7 +2326,7 @@ describe('ReactIncremental', () => { // Init ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Child', {withoutStack: true}, @@ -2334,7 +2334,7 @@ describe('ReactIncremental', () => { // Trigger an update in the middle of the tree instance.setState({}); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }); it('maintains the correct context when unwinding due to an error in render', () => { @@ -2376,7 +2376,7 @@ describe('ReactIncremental', () => { // Init ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: ContextProvider', {withoutStack: true}, @@ -2387,7 +2387,7 @@ describe('ReactIncremental', () => { instance.setState({ throwError: true, }); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Error boundaries should implement getDerivedStateFromError()', {withoutStack: true}, ); @@ -2425,7 +2425,7 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( [ 'componentWillReceiveProps: Please update the following components ' + 'to use static getDerivedStateFromProps instead: MyComponent', @@ -2496,7 +2496,7 @@ describe('ReactIncremental', () => { // Initial render of the entire tree. // Renders: Root, Middle, FirstChild, SecondChild ReactNoop.render(A); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(renderCounter).toBe(1); @@ -2518,7 +2518,7 @@ describe('ReactIncremental', () => { // The in-progress child content will bailout. // Renders: Root, Middle, FirstChild, SecondChild ReactNoop.render(B); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); // At this point the higher priority render has completed. // Since FirstChild props didn't change, sCU returned false. @@ -2575,14 +2575,14 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Child, TopContextProvider', {withoutStack: true}, ); expect(rendered).toEqual(['count:0']); instance.updateCount(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(rendered).toEqual(['count:0', 'count:1']); }); @@ -2637,14 +2637,14 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Child, MiddleContextProvider, TopContextProvider', {withoutStack: true}, ); expect(rendered).toEqual(['count:0']); instance.updateCount(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(rendered).toEqual(['count:0', 'count:1']); }); @@ -2708,14 +2708,14 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Child, MiddleContextProvider, TopContextProvider', {withoutStack: true}, ); expect(rendered).toEqual(['count:0']); instance.updateCount(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(rendered).toEqual(['count:0']); }); @@ -2789,17 +2789,17 @@ describe('ReactIncremental', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Child, MiddleContextProvider, TopContextProvider', {withoutStack: true}, ); expect(rendered).toEqual(['count:0, name:brian']); topInstance.updateCount(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(rendered).toEqual(['count:0, name:brian']); middleInstance.updateName('not brian'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(rendered).toEqual([ 'count:0, name:brian', 'count:1, name:not brian', @@ -2818,12 +2818,12 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flushThrough(['Parent: 1']); + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at same priority ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Child: 1', 'Parent: 2', 'Child: 2']); + expect(ReactNoop).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']); }); it('does not interrupt for update at lower priority', () => { @@ -2838,13 +2838,13 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flushThrough(['Parent: 1']); + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at lower priority ReactNoop.expire(2000); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Child: 1', 'Parent: 2', 'Child: 2']); + expect(ReactNoop).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']); }); it('does interrupt for update at higher priority', () => { @@ -2859,15 +2859,15 @@ describe('ReactIncremental', () => { } ReactNoop.render(); - ReactNoop.flushThrough(['Parent: 1']); + expect(ReactNoop).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at higher priority expect( ReactNoop.flushSync(() => ReactNoop.render()), ).toEqual(['Parent: 2', 'Child: 2']); - ReactNoop.clearYields(); + expect(ReactNoop).toHaveYielded(['Parent: 2', 'Child: 2']); - expect(ReactNoop.flush()).toEqual([]); + expect(ReactNoop).toFlushAndYield([]); }); // We don't currently use fibers as keys. Re-enable this test if we @@ -2889,7 +2889,7 @@ describe('ReactIncremental', () => { } } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); } // First, verify that this code path normally receives Fibers as keys, diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js index f4a24cfc0ae42..fe09a682cb45b 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js @@ -86,7 +86,7 @@ describe('ReactIncrementalErrorHandling', () => { ); // Start rendering asynchronously - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'ErrorBoundary (try)', 'Indirection', 'Indirection', @@ -96,9 +96,9 @@ describe('ReactIncrementalErrorHandling', () => { ]); // Still rendering async... - ReactNoop.flushThrough(['Indirection']); + expect(ReactNoop).toFlushAndYieldThrough(['Indirection']); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'Indirection', // Call getDerivedStateFromError and re-render the error boundary, this @@ -179,7 +179,7 @@ describe('ReactIncrementalErrorHandling', () => { ); // Start rendering asynchronously - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'ErrorBoundary (try)', 'Indirection', 'Indirection', @@ -189,9 +189,9 @@ describe('ReactIncrementalErrorHandling', () => { ]); // Still rendering async... - ReactNoop.flushThrough(['Indirection']); + expect(ReactNoop).toFlushAndYieldThrough(['Indirection']); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'Indirection', // Now that the tree is complete, and there's no remaining work, React // reverts to sync mode to retry one more time before handling the error. @@ -230,7 +230,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.expire(2000); ReactNoop.render(, onCommit); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // The first render fails. But because there's a lower priority pending // update, it doesn't throw. 'error', @@ -270,7 +270,7 @@ describe('ReactIncrementalErrorHandling', () => { // Initial mount const parent = React.createRef(null); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual(['Child']); + expect(ReactNoop).toFlushAndYield(['Child']); expect(ReactNoop.getChildren()).toEqual([span('Child')]); // Schedule a low priority update to hide the child @@ -281,7 +281,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.flushSync(() => { ReactNoop.render(); }); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ // First the sync update triggers an error 'Error!', // Because there's a pending low priority update, we restart at the @@ -321,10 +321,10 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.render(, () => ReactNoop.yield('commit')); // Render the bad component asynchronously - ReactNoop.flushThrough(['Parent', 'BadRender']); + expect(ReactNoop).toFlushAndYieldThrough(['Parent', 'BadRender']); // Finish the rest of the async work - ReactNoop.flushThrough(['Sibling']); + expect(ReactNoop).toFlushAndYieldThrough(['Sibling']); // React retries once, synchronously, before throwing. ops = []; @@ -371,7 +371,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'ErrorBoundary', 'BadMount', 'BadMount', @@ -408,7 +408,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]); }); @@ -442,10 +442,10 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flushThrough(['ErrorBoundary render success']); + expect(ReactNoop).toFlushAndYieldThrough(['ErrorBoundary render success']); expect(ReactNoop.getChildren()).toEqual([]); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'BrokenRender', // React retries one more time 'ErrorBoundary render success', @@ -570,7 +570,7 @@ describe('ReactIncrementalErrorHandling', () => { ); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ops).toEqual([ 'RethrowErrorBoundary render', @@ -609,12 +609,14 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flushThrough(['RethrowErrorBoundary render']); + expect(ReactNoop).toFlushAndYieldThrough(['RethrowErrorBoundary render']); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); - expect(ReactNoop.clearYields()).toEqual([ + expect(ReactNoop).toHaveYielded([ + 'BrokenRender', + // React retries one more time 'RethrowErrorBoundary render', 'BrokenRender', @@ -709,7 +711,7 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('Hello'); }); }).toThrow('Hello'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span('a:3')]); }); @@ -726,7 +728,7 @@ describe('ReactIncrementalErrorHandling', () => { }); }); }).toThrow('Hello'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span('a:5')]); }); @@ -759,7 +761,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.render(); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ops).toEqual([ 'BrokenRender', @@ -769,7 +771,7 @@ describe('ReactIncrementalErrorHandling', () => { ]); ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo']); }); @@ -790,12 +792,12 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ops = []; expect(() => { ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ops).toEqual([ 'BrokenRender', @@ -806,7 +808,7 @@ describe('ReactIncrementalErrorHandling', () => { ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo']); }); @@ -828,16 +830,16 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(() => { ReactNoop.render(
); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); ops = []; ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['Foo']); }); @@ -871,9 +873,9 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(null); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ // Parent unmounts before the error is thrown. 'Parent componentWillUnmount', 'ThrowsOnUnmount componentWillUnmount', @@ -910,7 +912,7 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.flushSync(() => { ReactNoop.render(); @@ -944,7 +946,7 @@ describe('ReactIncrementalErrorHandling', () => { 'a', ); ReactNoop.renderToRootWithID(, 'b'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren('a')).toEqual([ span('Caught an error: Hello.'), ]); @@ -958,14 +960,14 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.renderToRootWithID(, 'a'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([]); ReactNoop.renderToRootWithID(, 'a'); ReactNoop.renderToRootWithID(, 'b'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([]); @@ -974,7 +976,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.renderToRootWithID(, 'a'); ReactNoop.renderToRootWithID(, 'b'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([span('a:3')]); expect(ReactNoop.getChildren('b')).toEqual([]); @@ -983,7 +985,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.renderToRootWithID(, 'b'); ReactNoop.renderToRootWithID(, 'c'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([span('a:4')]); expect(ReactNoop.getChildren('b')).toEqual([]); @@ -995,7 +997,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.renderToRootWithID(, 'd'); ReactNoop.renderToRootWithID(, 'e'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([span('a:5')]); expect(ReactNoop.getChildren('b')).toEqual([span('b:5')]); @@ -1010,7 +1012,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.renderToRootWithID(, 'e'); ReactNoop.renderToRootWithID(, 'f'); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrow('Hello'); expect(ReactNoop.getChildren('a')).toEqual([]); expect(ReactNoop.getChildren('b')).toEqual([span('b:6')]); @@ -1025,7 +1027,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.unmountRootWithID('d'); ReactNoop.unmountRootWithID('e'); ReactNoop.unmountRootWithID('f'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren('a')).toEqual(null); expect(ReactNoop.getChildren('b')).toEqual(null); expect(ReactNoop.getChildren('c')).toEqual(null); @@ -1086,7 +1088,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Connector, Provider', {withoutStack: true}, @@ -1119,7 +1121,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - expect(ReactNoop.flush).toWarnDev([ + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([ 'Warning: React.createElement: type is invalid -- expected a string', // React retries once on error 'Warning: React.createElement: type is invalid -- expected a string', @@ -1161,14 +1163,14 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render( , ); - expect(ReactNoop.flush).toWarnDev([ + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev([ 'Warning: React.createElement: type is invalid -- expected a string', // React retries once on error 'Warning: React.createElement: type is invalid -- expected a string', @@ -1192,7 +1194,7 @@ describe('ReactIncrementalErrorHandling', () => { 'Warning: React.createElement: type is invalid -- expected a string', {withoutStack: true}, ); - expect(ReactNoop.flush).toThrowError( + expect(ReactNoop).toFlushAndThrow( 'Element type is invalid: expected a string (for built-in components) or ' + 'a class/function (for composite components) but got: undefined.' + (__DEV__ @@ -1202,7 +1204,7 @@ describe('ReactIncrementalErrorHandling', () => { ); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span('hi')]); }); @@ -1241,11 +1243,11 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); inst.setState({fail: true}); expect(() => { - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); }).toThrowError('Hello.'); expect(ops).toEqual([ @@ -1283,7 +1285,7 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual(['barRef attach']); expect(ReactNoop.getChildren()).toEqual([div(span('Bar'))]); @@ -1291,7 +1293,7 @@ describe('ReactIncrementalErrorHandling', () => { // Unmount ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow('Detach error'); + expect(ReactNoop).toFlushAndThrow('Detach error'); expect(ops).toEqual([ 'barRef detach', // Bar should unmount even though its ref threw an error while detaching @@ -1303,14 +1305,14 @@ describe('ReactIncrementalErrorHandling', () => { it('handles error thrown by host config while working on failed root', () => { ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow('Error in host config.'); + expect(ReactNoop).toFlushAndThrow('Error in host config.'); }); it('handles error thrown by top-level callback', () => { ReactNoop.render(
, () => { throw new Error('Error!'); }); - expect(() => ReactNoop.flush()).toThrow('Error!'); + expect(ReactNoop).toFlushAndThrow('Error!'); }); it('error boundaries capture non-errors', () => { @@ -1357,7 +1359,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ops).toEqual([ 'ErrorBoundary (try)', @@ -1428,7 +1430,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'ErrorBoundary (try)', 'throw', // Continue rendering siblings after BadRender throws @@ -1478,7 +1480,7 @@ describe('ReactIncrementalErrorHandling', () => { } ReactNoop.render(); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'render', 'throw', 'render', @@ -1520,7 +1522,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['render error message']); expect(ReactNoop.getChildren()).toEqual([ span( 'Caught an error:\n' + @@ -1556,7 +1558,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello')]); }); @@ -1580,7 +1582,7 @@ describe('ReactIncrementalErrorHandling', () => { ReactNoop.render(); expect(() => { - expect(() => ReactNoop.flush()).toThrow('Oops!'); + expect(ReactNoop).toFlushAndThrow('Oops!'); }).toWarnDev( 'Legacy context API has been detected within a strict-mode tree: \n\n' + 'Please update the following components: Provider', diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js index 4394b2822e79d..16b0393d3ddcc 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorLogging-test.js @@ -50,7 +50,7 @@ describe('ReactIncrementalErrorLogging', () => {
, ); - expect(() => ReactNoop.flush()).toThrowError('constructor error'); + expect(ReactNoop).toFlushAndThrow('constructor error'); expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( __DEV__ @@ -86,7 +86,7 @@ describe('ReactIncrementalErrorLogging', () => {
, ); - expect(() => ReactNoop.flush()).toThrowError('componentDidMount error'); + expect(ReactNoop).toFlushAndThrow('componentDidMount error'); expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( __DEV__ @@ -125,7 +125,7 @@ describe('ReactIncrementalErrorLogging', () => { , ); - expect(() => ReactNoop.flush()).toThrow('render error'); + expect(ReactNoop).toFlushAndThrow('render error'); expect(logCapturedErrorCalls.length).toBe(1); expect(logCapturedErrorCalls[0]).toEqual( __DEV__ @@ -181,7 +181,7 @@ describe('ReactIncrementalErrorLogging', () => { , ); - expect(ReactNoop.flush()).toEqual( + expect(ReactNoop).toFlushAndYield( [ 'render: 0', __DEV__ && 'render: 0', // replay diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js index 1474d012e67ec..0b4d20c4a56e8 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorReplay-test.js @@ -22,7 +22,7 @@ describe('ReactIncrementalErrorReplay', () => { it('should fail gracefully on error in the host environment', () => { ReactNoop.render(); - expect(() => ReactNoop.flush()).toThrow('Error in host config.'); + expect(ReactNoop).toFlushAndThrow('Error in host config.'); }); it("should ignore error if it doesn't throw on retry", () => { @@ -43,6 +43,6 @@ describe('ReactIncrementalErrorReplay', () => { } } ReactNoop.render(); - expect(() => ReactNoop.flush()).not.toThrow(); + expect(ReactNoop).toFlushWithoutYielding(); }); }); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js index c3b18696380bf..cab786974244e 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js @@ -144,7 +144,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Mount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render( @@ -152,11 +152,11 @@ describe('ReactDebugFiberPerf', () => { , ); addComment('Update'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(null); addComment('Unmount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -182,7 +182,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Mount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -200,7 +200,7 @@ describe('ReactDebugFiberPerf', () => { , ); addComment('Mount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -216,7 +216,7 @@ describe('ReactDebugFiberPerf', () => { , ); addComment('Mount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -248,13 +248,13 @@ describe('ReactDebugFiberPerf', () => {
, ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); resetFlamechart(); a.setState({}); b.setState({}); addComment('Should include just A and B, no Parents'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -274,7 +274,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Should print a warning'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -283,7 +283,7 @@ describe('ReactDebugFiberPerf', () => { componentDidMount() { ReactNoop.renderToRootWithID(, 'b'); addComment('Scheduling another root from componentDidMount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); } render() { return
{this.props.children}
; @@ -292,7 +292,7 @@ describe('ReactDebugFiberPerf', () => { ReactNoop.renderToRootWithID(, 'a'); addComment('Rendering the first root'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -315,7 +315,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Should not print a warning'); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( [ 'componentWillMount: Please update the following components ' + 'to use componentDidMount instead: NotCascading' + @@ -330,7 +330,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Should not print a warning'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -357,7 +357,7 @@ describe('ReactDebugFiberPerf', () => { } ReactNoop.render(); addComment('Mount'); - expect(ReactNoop.flush).toWarnDev( + expect(() => expect(ReactNoop).toFlushWithoutYielding()).toWarnDev( [ 'componentWillMount: Please update the following components ' + 'to use componentDidMount instead: AllLifecycles' + @@ -372,10 +372,10 @@ describe('ReactDebugFiberPerf', () => { ); ReactNoop.render(); addComment('Update'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render(null); addComment('Unmount'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -391,7 +391,7 @@ describe('ReactDebugFiberPerf', () => { ); }); addComment('Flush the child'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -431,9 +431,9 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Start rendering through B'); - ReactNoop.flushThrough(['A', 'B']); + expect(ReactNoop).toFlushAndYieldThrough(['A', 'B']); addComment('Complete the rest'); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['C']); expect(getFlameChart()).toMatchSnapshot(); }); @@ -449,7 +449,7 @@ describe('ReactDebugFiberPerf', () => { ); try { addComment('Will fatal'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); } catch (err) { expect(err.message).toBe('Game over'); } @@ -459,7 +459,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Will reconcile from a clean state'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -495,7 +495,7 @@ describe('ReactDebugFiberPerf', () => {
, ); addComment('Stop on Baddie and restart from Boundary'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -526,7 +526,7 @@ describe('ReactDebugFiberPerf', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); resetFlamechart(); ReactNoop.render( @@ -538,7 +538,7 @@ describe('ReactDebugFiberPerf', () => { , ); addComment('The commit phase should mention A and B just once'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); ReactNoop.render( @@ -549,7 +549,7 @@ describe('ReactDebugFiberPerf', () => { ); addComment("Because of deduplication, we don't know B was cascading,"); addComment('but we should still see the warning for the commit phase.'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -562,7 +562,7 @@ describe('ReactDebugFiberPerf', () => { {ReactNoop.createPortal(, portalContainer, null)} , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -575,7 +575,7 @@ describe('ReactDebugFiberPerf', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -603,7 +603,7 @@ describe('ReactDebugFiberPerf', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); resolve( @@ -621,7 +621,7 @@ describe('ReactDebugFiberPerf', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -652,7 +652,8 @@ describe('ReactDebugFiberPerf', () => { ReactNoop.flushSync(() => { ReactNoop.render(); }); - ReactNoop.flush(); + expect(ReactNoop).toHaveYielded(['Foo']); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); @@ -663,7 +664,7 @@ describe('ReactDebugFiberPerf', () => { ReactNoop.render(); ReactNoop.expire(6000); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(getFlameChart()).toMatchSnapshot(); }); }); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js index c82b2f990ef25..0f67ff943c190 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.internal.js @@ -23,6 +23,17 @@ describe('ReactIncrementalReflection', () => { ReactNoop = require('react-noop-renderer'); }); + function div(...children) { + children = children.map( + c => (typeof c === 'string' ? {text: c, hidden: false} : c), + ); + return {type: 'div', children, prop: undefined, hidden: false}; + } + + function span(prop) { + return {type: 'span', children: [], prop, hidden: false}; + } + it('handles isMounted even when the initial render is deferred', () => { const instances = []; @@ -51,13 +62,13 @@ describe('ReactIncrementalReflection', () => { ReactNoop.render(); // Render part way through but don't yet commit the updates. - ReactNoop.flushThrough(['componentWillMount: false']); + expect(ReactNoop).toFlushAndYieldThrough(['componentWillMount: false']); expect(instances[0]._isMounted()).toBe(false); // Render the rest and commit the updates. expect(() => - expect(ReactNoop.flush()).toEqual(['componentDidMount: true']), + expect(ReactNoop).toFlushAndYield(['componentDidMount: true']), ).toWarnDev( 'componentWillMount: Please update the following components ' + 'to use componentDidMount instead: Component', @@ -96,7 +107,7 @@ describe('ReactIncrementalReflection', () => { } ReactNoop.render(); - expect(() => expect(ReactNoop.flush()).toEqual(['Component'])).toWarnDev( + expect(() => expect(ReactNoop).toFlushAndYield(['Component'])).toWarnDev( 'componentWillMount: Please update the following components ' + 'to use componentDidMount instead: Component', {withoutStack: true}, @@ -107,12 +118,12 @@ describe('ReactIncrementalReflection', () => { ReactNoop.render(); // Render part way through but don't yet commit the updates so it is not // fully unmounted yet. - ReactNoop.flushThrough(['Other']); + expect(ReactNoop).toFlushAndYieldThrough(['Other']); expect(instances[0]._isMounted()).toBe(true); // Finish flushing the unmount. - expect(ReactNoop.flush()).toEqual(['componentWillUnmount: true']); + expect(ReactNoop).toFlushAndYield(['componentWillUnmount: true']); expect(instances[0]._isMounted()).toBe(false); }); @@ -174,7 +185,7 @@ describe('ReactIncrementalReflection', () => { ReactNoop.render(); // Flush past Component but don't complete rendering everything yet. - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ ['componentWillMount', null], 'render', 'render sibling', @@ -186,9 +197,7 @@ describe('ReactIncrementalReflection', () => { expect(findInstance(classInstance)).toBe(null); expect(() => - expect(ReactNoop.flush()).toEqual([ - ['componentDidMount', classInstance.span], - ]), + expect(ReactNoop).toFlushAndYield([['componentDidMount', span()]]), ).toWarnDev( 'componentWillMount: Please update the following components ' + 'to use componentDidMount instead: Component' + @@ -205,7 +214,7 @@ describe('ReactIncrementalReflection', () => { // Flush next step which will cause an update but not yet render a new host // node. ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ ['componentWillUpdate', hostSpan], 'render', 'render sibling', @@ -217,7 +226,7 @@ describe('ReactIncrementalReflection', () => { // The next step will render a new host node but won't get committed yet. // We expect this to mutate the original Fiber. ReactNoop.render(); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ ['componentWillUpdate', hostSpan], 'render', 'render sibling', @@ -227,9 +236,7 @@ describe('ReactIncrementalReflection', () => { expect(ReactNoop.findInstance(classInstance)).toBe(hostSpan); // When we finally flush the tree it will get committed. - expect(ReactNoop.flush()).toEqual([ - ['componentDidUpdate', classInstance.div], - ]); + expect(ReactNoop).toFlushAndYield([['componentDidUpdate', div()]]); const hostDiv = classInstance.div; expect(hostDiv).toBeDefined(); @@ -240,7 +247,7 @@ describe('ReactIncrementalReflection', () => { // Render to null but don't commit it yet. ReactNoop.render(); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ ['componentWillUpdate', hostDiv], 'render', 'render sibling', @@ -249,17 +256,22 @@ describe('ReactIncrementalReflection', () => { // This should still be the host div since the deletion is not committed. expect(ReactNoop.findInstance(classInstance)).toBe(hostDiv); - expect(ReactNoop.flush()).toEqual([['componentDidUpdate', null]]); + expect(ReactNoop).toFlushAndYield([['componentDidUpdate', null]]); // This should still be the host div since the deletion is not committed. expect(ReactNoop.findInstance(classInstance)).toBe(null); // Render a div again ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield([ + ['componentWillUpdate', null], + 'render', + 'render sibling', + ['componentDidUpdate', div()], + ]); // Unmount the component. ReactNoop.render([]); - expect(ReactNoop.flush()).toEqual([['componentWillUnmount', hostDiv]]); + expect(ReactNoop).toFlushAndYield([['componentWillUnmount', hostDiv]]); }); }); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js index 353a20ce65b28..b1896b97b37a5 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.internal.js @@ -31,8 +31,8 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.render(); expect(ReactNoop.getChildren()).toEqual([]); - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span('1')]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); }); it('searches for work on other roots once the current root completes', () => { @@ -40,7 +40,7 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.renderToRootWithID(, 'b'); ReactNoop.renderToRootWithID(, 'c'); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren('a')).toEqual([span('a:1')]); expect(ReactNoop.getChildren('b')).toEqual([span('b:1')]); @@ -50,8 +50,8 @@ describe('ReactIncrementalScheduling', () => { it('schedules top-level updates in order of priority', () => { // Initial render. ReactNoop.render(); - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span(1)]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); ReactNoop.batchedUpdates(() => { ReactNoop.render(); @@ -62,27 +62,27 @@ describe('ReactIncrementalScheduling', () => { }); }); // The sync updates flush first. - expect(ReactNoop.getChildren()).toEqual([span(4)]); + expect(ReactNoop).toMatchRenderedOutput(); // The terminal value should be the last update that was scheduled, // regardless of priority. In this case, that's the last sync update. - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span(4)]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); }); it('schedules top-level updates with same priority in order of insertion', () => { // Initial render. ReactNoop.render(); - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span(1)]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); ReactNoop.render(); ReactNoop.render(); ReactNoop.render(); ReactNoop.render(); - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span(5)]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); }); it('works on deferred roots in the order they were scheduled', () => { @@ -102,7 +102,7 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.renderToRootWithID(, 'b'); ReactNoop.renderToRootWithID(, 'c'); }); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['a:1', 'b:1', 'c:1']); expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1'); expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:1'); @@ -114,7 +114,7 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.renderToRootWithID(, 'b'); }); // Ensure it starts in the order it was scheduled - ReactNoop.flushThrough(['c:2']); + expect(ReactNoop).toFlushAndYieldThrough(['c:2']); expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1'); expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:1'); @@ -124,12 +124,12 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.renderToRootWithID(, 'a'); }); // Keep performing work in the order it was scheduled - ReactNoop.flushThrough(['b:2']); + expect(ReactNoop).toFlushAndYieldThrough(['b:2']); expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:1'); expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:2'); expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2'); - ReactNoop.flushThrough(['a:2']); + expect(ReactNoop).toFlushAndYieldThrough(['a:2']); expect(ReactNoop.getChildrenAsJSX('a')).toEqual('a:2'); expect(ReactNoop.getChildrenAsJSX('b')).toEqual('b:2'); expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2'); @@ -175,7 +175,7 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.render(); // Render without committing - ReactNoop.flushThrough(['render: 0']); + expect(ReactNoop).toFlushAndYieldThrough(['render: 0']); // Do one more unit of work to commit expect(ReactNoop.flushNextYield()).toEqual([ @@ -188,7 +188,7 @@ describe('ReactIncrementalScheduling', () => { ]); instance.setState({tick: 2}); - ReactNoop.flushThrough(['render: 2']); + expect(ReactNoop).toFlushAndYieldThrough(['render: 2']); expect(ReactNoop.flushNextYield()).toEqual([ 'componentDidUpdate: 2', 'componentDidUpdate (before setState): 2', @@ -243,27 +243,31 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.render(); }); // The cDM update should not have flushed yet because it has async priority. - expect(ReactNoop.getChildren()).toEqual([span(0)]); + expect(ReactNoop).toHaveYielded([ + 'render: 0', + 'componentDidMount (before setState): 0', + 'componentDidMount (after setState): 0', + ]); + expect(ReactNoop).toMatchRenderedOutput(); // Now flush the cDM update. - ReactNoop.clearYields(); - expect(ReactNoop.flush()).toEqual(['render: 1', 'componentDidUpdate: 1']); - expect(ReactNoop.getChildren()).toEqual([span(1)]); + expect(ReactNoop).toFlushAndYield(['render: 1', 'componentDidUpdate: 1']); + expect(ReactNoop).toMatchRenderedOutput(); // Increment the tick to 2. This will trigger an update inside cDU. Flush // the first update without flushing the second one. instance.setState({tick: 2}); - ReactNoop.flushThrough([ + expect(ReactNoop).toFlushAndYieldThrough([ 'render: 2', 'componentDidUpdate: 2', 'componentDidUpdate (before setState): 2', 'componentDidUpdate (after setState): 2', ]); - expect(ReactNoop.getChildren()).toEqual([span(2)]); + expect(ReactNoop).toMatchRenderedOutput(); // Now flush the cDU update. - expect(ReactNoop.flush()).toEqual(['render: 3', 'componentDidUpdate: 3']); - expect(ReactNoop.getChildren()).toEqual([span(3)]); + expect(ReactNoop).toFlushAndYield(['render: 3', 'componentDidUpdate: 3']); + expect(ReactNoop).toMatchRenderedOutput(); }); it('performs Task work even after time runs out', () => { @@ -286,13 +290,13 @@ describe('ReactIncrementalScheduling', () => { ReactNoop.render(); // This should be just enough to complete all the work, but not enough to // commit it. - ReactNoop.flushThrough(['Foo']); - expect(ReactNoop.getChildren()).toEqual([]); + expect(ReactNoop).toFlushAndYieldThrough(['Foo']); + expect(ReactNoop).toMatchRenderedOutput(null); // Do one more unit of work. ReactNoop.flushNextYield(); // The updates should all be flushed with Task priority - expect(ReactNoop.getChildren()).toEqual([span(5)]); + expect(ReactNoop).toMatchRenderedOutput(); }); it('can opt-out of batching using unbatchedUpdates', () => { @@ -305,16 +309,16 @@ describe('ReactIncrementalScheduling', () => { // updates are not batched ReactNoop.unbatchedUpdates(() => { ReactNoop.render(); - expect(ReactNoop.getChildren()).toEqual([span(1)]); + expect(ReactNoop).toMatchRenderedOutput(); ReactNoop.render(); - expect(ReactNoop.getChildren()).toEqual([span(2)]); + expect(ReactNoop).toMatchRenderedOutput(); }); ReactNoop.render(); - expect(ReactNoop.getChildren()).toEqual([span(2)]); + expect(ReactNoop).toMatchRenderedOutput(); }); // Remaining update is now flushed - expect(ReactNoop.getChildren()).toEqual([span(3)]); + expect(ReactNoop).toMatchRenderedOutput(); }); it('nested updates are always deferred, even inside unbatchedUpdates', () => { @@ -331,7 +335,7 @@ describe('ReactIncrementalScheduling', () => { // in unbatchedUpdates. this.setState({step: 2}); }); - expect(ReactNoop.getChildren()).toEqual([span(1)]); + expect(ReactNoop).toMatchRenderedOutput(); } } render() { @@ -341,13 +345,13 @@ describe('ReactIncrementalScheduling', () => { } } ReactNoop.render(); - ReactNoop.flush(); - expect(ReactNoop.getChildren()).toEqual([span(0)]); + expect(ReactNoop).toFlushWithoutYielding(); + expect(ReactNoop).toMatchRenderedOutput(); ReactNoop.flushSync(() => { instance.setState({step: 1}); }); - expect(ReactNoop.getChildren()).toEqual([span(2)]); + expect(ReactNoop).toMatchRenderedOutput(); expect(ops).toEqual([ 'render: 0', @@ -376,14 +380,16 @@ describe('ReactIncrementalScheduling', () => { } ReactNoop.render(); - expect(ReactNoop.flush).toWarnDev( + expect(() => { + expect(ReactNoop).toFlushWithoutYielding(); + }).toWarnDev( 'componentWillReceiveProps: Please update the following components ' + 'to use static getDerivedStateFromProps instead: Foo', {withoutStack: true}, ); ReactNoop.render(); - expect(ReactNoop.flush()).toEqual([ + expect(ReactNoop).toFlushAndYield([ 'has callback before setState: false', 'has callback after setState: false', ]); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js index 9e14dd202fb59..e96f61f88b7c4 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js @@ -53,11 +53,11 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span())]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span(), span())]); }); @@ -81,17 +81,17 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span(), span('test'))]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([ div(span(), span(), div(), span('test')), ]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([ div(span(), div(), span(), span('test')), ]); @@ -114,11 +114,11 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div('Hello')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div('World', 'World', '!')]); }); @@ -138,13 +138,13 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([ div(div(), span('Hello'), 'World'), ]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div()]); }); @@ -180,23 +180,23 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]); expect(unmounted).toBe(false); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]); expect(unmounted).toBe(true); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div('Text', 'Trail')]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div('Trail')]); }); @@ -230,19 +230,19 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]); expect(unmounted).toBe(false); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]); expect(unmounted).toBe(true); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div('Trail')]); }); @@ -267,7 +267,7 @@ describe('ReactIncrementalSideEffects', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div()]); expect(ReactNoop.getChildren('portalContainer')).toEqual([ div(), @@ -280,7 +280,7 @@ describe('ReactIncrementalSideEffects', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div()]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); @@ -289,7 +289,7 @@ describe('ReactIncrementalSideEffects', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div()]); expect(ReactNoop.getChildren('portalContainer')).toEqual([ div(), @@ -298,17 +298,17 @@ describe('ReactIncrementalSideEffects', () => { ]); ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([ div(), @@ -317,7 +317,7 @@ describe('ReactIncrementalSideEffects', () => { ]); ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); }); @@ -343,7 +343,7 @@ describe('ReactIncrementalSideEffects', () => { , ); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([div()]); expect(ReactNoop.getChildren('portalContainer')).toEqual([ div(), @@ -352,12 +352,12 @@ describe('ReactIncrementalSideEffects', () => { ]); ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([ div(), @@ -366,7 +366,7 @@ describe('ReactIncrementalSideEffects', () => { ]); ReactNoop.render(null); - ReactNoop.flush(); + expect(ReactNoop).toFlushWithoutYielding(); expect(ReactNoop.getChildren()).toEqual([]); expect(ReactNoop.getChildren('portalContainer')).toEqual([]); }); @@ -391,7 +391,7 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Foo', 'Bar', 'Bar', 'Bar']); expect(ReactNoop.getChildren()).toEqual([ div(div(span('Hello'), span('Hello')), span('Yo')), ]); @@ -399,7 +399,7 @@ describe('ReactIncrementalSideEffects', () => { ReactNoop.render(); // Flush some of the work without committing - ReactNoop.flushThrough(['Foo', 'Bar']); + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'Bar']); expect(ReactNoop.getChildren()).toEqual([ div(div(span('Hello'), span('Hello')), span('Yo')), ]); @@ -423,7 +423,7 @@ describe('ReactIncrementalSideEffects', () => { } ReactNoop.render(); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Foo', 'Middle']); expect(ReactNoop.getChildrenAsJSX()).toEqual(
@@ -434,7 +434,7 @@ describe('ReactIncrementalSideEffects', () => { ); ReactNoop.render(, () => ReactNoop.yield('commit')); - ReactNoop.flushThrough(['Foo', 'commit']); + expect(ReactNoop).toFlushAndYieldThrough(['Foo', 'commit']); expect(ReactNoop.getChildrenAsJSX()).toEqual(
, ); - ReactNoop.flush(); + expect(ReactNoop).toFlushAndYield(['Middle']); expect(ReactNoop.getChildrenAsJSX()).toEqual(