diff --git a/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js
new file mode 100644
index 0000000000000..519507c8ef191
--- /dev/null
+++ b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js
@@ -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(
+
Hello'}} />,
+ container,
+ );
+ expect(node.innerHTML).toBe('
Hello
');
+ });
+ });
+
+ 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 = '';
+ const container = document.createElementNS(
+ 'http://www.w3.org/2000/svg',
+ 'svg',
+ );
+ ReactDOM.render(
+ ,
+ container,
+ );
+ const circle = container.firstChild.firstChild;
+ expect(circle.tagName).toBe('circle');
+ });
+
+ it('clears previous children', () => {
+ const firstHtml = '';
+ const secondHtml = '';
+
+ const container = document.createElementNS(
+ 'http://www.w3.org/2000/svg',
+ 'svg',
+ );
+ ReactDOM.render(
+ ,
+ container,
+ );
+ const rect = container.firstChild.firstChild;
+ expect(rect.tagName).toBe('rect');
+ ReactDOM.render(
+ ,
+ container,
+ );
+ const circle = container.firstChild.firstChild;
+ expect(circle.tagName).toBe('circle');
+ });
+ });
+});
diff --git a/packages/react-dom/src/client/__tests__/setInnerHTML-test.js b/packages/react-dom/src/client/__tests__/setInnerHTML-test.js
deleted file mode 100644
index 13133a58f1108..0000000000000
--- a/packages/react-dom/src/client/__tests__/setInnerHTML-test.js
+++ /dev/null
@@ -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 = 'hello
';
- 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 = '';
- setInnerHTML(nodeProxy, html);
-
- expect(node.appendChild.calls.argsFor(0)[0].outerHTML).toBe(
- '',
- );
- expect(node.appendChild.calls.argsFor(1)[0].outerHTML).toBe(
- '',
- );
- });
-
- it('clears previous children', () => {
- var firstHtml = '';
- var secondHtml = '';
- setInnerHTML(nodeProxy, firstHtml);
-
- setInnerHTML(nodeProxy, secondHtml);
-
- expect(node.removeChild.calls.argsFor(0)[0].outerHTML).toBe(
- '',
- );
- expect(node.innerHTML).toBe('');
- });
- });
-});