A new helper for tests: createHierarchyRenderer
We aren't using this in any of the React tests, but we've found it useful testing product code.
Tim Yung committed
Dec 17, 2013 at 15:48 UTC
41230ef5dda5a95d297cd3fdd09c8ab3512340d9
1 file changed
+87
src/test/createHierarchyRenderer.js
new
+87
@@ -0,0 +1,87 @@
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
+ * @providesModule createHierarchyRenderer
17
+ */
18
+
19
+var React = require('React');
20
+
21
+/**
22
+ * Creates a render method that makes it easier to create, render, and inspect a
23
+ * hierarchy of mock React component classes.
24
+ *
25
+ * A component class is created for each of the supplied render methods. Each
26
+ * render method is invoked with the classes created using the render methods
27
+ * that come after it in the supplied list of render methods.
28
+ *
29
+ * var renderHierarchy = createHierarchyRenderer(
30
+ * function ComponentA(ComponentB, ComponentC) {...},
31
+ * function ComponentB(ComponentC) {...},
32
+ * function ComponentC() {...}
33
+ * );
34
+ *
35
+ * When the hierarchy is invoked, a two-dimensional array is returned. Each
36
+ * array corresponds to a supplied render method and contains the instances
37
+ * returned by that render method in the order it was invoked.
38
+ *
39
+ * var instances = renderHierarchy(
40
+ * function(ComponentA[, ComponentB, ComponentC]) {
41
+ * React.renderComponent(<ComponentA />, ...);
42
+ * })
43
+ * );
44
+ * instances[0][0]; // First return value of first render method.
45
+ * instances[1][0]; // First return value of second render method.
46
+ * instances[1][1]; // Second return value of second render method.
47
+ *
48
+ * Refs should be used to reference components that are not the return value of
49
+ * render methods.
50
+ *
51
+ * expect(instances[0][0].refs.X).toBe(...);
52
+ *
53
+ * NOTE: The component classes created for each render method are re-used for
54
+ * each invocation of the hierarchy renderer. If new classes are needed, you
55
+ * should re-execute `createHierarchyRenderer` with the same arguments.
56
+ *
57
+ * @param {array<function>} ...renderMethods
58
+ * @return {function}
59
+ */
60
+function createHierarchyRenderer(...renderMethods) {
61
+ var instances;
62
+ var Components = renderMethods.reduceRight(
63
+ function(Components, renderMethod, depth) {
64
+ var Component = React.createClass({
65
+ displayName: renderMethod.name,
66
+ render: function() {
67
+ instances[depth].push(this);
68
+ return renderMethod.apply(this, Components);
69
+ }
70
+ });
71
+ return [Component].concat(Components);
72
+ },
73
+ []
74
+ );
75
+ /**
76
+ * @param {function} renderComponent
77
+ * @return {array<array<*>>}
78
+ */
79
+ function renderHierarchy(renderComponent) {
80
+ instances = renderMethods.map(() => []);
81
+ renderComponent.apply(null, Components);
82
+ return instances;
83
+ }
84
+ return renderHierarchy;
85
+}
86
+
87
+module.exports = createHierarchyRenderer;