@samitouri / QOS-React-2 / commits / 41230ef5dd

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;