Rewrite setInnerHTML tests to use Public API. (#11385)

* Rewrite setInnerHTML tests to use Public API.

* Rename variables and drop unnecessary variable assignments.

* Rename testfile to dangerouslySetInnerHTML-test.js

* Properly prettify test file.

* Rewrite SVG tests to verify we recover from missing innerHTML
This commit is contained in:
Jonathan Silvestri
2017-11-04 18:04:13 +00:00
committed by Dan Abramov
parent 51c101fc48
commit 366600d0b2
2 changed files with 94 additions and 68 deletions
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2016-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');
describe('dangerouslySetInnerHTML', () => {
describe('when the node has innerHTML property', () => {
it('sets innerHTML on it', () => {
const container = document.createElement('div');
const node = ReactDOM.render(
<div dangerouslySetInnerHTML={{__html: '<h1>Hello</h1>'}} />,
container,
);
expect(node.innerHTML).toBe('<h1>Hello</h1>');
});
});
describe('when the node does not have an innerHTML property', () => {
let innerHTMLDescriptor;
// In some versions of IE (TODO: which ones?) SVG nodes don't have
// innerHTML. To simulate this, we will take it off the Element prototype
// and put it onto the HTMLDivElement prototype. We expect that the logic
// checks for existence of innerHTML on SVG, and if one doesn't exist, falls
// back to using appendChild and removeChild.
beforeEach(() => {
innerHTMLDescriptor = Object.getOwnPropertyDescriptor(
Element.prototype,
'innerHTML',
);
delete Element.prototype.innerHTML;
Object.defineProperty(
HTMLDivElement.prototype,
'innerHTML',
innerHTMLDescriptor,
);
});
afterEach(() => {
delete HTMLDivElement.prototype.innerHTML;
Object.defineProperty(
Element.prototype,
'innerHTML',
innerHTMLDescriptor,
);
});
it('sets innerHTML on it', () => {
const html = '<circle></circle>';
const container = document.createElementNS(
'http://www.w3.org/2000/svg',
'svg',
);
ReactDOM.render(
<g dangerouslySetInnerHTML={{__html: html}} />,
container,
);
const circle = container.firstChild.firstChild;
expect(circle.tagName).toBe('circle');
});
it('clears previous children', () => {
const firstHtml = '<rect></rect>';
const secondHtml = '<circle></circle>';
const container = document.createElementNS(
'http://www.w3.org/2000/svg',
'svg',
);
ReactDOM.render(
<g dangerouslySetInnerHTML={{__html: firstHtml}} />,
container,
);
const rect = container.firstChild.firstChild;
expect(rect.tagName).toBe('rect');
ReactDOM.render(
<g dangerouslySetInnerHTML={{__html: secondHtml}} />,
container,
);
const circle = container.firstChild.firstChild;
expect(circle.tagName).toBe('circle');
});
});
});
@@ -1,68 +0,0 @@
/**
* Copyright (c) 2016-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';
// TODO: can we express this test with only public API?
var setInnerHTML = require('../setInnerHTML').default;
var Namespaces = require('../../shared/DOMNamespaces').Namespaces;
describe('setInnerHTML', () => {
describe('when the node has innerHTML property', () => {
it('sets innerHTML on it', () => {
var node = document.createElement('div');
var html = '<h1>hello</h1>';
setInnerHTML(node, html);
expect(node.innerHTML).toBe(html);
});
});
describe('when the node does not have an innerHTML property', () => {
var node;
var nodeProxy;
beforeEach(() => {
// Create a mock node that looks like an SVG in IE (without innerHTML)
node = document.createElementNS(Namespaces.svg, 'svg');
nodeProxy = new Proxy(node, {
has: (target, prop) => {
return prop === 'innerHTML' ? false : prop in target;
},
});
spyOn(node, 'appendChild').and.callThrough();
spyOn(node, 'removeChild').and.callThrough();
});
it('sets innerHTML on it', () => {
var html = '<circle></circle><rect></rect>';
setInnerHTML(nodeProxy, html);
expect(node.appendChild.calls.argsFor(0)[0].outerHTML).toBe(
'<circle></circle>',
);
expect(node.appendChild.calls.argsFor(1)[0].outerHTML).toBe(
'<rect></rect>',
);
});
it('clears previous children', () => {
var firstHtml = '<rect></rect>';
var secondHtml = '<circle></circle>';
setInnerHTML(nodeProxy, firstHtml);
setInnerHTML(nodeProxy, secondHtml);
expect(node.removeChild.calls.argsFor(0)[0].outerHTML).toBe(
'<rect></rect>',
);
expect(node.innerHTML).toBe('<circle></circle>');
});
});
});