Skip to content

Commit f0476c9

Browse files
committed
Current behavior with lazy types
1 parent f589d8b commit f0476c9

File tree

1 file changed

+182
-7
lines changed

1 file changed

+182
-7
lines changed

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js

Lines changed: 182 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,31 @@ describe('ReactFlightDOMNode', () => {
108108
);
109109
}
110110

111+
/**
112+
* Removes all stackframes not pointing into this file
113+
*/
114+
function ignoreListStack(str) {
115+
if (!str) {
116+
return str;
117+
}
118+
119+
let ignoreListedStack = '';
120+
const lines = str.split('\n');
121+
122+
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
123+
for (const line of lines) {
124+
if (
125+
line.indexOf(__filename) === -1 &&
126+
line.indexOf('<anonymous>') === -1
127+
) {
128+
} else {
129+
ignoreListedStack += '\n' + line.replace(__dirname, '.');
130+
}
131+
}
132+
133+
return ignoreListedStack;
134+
}
135+
111136
function readResult(stream) {
112137
return new Promise((resolve, reject) => {
113138
let buffer = '';
@@ -762,6 +787,156 @@ describe('ReactFlightDOMNode', () => {
762787
}
763788
});
764789

790+
// @gate enableHalt
791+
it('includes source locations in component and owner stacks for halted Client components', async () => {
792+
function SharedComponent({p1, p2, p3}) {
793+
use(p1);
794+
use(p2);
795+
use(p3);
796+
return <div>Hello, Dave!</div>;
797+
}
798+
const ClientComponentOnTheServer = clientExports(SharedComponent);
799+
const ClientComponentOnTheClient = clientExports(
800+
SharedComponent,
801+
123,
802+
'path/to/chunk.js',
803+
);
804+
805+
let resolvePendingPromise;
806+
function ServerComponent() {
807+
const p1 = Promise.resolve();
808+
const p2 = new Promise(resolve => {
809+
resolvePendingPromise = value => {
810+
p2.status = 'fulfilled';
811+
p2.value = value;
812+
};
813+
});
814+
const p3 = new Promise(() => {});
815+
return ReactServer.createElement(ClientComponentOnTheClient, {
816+
p1: p1,
817+
p2: p2,
818+
p3: p3,
819+
});
820+
}
821+
822+
function App() {
823+
return ReactServer.createElement(
824+
'html',
825+
null,
826+
ReactServer.createElement(
827+
'body',
828+
null,
829+
ReactServer.createElement(
830+
ReactServer.Suspense,
831+
{fallback: 'Loading...'},
832+
ReactServer.createElement(ServerComponent, null),
833+
),
834+
),
835+
);
836+
}
837+
838+
const errors = [];
839+
const rscStream = await serverAct(() =>
840+
ReactServerDOMServer.renderToPipeableStream(
841+
ReactServer.createElement(App, null),
842+
webpackMap,
843+
),
844+
);
845+
846+
const readable = new Stream.PassThrough(streamOptions);
847+
rscStream.pipe(readable);
848+
849+
function ClientRoot({response}) {
850+
return use(response);
851+
}
852+
853+
const serverConsumerManifest = {
854+
moduleMap: {
855+
[webpackMap[ClientComponentOnTheClient.$$id].id]: {
856+
'*': webpackMap[ClientComponentOnTheServer.$$id],
857+
},
858+
},
859+
moduleLoading: webpackModuleLoading,
860+
};
861+
862+
expect(errors).toEqual([]);
863+
864+
function ClientRoot({response}) {
865+
return use(response);
866+
}
867+
868+
const response = ReactServerDOMClient.createFromNodeStream(
869+
readable,
870+
serverConsumerManifest,
871+
);
872+
873+
let componentStack;
874+
let ownerStack;
875+
876+
const clientAbortController = new AbortController();
877+
878+
const fizzPrerenderStreamResult = ReactDOMFizzStatic.prerender(
879+
React.createElement(ClientRoot, {response}),
880+
{
881+
signal: clientAbortController.signal,
882+
onError(error, errorInfo) {
883+
componentStack = errorInfo.componentStack;
884+
ownerStack = React.captureOwnerStack
885+
? React.captureOwnerStack()
886+
: null;
887+
},
888+
},
889+
);
890+
891+
await serverAct(
892+
async () =>
893+
new Promise(resolve => {
894+
setImmediate(() => {
895+
resolvePendingPromise();
896+
clientAbortController.abort();
897+
resolve();
898+
});
899+
}),
900+
);
901+
902+
const fizzPrerenderStream = await fizzPrerenderStreamResult;
903+
const prerenderHTML = await readWebResult(fizzPrerenderStream.prelude);
904+
905+
expect(prerenderHTML).toContain('Loading...');
906+
907+
if (__DEV__) {
908+
expect(normalizeCodeLocInfo(componentStack)).toBe(
909+
'\n' +
910+
' in SharedComponent (at **)\n' +
911+
' in ServerComponent\n' +
912+
' in Suspense\n' +
913+
' in body\n' +
914+
' in html\n' +
915+
' in App (at **)\n' +
916+
' in ClientRoot (at **)',
917+
);
918+
} else {
919+
expect(normalizeCodeLocInfo(componentStack)).toBe(
920+
'\n' +
921+
' in SharedComponent (at **)\n' +
922+
' in Suspense\n' +
923+
' in body\n' +
924+
' in html\n' +
925+
' in ClientRoot (at **)',
926+
);
927+
}
928+
929+
if (__DEV__) {
930+
expect(ignoreListStack(ownerStack)).toBe(
931+
'' +
932+
'\n at ServerComponent (file://./ReactFlightDOMNode-test.js:815:26)' +
933+
'\n at App (file://./ReactFlightDOMNode-test.js:832:25)',
934+
);
935+
} else {
936+
expect(ownerStack).toBeNull();
937+
}
938+
});
939+
765940
// @gate enableHalt
766941
it('includes deeper location for aborted stacks', async () => {
767942
async function getData() {
@@ -1346,12 +1521,12 @@ describe('ReactFlightDOMNode', () => {
13461521
'\n' +
13471522
' in Dynamic' +
13481523
(gate(flags => flags.enableAsyncDebugInfo)
1349-
? ' (file://ReactFlightDOMNode-test.js:1216:27)\n'
1524+
? ' (file://ReactFlightDOMNode-test.js:1391:27)\n'
13501525
: '\n') +
13511526
' in body\n' +
13521527
' in html\n' +
1353-
' in App (file://ReactFlightDOMNode-test.js:1233:25)\n' +
1354-
' in ClientRoot (ReactFlightDOMNode-test.js:1308:16)',
1528+
' in App (file://ReactFlightDOMNode-test.js:1408:25)\n' +
1529+
' in ClientRoot (ReactFlightDOMNode-test.js:1483:16)',
13551530
);
13561531
} else {
13571532
expect(
@@ -1360,7 +1535,7 @@ describe('ReactFlightDOMNode', () => {
13601535
'\n' +
13611536
' in body\n' +
13621537
' in html\n' +
1363-
' in ClientRoot (ReactFlightDOMNode-test.js:1308:16)',
1538+
' in ClientRoot (ReactFlightDOMNode-test.js:1483:16)',
13641539
);
13651540
}
13661541

@@ -1370,16 +1545,16 @@ describe('ReactFlightDOMNode', () => {
13701545
normalizeCodeLocInfo(ownerStack, {preserveLocation: true}),
13711546
).toBe(
13721547
'\n' +
1373-
' in Dynamic (file://ReactFlightDOMNode-test.js:1216:27)\n' +
1374-
' in App (file://ReactFlightDOMNode-test.js:1233:25)',
1548+
' in Dynamic (file://ReactFlightDOMNode-test.js:1391:27)\n' +
1549+
' in App (file://ReactFlightDOMNode-test.js:1408:25)',
13751550
);
13761551
} else {
13771552
expect(
13781553
normalizeCodeLocInfo(ownerStack, {preserveLocation: true}),
13791554
).toBe(
13801555
'' +
13811556
'\n' +
1382-
' in App (file://ReactFlightDOMNode-test.js:1233:25)',
1557+
' in App (file://ReactFlightDOMNode-test.js:1408:25)',
13831558
);
13841559
}
13851560
} else {

0 commit comments

Comments
 (0)