Files
react/packages/react-dom/src/__tests__/validateDOMNesting-test.js
T
Dan Abramov d289d4b634 Update to Jest 22 (#11956)
* Bump deps to Jest 22

* Prevent jsdom from logging intentionally thrown errors

This relies on our existing special field that we use to mute errors.
Perhaps, it would be better to instead rely on preventDefault() directly.
I outlined a possible strategy here: https://github.com/facebook/react/issues/11098#issuecomment-355032539

* Update snapshots

* Mock out a method called by ReactART that now throws

* Calling .click() no longer works, dispatch event instead

* Fix incorrect SVG element creation in test

* Render SVG elements inside <svg> to avoid extra warnings

* Fix range input test to use numeric value

* Fix creating SVG element in test

* Replace brittle test that relied on jsdom behavior

The test passed in jsdom due to its implementation details.

The original intention was to test the mutation method, but it was removed a while ago.

Following @nhunzaker's suggestion, I moved the tests to ReactDOMInput and adjusted them to not rely on implementation details.

* Add a workaround for the expected extra client-side warning

This is a bit ugly but it's just two places. I think we can live with this.

* Only warn once for mismatches caused by bad attribute casing

We used to warn both about bad casing and about a mismatch.
The mismatch warning was a bit confusing. We didn't know we warned twice because jsdom didn't faithfully emulate SVG.

This changes the behavior to only leave the warning about bad casing if that's what caused the mismatch.
It also adjusts the test to have an expectation that matches the real world behavior.

* Add an expected warning per comment in the same test
2018-01-04 18:57:30 +00:00

120 lines
3.4 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* 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');
function expectWarnings(tags, warnings = []) {
tags = [...tags];
warnings = [...warnings];
let element = null;
const containerTag = tags.shift();
const container =
containerTag === 'svg'
? document.createElementNS('http://www.w3.org/2000/svg', containerTag)
: document.createElement(containerTag);
while (tags.length) {
const Tag = tags.pop();
element = <Tag>{element}</Tag>;
}
expect(() => ReactDOM.render(element, container)).toWarnDev(warnings);
}
describe('validateDOMNesting', () => {
it('allows valid nestings', () => {
expectWarnings(['table', 'tbody', 'tr', 'td', 'b']);
expectWarnings(
['body', 'datalist', 'option'],
[
'render(): Rendering components directly into document.body is discouraged',
],
);
expectWarnings(['div', 'a', 'object', 'a']);
expectWarnings(['div', 'p', 'button', 'p']);
expectWarnings(['p', 'svg', 'foreignObject', 'p']);
expectWarnings(['html', 'body', 'div']);
// Invalid, but not changed by browser parsing so we allow them
expectWarnings(['div', 'ul', 'ul', 'li']);
expectWarnings(['div', 'label', 'div']);
expectWarnings(['div', 'ul', 'li', 'section', 'li']);
expectWarnings(['div', 'ul', 'li', 'dd', 'li']);
});
it('prevents problematic nestings', () => {
expectWarnings(
['a', 'a'],
[
'validateDOMNesting(...): <a> cannot appear as a descendant of <a>.\n' +
' in a (at **)',
],
);
expectWarnings(
['form', 'form'],
[
'validateDOMNesting(...): <form> cannot appear as a descendant of <form>.\n' +
' in form (at **)',
],
);
expectWarnings(
['p', 'p'],
[
'validateDOMNesting(...): <p> cannot appear as a descendant of <p>.\n' +
' in p (at **)',
],
);
expectWarnings(
['table', 'tr'],
[
'validateDOMNesting(...): <tr> cannot appear as a child of <table>. ' +
'Add a <tbody> to your code to match the DOM tree generated by the browser.\n' +
' in tr (at **)',
],
);
expectWarnings(
['div', 'ul', 'li', 'div', 'li'],
[
'validateDOMNesting(...): <li> cannot appear as a descendant of <li>.\n' +
' in li (at **)\n' +
' in div (at **)\n' +
' in li (at **)\n' +
' in ul (at **)',
],
);
expectWarnings(
['div', 'html'],
[
'validateDOMNesting(...): <html> cannot appear as a child of <div>.\n' +
' in html (at **)',
],
);
expectWarnings(
['body', 'body'],
[
'render(): Rendering components directly into document.body is discouraged',
'validateDOMNesting(...): <body> cannot appear as a child of <body>.\n' +
' in body (at **)',
],
);
expectWarnings(
['svg', 'foreignObject', 'body', 'p'],
[
'validateDOMNesting(...): <body> cannot appear as a child of <foreignObject>.\n' +
' in body (at **)\n' +
' in foreignObject (at **)',
],
);
});
});