diff --git a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
index ed685741e6..203cfcc02d 100644
--- a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
+++ b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
@@ -17,6 +17,7 @@ describe('ReactComponentTreeDevtool', () => {
var ReactDOMServer;
var ReactInstanceMap;
var ReactComponentTreeDevtool;
+ var ReactComponentTreeTestUtils;
beforeEach(() => {
jest.resetModuleRegistry();
@@ -26,54 +27,10 @@ describe('ReactComponentTreeDevtool', () => {
ReactDOMServer = require('ReactDOMServer');
ReactInstanceMap = require('ReactInstanceMap');
ReactComponentTreeDevtool = require('ReactComponentTreeDevtool');
+ ReactComponentTreeTestUtils = require('ReactComponentTreeTestUtils');
});
- function getRootDisplayNames() {
- return ReactComponentTreeDevtool.getRootIDs()
- .map(ReactComponentTreeDevtool.getDisplayName);
- }
-
- function getRegisteredDisplayNames() {
- return ReactComponentTreeDevtool.getRegisteredIDs()
- .map(ReactComponentTreeDevtool.getDisplayName);
- }
-
- function getTree(rootID, options = {}) {
- var {
- includeOwnerDisplayName = false,
- includeParentDisplayName = false,
- expectedParentID = null,
- } = options;
-
- var result = {
- displayName: ReactComponentTreeDevtool.getDisplayName(rootID),
- };
-
- var ownerID = ReactComponentTreeDevtool.getOwnerID(rootID);
- var parentID = ReactComponentTreeDevtool.getParentID(rootID);
- expect(parentID).toBe(expectedParentID);
-
- if (includeParentDisplayName && parentID) {
- result.parentDisplayName = ReactComponentTreeDevtool.getDisplayName(parentID);
- }
- if (includeOwnerDisplayName && ownerID) {
- result.ownerDisplayName = ReactComponentTreeDevtool.getDisplayName(ownerID);
- }
-
- var childIDs = ReactComponentTreeDevtool.getChildIDs(rootID);
- var text = ReactComponentTreeDevtool.getText(rootID);
- if (text != null) {
- result.text = text;
- } else {
- result.children = childIDs.map(childID =>
- getTree(childID, {...options, expectedParentID: rootID })
- );
- }
-
- return result;
- }
-
- function assertTreeMatches(pairs, options) {
+ function assertTreeMatches(pairs) {
if (!Array.isArray(pairs[0])) {
pairs = [pairs];
}
@@ -89,8 +46,15 @@ describe('ReactComponentTreeDevtool', () => {
}
}
- function getActualTree() {
- return getTree(rootInstance._debugID, options).children[0];
+ function expectWrapperTreeToEqual(expectedTree) {
+ ReactComponentTreeTestUtils.expectTree(rootInstance._debugID, {
+ displayName: 'Wrapper',
+ children: expectedTree ? [expectedTree] : [],
+ });
+ if (!expectedTree) {
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual([]);
+ }
}
// Mount once, render updates, then unmount.
@@ -100,20 +64,18 @@ describe('ReactComponentTreeDevtool', () => {
// Mount a new tree or update the existing tree.
ReactDOM.render(, node);
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
// Purging should have no effect
// on the tree we expect to see.
ReactComponentTreeDevtool.purgeUnmountedComponents();
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
});
// Unmounting the root node should purge
// the whole subtree automatically.
ReactDOM.unmountComponentAtNode(node);
- expect(getActualTree()).toBe(undefined);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expectWrapperTreeToEqual(null);
// Server render every pair.
// Ensure the tree is correct on every step.
@@ -123,9 +85,7 @@ describe('ReactComponentTreeDevtool', () => {
// Rendering to string should not produce any entries
// because ReactDebugTool purges it when the flush ends.
ReactDOMServer.renderToString();
- expect(getActualTree()).toBe(undefined);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expectWrapperTreeToEqual(null);
// To test it, we tell the devtool to ignore next purge
// so the cleanup request by ReactDebugTool is ignored.
@@ -133,13 +93,11 @@ describe('ReactComponentTreeDevtool', () => {
ReactComponentTreeDevtool._preventPurging = true;
ReactDOMServer.renderToString();
ReactComponentTreeDevtool._preventPurging = false;
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
// Purge manually since we skipped the automatic purge.
ReactComponentTreeDevtool.purgeUnmountedComponents();
- expect(getActualTree()).toBe(undefined);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expectWrapperTreeToEqual(null);
});
}
@@ -1650,7 +1608,7 @@ describe('ReactComponentTreeDevtool', () => {
}],
}],
};
- assertTreeMatches([element, tree], {includeOwnerDisplayName: true});
+ assertTreeMatches([element, tree]);
});
it('purges unmounted components automatically', () => {
@@ -1674,33 +1632,28 @@ describe('ReactComponentTreeDevtool', () => {
}
ReactDOM.render(, node);
- expect(
- getTree(barInstance._debugID, {
- includeParentDisplayName: true,
- expectedParentID: fooInstance._debugID,
- })
- ).toEqual({
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Bar',
parentDisplayName: 'Foo',
+ parentID: fooInstance._debugID,
children: [],
- });
+ }, 'Foo');
renderBar = false;
ReactDOM.render(, node);
- expect(
- getTree(barInstance._debugID, {expectedParentID: null})
- ).toEqual({
+ ReactDOM.render(, node);
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Unknown',
children: [],
- });
+ parentID: null,
+ }, 'Foo');
ReactDOM.unmountComponentAtNode(node);
- expect(
- getTree(barInstance._debugID, {expectedParentID: null})
- ).toEqual({
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Unknown',
children: [],
- });
+ parentID: null,
+ }, 'Foo');
});
it('reports update counts', () => {
@@ -1732,14 +1685,14 @@ describe('ReactComponentTreeDevtool', () => {
var node = document.createElement('div');
ReactDOM.render(
, node);
- expect(getRootDisplayNames()).toEqual(['div']);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual(['div']);
ReactDOM.render(, node);
- expect(getRootDisplayNames()).toEqual(['div']);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual(['div']);
ReactDOM.unmountComponentAtNode(node);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual([]);
});
it('creates stack addenda', () => {
diff --git a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js
index 6841cbd0c6..b65e4dab80 100644
--- a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js
+++ b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js
@@ -16,6 +16,7 @@ describe('ReactComponentTreeDevtool', () => {
var ReactNative;
var ReactInstanceMap;
var ReactComponentTreeDevtool;
+ var ReactComponentTreeTestUtils;
var createReactNativeComponentClass;
var View;
var Image;
@@ -28,6 +29,7 @@ describe('ReactComponentTreeDevtool', () => {
ReactNative = require('ReactNative');
ReactInstanceMap = require('ReactInstanceMap');
ReactComponentTreeDevtool = require('ReactComponentTreeDevtool');
+ ReactComponentTreeTestUtils = require('ReactComponentTreeTestUtils');
View = require('View');
createReactNativeComponentClass = require('createReactNativeComponentClass');
Image = createReactNativeComponentClass({
@@ -51,51 +53,6 @@ describe('ReactComponentTreeDevtool', () => {
});
});
- function getRootDisplayNames() {
- return ReactComponentTreeDevtool.getRootIDs()
- .map(ReactComponentTreeDevtool.getDisplayName);
- }
-
- function getRegisteredDisplayNames() {
- return ReactComponentTreeDevtool.getRegisteredIDs()
- .map(ReactComponentTreeDevtool.getDisplayName);
- }
-
- function getTree(rootID, options = {}) {
- var {
- includeOwnerDisplayName = false,
- includeParentDisplayName = false,
- expectedParentID = null,
- } = options;
-
- var result = {
- displayName: ReactComponentTreeDevtool.getDisplayName(rootID),
- };
-
- var ownerID = ReactComponentTreeDevtool.getOwnerID(rootID);
- var parentID = ReactComponentTreeDevtool.getParentID(rootID);
- expect(parentID).toBe(expectedParentID);
-
- if (includeParentDisplayName && parentID) {
- result.parentDisplayName = ReactComponentTreeDevtool.getDisplayName(parentID);
- }
- if (includeOwnerDisplayName && ownerID) {
- result.ownerDisplayName = ReactComponentTreeDevtool.getDisplayName(ownerID);
- }
-
- var childIDs = ReactComponentTreeDevtool.getChildIDs(rootID);
- var text = ReactComponentTreeDevtool.getText(rootID);
- if (text != null) {
- result.text = text;
- } else {
- result.children = childIDs.map(childID =>
- getTree(childID, {...options, expectedParentID: rootID })
- );
- }
-
- return result;
- }
-
function assertTreeMatches(pairs, options) {
if (!Array.isArray(pairs[0])) {
pairs = [pairs];
@@ -111,8 +68,15 @@ describe('ReactComponentTreeDevtool', () => {
}
}
- function getActualTree() {
- return getTree(rootInstance._debugID, options).children[0];
+ function expectWrapperTreeToEqual(expectedTree) {
+ ReactComponentTreeTestUtils.expectTree(rootInstance._debugID, {
+ displayName: 'Wrapper',
+ children: expectedTree ? [expectedTree] : [],
+ });
+ if (!expectedTree) {
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual([]);
+ }
}
// Mount once, render updates, then unmount.
@@ -122,20 +86,18 @@ describe('ReactComponentTreeDevtool', () => {
// Mount a new tree or update the existing tree.
ReactNative.render(, 1);
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
// Purging should have no effect
// on the tree we expect to see.
ReactComponentTreeDevtool.purgeUnmountedComponents();
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
});
// Unmounting the root node should purge
// the whole subtree automatically.
ReactNative.unmountComponentAtNode(1);
- expect(getActualTree()).toBe(undefined);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expectWrapperTreeToEqual(null);
// Mount and unmount for every pair.
// Ensure the tree is correct on every step.
@@ -144,13 +106,11 @@ describe('ReactComponentTreeDevtool', () => {
// Mount a new tree.
ReactNative.render(, 1);
- expect(getActualTree()).toEqual(expectedTree);
+ expectWrapperTreeToEqual(expectedTree);
// Unmounting should clean it up.
ReactNative.unmountComponentAtNode(1);
- expect(getActualTree()).toBe(undefined);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expectWrapperTreeToEqual(null);
});
}
@@ -1650,33 +1610,27 @@ describe('ReactComponentTreeDevtool', () => {
}
ReactNative.render(, 1);
- expect(
- getTree(barInstance._debugID, {
- includeParentDisplayName: true,
- expectedParentID: fooInstance._debugID,
- })
- ).toEqual({
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Bar',
parentDisplayName: 'Foo',
+ parentID: fooInstance._debugID,
children: [],
- });
+ }, 'Foo');
renderBar = false;
ReactNative.render(, 1);
- expect(
- getTree(barInstance._debugID, {expectedParentID: null})
- ).toEqual({
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Unknown',
children: [],
- });
+ parentID: null,
+ }, 'Foo');
ReactNative.unmountComponentAtNode(1);
- expect(
- getTree(barInstance._debugID, {expectedParentID: null})
- ).toEqual({
+ ReactComponentTreeTestUtils.expectTree(barInstance._debugID, {
displayName: 'Unknown',
children: [],
- });
+ parentID: null,
+ }, 'Foo');
});
it('reports update counts', () => {
@@ -1704,13 +1658,13 @@ describe('ReactComponentTreeDevtool', () => {
it('does not report top-level wrapper as a root', () => {
ReactNative.render(, 1);
- expect(getRootDisplayNames()).toEqual(['View']);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual(['View']);
ReactNative.render(, 1);
- expect(getRootDisplayNames()).toEqual(['View']);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual(['View']);
ReactNative.unmountComponentAtNode(1);
- expect(getRootDisplayNames()).toEqual([]);
- expect(getRegisteredDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
+ expect(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual([]);
});
});
diff --git a/src/test/ReactComponentTreeTestUtils.js b/src/test/ReactComponentTreeTestUtils.js
new file mode 100644
index 0000000000..32ba3b37ca
--- /dev/null
+++ b/src/test/ReactComponentTreeTestUtils.js
@@ -0,0 +1,92 @@
+/**
+ * Copyright 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @providesModule ReactComponentTreeTestUtils
+ */
+
+'use strict';
+
+var ReactComponentTreeDevtool = require('ReactComponentTreeDevtool');
+
+function getRootDisplayNames() {
+ return ReactComponentTreeDevtool.getRootIDs()
+ .map(ReactComponentTreeDevtool.getDisplayName);
+}
+
+function getRegisteredDisplayNames() {
+ return ReactComponentTreeDevtool.getRegisteredIDs()
+ .map(ReactComponentTreeDevtool.getDisplayName);
+}
+
+function expectTree(rootID, expectedTree, parentPath = '') {
+ var displayName = ReactComponentTreeDevtool.getDisplayName(rootID);
+ var ownerID = ReactComponentTreeDevtool.getOwnerID(rootID);
+ var parentID = ReactComponentTreeDevtool.getParentID(rootID);
+ var childIDs = ReactComponentTreeDevtool.getChildIDs(rootID);
+ var text = ReactComponentTreeDevtool.getText(rootID);
+ var path = parentPath ? `${parentPath} > ${displayName}` : displayName;
+
+ function expectEqual(actual, expected, name) {
+ // Get Jasmine to print descriptive error messages.
+ // We pass path so that we know where the mismatch occurred.
+ expect({
+ path,
+ [name]: actual,
+ }).toEqual({
+ path,
+ [name]: expected,
+ });
+ }
+
+ if (expectedTree.parentDisplayName !== undefined) {
+ expectEqual(
+ ReactComponentTreeDevtool.getDisplayName(parentID),
+ expectedTree.parentDisplayName,
+ 'parentDisplayName'
+ );
+ }
+ if (expectedTree.ownerDisplayName !== undefined) {
+ expectEqual(
+ ReactComponentTreeDevtool.getDisplayName(ownerID),
+ expectedTree.ownerDisplayName,
+ 'ownerDisplayName'
+ );
+ }
+ if (expectedTree.parentID !== undefined) {
+ expectEqual(parentID, expectedTree.parentID, 'parentID');
+ }
+ if (expectedTree.text !== undefined) {
+ expectEqual(text, expectedTree.text, 'text');
+ } else {
+ expectEqual(text, null, 'text');
+ }
+ if (expectedTree.children !== undefined) {
+ expectEqual(
+ childIDs.length,
+ expectedTree.children.length,
+ 'children.length'
+ );
+ for (var i = 0; i < childIDs.length; i++) {
+ expectTree(
+ childIDs[i],
+ {parentID: rootID, ...expectedTree.children[i]},
+ path
+ );
+ }
+ } else {
+ expectEqual(childIDs, [], 'childIDs');
+ }
+}
+
+var ReactComponentTreeTestUtils = {
+ expectTree,
+ getRootDisplayNames,
+ getRegisteredDisplayNames,
+};
+
+module.exports = ReactComponentTreeTestUtils;