Skip to content

Commit 135e5c1

Browse files
committed
Add some legacy mode and suspense boundary flushing tests
1 parent ffe59a8 commit 135e5c1

File tree

1 file changed

+186
-10
lines changed

1 file changed

+186
-10
lines changed

packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js

Lines changed: 186 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,20 +1302,25 @@ describe('ReactLazy', () => {
13021302
Scheduler.unstable_yieldValue('Init A2');
13031303
return fakeImport(ChildA);
13041304
});
1305+
let resolveB2;
13051306
const LazyChildB2 = lazy(() => {
13061307
Scheduler.unstable_yieldValue('Init B2');
1307-
return fakeImport(ChildB);
1308+
return new Promise(r => {
1309+
resolveB2 = r;
1310+
});
13081311
});
13091312

13101313
function Parent({swap}) {
13111314
return (
1312-
<Suspense fallback={<Text text="Loading..." />}>
1313-
{swap
1314-
? [
1315-
<LazyChildB2 key="B" lowerCase={true} />,
1316-
<LazyChildA2 key="A" lowerCase={true} />,
1317-
]
1318-
: [<LazyChildA key="A" />, <LazyChildB key="B" />]}
1315+
<Suspense fallback={<Text text="Outer..." />}>
1316+
<Suspense fallback={<Text text="Loading..." />}>
1317+
{swap
1318+
? [
1319+
<LazyChildB2 key="B" lowerCase={true} />,
1320+
<LazyChildA2 key="A" lowerCase={true} />,
1321+
]
1322+
: [<LazyChildA key="A" />, <LazyChildB key="B" />]}
1323+
</Suspense>
13191324
</Suspense>
13201325
);
13211326
}
@@ -1338,12 +1343,107 @@ describe('ReactLazy', () => {
13381343
]);
13391344
expect(root).toMatchRenderedOutput('AB');
13401345

