@@ -164,5 +164,185 @@ describe('ReactScope', () => {
164164 const aChildren = refA . current . getChildren ( ) ;
165165 expect ( aChildren ) . toEqual ( [ refC . current ] ) ;
166166 } ) ;
167+
168+ it ( 'scopes support server-side rendering and hydration' , ( ) => {
169+ const TestScope = React . unstable_createScope ( ( type , props ) => true ) ;
170+ const ReactDOMServer = require ( 'react-dom/server' ) ;
171+ const scopeRef = React . createRef ( ) ;
172+ const divRef = React . createRef ( ) ;
173+ const spanRef = React . createRef ( ) ;
174+ const aRef = React . createRef ( ) ;
175+
176+ function Test ( { toggle} ) {
177+ return (
178+ < div >
179+ < TestScope ref = { scopeRef } >
180+ < div ref = { divRef } > DIV</ div >
181+ < span ref = { spanRef } > SPAN</ span >
182+ < a ref = { aRef } > A</ a >
183+ </ TestScope >
184+ < div > Outside content!</ div >
185+ </ div >
186+ ) ;
187+ }
188+ const html = ReactDOMServer . renderToString ( < Test /> ) ;
189+ expect ( html ) . toBe (
190+ '<div data-reactroot=""><div>DIV</div><span>SPAN</span><a>A</a><div>Outside content!</div></div>' ,
191+ ) ;
192+ container . innerHTML = html ;
193+ ReactDOM . hydrate ( < Test /> , container ) ;
194+ const nodes = scopeRef . current . getScopedNodes ( ) ;
195+ expect ( nodes ) . toEqual ( [ divRef . current , spanRef . current , aRef . current ] ) ;
196+ } ) ;
197+ } ) ;
198+
199+ describe ( 'ReactTestRenderer' , ( ) => {
200+ let ReactTestRenderer ;
201+
202+ beforeEach ( ( ) => {
203+ ReactTestRenderer = require ( 'react-test-renderer' ) ;
204+ } ) ;
205+
206+ it ( 'getScopedNodes() works as intended' , ( ) => {
207+ const TestScope = React . unstable_createScope ( ( type , props ) => true ) ;
208+ const scopeRef = React . createRef ( ) ;
209+ const divRef = React . createRef ( ) ;
210+ const spanRef = React . createRef ( ) ;
211+ const aRef = React . createRef ( ) ;
212+
213+ function Test ( { toggle} ) {
214+ return toggle ? (
215+ < TestScope ref = { scopeRef } >
216+ < div ref = { divRef } > DIV</ div >
217+ < span ref = { spanRef } > SPAN</ span >
218+ < a ref = { aRef } > A</ a >
219+ </ TestScope >
220+ ) : (
221+ < TestScope ref = { scopeRef } >
222+ < a ref = { aRef } > A</ a >
223+ < div ref = { divRef } > DIV</ div >
224+ < span ref = { spanRef } > SPAN</ span >
225+ </ TestScope >
226+ ) ;
227+ }
228+
229+ const renderer = ReactTestRenderer . create ( < Test toggle = { true } /> , {
230+ createNodeMock : element => {
231+ return element ;
232+ } ,
233+ } ) ;
234+ let nodes = scopeRef . current . getScopedNodes ( ) ;
235+ expect ( nodes ) . toEqual ( [ divRef . current , spanRef . current , aRef . current ] ) ;
236+ renderer . update ( < Test toggle = { false } /> ) ;
237+ nodes = scopeRef . current . getScopedNodes ( ) ;
238+ expect ( nodes ) . toEqual ( [ aRef . current , divRef . current , spanRef . current ] ) ;
239+ } ) ;
240+
241+ it ( 'mixed getParent() and getScopedNodes() works as intended' , ( ) => {
242+ const TestScope = React . unstable_createScope ( ( type , props ) => true ) ;
243+ const TestScope2 = React . unstable_createScope ( ( type , props ) => true ) ;
244+ const refA = React . createRef ( ) ;
245+ const refB = React . createRef ( ) ;
246+ const refC = React . createRef ( ) ;
247+ const refD = React . createRef ( ) ;
248+ const spanA = React . createRef ( ) ;
249+ const spanB = React . createRef ( ) ;
250+ const divA = React . createRef ( ) ;
251+ const divB = React . createRef ( ) ;
252+
253+ function Test ( ) {
254+ return (
255+ < div >
256+ < TestScope ref = { refA } >
257+ < span ref = { spanA } >
258+ < TestScope2 ref = { refB } >
259+ < div ref = { divA } >
260+ < TestScope ref = { refC } >
261+ < span ref = { spanB } >
262+ < TestScope2 ref = { refD } >
263+ < div ref = { divB } > > Hello world </ div >
264+ </ TestScope2 >
265+ </ span >
266+ </ TestScope >
267+ </ div >
268+ </ TestScope2 >
269+ </ span >
270+ </ TestScope >
271+ </ div >
272+ ) ;
273+ }
274+
275+ ReactTestRenderer . create ( < Test /> , {
276+ createNodeMock : element => {
277+ return element ;
278+ } ,
279+ } ) ;
280+ const dParent = refD . current . getParent ( ) ;
281+ expect ( dParent ) . not . toBe ( null ) ;
282+ expect ( dParent . getScopedNodes ( ) ) . toEqual ( [
283+ divA . current ,
284+ spanB . current ,
285+ divB . current ,
286+ ] ) ;
287+ const cParent = refC . current . getParent ( ) ;
288+ expect ( cParent ) . not . toBe ( null ) ;
289+ expect ( cParent . getScopedNodes ( ) ) . toEqual ( [
290+ spanA . current ,
291+ divA . current ,
292+ spanB . current ,
293+ divB . current ,
294+ ] ) ;
295+ expect ( refB . current . getParent ( ) ) . toBe ( null ) ;
296+ expect ( refA . current . getParent ( ) ) . toBe ( null ) ;
297+ } ) ;
298+
299+ it ( 'getChildren() works as intended' , ( ) => {
300+ const TestScope = React . unstable_createScope ( ( type , props ) => true ) ;
301+ const TestScope2 = React . unstable_createScope ( ( type , props ) => true ) ;
302+ const refA = React . createRef ( ) ;
303+ const refB = React . createRef ( ) ;
304+ const refC = React . createRef ( ) ;
305+ const refD = React . createRef ( ) ;
306+ const spanA = React . createRef ( ) ;
307+ const spanB = React . createRef ( ) ;
308+ const divA = React . createRef ( ) ;
309+ const divB = React . createRef ( ) ;
310+
311+ function Test ( ) {
312+ return (
313+ < div >
314+ < TestScope ref = { refA } >
315+ < span ref = { spanA } >
316+ < TestScope2 ref = { refB } >
317+ < div ref = { divA } >
318+ < TestScope ref = { refC } >
319+ < span ref = { spanB } >
320+ < TestScope2 ref = { refD } >
321+ < div ref = { divB } > > Hello world </ div >
322+ </ TestScope2 >
323+ </ span >
324+ </ TestScope >
325+ </ div >
326+ </ TestScope2 >
327+ </ span >
328+ </ TestScope >
329+ </ div >
330+ ) ;
331+ }
332+
333+ ReactTestRenderer . create ( < Test /> , {
334+ createNodeMock : element => {
335+ return element ;
336+ } ,
337+ } ) ;
338+ const dChildren = refD . current . getChildren ( ) ;
339+ expect ( dChildren ) . toBe ( null ) ;
340+ const cChildren = refC . current . getChildren ( ) ;
341+ expect ( cChildren ) . toBe ( null ) ;
342+ const bChildren = refB . current . getChildren ( ) ;
343+ expect ( bChildren ) . toEqual ( [ refD . current ] ) ;
344+ const aChildren = refA . current . getChildren ( ) ;
345+ expect ( aChildren ) . toEqual ( [ refC . current ] ) ;
346+ } ) ;
167347 } ) ;
168348} ) ;
0 commit comments