@@ -1058,6 +1058,118 @@ describe('ReactDOMFizzServer', () => {
10581058 ) ;
10591059 } ) ;
10601060
1061+ function normalizeCodeLocInfo ( str ) {
1062+ return (
1063+ str &&
1064+ str . replace ( / \n + (?: a t | i n ) ( [ \S ] + ) [ ^ \n ] * / g, function ( m , name ) {
1065+ return '\n in ' + name + ' (at **)' ;
1066+ } )
1067+ ) ;
1068+ }
1069+
1070+ // @gate experimental
1071+ it ( 'should include a component stack across suspended boundaries' , async ( ) => {
1072+ function B ( ) {
1073+ const children = [ readText ( 'Hello' ) , readText ( 'World' ) ] ;
1074+ // Intentionally trigger a key warning here.
1075+ return (
1076+ < div >
1077+ { children . map ( t => (
1078+ < span > { t } </ span >
1079+ ) ) }
1080+ </ div >
1081+ ) ;
1082+ }
1083+ function C ( ) {
1084+ return (
1085+ < inCorrectTag >
1086+ < Text text = "Loading" />
1087+ </ inCorrectTag >
1088+ ) ;
1089+ }
1090+ function A ( ) {
1091+ return (
1092+ < div >
1093+ < Suspense fallback = { < C /> } >
1094+ < B />
1095+ </ Suspense >
1096+ </ div >
1097+ ) ;
1098+ }
1099+
1100+ // We can't use the toErrorDev helper here because this is an async act.
1101+ const originalConsoleError = console . error ;
1102+ const mockError = jest . fn ( ) ;
1103+ console . error = ( ...args ) => {
1104+ mockError ( ...args . map ( normalizeCodeLocInfo ) ) ;
1105+ } ;
1106+
1107+ try {
1108+ await act ( async ( ) => {
1109+ const { startWriting} = ReactDOMFizzServer . pipeToNodeWritable (
1110+ < A /> ,
1111+ writable ,
1112+ ) ;
1113+ startWriting ( ) ;
1114+ } ) ;
1115+
1116+ expect ( getVisibleChildren ( container ) ) . toEqual (
1117+ < div >
1118+ < incorrecttag > Loading</ incorrecttag >
1119+ </ div > ,
1120+ ) ;
1121+
1122+ if ( __DEV__ ) {
1123+ expect ( mockError ) . toHaveBeenCalledWith (
1124+ 'Warning: <%s /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.%s' ,
1125+ 'inCorrectTag' ,
1126+ '\n' +
1127+ ' in inCorrectTag (at **)\n' +
1128+ ' in C (at **)\n' +
1129+ ' in Suspense (at **)\n' +
1130+ ' in div (at **)\n' +
1131+ ' in A (at **)' ,
1132+ ) ;
1133+ mockError . mockClear ( ) ;
1134+ } else {
1135+ expect ( mockError ) . not . toHaveBeenCalled ( ) ;
1136+ }
1137+
1138+ await act ( async ( ) => {
1139+ resolveText ( 'Hello' ) ;
1140+ resolveText ( 'World' ) ;
1141+ } ) ;
1142+
1143+ if ( __DEV__ ) {
1144+ expect ( mockError ) . toHaveBeenCalledWith (
1145+ 'Warning: Each child in a list should have a unique "key" prop.%s%s' +
1146+ ' See https://reactjs.org/link/warning-keys for more information.%s' ,
1147+ '\n\nCheck the top-level render call using <div>.' ,
1148+ '' ,
1149+ '\n' +
1150+ ' in span (at **)\n' +
1151+ ' in B (at **)\n' +
1152+ ' in Suspense (at **)\n' +
1153+ ' in div (at **)\n' +
1154+ ' in A (at **)' ,
1155+ ) ;
1156+ } else {
1157+ expect ( mockError ) . not . toHaveBeenCalled ( ) ;
1158+ }
1159+
1160+ expect ( getVisibleChildren ( container ) ) . toEqual (
1161+ < div >
1162+ < div >
1163+ < span > Hello</ span >
1164+ < span > World</ span >
1165+ </ div >
1166+ </ div > ,
1167+ ) ;
1168+ } finally {
1169+ console . error = originalConsoleError ;
1170+ }
1171+ } ) ;
1172+
10611173 // @gate experimental
10621174 it ( 'should can suspend in a class component with legacy context' , async ( ) => {
10631175 class TestProvider extends React . Component {
0 commit comments