Skip to content

Commit 2ac6595

Browse files
author
Brian Vaughn
committed
Added DevTools component stack test
1 parent 9f4624a commit 2ac6595

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
function normalizeCodeLocInfo(str) {
11+
if (typeof str !== 'string') {
12+
return str;
13+
}
14+
// This special case exists only for the special source location in
15+
// ReactElementValidator. That will go away if we remove source locations.
16+
str = str.replace(/Check your code at .+?:\d+/g, 'Check your code at **');
17+
// V8 format:
18+
// at Component (/path/filename.js:123:45)
19+
// React format:
20+
// in Component (at filename.js:123)
21+
return str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
22+
return '\n in ' + name + ' (at **)';
23+
});
24+
}
25+
26+
describe('component stack', () => {
27+
let React;
28+
let ReactDOM;
29+
let act;
30+
let mockError;
31+
let mockWarn;
32+
33+
beforeEach(() => {
34+
// Intercept native console methods before DevTools bootstraps.
35+
// Normalize component stack locations.
36+
mockError = jest.fn();
37+
mockWarn = jest.fn();
38+
console.error = (...args) => {
39+
mockError(...args.map(normalizeCodeLocInfo));
40+
};
41+
console.warn = (...args) => {
42+
mockWarn(...args.map(normalizeCodeLocInfo));
43+
};
44+
45+
const utils = require('./utils');
46+
act = utils.act;
47+
48+
React = require('react');
49+
ReactDOM = require('react-dom');
50+
});
51+
52+
it('should log the current component stack along with an error or warning', () => {
53+
const Grandparent = () => <Parent />;
54+
const Parent = () => <Child />;
55+
const Child = () => {
56+
console.error('Test error.');
57+
console.warn('Test warning.');
58+
return null;
59+
};
60+
61+
const container = document.createElement('div');
62+
63+
act(() => ReactDOM.render(<Grandparent />, container));
64+
65+
expect(mockError).toHaveBeenCalledWith(
66+
'Test error.',
67+
'\n in Child (at **)' +
68+
'\n in Parent (at **)' +
69+
'\n in Grandparent (at **)',
70+
);
71+
expect(mockWarn).toHaveBeenCalledWith(
72+
'Test warning.',
73+
'\n in Child (at **)' +
74+
'\n in Parent (at **)' +
75+
'\n in Grandparent (at **)',
76+
);
77+
});
78+
79+
/** This test should have caught #19911
80+
but didn't because both DevTools and ReactDOM are running in the same memory space,
81+
so the case we're testing against (DevTools prod build and React DEV build) doesn't exist.
82+
It would be nice to figure out a way to test this combination at some point...
83+
it('should disable the current dispatcher before shallow rendering so no effects get scheduled', () => {
84+
let useEffectCount = 0;
85+
86+
const Example = (props) => {
87+
React.useEffect(() => {
88+
useEffectCount++;
89+
expect(props).toBeDefined();
90+
}, [props]);
91+
console.warn('Warning to trigger appended component stacks.');
92+
return null;
93+
};
94+
95+
const container = document.createElement('div');
96+
act(() => ReactDOM.render(<Example test="abc" />, container));
97+
98+
expect(useEffectCount).toBe(1);
99+
100+
expect(mockWarn).toHaveBeenCalledWith(
101+
'Warning to trigger appended component stacks.',
102+
'\n in Example (at **)',
103+
);
104+
});
105+
*/
106+
});

0 commit comments

Comments
 (0)