/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core */ 'use strict'; const React = require('react'); const ReactDOM = require('react-dom'); const ReactTestUtils = require('react-dom/test-utils'); // Helpers const testAllPermutations = function(testCases) { for (let i = 0; i < testCases.length; i += 2) { const renderWithChildren = testCases[i]; const expectedResultAfterRender = testCases[i + 1]; for (let j = 0; j < testCases.length; j += 2) { const updateWithChildren = testCases[j]; const expectedResultAfterUpdate = testCases[j + 1]; const container = document.createElement('div'); ReactDOM.render(
{renderWithChildren}
, container); expectChildren(container, expectedResultAfterRender); ReactDOM.render(
{updateWithChildren}
, container); expectChildren(container, expectedResultAfterUpdate); } } }; const expectChildren = function(container, children) { const outerNode = container.firstChild; let textNode; if (typeof children === 'string') { textNode = outerNode.firstChild; if (children === '') { expect(textNode != null).toBe(false); } else { expect(textNode != null).toBe(true); expect(textNode.nodeType).toBe(3); expect(textNode.data).toBe('' + children); } } else { let mountIndex = 0; for (let i = 0; i < children.length; i++) { const child = children[i]; if (typeof child === 'string') { textNode = outerNode.childNodes[mountIndex]; expect(textNode.nodeType).toBe(3); expect(textNode.data).toBe('' + child); mountIndex++; } else { const elementDOMNode = outerNode.childNodes[mountIndex]; expect(elementDOMNode.tagName).toBe('DIV'); mountIndex++; } } } }; /** * ReactMultiChild DOM integration test. In ReactDOM components, we make sure * that single children that are strings are treated as "content" which is much * faster to render and update. */ describe('ReactMultiChildText', () => { it('should correctly handle all possible children for render and update', () => { expect(() => { // prettier-ignore testAllPermutations([ // basic values undefined, [], null, [], false, [], true, [], 0, '0', 1.2, '1.2', '', '', 'foo', 'foo', [], [], [undefined], [], [null], [], [false], [], [true], [], [0], ['0'], [1.2], ['1.2'], [''], [''], ['foo'], ['foo'], [
], [
], // two adjacent values [true, 0], ['0'], [0, 0], ['0', '0'], [1.2, 0], ['1.2', '0'], [0, ''], ['0', ''], ['foo', 0], ['foo', '0'], [0,
], ['0',
], [true, 1.2], ['1.2'], [1.2, 0], ['1.2', '0'], [1.2, 1.2], ['1.2', '1.2'], [1.2, ''], ['1.2', ''], ['foo', 1.2], ['foo', '1.2'], [1.2,
], ['1.2',
], [true, ''], [''], ['', 0], ['', '0'], [1.2, ''], ['1.2', ''], ['', ''], ['', ''], ['foo', ''], ['foo', ''], ['',
], ['',
], [true, 'foo'], ['foo'], ['foo', 0], ['foo', '0'], [1.2, 'foo'], ['1.2', 'foo'], ['foo', ''], ['foo', ''], ['foo', 'foo'], ['foo', 'foo'], ['foo',
], ['foo',
], // values separated by an element [true,
, true], [
], [1.2,
, 1.2], ['1.2',
, '1.2'], ['',
, ''], ['',
, ''], ['foo',
, 'foo'], ['foo',
, 'foo'], [true, 1.2,
, '', 'foo'], ['1.2',
, '', 'foo'], [1.2, '',
, 'foo', true], ['1.2', '',
, 'foo'], ['', 'foo',
, true, 1.2], ['', 'foo',
, '1.2'], [true, 1.2, '',
, 'foo', true, 1.2], ['1.2', '',
, 'foo', '1.2'], ['', 'foo', true,
, 1.2, '', 'foo'], ['', 'foo',
, '1.2', '', 'foo'], // values inside arrays [[true], [true]], [], [[1.2], [1.2]], ['1.2', '1.2'], [[''], ['']], ['', ''], [['foo'], ['foo']], ['foo', 'foo'], [[
], [
]], [
,
], [[true, 1.2,
], '', 'foo'], ['1.2',
, '', 'foo'], [1.2, '', [
, 'foo', true]], ['1.2', '',
, 'foo'], ['', ['foo',
, true], 1.2], ['', 'foo',
, '1.2'], [true, [1.2, '',
, 'foo'], true, 1.2], ['1.2', '',
, 'foo', '1.2'], ['', 'foo', [true,
, 1.2, ''], 'foo'], ['', 'foo',
, '1.2', '', 'foo'], // values inside elements [
{true}{1.2}{
}
, '', 'foo'], [
, '', 'foo'], [1.2, '',
{
}{'foo'}{true}
], ['1.2', '',
], ['',
{'foo'}{
}{true}
, 1.2], ['',
, '1.2'], [true,
{1.2}{''}{
}{'foo'}
, true, 1.2], [
, '1.2'], ['', 'foo',
{true}{
}{1.2}{''}
, 'foo'], ['', 'foo',
, 'foo'], ]); }).toErrorDev([ 'Warning: Each child in a list should have a unique "key" prop.', 'Warning: Each child in a list should have a unique "key" prop.', ]); }); it('should throw if rendering both HTML and children', () => { expect(function() { ReactTestUtils.renderIntoDocument(
ghjkl
, ); }).toThrow(); }); it('should render between nested components and inline children', () => { ReactTestUtils.renderIntoDocument(

, ); expect(function() { ReactTestUtils.renderIntoDocument(

A

, ); }).not.toThrow(); expect(function() { ReactTestUtils.renderIntoDocument(

{['A']}

, ); }).not.toThrow(); expect(function() { ReactTestUtils.renderIntoDocument(

{['A', 'B']}

, ); }).not.toThrow(); }); });