mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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:
committed by
Dan Abramov
parent
51c101fc48
commit
366600d0b2
@@ -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>');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user