1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  * @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
    
  9.  */
    
  10. 
    
  11. 'use strict';
    
  12. 
    
  13. const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
    
  14. 
    
  15. const TEXT_NODE_TYPE = 3;
    
  16. 
    
  17. let React;
    
  18. let ReactDOM;
    
  19. let ReactDOMServer;
    
  20. let ReactTestUtils;
    
  21. 
    
  22. function initModules() {
    
  23.   // Reset warning cache.
    
  24.   jest.resetModules();
    
  25.   React = require('react');
    
  26.   ReactDOM = require('react-dom');
    
  27.   ReactDOMServer = require('react-dom/server');
    
  28.   ReactTestUtils = require('react-dom/test-utils');
    
  29. 
    
  30.   // Make them available to the helpers.
    
  31.   return {
    
  32.     ReactDOM,
    
  33.     ReactDOMServer,
    
  34.     ReactTestUtils,
    
  35.   };
    
  36. }
    
  37. 
    
  38. const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules);
    
  39. 
    
  40. describe('ReactDOMServerIntegration', () => {
    
  41.   beforeEach(() => {
    
  42.     resetModules();
    
  43.   });
    
  44. 
    
  45.   describe('basic rendering', function () {
    
  46.     itRenders('a blank div', async render => {
    
  47.       const e = await render(<div />);
    
  48.       expect(e.tagName).toBe('DIV');
    
  49.     });
    
  50. 
    
  51.     itRenders('a self-closing tag', async render => {
    
  52.       const e = await render(<br />);
    
  53.       expect(e.tagName).toBe('BR');
    
  54.     });
    
  55. 
    
  56.     itRenders('a self-closing tag as a child', async render => {
    
  57.       const e = await render(
    
  58.         <div>
    
  59.           <br />
    
  60.         </div>,
    
  61.       );
    
  62.       expect(e.childNodes.length).toBe(1);
    
  63.       expect(e.firstChild.tagName).toBe('BR');
    
  64.     });
    
  65. 
    
  66.     itRenders('a string', async render => {
    
  67.       const e = await render('Hello');
    
  68.       expect(e.nodeType).toBe(3);
    
  69.       expect(e.nodeValue).toMatch('Hello');
    
  70.     });
    
  71. 
    
  72.     itRenders('a number', async render => {
    
  73.       const e = await render(42);
    
  74.       expect(e.nodeType).toBe(3);
    
  75.       expect(e.nodeValue).toMatch('42');
    
  76.     });
    
  77. 
    
  78.     itRenders('an array with one child', async render => {
    
  79.       const e = await render([<div key={1}>text1</div>]);
    
  80.       const parent = e.parentNode;
    
  81.       expect(parent.childNodes[0].tagName).toBe('DIV');
    
  82.     });
    
  83. 
    
  84.     itRenders('an array with several children', async render => {
    
  85.       const Header = props => {
    
  86.         return <p>header</p>;
    
  87.       };
    
  88.       const Footer = props => {
    
  89.         return [<h2 key={1}>footer</h2>, <h3 key={2}>about</h3>];
    
  90.       };
    
  91.       const e = await render([
    
  92.         <div key={1}>text1</div>,
    
  93.         <span key={2}>text2</span>,
    
  94.         <Header key={3} />,
    
  95.         <Footer key={4} />,
    
  96.       ]);
    
  97.       const parent = e.parentNode;
    
  98.       expect(parent.childNodes[0].tagName).toBe('DIV');
    
  99.       expect(parent.childNodes[1].tagName).toBe('SPAN');
    
  100.       expect(parent.childNodes[2].tagName).toBe('P');
    
  101.       expect(parent.childNodes[3].tagName).toBe('H2');
    
  102.       expect(parent.childNodes[4].tagName).toBe('H3');
    
  103.     });
    
  104. 
    
  105.     itRenders('a nested array', async render => {
    
  106.       const e = await render([
    
  107.         [<div key={1}>text1</div>],
    
  108.         <span key={1}>text2</span>,
    
  109.         [[[null, <p key={1} />], false]],
    
  110.       ]);
    
  111.       const parent = e.parentNode;
    
  112.       expect(parent.childNodes[0].tagName).toBe('DIV');
    
  113.       expect(parent.childNodes[1].tagName).toBe('SPAN');
    
  114.       expect(parent.childNodes[2].tagName).toBe('P');
    
  115.     });
    
  116. 
    
  117.     itRenders('an iterable', async render => {
    
  118.       const threeDivIterable = {
    
  119.         '@@iterator': function () {
    
  120.           let i = 0;
    
  121.           return {
    
  122.             next: function () {
    
  123.               if (i++ < 3) {
    
  124.                 return {value: <div key={i} />, done: false};
    
  125.               } else {
    
  126.                 return {value: undefined, done: true};
    
  127.               }
    
  128.             },
    
  129.           };
    
  130.         },
    
  131.       };
    
  132.       const e = await render(threeDivIterable);
    
  133.       const parent = e.parentNode;
    
  134.       expect(parent.childNodes.length).toBe(3);
    
  135.       expect(parent.childNodes[0].tagName).toBe('DIV');
    
  136.       expect(parent.childNodes[1].tagName).toBe('DIV');
    
  137.       expect(parent.childNodes[2].tagName).toBe('DIV');
    
  138.     });
    
  139. 
    
  140.     itRenders('emptyish values', async render => {
    
  141.       const e = await render(0);
    
  142.       expect(e.nodeType).toBe(TEXT_NODE_TYPE);
    
  143.       expect(e.nodeValue).toMatch('0');
    
  144. 
    
  145.       // Empty string is special because client renders a node
    
  146.       // but server returns empty HTML. So we compare parent text.
    
  147.       expect((await render(<div>{''}</div>)).textContent).toBe('');
    
  148. 
    
  149.       expect(await render([])).toBe(null);
    
  150.       expect(await render(false)).toBe(null);
    
  151.       expect(await render(true)).toBe(null);
    
  152.       expect(await render(undefined)).toBe(null);
    
  153.       expect(await render([[[false]], undefined])).toBe(null);
    
  154.     });
    
  155.   });
    
  156. });