@samitouri / QOS-React-2 / commits / c3310d3e32

Fix MultiChild tests so they work with Fiber

Dropped the unnecessary use of findDOMNode. Dropped unnecessary arrow functions. Math.random() -> id counter, since this used to be non-deterministic which is not ideal for unit tests. getOriginalKeys() used to rely on implementation details to scan that the internal data structure maintained its structure, however, since that is unobservable we don't need to test the internal data structure itself. We're already testing refs and dom structure which is the only observable effect of the reorder.

Sebastian Markbage committed Sep 13, 2016 at 01:43 UTC c3310d3e326d241ec42e3db34586ce3d01cf554c
2 files changed +39 -63
src/renderers/shared/stack/reconciler/__tests__/ReactMultiChildReconcile-test.js
+33 -57
@@ -13,13 +13,10 @@
13
14 var React = require('React');
15 var ReactDOM = require('ReactDOM');
16 -var ReactDOMComponentTree = require('ReactDOMComponentTree');
17 -var ReactInstanceMap = require('ReactInstanceMap');
16
17 var stripEmptyValues = function(obj) {
18 var ret = {};
21 - var name;
22 - for (name in obj) {
19 + for (var name in obj) {
20 if (!obj.hasOwnProperty(name)) {
21 continue;
22 }
@@ -30,15 +27,7 @@ var stripEmptyValues = function(obj) {
27 return ret;
28 };
29
33 -/**
34 - * Child key names are wrapped like '.$key:0'. We strip the extra chars out
35 - * here. This relies on an implementation detail of the rendering system.
36 - */
37 -var getOriginalKey = function(childName) {
38 - var match = childName.match(/^\.\$([^.]+)$/);
39 - expect(match).not.toBeNull();
40 - return match[1];
41 -};
30 +var idCounter = 123;
31
32 /**
33 * Contains internal static internal state in order to test that updates to
@@ -46,15 +35,15 @@ var getOriginalKey = function(childName) {
35 * reusing existing DOM/memory resources.
36 */
37 class StatusDisplay extends React.Component {
49 - state = {internalState: Math.random()};
38 + state = {internalState: idCounter++};
39
51 - getStatus = () => {
40 + getStatus() {
41 return this.props.status;
53 - };
42 + }
43
55 - getInternalState = () => {
44 + getInternalState() {
45 return this.state.internalState;
57 - };
46 + }
47
48 componentDidMount() {
49 this.props.onFlush();
@@ -67,7 +56,7 @@ class StatusDisplay extends React.Component {
56 render() {
57 return (
58 <div>
70 - {this.state.internalState}
59 + {this.props.contentKey}
60 </div>
61 );
62 }
@@ -82,39 +71,29 @@ class FriendsStatusDisplay extends React.Component {
71 * Refs are not maintained in the rendered order, and neither is
72 * `this._renderedChildren` (surprisingly).
73 */
85 - getOriginalKeys = () => {
74 + getOriginalKeys() {
75 var originalKeys = [];
87 - // TODO: Update this to a better test that doesn't rely so much on internal
88 - // implementation details.
89 - var statusDisplays =
90 - ReactInstanceMap.get(this)
91 - ._renderedComponent
92 - ._renderedChildren;
93 - var name;
94 - for (name in statusDisplays) {
95 - var child = statusDisplays[name];
96 - var isPresent = !!child;
97 - if (isPresent) {
98 - originalKeys[child._mountIndex] = getOriginalKey(name);
76 + for (var key in this.props.usernameToStatus) {
77 + if (this.props.usernameToStatus[key]) {
78 + originalKeys.push(key);
79 }
80 }
81 return originalKeys;
102 - };
82 + }
83
84 /**
85 * Retrieves the rendered children in a nice format for comparing to the input
86 * `this.props.usernameToStatus`.
87 */
108 - getStatusDisplays = () => {
88 + getStatusDisplays() {
89 var res = {};
110 - var i;
90 var originalKeys = this.getOriginalKeys();
112 - for (i = 0; i < originalKeys.length; i++) {
91 + for (var i = 0; i < originalKeys.length; i++) {
92 var key = originalKeys[i];
93 res[key] = this.refs[key];
94 }
95 return res;
117 - };
96 + }
97
98 /**
99 * Verifies that by the time a child is flushed, the refs that appeared
@@ -123,10 +102,9 @@ class FriendsStatusDisplay extends React.Component {
102 * but our internal layer API depends on this assumption. We need to change
103 * it to be more declarative before making ref resolution indeterministic.
104 */
126 - verifyPreviousRefsResolved = (flushedKey) => {
127 - var i;
105 + verifyPreviousRefsResolved(flushedKey) {
106 var originalKeys = this.getOriginalKeys();
129 - for (i = 0; i < originalKeys.length; i++) {
107 + for (var i = 0; i < originalKeys.length; i++) {
108 var key = originalKeys[i];
109 if (key === flushedKey) {
110 // We are only interested in children up to the current key.
@@ -134,18 +112,18 @@ class FriendsStatusDisplay extends React.Component {
112 }
113 expect(this.refs[key]).toBeTruthy();
114 }
137 - };
115 + }
116
117 render() {
118 var children = [];
141 - var key;
142 - for (key in this.props.usernameToStatus) {
119 + for (var key in this.props.usernameToStatus) {
120 var status = this.props.usernameToStatus[key];
121 children.push(
122 !status ? null :
123 <StatusDisplay
124 key={key}
125 ref={key}
126 + contentKey={key}
127 onFlush={this.verifyPreviousRefsResolved.bind(this, key)}
128 status={status}
129 />
@@ -223,35 +201,33 @@ function verifyStatesPreserved(lastInternalStates, statusDisplays) {
201 * Verifies that the internal representation of a set of `renderedChildren`
202 * accurately reflects what is in the DOM.
203 */
226 -function verifyDomOrderingAccurate(parentInstance, statusDisplays) {
227 - var containerNode = ReactDOM.findDOMNode(parentInstance);
204 +function verifyDomOrderingAccurate(outerContainer, statusDisplays) {
205 + var containerNode = outerContainer.firstChild;
206 var statusDisplayNodes = containerNode.childNodes;
229 - var i;
230 - var orderedDomIDs = [];
231 - for (i = 0; i < statusDisplayNodes.length; i++) {
232 - var inst = ReactDOMComponentTree.getInstanceFromNode(statusDisplayNodes[i]);
233 - orderedDomIDs.push(inst._rootNodeID);
207 + var orderedDomKeys = [];
208 + for (var i = 0; i < statusDisplayNodes.length; i++) {
209 + var contentKey = statusDisplayNodes[i].textContent;
210 + orderedDomKeys.push(contentKey);
211 }
212
236 - var orderedLogicalIDs = [];
213 + var orderedLogicalKeys = [];
214 var username;
215 for (username in statusDisplays) {
216 if (!statusDisplays.hasOwnProperty(username)) {
217 continue;
218 }
219 var statusDisplay = statusDisplays[username];
243 - orderedLogicalIDs.push(
244 - ReactInstanceMap.get(statusDisplay)._renderedComponent._rootNodeID
220 + orderedLogicalKeys.push(
221 + statusDisplay.props.contentKey
222 );
223 }
247 - expect(orderedDomIDs).toEqual(orderedLogicalIDs);
224 + expect(orderedDomKeys).toEqual(orderedLogicalKeys);
225 }
226
227 /**
228 * Todo: Check that internal state is preserved across transitions
229 */
230 function testPropsSequence(sequence) {
254 - var i;
231 var container = document.createElement('div');
232 var parentInstance = ReactDOM.render(
233 <FriendsStatusDisplay {...sequence[0]} />,
@@ -261,7 +237,7 @@ function testPropsSequence(sequence) {
237 var lastInternalStates = getInternalStateByUserName(statusDisplays);
238 verifyStatuses(statusDisplays, sequence[0]);
239
264 - for (i = 1; i < sequence.length; i++) {
240 + for (var i = 1; i < sequence.length; i++) {
241 ReactDOM.render(
242 <FriendsStatusDisplay {...sequence[i]} />,
243 container
@@ -269,7 +245,7 @@ function testPropsSequence(sequence) {
245 statusDisplays = parentInstance.getStatusDisplays();
246 verifyStatuses(statusDisplays, sequence[i]);
247 verifyStatesPreserved(lastInternalStates, statusDisplays);
272 - verifyDomOrderingAccurate(parentInstance, statusDisplays);
248 + verifyDomOrderingAccurate(container, statusDisplays);
249
250 lastInternalStates = getInternalStateByUserName(statusDisplays);
251 }
src/renderers/shared/stack/reconciler/__tests__/ReactMultiChildText-test.js
+6 -6
@@ -26,17 +26,17 @@ var testAllPermutations = function(testCases) {
26 var expectedResultAfterUpdate = testCases[j + 1];
27
28 var container = document.createElement('div');
29 - var d = ReactDOM.render(<div>{renderWithChildren}</div>, container);
30 - expectChildren(d, expectedResultAfterRender);
29 + ReactDOM.render(<div>{renderWithChildren}</div>, container);
30 + expectChildren(container, expectedResultAfterRender);
31
32 - d = ReactDOM.render(<div>{updateWithChildren}</div>, container);
33 - expectChildren(d, expectedResultAfterUpdate);
32 + ReactDOM.render(<div>{updateWithChildren}</div>, container);
33 + expectChildren(container, expectedResultAfterUpdate);
34 }
35 }
36 };
37
38 -var expectChildren = function(d, children) {
39 - var outerNode = ReactDOM.findDOMNode(d);
38 +var expectChildren = function(container, children) {
39 + var outerNode = container.firstChild;
40 var textNode;
41 if (typeof children === 'string') {
42 textNode = outerNode.firstChild;