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
+});