@@ -1003,4 +1003,74 @@ describe('ReactDOMServerPartialHydration', () => {
1003
1003
let div = container . getElementsByTagName ( 'div' ) [ 0 ] ;
1004
1004
expect ( ref . current ) . toBe ( div ) ;
1005
1005
} ) ;
1006
+
1007
+ it ( 'warns when a sibling before the dehydrated boundary has inner text mismatch' , async ( ) => {
1008
+ let suspend = false ;
1009
+ let resolve ;
1010
+ let promise = new Promise ( resolvePromise => ( resolve = resolvePromise ) ) ;
1011
+
1012
+ function Child ( { text} ) {
1013
+ if ( suspend ) {
1014
+ throw promise ;
1015
+ } else {
1016
+ return 'Second ' + text ;
1017
+ }
1018
+ }
1019
+
1020
+ function Sibling ( { text} ) {
1021
+ return < div > First { text } </ div > ;
1022
+ }
1023
+
1024
+ function App ( { text} ) {
1025
+ return (
1026
+ < div >
1027
+ < Sibling text = { text } />
1028
+ < Suspense fallback = "Loading..." >
1029
+ < span >
1030
+ < Child text = { text } />
1031
+ </ span >
1032
+ </ Suspense >
1033
+ </ div >
1034
+ ) ;
1035
+ }
1036
+
1037
+ suspend = false ;
1038
+ let finalHTML = ReactDOMServer . renderToString ( < App text = { 'server text' } /> ) ;
1039
+ let container = document . createElement ( 'div' ) ;
1040
+ container . innerHTML = finalHTML ;
1041
+
1042
+ // On the client we don't have all data yet but we want to start
1043
+ // hydrating anyway.
1044
+ suspend = true ;
1045
+
1046
+ expect ( ( ) => {
1047
+ act ( ( ) => {
1048
+ ReactDOM . hydrate ( < App text = { 'client text' } /> , container ) ;
1049
+ } ) ;
1050
+ } ) . toWarnDev (
1051
+ 'Text content did not match. ' +
1052
+ 'Server: "server text" ' +
1053
+ 'Client: "client text"\n' +
1054
+ ' in div (at **)\n' +
1055
+ ' in Sibling (at **)\n' +
1056
+ ' in div (at **)\n' +
1057
+ ' in App (at **)' ,
1058
+ ) ;
1059
+
1060
+ expect ( container . firstChild . firstChild . tagName ) . toBe ( 'DIV' ) ;
1061
+ expect ( container . firstChild . firstChild . textContent ) . toBe (
1062
+ 'First client text' ,
1063
+ ) ;
1064
+
1065
+ // Resolving the promise should continue hydration
1066
+ suspend = false ;
1067
+ resolve ( ) ;
1068
+ await promise ;
1069
+ Scheduler . flushAll ( ) ;
1070
+ jest . runAllTimers ( ) ;
1071
+
1072
+ let span = container . getElementsByTagName ( 'span' ) [ 0 ] ;
1073
+ expect ( span . textContent ) . toBe ( 'Second client text' ) ;
1074
+ expect ( container . textContent ) . toBe ( 'First client textSecond client text' ) ;
1075
+ } ) ;
1006
1076
} ) ;
0 commit comments