@samitouri / QOS-React-2 / commits / 5d4f903482
Fork 0

The library for web and native user interfaces.

[React Children] Step Three: New test case for `traverseChildren`.

If we're going to build utilities off of this, we should have good test coverage.

Jordan Walke committed Jul 16, 2013 at 11:29 UTC 5d4f9034824ca0af60db9661628f0b5b0f165c50
1 file changed +233
src/utils/__tests__/traverseAllChildren-test.js new
+233
@@ -0,0 +1,233 @@
1 +/**
2 + * Copyright 2013 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @emails react-core
17 + * @jsx React.DOM
18 + */
19 +
20 +"use strict";
21 +
22 +describe('traverseAllChildren', function() {
23 + var traverseAllChildren;
24 + var React;
25 + beforeEach(function() {
26 + traverseAllChildren = require('traverseAllChildren');
27 + React = require('React');
28 + });
29 +
30 +
31 + it('should support identity for simple', function() {
32 + var traverseContext = [];
33 + var traverseFn =
34 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
35 + context.push(true);
36 + });
37 +
38 + var simpleKid = <span key="simple" />;
39 +
40 + // Jasmine doesn't provide a way to test that the fn was invoked with scope.
41 + var instance = <div>{simpleKid}</div>;
42 + traverseAllChildren(instance.props.children, traverseFn, traverseContext);
43 + expect(traverseFn).toHaveBeenCalledWith(
44 + traverseContext,
45 + simpleKid,
46 + '[simple]',
47 + 0
48 + );
49 + expect(traverseContext.length).toEqual(1);
50 + });
51 +
52 + it('should treat single arrayless child as being in array', function() {
53 + var traverseContext = [];
54 + var traverseFn =
55 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
56 + context.push(true);
57 + });
58 +
59 + var simpleKid = <span />;
60 + var instance = <div>{simpleKid}</div>;
61 + traverseAllChildren(instance.props.children, traverseFn, traverseContext);
62 + expect(traverseFn).toHaveBeenCalledWith(
63 + traverseContext,
64 + simpleKid,
65 + '[0]',
66 + 0
67 + );
68 + expect(traverseContext.length).toEqual(1);
69 + });
70 +
71 + it('should treat single child in array as expected', function() {
72 + var traverseContext = [];
73 + var traverseFn =
74 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
75 + context.push(true);
76 + });
77 +
78 + var simpleKid = <span />;
79 + var instance = <div>{[simpleKid]}</div>;
80 + traverseAllChildren(instance.props.children, traverseFn, traverseContext);
81 + expect(traverseFn).toHaveBeenCalledWith(
82 + traverseContext,
83 + simpleKid,
84 + '[0]',
85 + 0
86 + );
87 + expect(traverseContext.length).toEqual(1);
88 + });
89 +
90 + it('should be called for each child', function() {
91 + var zero = <div key="keyZero" />;
92 + var one = null;
93 + var two = <div key="keyTwo" />;
94 + var three = null;
95 + var four = <div key="keyFour" />;
96 +
97 + var traverseContext = [];
98 + var traverseFn =
99 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
100 + context.push(true);
101 + });
102 +
103 + var instance = (
104 + <div>
105 + {zero}
106 + {one}
107 + {two}
108 + {three}
109 + {four}
110 + </div>
111 + );
112 +
113 + traverseAllChildren(instance.props.children, traverseFn, traverseContext);
114 + expect(traverseFn).toHaveBeenCalledWith(
115 + traverseContext,
116 + zero,
117 + '[keyZero]',
118 + 0
119 + );
120 + expect(traverseFn).toHaveBeenCalledWith(traverseContext, one, '[1]', 1);
121 + expect(traverseFn).toHaveBeenCalledWith(
122 + traverseContext,
123 + two,
124 + '[keyTwo]',
125 + 2
126 + );
127 + expect(traverseFn).toHaveBeenCalledWith(traverseContext, three, '[3]', 3);
128 + expect(traverseFn).toHaveBeenCalledWith(
129 + traverseContext,
130 + four,
131 + '[keyFour]',
132 + 4
133 + );
134 + });
135 +
136 + // Todo: test that nums/strings are converted to ReactComponents.
137 +
138 + it('should be called for each child in nested structure', function() {
139 + var zero = <div key="keyZero" />;
140 + var one = null;
141 + var two = <div key="keyTwo" />;
142 + var three = null;
143 + var four = <div key="keyFour" />;
144 + var five = <div key="keyFiveCompletelyIgnored" />;
145 + // Name precedence is as follows:
146 + // 1. JavaScript Object key if in a JavaScript object:
147 + // 2. If grouped in an Array, the `key` attribute.
148 + // 3. The array index if in a JavaScript Array.
149 +
150 +
151 + var traverseContext = [];
152 + var traverseFn =
153 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
154 + context.push(true);
155 + });
156 +
157 + var instance = (
158 + <div>{
159 + [{
160 + firstHalfKey: [zero, one, two],
161 + secondHalfKey: [three, four],
162 + keyFive: five
163 + }]
164 + }</div>
165 + );
166 +
167 + traverseAllChildren(instance.props.children, traverseFn, traverseContext);
168 + expect(traverseFn.calls.length).toBe(6);
169 + expect(traverseContext.length).toEqual(6);
170 + expect(traverseFn).toHaveBeenCalledWith(
171 + traverseContext,
172 + zero,
173 + '[0]{firstHalfKey}[keyZero]',
174 + 0
175 + );
176 +
177 + expect(traverseFn)
178 + .toHaveBeenCalledWith(traverseContext, one, '[0]{firstHalfKey}[1]', 1);
179 +
180 + expect(traverseFn).toHaveBeenCalledWith(
181 + traverseContext,
182 + two,
183 + '[0]{firstHalfKey}[keyTwo]',
184 + 2
185 + );
186 +
187 + expect(traverseFn)
188 + .toHaveBeenCalledWith(traverseContext, three, '[0]{secondHalfKey}[0]', 3);
189 +
190 + expect(traverseFn).toHaveBeenCalledWith(
191 + traverseContext,
192 + four,
193 + '[0]{secondHalfKey}[keyFour]',
194 + 4
195 + );
196 +
197 + expect(traverseFn)
198 + .toHaveBeenCalledWith(traverseContext, five, '[0]{keyFive}', 5);
199 + });
200 +
201 + it('should retain key across two mappings', function() {
202 + var zeroForceKey = <div key="keyZero" />;
203 + var oneForceKey = <div key="keyOne" />;
204 + var traverseContext = [];
205 + var traverseFn =
206 + jasmine.createSpy().andCallFake(function (context, kid, key, index) {
207 + context.push(true);
208 + });
209 +
210 + var forcedKeys = (
211 + <div>
212 + {zeroForceKey}
213 + {oneForceKey}
214 + </div>
215 + );
216 +
217 + traverseAllChildren(forcedKeys.props.children, traverseFn, traverseContext);
218 + expect(traverseContext.length).toEqual(2);
219 + expect(traverseFn).toHaveBeenCalledWith(
220 + traverseContext,
221 + zeroForceKey,
222 + '[keyZero]',
223 + 0
224 + );
225 + expect(traverseFn).toHaveBeenCalledWith(
226 + traverseContext,
227 + oneForceKey,
228 + '[keyOne]',
229 + 1
230 + );
231 + });
232 +
233 +});