1346+
// Swap the position of A and B
1347+
ReactTestRenderer.act(() => {
1348+
root.update(<Parent swap={true} />);
1349+
expect(Scheduler).toFlushAndYield(['Init B2', 'Loading...']);
1350+
});
1351+
1352+
// The suspense boundary should've triggered now.
1353+
expect(root).toMatchRenderedOutput('Loading...');
1354+
await resolveB2({default: ChildB});
1355+
1356+
// We need to flush to trigger the second one to load.
1357+
expect(Scheduler).toFlushAndYield(['Init A2']);
1358+
await LazyChildA2;
1359+
1360+
expect(Scheduler).toFlushAndYield([
1361+
'b',
1362+
'a',
1363+
'Did update: b',
1364+
'Did update: a',
1365+
]);
1366+
expect(root).toMatchRenderedOutput('ba');
1367+
});
1368+
1369+
// @gate enableLazyElements
1370+
it('mount and reorder lazy types (legacy mode)', async () => {
1371+
class Child extends React.Component {
1372+
componentDidMount() {
1373+
Scheduler.unstable_yieldValue('Did mount: ' + this.props.label);
1374+
}
1375+
componentDidUpdate() {
1376+
Scheduler.unstable_yieldValue('Did update: ' + this.props.label);
1377+
}
1378+
render() {
1379+
return <Text text={this.props.label} />;
1380+
}
1381+
}
1382+
1383+
function ChildA({lowerCase}) {
1384+
return <Child label={lowerCase ? 'a' : 'A'} />;
1385+
}
1386+
1387+
function ChildB({lowerCase}) {
1388+
return <Child label={lowerCase ? 'b' : 'B'} />;
1389+
}
1390+
1391+
const LazyChildA = lazy(() => {
1392+
Scheduler.unstable_yieldValue('Init A');
1393+
return fakeImport(ChildA);
1394+
});
1395+
const LazyChildB = lazy(() => {
1396+
Scheduler.unstable_yieldValue('Init B');
1397+
return fakeImport(ChildB);
1398+
});
1399+
const LazyChildA2 = lazy(() => {
1400+
Scheduler.unstable_yieldValue('Init A2');
1401+
return fakeImport(ChildA);
1402+
});
1403+
const LazyChildB2 = lazy(() => {
1404+
Scheduler.unstable_yieldValue('Init B2');
1405+
return fakeImport(ChildB);
1406+
});
1407+
1408+
function Parent({swap}) {
1409+
return (
1410+
<Suspense fallback={<Text text="Outer..." />}>
1411+
<Suspense fallback={<Text text="Loading..." />}>
1412+
{swap
1413+
? [
1414+
<LazyChildB2 key="B" lowerCase={true} />,
1415+
<LazyChildA2 key="A" lowerCase={true} />,
1416+
]
1417+
: [<LazyChildA key="A" />, <LazyChildB key="B" />]}
1418+
</Suspense>
1419+
</Suspense>
1420+
);
1421+
}
1422+
1423+
const root = ReactTestRenderer.create(<Parent swap={false} />, {
1424+
unstable_isConcurrent: false,
1425+
});
1426+
1427+
expect(Scheduler).toHaveYielded(['Init A', 'Init B', 'Loading...']);
1428+
expect(root).not.toMatchRenderedOutput('AB');
1429+
1430+
await LazyChildA;
1431+
await LazyChildB;
1432+
1433+
expect(Scheduler).toFlushAndYield([
1434+
'A',
1435+
'B',
1436+
'Did mount: A',
1437+
'Did mount: B',
1438+
]);
1439+
expect(root).toMatchRenderedOutput('AB');
1440+
13411441
// Swap the position of A and B
13421442
root.update(<Parent swap={true} />);
1343-
expect(Scheduler).toFlushAndYield(['Init B2', 'Loading...']);
1443+
expect(Scheduler).toHaveYielded(['Init B2', 'Loading...']);
13441444
await LazyChildB2;
13451445
// We need to flush to trigger the second one to load.
1346-
expect(Scheduler).toFlushAndYield(['Init A2', 'Loading...']);
1446+
expect(Scheduler).toFlushAndYield(['Init A2']);
13471447
await LazyChildA2;
13481448

13491449
expect(Scheduler).toFlushAndYield([
@@ -1430,4 +1530,80 @@ describe('ReactLazy', () => {
14301530
]);
14311531
expect(root).toMatchRenderedOutput('ba');
14321532
});
1533+
1534+
// @gate enableLazyElements
1535+
it('mount and reorder lazy elements (legacy mode)', async () => {
1536+
class Child extends React.Component {
1537+
componentDidMount() {
1538+
Scheduler.unstable_yieldValue('Did mount: ' + this.props.label);
1539+
}
1540+
componentDidUpdate() {
1541+
Scheduler.unstable_yieldValue('Did update: ' + this.props.label);
1542+
}
1543+
render() {
1544+
return <Text text={this.props.label} />;
1545+
}
1546+
}
1547+
1548+
const lazyChildA = lazy(() => {
1549+
Scheduler.unstable_yieldValue('Init A');
1550+
return fakeImport(<Child key="A" label="A" />);
1551+
});
1552+
const lazyChildB = lazy(() => {
1553+
Scheduler.unstable_yieldValue('Init B');
1554+
return fakeImport(<Child key="B" label="B" />);
1555+
});
1556+
const lazyChildA2 = lazy(() => {
1557+
Scheduler.unstable_yieldValue('Init A2');
1558+
return fakeImport(<Child key="A" label="a" />);
1559+
});
1560+
const lazyChildB2 = lazy(() => {
1561+
Scheduler.unstable_yieldValue('Init B2');
1562+
return fakeImport(<Child key="B" label="b" />);
1563+
});
1564+
1565+
function Parent({swap}) {
1566+
return (
1567+
<Suspense fallback={<Text text="Loading..." />}>
1568+
{swap ? [lazyChildB2, lazyChildA2] : [lazyChildA, lazyChildB]}
1569+
</Suspense>
1570+
);
1571+
}
1572+
1573+
const root = ReactTestRenderer.create(<Parent swap={false} />, {
1574+
unstable_isConcurrent: false,
1575+
});
1576+
1577+
expect(Scheduler).toHaveYielded(['Init A', 'Loading...']);
1578+
expect(root).not.toMatchRenderedOutput('AB');
1579+
1580+
await lazyChildA;
1581+
// We need to flush to trigger the B to load.
1582+
expect(Scheduler).toFlushAndYield(['Init B']);
1583+
await lazyChildB;
1584+
1585+
expect(Scheduler).toFlushAndYield([
1586+
'A',
1587+
'B',
1588+
'Did mount: A',
1589+
'Did mount: B',
1590+
]);
1591+
expect(root).toMatchRenderedOutput('AB');
1592+
1593+
// Swap the position of A and B
1594+
root.update(<Parent swap={true} />);
1595+
expect(Scheduler).toHaveYielded(['Init B2', 'Loading...']);
1596+
await lazyChildB2;
1597+
// We need to flush to trigger the second one to load.
1598+
expect(Scheduler).toFlushAndYield(['Init A2']);
1599+
await lazyChildA2;
1600+
1601+
expect(Scheduler).toFlushAndYield([
1602+
'b',
1603+
'a',
1604+
'Did update: b',
1605+
'Did update: a',
1606+
]);
1607+
expect(root).toMatchRenderedOutput('ba');
1608+
});
14331609
});

0 commit comments

Comments
 (0)