@samitouri / QOS-React-2 / commits / 47de0a8ce6

Add unit test to ensure DOM mutations are instrumented

Ben Alpert committed Sep 27, 2015 at 14:25 UTC 47de0a8ce646641048b1195c9affbcdb2e827e3b
1 file changed +191
src/test/__tests__/ReactDefaultPerf-test.js new
+191
@@ -0,0 +1,191 @@
1 +/**
2 + * Copyright 2013-2015, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @emails react-core
10 + */
11 +
12 +'use strict';
13 +
14 +describe('ReactDefaultPerf', function() {
15 + var React;
16 + var ReactDOM;
17 + var ReactDefaultPerf;
18 + var ReactTestUtils;
19 +
20 + var App;
21 + var Box;
22 + var Div;
23 +
24 + beforeEach(function() {
25 + var now = 0;
26 + require('mock-modules').setMock('performanceNow', function() {
27 + return now++;
28 + });
29 +
30 + React = require('React');
31 + ReactDOM = require('ReactDOM');
32 + ReactDefaultPerf = require('ReactDefaultPerf');
33 + ReactTestUtils = require('ReactTestUtils');
34 +
35 + App = React.createClass({
36 + render: function() {
37 + return <div><Box /><Box /></div>;
38 + },
39 + });
40 +
41 + Box = React.createClass({
42 + render: function() {
43 + return <div><input /></div>;
44 + },
45 + });
46 +
47 + // ReactPerf only measures composites, so we put everything in one.
48 + Div = React.createClass({
49 + render: function() {
50 + return <div {...this.props} />;
51 + },
52 + });
53 + });
54 +
55 + function measure(fn) {
56 + ReactDefaultPerf.start();
57 + fn();
58 + ReactDefaultPerf.stop();
59 + return ReactDefaultPerf.getLastMeasurements();
60 + }
61 +
62 + it('should count no-op update as waste', function() {
63 + var container = document.createElement('div');
64 + ReactDOM.render(<App />, container);
65 + var measurements = measure(() => {
66 + ReactDOM.render(<App />, container);
67 + });
68 +
69 + var summary = ReactDefaultPerf.getMeasurementsSummaryMap(measurements);
70 + expect(summary.length).toBe(2);
71 +
72 + /*eslint-disable dot-notation */
73 +
74 + expect(summary[0]['Owner > component']).toBe('<root> > App');
75 + expect(summary[0]['Wasted time (ms)']).not.toBe(0);
76 + expect(summary[0]['Instances']).toBe(1);
77 +
78 + expect(summary[1]['Owner > component']).toBe('App > Box');
79 + expect(summary[1]['Wasted time (ms)']).not.toBe(0);
80 + expect(summary[1]['Instances']).toBe(2);
81 +
82 + /*eslint-enable dot-notation */
83 + });
84 +
85 + function expectNoWaste(fn) {
86 + var measurements = measure(fn);
87 + var summary = ReactDefaultPerf.getMeasurementsSummaryMap(measurements);
88 + expect(summary).toEqual([]);
89 + }
90 +
91 + it('should not count initial render as waste', function() {
92 + expectNoWaste(() => {
93 + ReactTestUtils.renderIntoDocument(<App />);
94 + });
95 + });
96 +
97 + it('should not count unmount as waste', function() {
98 + var container = document.createElement('div');
99 + ReactDOM.render(<Div>hello</Div>, container);
100 + expectNoWaste(() => {
101 + ReactDOM.unmountComponentAtNode(container);
102 + });
103 + });
104 +
105 + it('should not count content update as waste', function() {
106 + var container = document.createElement('div');
107 + ReactDOM.render(<Div>hello</Div>, container);
108 + expectNoWaste(() => {
109 + ReactDOM.render(<Div>hello world</Div>, container);
110 + });
111 + });
112 +
113 + it('should not count child addition as waste', function() {
114 + var container = document.createElement('div');
115 + ReactDOM.render(<Div><span /></Div>, container);
116 + expectNoWaste(() => {
117 + ReactDOM.render(<Div><span /><span /></Div>, container);
118 + });
119 + });
120 +
121 + it('should not count child removal as waste', function() {
122 + var container = document.createElement('div');
123 + ReactDOM.render(<Div><span /><span /></Div>, container);
124 + expectNoWaste(() => {
125 + ReactDOM.render(<Div><span /></Div>, container);
126 + });
127 + });
128 +
129 + it('should not count property update as waste', function() {
130 + var container = document.createElement('div');
131 + ReactDOM.render(<Div className="yellow">hey</Div>, container);
132 + expectNoWaste(() => {
133 + ReactDOM.render(<Div className="blue">hey</Div>, container);
134 + });
135 + });
136 +
137 + it('should not count style update as waste', function() {
138 + var container = document.createElement('div');
139 + ReactDOM.render(<Div style={{color: 'yellow'}}>hey</Div>, container);
140 + expectNoWaste(() => {
141 + ReactDOM.render(<Div style={{color: 'blue'}}>hey</Div>, container);
142 + });
143 + });
144 +
145 + it('should not count listener update as waste', function() {
146 + var container = document.createElement('div');
147 + ReactDOM.render(<Div onClick={function() {}}>hey</Div>, container);
148 + expectNoWaste(() => {
149 + ReactDOM.render(<Div onClick={function() {}}>hey</Div>, container);
150 + });
151 + });
152 +
153 + it('should not count property removal as waste', function() {
154 + var container = document.createElement('div');
155 + ReactDOM.render(<Div className="yellow">hey</Div>, container);
156 + expectNoWaste(() => {
157 + ReactDOM.render(<Div>hey</Div>, container);
158 + });
159 + });
160 +
161 + it('should not count raw HTML update as waste', function() {
162 + var container = document.createElement('div');
163 + ReactDOM.render(
164 + <Div dangerouslySetInnerHTML={{__html: 'me'}} />,
165 + container
166 + );
167 + expectNoWaste(() => {
168 + ReactDOM.render(
169 + <Div dangerouslySetInnerHTML={{__html: 'you'}} />,
170 + container
171 + );
172 + });
173 + });
174 +
175 + it('should not count child reordering as waste', function() {
176 + var container = document.createElement('div');
177 + ReactDOM.render(<Div><div key="A" /><div key="B" /></Div>, container);
178 + expectNoWaste(() => {
179 + ReactDOM.render(<Div><div key="B" /><div key="A" /></Div>, container);
180 + });
181 + });
182 +
183 + it('should not count text update as waste', function() {
184 + var container = document.createElement('div');
185 + ReactDOM.render(<Div>{'hello'}{'world'}</Div>, container);
186 + expectNoWaste(() => {
187 + ReactDOM.render(<Div>{'hello'}{'friend'}</Div>, container);
188 + });
189 + });
190 +
191 +});