mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Add back accidentally deleted test comments (#26294)
The codemod I used in #26288 accidentally caused some comments to be deleted. Because not all affected lines included comments, I didn't notice until after landing. This adds the comments back.
This commit is contained in:
@@ -166,9 +166,11 @@ describe('ReactBlockingMode', () => {
|
||||
assertLog(['A1', 'B1']);
|
||||
expect(root).toMatchRenderedOutput('A1B1');
|
||||
} else {
|
||||
// Only the second update should have flushed synchronously
|
||||
assertLog(['B1']);
|
||||
expect(root).toMatchRenderedOutput('A0B1');
|
||||
|
||||
// Now flush the first update
|
||||
await waitForAll(['A1']);
|
||||
expect(root).toMatchRenderedOutput('A1B1');
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
</>,
|
||||
);
|
||||
});
|
||||
// Inner contents finish in separate commit from outer
|
||||
assertLog(['Inner']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -178,6 +179,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await act(async () => {
|
||||
root.render(<App />);
|
||||
});
|
||||
// Inner contents finish in separate commit from outer
|
||||
assertLog(['Outer', 'Loading...', 'Inner [0]']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -190,6 +192,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await act(async () => {
|
||||
setCount(1);
|
||||
});
|
||||
// Entire update finishes in a single commit
|
||||
assertLog(['Outer', 'Inner [1]']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -227,6 +230,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
</>,
|
||||
);
|
||||
});
|
||||
// Inner contents suspended, so we continue showing a fallback.
|
||||
assertLog(['Suspend! [Inner]']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -276,6 +280,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await act(async () => {
|
||||
root.render(<App />);
|
||||
});
|
||||
// Each level commits separately
|
||||
assertLog(['A', 'Loading B...', 'B', 'Loading C...', 'C']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
|
||||
@@ -219,6 +219,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -245,6 +246,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -273,6 +275,8 @@ describe('ReactCache', () => {
|
||||
root.render(<App showMore={false} />);
|
||||
});
|
||||
|
||||
// Even though there are two new <Cache /> trees, they should share the same
|
||||
// data cache. So there should be only a single cache miss for A.
|
||||
assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
|
||||
expect(root).toMatchRenderedOutput('Loading...Loading...');
|
||||
|
||||
@@ -285,6 +289,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -320,6 +325,8 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render(<App showMore={true} />);
|
||||
});
|
||||
// Even though there are two new <Cache /> trees, they should share the same
|
||||
// data cache. So there should be only a single cache miss for A.
|
||||
assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
|
||||
expect(root).toMatchRenderedOutput('Loading...Loading...');
|
||||
|
||||
@@ -332,6 +339,9 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// cleanup occurs for the cache shared by the inner cache boundaries (which
|
||||
// are not shared w the root because they were added in an update)
|
||||
// note that no cache is created for the root since the cache is never accessed
|
||||
assertLog(['Cache cleanup: A [v1]']);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -356,6 +366,8 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render(<App />);
|
||||
});
|
||||
// Even though there is a nested <Cache /> boundary, it should share the same
|
||||
// data cache as the root. So there should be only a single cache miss for A.
|
||||
assertLog(['Cache miss! [A]', 'Loading...']);
|
||||
expect(root).toMatchRenderedOutput('Loading...');
|
||||
|
||||
@@ -368,6 +380,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
},
|
||||
@@ -412,6 +425,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -468,6 +482,8 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye!');
|
||||
});
|
||||
// Cleanup occurs for the *second* cache instance: the first is still
|
||||
// referenced by the root
|
||||
assertLog(['Cache cleanup: A [v2]']);
|
||||
expect(root).toMatchRenderedOutput('Bye!');
|
||||
});
|
||||
@@ -549,6 +565,7 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// no cleanup: cache is still retained at the root
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -728,12 +745,14 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
resolveMostRecentTextCache('A');
|
||||
});
|
||||
// Note that the version has updated, and the previous cache is cleared
|
||||
assertLog(['A [v2]', 'Cache cleanup: A [v1]']);
|
||||
expect(root).toMatchRenderedOutput('A [v2]');
|
||||
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// the original root cache already cleaned up when the refresh completed
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -781,12 +800,14 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
resolveMostRecentTextCache('A');
|
||||
});
|
||||
// Note that the version has updated, and the previous cache is cleared
|
||||
assertLog(['A [v2]']);
|
||||
expect(root).toMatchRenderedOutput('A [v2]');
|
||||
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// the original root cache already cleaned up when the refresh completed
|
||||
assertLog([]);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -841,12 +862,15 @@ describe('ReactCache', () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
// The root should re-render without a cache miss.
|
||||
// The cache is not cleared up yet, since it's still reference by the root
|
||||
assertLog(['A [v2]']);
|
||||
expect(root).toMatchRenderedOutput('A [v2]');
|
||||
|
||||
await act(async () => {
|
||||
root.render('Bye');
|
||||
});
|
||||
// the refreshed cache boundary is unmounted and cleans up
|
||||
assertLog(['Cache cleanup: A [v2]']);
|
||||
expect(root).toMatchRenderedOutput('Bye');
|
||||
});
|
||||
@@ -920,6 +944,8 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye!');
|
||||
});
|
||||
// Unmounting children releases the refreshed cache instance only; the root
|
||||
// still retains the original cache instance used for the first render
|
||||
assertLog(['Cache cleanup: A [v3]']);
|
||||
expect(root).toMatchRenderedOutput('Bye!');
|
||||
});
|
||||
@@ -967,6 +993,8 @@ describe('ReactCache', () => {
|
||||
root.render(<App showMore={true} />);
|
||||
});
|
||||
|
||||
// Even though there are two new <Cache /> trees, they should share the same
|
||||
// data cache. So there should be only a single cache miss for A.
|
||||
assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
|
||||
expect(root).toMatchRenderedOutput('Loading...Loading...');
|
||||
|
||||
@@ -1064,6 +1092,9 @@ describe('ReactCache', () => {
|
||||
await act(async () => {
|
||||
root.render('Bye!');
|
||||
});
|
||||
// Unmounting children releases both cache boundaries, but the original
|
||||
// cache instance (used by second boundary) is still referenced by the root.
|
||||
// only the second cache instance is freed.
|
||||
assertLog(['Cache cleanup: A [v2]']);
|
||||
expect(root).toMatchRenderedOutput('Bye!');
|
||||
},
|
||||
|
||||
@@ -339,6 +339,11 @@ describe('ReactLazyContextPropagation', () => {
|
||||
setOtherValue(1);
|
||||
setOtherValue(0);
|
||||
});
|
||||
// NOTE: If this didn't yield anything, that indicates that we never visited
|
||||
// the consumer during the render phase, which probably means the eager
|
||||
// bailout mechanism kicked in. Because we're testing the _lazy_ bailout
|
||||
// mechanism, update this test to foil the _eager_ bailout, somehow. Perhaps
|
||||
// by switching to useReducer.
|
||||
assertLog(['Consumer']);
|
||||
expect(root).toMatchRenderedOutput('0');
|
||||
});
|
||||
|
||||
@@ -78,6 +78,7 @@ describe('ReactDeferredValue', () => {
|
||||
root.render(<App value={2} />);
|
||||
|
||||
await waitForPaint(['Original: 2']);
|
||||
// The deferred value updates in a separate render
|
||||
await waitForPaint(['Deferred: 2']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -92,6 +93,7 @@ describe('ReactDeferredValue', () => {
|
||||
startTransition(() => {
|
||||
root.render(<App value={3} />);
|
||||
});
|
||||
// The deferred value updates in the same render as the original
|
||||
await waitForPaint(['Original: 3', 'Deferred: 3']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -137,6 +139,7 @@ describe('ReactDeferredValue', () => {
|
||||
root.render(<App value={2} />);
|
||||
|
||||
await waitForPaint(['Original: 2']);
|
||||
// The deferred value updates in a separate render
|
||||
await waitForPaint(['Deferred: 2']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -151,6 +154,7 @@ describe('ReactDeferredValue', () => {
|
||||
startTransition(() => {
|
||||
root.render(<App value={3} />);
|
||||
});
|
||||
// The deferred value updates in the same render as the original
|
||||
await waitForPaint(['Original: 3', 'Deferred: 3']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -201,6 +205,7 @@ describe('ReactDeferredValue', () => {
|
||||
root.render(<App value={2} />);
|
||||
|
||||
await waitForPaint(['Original: 2']);
|
||||
// The deferred value updates in a separate render
|
||||
await waitForPaint(['Deferred: 2']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -215,6 +220,7 @@ describe('ReactDeferredValue', () => {
|
||||
startTransition(() => {
|
||||
root.render(<App value={3} />);
|
||||
});
|
||||
// The deferred value updates in the same render as the original
|
||||
await waitForPaint(['Original: 3', 'Deferred: 3']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput(
|
||||
@@ -270,6 +276,9 @@ describe('ReactDeferredValue', () => {
|
||||
startTransition(() => {
|
||||
root.render(<App value={2} />);
|
||||
});
|
||||
// In the regression, the memoized value was not updated during non-urgent
|
||||
// updates, so this would flip the deferred value back to the initial
|
||||
// value (1) instead of reusing the current one (2).
|
||||
await waitForPaint(['Original: 2', 'Deferred: 2']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<div>
|
||||
|
||||
@@ -171,14 +171,17 @@ describe('ReactExpiration', () => {
|
||||
});
|
||||
// Advance the timer.
|
||||
Scheduler.unstable_advanceTime(2000);
|
||||
// Partially flush the first update, then interrupt it.
|
||||
await waitFor(['A [render]']);
|
||||
interrupt();
|
||||
|
||||
// Don't advance time by enough to expire the first update.
|
||||
assertLog([]);
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
|
||||
// Schedule another update.
|
||||
ReactNoop.render(<TextClass text="B" />);
|
||||
// Both updates are batched
|
||||
await waitForAll(['B [render]', 'B [commit]']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="B" />);
|
||||
|
||||
@@ -190,6 +193,8 @@ describe('ReactExpiration', () => {
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="B" />);
|
||||
// Schedule another update.
|
||||
ReactNoop.render(<TextClass text="B" />);
|
||||
// The updates should flush in the same batch, since as far as the scheduler
|
||||
// knows, they may have occurred inside the same event.
|
||||
await waitForAll(['B [render]', 'B [commit]']);
|
||||
});
|
||||
|
||||
@@ -223,14 +228,17 @@ describe('ReactExpiration', () => {
|
||||
});
|
||||
// Advance the timer.
|
||||
Scheduler.unstable_advanceTime(2000);
|
||||
// Partially flush the first update, then interrupt it.
|
||||
await waitFor(['A [render]']);
|
||||
interrupt();
|
||||
|
||||
// Don't advance time by enough to expire the first update.
|
||||
assertLog([]);
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
|
||||
// Schedule another update.
|
||||
ReactNoop.render(<TextClass text="B" />);
|
||||
// Both updates are batched
|
||||
await waitForAll(['B [render]', 'B [commit]']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="B" />);
|
||||
|
||||
@@ -247,6 +255,8 @@ describe('ReactExpiration', () => {
|
||||
|
||||
// Schedule another update.
|
||||
ReactNoop.render(<TextClass text="B" />);
|
||||
// The updates should flush in the same batch, since as far as the scheduler
|
||||
// knows, they may have occurred inside the same event.
|
||||
await waitForAll(['B [render]', 'B [commit]']);
|
||||
},
|
||||
);
|
||||
@@ -471,7 +481,9 @@ describe('ReactExpiration', () => {
|
||||
// In other words, we can flush just the first child without flushing
|
||||
// the rest.
|
||||
Scheduler.unstable_flushNumberOfYields(1);
|
||||
// Yield right after first child.
|
||||
assertLog(['Sync pri: 1']);
|
||||
// Now do the rest.
|
||||
await waitForAll(['Normal pri: 1']);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput('Sync pri: 1, Normal pri: 1');
|
||||
@@ -533,6 +545,7 @@ describe('ReactExpiration', () => {
|
||||
await waitFor(['Sync pri: 0']);
|
||||
updateSyncPri();
|
||||
});
|
||||
// Same thing should happen as last time
|
||||
assertLog([
|
||||
// Interrupt idle update to render sync update
|
||||
'Sync pri: 1',
|
||||
@@ -733,6 +746,7 @@ describe('ReactExpiration', () => {
|
||||
Scheduler.unstable_flushNumberOfYields(1);
|
||||
assertLog(['A1', 'B1', 'C1']);
|
||||
});
|
||||
// The effect flushes after paint.
|
||||
assertLog(['Effect: 1']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +52,7 @@ describe('ReactFlushSync', () => {
|
||||
React.startTransition(() => {
|
||||
root.render(<App />);
|
||||
});
|
||||
// This will yield right before the passive effect fires
|
||||
await waitForPaint(['0, 0']);
|
||||
|
||||
// The passive effect will schedule a sync update and a normal update.
|
||||
@@ -67,6 +68,7 @@ describe('ReactFlushSync', () => {
|
||||
if (gate(flags => flags.enableUnifiedSyncLane)) {
|
||||
await waitForPaint([]);
|
||||
} else {
|
||||
// Now flush it.
|
||||
await waitForPaint(['1, 1']);
|
||||
}
|
||||
});
|
||||
@@ -112,9 +114,11 @@ describe('ReactFlushSync', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
// Only the sync update should have flushed
|
||||
assertLog(['1, 0']);
|
||||
expect(root).toMatchRenderedOutput('1, 0');
|
||||
});
|
||||
// Now the async update has flushed, too.
|
||||
assertLog(['1, 1']);
|
||||
expect(root).toMatchRenderedOutput('1, 1');
|
||||
});
|
||||
@@ -162,6 +166,7 @@ describe('ReactFlushSync', () => {
|
||||
]);
|
||||
expect(root).toMatchRenderedOutput('Child');
|
||||
});
|
||||
// Effect flushes after paint.
|
||||
assertLog(['Effect']);
|
||||
});
|
||||
|
||||
@@ -217,6 +222,7 @@ describe('ReactFlushSync', () => {
|
||||
]);
|
||||
expect(root).toMatchRenderedOutput('Child');
|
||||
});
|
||||
// Effect flushes after paint.
|
||||
assertLog(['Effect']);
|
||||
});
|
||||
|
||||
@@ -236,8 +242,10 @@ describe('ReactFlushSync', () => {
|
||||
|
||||
// Passive effects are pending. Calling flushSync should not affect them.
|
||||
ReactNoop.flushSync();
|
||||
// Effects still haven't fired.
|
||||
assertLog([]);
|
||||
});
|
||||
// Now the effects have fired.
|
||||
assertLog(['Effect']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -944,6 +944,7 @@ describe('ReactFragment', () => {
|
||||
);
|
||||
|
||||
ReactNoop.render(<Foo condition={false} />);
|
||||
// The key warning gets deduped because it's in the same component.
|
||||
await waitForAll([]);
|
||||
|
||||
expect(ops).toEqual(['Update Stateful']);
|
||||
@@ -955,6 +956,7 @@ describe('ReactFragment', () => {
|
||||
);
|
||||
|
||||
ReactNoop.render(<Foo condition={true} />);
|
||||
// The key warning gets deduped because it's in the same component.
|
||||
await waitForAll([]);
|
||||
|
||||
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
|
||||
|
||||
+48
@@ -299,6 +299,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Resolve the data
|
||||
await resolveText('A');
|
||||
// Renders successfully
|
||||
await waitForAll(['Foo', 'Bar', 'A', 'B']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -375,6 +376,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
</Suspense>,
|
||||
);
|
||||
});
|
||||
// B suspends. Continue rendering the remaining siblings.
|
||||
await waitForAll(['A', 'Suspend! [B]', 'C', 'D', 'Loading...']);
|
||||
// Did not commit yet.
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
@@ -382,6 +384,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Wait for data to resolve
|
||||
await resolveText('B');
|
||||
await waitForAll(['A', 'B', 'C', 'D']);
|
||||
// Renders successfully
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
<span prop="A" />
|
||||
@@ -730,6 +733,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// the update.
|
||||
ReactNoop.expire(10000);
|
||||
await advanceTimers(10000);
|
||||
// No additional rendering work is required, since we already prepared
|
||||
// the placeholder.
|
||||
assertLog([]);
|
||||
// Should have committed the placeholder.
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
@@ -974,6 +979,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// but not by enough to flush the promise or reach the true expiration time.
|
||||
ReactNoop.expire(2000);
|
||||
await advanceTimers(2000);
|
||||
// Even flushing won't yield a fallback in a transition.
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
|
||||
await waitForAll([]);
|
||||
@@ -1014,6 +1020,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
await resolveText('Async');
|
||||
|
||||
// Because we're already showing a fallback, interrupt the current render
|
||||
// and restart immediately.
|
||||
await waitForAll(['Async', 'Sibling']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -1081,6 +1089,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Resolve the promise
|
||||
await resolveText('Async');
|
||||
// We can now resume rendering
|
||||
await waitForAll(['Async']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="Async" />);
|
||||
});
|
||||
@@ -1106,6 +1115,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Schedule an update, and suspend for up to 5 seconds.
|
||||
React.startTransition(() => ReactNoop.render(<App text="A" />));
|
||||
// The update should suspend.
|
||||
await waitForAll(['Suspend! [A]', 'Loading...']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="S" />);
|
||||
|
||||
@@ -1117,6 +1127,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Schedule another low priority update.
|
||||
React.startTransition(() => ReactNoop.render(<App text="B" />));
|
||||
// This update should also suspend.
|
||||
await waitForAll(['Suspend! [B]', 'Loading...']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="S" />);
|
||||
|
||||
@@ -1129,6 +1140,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Flush the remaining work.
|
||||
await resolveText('A');
|
||||
await resolveText('B');
|
||||
// Nothing else to render.
|
||||
await waitForAll([]);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="C" />);
|
||||
});
|
||||
@@ -1778,6 +1790,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
'Commit root',
|
||||
]);
|
||||
|
||||
// Flush passive effects.
|
||||
await waitForAll([
|
||||
'Effect [A]',
|
||||
// B's effect should not fire because it suspended
|
||||
@@ -1823,6 +1836,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
'Commit root',
|
||||
]);
|
||||
|
||||
// Flush passive effects.
|
||||
await waitForAll([
|
||||
// B2's effect should not fire because it suspended
|
||||
// 'Effect [B2]',
|
||||
@@ -1863,6 +1877,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
});
|
||||
Scheduler.unstable_advanceTime(100);
|
||||
await advanceTimers(100);
|
||||
// Start rendering
|
||||
await waitFor(['Foo']);
|
||||
// For some reason it took a long time to render Foo.
|
||||
Scheduler.unstable_advanceTime(1250);
|
||||
@@ -1878,12 +1893,15 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Flush some of the time
|
||||
Scheduler.unstable_advanceTime(450);
|
||||
await advanceTimers(450);
|
||||
// Because we've already been waiting for so long we can
|
||||
// wait a bit longer. Still nothing...
|
||||
await waitForAll([]);
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
|
||||
// Eventually we'll show the fallback.
|
||||
Scheduler.unstable_advanceTime(500);
|
||||
await advanceTimers(500);
|
||||
// No need to rerender.
|
||||
await waitForAll([]);
|
||||
// Since this is a transition, we never fallback.
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
@@ -1891,6 +1909,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Flush the promise completely
|
||||
await resolveText('A');
|
||||
await waitForAll(['Foo', 'A']);
|
||||
// Renders successfully
|
||||
// TODO: Why does this render Foo
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="A" />);
|
||||
});
|
||||
|
||||
@@ -1909,6 +1929,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo />);
|
||||
// Start rendering
|
||||
await waitForAll([
|
||||
'Foo',
|
||||
// A suspends
|
||||
@@ -1925,6 +1946,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
Scheduler.unstable_advanceTime(5000);
|
||||
await advanceTimers(5000);
|
||||
|
||||
// Retry with the new content.
|
||||
await waitForAll([
|
||||
'A',
|
||||
// B still suspends
|
||||
@@ -1943,6 +1965,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Flush the last promise completely
|
||||
await resolveText('B');
|
||||
// Renders successfully
|
||||
await waitForAll(['B']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -1967,6 +1990,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
}
|
||||
|
||||
ReactNoop.render(<Foo />);
|
||||
// Start rendering
|
||||
await waitForAll([
|
||||
'Foo',
|
||||
// A suspends
|
||||
@@ -1980,6 +2004,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
await resolveText('A');
|
||||
|
||||
// Retry with the new content.
|
||||
await waitForAll([
|
||||
'A',
|
||||
// B still suspends
|
||||
@@ -1995,6 +2020,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Before we commit another Promise resolves.
|
||||
// We're still showing the first loading state.
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="Loading..." />);
|
||||
// Restart and render the complete content.
|
||||
await waitForAll(['A', 'B']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -2040,6 +2066,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
Scheduler.unstable_advanceTime(500);
|
||||
jest.advanceTimersByTime(500);
|
||||
|
||||
// We should have already shown the fallback.
|
||||
// When we wrote this test, we inferred the start time of high priority
|
||||
// updates as way earlier in the past. This test ensures that we don't
|
||||
// use this assumption to add a very long JND.
|
||||
await waitForAll([]);
|
||||
// Transitions never fallback.
|
||||
expect(ReactNoop).toMatchRenderedOutput(null);
|
||||
@@ -2481,6 +2511,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
|
||||
// Schedule an update at idle pri.
|
||||
ReactNoop.idleUpdates(() => ReactNoop.render(<Foo renderContent={2} />));
|
||||
// We won't even work on Idle priority.
|
||||
await waitForAll([]);
|
||||
|
||||
// We're still suspended.
|
||||
@@ -3040,6 +3071,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await act(async () => {
|
||||
foo.setState({suspend: true});
|
||||
|
||||
// In the regression that this covers, we would neglect to reset the
|
||||
// current debug phase after suspending (in the catch block), so React
|
||||
// thinks we're still inside the render phase.
|
||||
await waitFor(['Suspend!']);
|
||||
|
||||
// Then when this setState happens, React would incorrectly fire a warning
|
||||
@@ -3130,6 +3164,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await waitFor(['Commit']);
|
||||
expect(ReactNoop).toMatchRenderedOutput(<div hidden={true} />);
|
||||
|
||||
// Partially render through the hidden content.
|
||||
await waitFor(['Suspend! [A]']);
|
||||
|
||||
// Start transition.
|
||||
@@ -3270,6 +3305,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
</>,
|
||||
);
|
||||
|
||||
// Now flush the remaining work. The Idle update successfully finishes.
|
||||
await waitForAll(['C']);
|
||||
expect(root).toMatchRenderedOutput(<span prop="C" />);
|
||||
});
|
||||
@@ -3433,6 +3469,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
await act(async () => {
|
||||
setText('D');
|
||||
});
|
||||
// Even though the fragment fiber is not part of the return path, we should
|
||||
// be able to finish rendering.
|
||||
assertLog(['D']);
|
||||
expect(root).toMatchRenderedOutput(<span prop="D" />);
|
||||
},
|
||||
@@ -3513,6 +3551,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
setText('E');
|
||||
});
|
||||
});
|
||||
// Even though the fragment fiber is not part of the return path, we should
|
||||
// be able to finish rendering.
|
||||
assertLog(['Suspend! [D]', 'E']);
|
||||
expect(root).toMatchRenderedOutput(<span prop="E" />);
|
||||
},
|
||||
@@ -3622,6 +3662,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Only the outer part can update. The inner part should still show a
|
||||
// fallback because we haven't finished loading B yet. Otherwise, the
|
||||
// inner text would be inconsistent with the outer text.
|
||||
assertLog([
|
||||
'Outer text: B',
|
||||
'Outer step: 1',
|
||||
@@ -3882,11 +3925,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
ReactNoop.idleUpdates(() => {
|
||||
setText('B');
|
||||
});
|
||||
// Suspend the first update. The second update doesn't run because it has
|
||||
// Idle priority.
|
||||
await waitForAll(['Suspend! [B]', 'Loading...']);
|
||||
|
||||
// Commit the fallback. Now we'll try working on Idle.
|
||||
jest.runAllTimers();
|
||||
|
||||
// It also suspends.
|
||||
await waitForAll(['Suspend! [B]']);
|
||||
});
|
||||
|
||||
@@ -3934,6 +3980,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
// Before the retry happens, schedule a new update.
|
||||
setText('B');
|
||||
|
||||
// The update should be allowed to finish before the retry is attempted.
|
||||
await waitForPaint(['B']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
@@ -3942,6 +3989,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
||||
</>,
|
||||
);
|
||||
});
|
||||
// Then do the retry.
|
||||
assertLog(['Async']);
|
||||
expect(root).toMatchRenderedOutput(
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user