7
* @flow
8
*/
9
10
-import {getVersionedRenderImplementation, normalizeCodeLocInfo} from './utils';
10
+import {
11
+ getVersionedRenderImplementation,
12
+ normalizeCodeLocInfo,
13
+} from 'react-devtools-shared/src/__tests__/utils';
14
15
let React;
16
let ReactDOMClient;
17
let act;
15
-let fakeConsole;
16
-let mockError;
17
-let mockInfo;
18
-let mockGroup;
19
-let mockGroupCollapsed;
20
-let mockLog;
21
-let mockWarn;
22
-let patchConsole;
23
-let unpatchConsole;
18
let rendererID;
19
let supportsOwnerStacks = false;
20
21
describe('console', () => {
22
beforeEach(() => {
29
- const Console = require('react-devtools-shared/src/backend/console');
30
-
31
- patchConsole = Console.patch;
32
- unpatchConsole = Console.unpatch;
33
-
34
- // Patch a fake console so we can verify with tests below.
35
- // Patching the real console is too complicated,
36
- // because Jest itself has hooks into it as does our test env setup.
37
- mockError = jest.fn();
38
- mockInfo = jest.fn();
39
- mockGroup = jest.fn();
40
- mockGroupCollapsed = jest.fn();
41
- mockLog = jest.fn();
42
- mockWarn = jest.fn();
43
- fakeConsole = {
44
- error: mockError,
45
- info: mockInfo,
46
- log: mockLog,
47
- warn: mockWarn,
48
- group: mockGroup,
49
- groupCollapsed: mockGroupCollapsed,
50
- };
23
+ const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject;
24
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => {
25
+ rendererID = inject(internals);
26
52
- Console.dangerous_setTargetConsoleForTesting(fakeConsole);
53
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__.dangerous_setTargetConsoleForTesting(
54
- fakeConsole,
55
- );
27
+ return rendererID;
28
+ };
29
30
React = require('react');
31
if (
42
43
const {render} = getVersionedRenderImplementation();
44
72
- // @reactVersion >=18.0
73
- it('should not patch console methods that are not explicitly overridden', () => {
74
- expect(fakeConsole.error).not.toBe(mockError);
75
- expect(fakeConsole.info).toBe(mockInfo);
76
- expect(fakeConsole.log).toBe(mockLog);
77
- expect(fakeConsole.warn).not.toBe(mockWarn);
78
- expect(fakeConsole.group).toBe(mockGroup);
79
- expect(fakeConsole.groupCollapsed).toBe(mockGroupCollapsed);
80
- });
81
-
82
- // @reactVersion >=18.0
83
- it('should patch the console when appendComponentStack is enabled', () => {
84
- unpatchConsole();
85
-
86
- expect(fakeConsole.error).toBe(mockError);
87
- expect(fakeConsole.warn).toBe(mockWarn);
88
-
89
- patchConsole({
90
- appendComponentStack: true,
91
- breakOnConsoleErrors: false,
92
- showInlineWarningsAndErrors: false,
93
- });
94
-
95
- expect(fakeConsole.error).not.toBe(mockError);
96
- expect(fakeConsole.warn).not.toBe(mockWarn);
97
- });
98
-
99
- // @reactVersion >=18.0
100
- it('should patch the console when breakOnConsoleErrors is enabled', () => {
101
- unpatchConsole();
102
-
103
- expect(fakeConsole.error).toBe(mockError);
104
- expect(fakeConsole.warn).toBe(mockWarn);
105
-
106
- patchConsole({
107
- appendComponentStack: false,
108
- breakOnConsoleErrors: true,
109
- showInlineWarningsAndErrors: false,
110
- });
111
-
112
- expect(fakeConsole.error).not.toBe(mockError);
113
- expect(fakeConsole.warn).not.toBe(mockWarn);
114
- });
115
-
116
- // @reactVersion >=18.0
117
- it('should patch the console when showInlineWarningsAndErrors is enabled', () => {
118
- unpatchConsole();
119
-
120
- expect(fakeConsole.error).toBe(mockError);
121
- expect(fakeConsole.warn).toBe(mockWarn);
122
-
123
- patchConsole({
124
- appendComponentStack: false,
125
- breakOnConsoleErrors: false,
126
- showInlineWarningsAndErrors: true,
127
- });
128
-
129
- expect(fakeConsole.error).not.toBe(mockError);
130
- expect(fakeConsole.warn).not.toBe(mockWarn);
131
- });
132
-
133
- // @reactVersion >=18.0
134
- it('should only patch the console once', () => {
135
- const {error, warn} = fakeConsole;
136
-
137
- patchConsole({
138
- appendComponentStack: true,
139
- breakOnConsoleErrors: false,
140
- showInlineWarningsAndErrors: false,
141
- });
142
-
143
- expect(fakeConsole.error).toBe(error);
144
- expect(fakeConsole.warn).toBe(warn);
145
- });
146
-
147
- // @reactVersion >=18.0
148
- it('should un-patch when requested', () => {
149
- expect(fakeConsole.error).not.toBe(mockError);
150
- expect(fakeConsole.warn).not.toBe(mockWarn);
45
+ // @reactVersion >= 18.0
46
+ it('should pass through logs when there is no current fiber', () => {
47
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(0);
48
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(0);
49
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(0);
50
152
- unpatchConsole();
51
+ console.log('log');
52
+ console.warn('warn');
53
+ console.error('error');
54
154
- expect(fakeConsole.error).toBe(mockError);
155
- expect(fakeConsole.warn).toBe(mockWarn);
55
+ expect(global.consoleLogMock.mock.calls).toEqual([['log']]);
56
+ expect(global.consoleWarnMock.mock.calls).toEqual([['warn']]);
57
+ expect(global.consoleErrorMock.mock.calls).toEqual([['error']]);
58
});
59
158
- // @reactVersion >=18.0
159
- it('should pass through logs when there is no current fiber', () => {
160
- expect(mockLog).toHaveBeenCalledTimes(0);
161
- expect(mockWarn).toHaveBeenCalledTimes(0);
162
- expect(mockError).toHaveBeenCalledTimes(0);
163
- fakeConsole.log('log');
164
- fakeConsole.warn('warn');
165
- fakeConsole.error('error');
166
- expect(mockLog).toHaveBeenCalledTimes(1);
167
- expect(mockLog.mock.calls[0]).toHaveLength(1);
168
- expect(mockLog.mock.calls[0][0]).toBe('log');
169
- expect(mockWarn).toHaveBeenCalledTimes(1);
170
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
171
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
172
- expect(mockError).toHaveBeenCalledTimes(1);
173
- expect(mockError.mock.calls[0]).toHaveLength(1);
174
- expect(mockError.mock.calls[0][0]).toBe('error');
175
- });
176
-
177
- // @reactVersion >=18.0
60
+ // @reactVersion >= 18.0
61
it('should not append multiple stacks', () => {
179
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = true;
62
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = true;
63
64
const Child = ({children}) => {
182
- fakeConsole.warn('warn\n in Child (at fake.js:123)');
183
- fakeConsole.error('error', '\n in Child (at fake.js:123)');
65
+ console.warn('warn', '\n in Child (at fake.js:123)');
66
+ console.error('error', '\n in Child (at fake.js:123)');
67
return null;
68
};
69
70
act(() => render(<Child />));
71
189
- expect(mockWarn).toHaveBeenCalledTimes(1);
190
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
191
- expect(mockWarn.mock.calls[0][0]).toBe(
192
- 'warn\n in Child (at fake.js:123)',
193
- );
194
- expect(mockError).toHaveBeenCalledTimes(1);
195
- expect(mockError.mock.calls[0]).toHaveLength(2);
196
- expect(mockError.mock.calls[0][0]).toBe('error');
197
- expect(mockError.mock.calls[0][1]).toBe('\n in Child (at fake.js:123)');
72
+ expect(
73
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
74
+ ).toEqual(['warn', '\n in Child (at **)']);
75
+ expect(
76
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
77
+ ).toEqual(['error', '\n in Child (at **)']);
78
});
79
200
- // @reactVersion >=18.0
80
+ // @reactVersion >= 18.0
81
it('should append component stacks to errors and warnings logged during render', () => {
202
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = true;
82
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = true;
83
84
const Intermediate = ({children}) => children;
85
const Parent = ({children}) => (
88
</Intermediate>
89
);
90
const Child = ({children}) => {
211
- fakeConsole.error('error');
212
- fakeConsole.log('log');
213
- fakeConsole.warn('warn');
91
+ console.error('error');
92
+ console.log('log');
93
+ console.warn('warn');
94
return null;
95
};
96
97
act(() => render(<Parent />));
98
219
- expect(mockLog).toHaveBeenCalledTimes(1);
220
- expect(mockLog.mock.calls[0]).toHaveLength(1);
221
- expect(mockLog.mock.calls[0][0]).toBe('log');
222
- expect(mockWarn).toHaveBeenCalledTimes(1);
223
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
224
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
225
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
99
+ expect(global.consoleLogMock.mock.calls).toEqual([['log']]);
100
+ expect(
101
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
102
+ ).toEqual([
103
+ 'warn',
104
supportsOwnerStacks
105
? '\n in Child (at **)\n in Parent (at **)'
106
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
229
- );
230
- expect(mockError).toHaveBeenCalledTimes(1);
231
- expect(mockError.mock.calls[0]).toHaveLength(2);
232
- expect(mockError.mock.calls[0][0]).toBe('error');
233
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
107
+ ]);
108
+ expect(
109
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
110
+ ).toEqual([
111
+ 'error',
112
supportsOwnerStacks
113
? '\n in Child (at **)\n in Parent (at **)'
114
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
237
- );
115
+ ]);
116
});
117
240
- // @reactVersion >=18.0
118
+ // @reactVersion >= 18.0
119
it('should append component stacks to errors and warnings logged from effects', () => {
120
const Intermediate = ({children}) => children;
121
const Parent = ({children}) => (
125
);
126
const Child = ({children}) => {
127
React.useLayoutEffect(function Child_useLayoutEffect() {
250
- fakeConsole.error('active error');
251
- fakeConsole.log('active log');
252
- fakeConsole.warn('active warn');
128
+ console.error('active error');
129
+ console.log('active log');
130
+ console.warn('active warn');
131
});
132
React.useEffect(function Child_useEffect() {
255
- fakeConsole.error('passive error');
256
- fakeConsole.log('passive log');
257
- fakeConsole.warn('passive warn');
133
+ console.error('passive error');
134
+ console.log('passive log');
135
+ console.warn('passive warn');
136
});
137
return null;
138
};
139
140
act(() => render(<Parent />));
141
264
- expect(mockLog).toHaveBeenCalledTimes(2);
265
- expect(mockLog.mock.calls[0]).toHaveLength(1);
266
- expect(mockLog.mock.calls[0][0]).toBe('active log');
267
- expect(mockLog.mock.calls[1]).toHaveLength(1);
268
- expect(mockLog.mock.calls[1][0]).toBe('passive log');
269
- expect(mockWarn).toHaveBeenCalledTimes(2);
270
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
271
- expect(mockWarn.mock.calls[0][0]).toBe('active warn');
272
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
142
+ expect(global.consoleLogMock.mock.calls).toEqual([
143
+ ['active log'],
144
+ ['passive log'],
145
+ ]);
146
+
147
+ expect(
148
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
149
+ ).toEqual([
150
+ 'active warn',
151
supportsOwnerStacks
152
? '\n in Child_useLayoutEffect (at **)\n in Parent (at **)'
153
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
276
- );
277
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
278
- expect(mockWarn.mock.calls[1][0]).toBe('passive warn');
279
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
154
+ ]);
155
+ expect(
156
+ global.consoleWarnMock.mock.calls[1].map(normalizeCodeLocInfo),
157
+ ).toEqual([
158
+ 'passive warn',
159
supportsOwnerStacks
160
? '\n in Child_useEffect (at **)\n in Parent (at **)'
161
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
283
- );
284
- expect(mockError).toHaveBeenCalledTimes(2);
285
- expect(mockError.mock.calls[0]).toHaveLength(2);
286
- expect(mockError.mock.calls[0][0]).toBe('active error');
287
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
162
+ ]);
163
+
164
+ expect(
165
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
166
+ ).toEqual([
167
+ 'active error',
168
supportsOwnerStacks
169
? '\n in Child_useLayoutEffect (at **)\n in Parent (at **)'
170
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
291
- );
292
- expect(mockError.mock.calls[1]).toHaveLength(2);
293
- expect(mockError.mock.calls[1][0]).toBe('passive error');
294
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
171
+ ]);
172
+ expect(
173
+ global.consoleErrorMock.mock.calls[1].map(normalizeCodeLocInfo),
174
+ ).toEqual([
175
+ 'passive error',
176
supportsOwnerStacks
177
? '\n in Child_useEffect (at **)\n in Parent (at **)'
178
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
298
- );
179
+ ]);
180
});
181
301
- // @reactVersion >=18.0
182
+ // @reactVersion >= 18.0
183
it('should append component stacks to errors and warnings logged from commit hooks', () => {
303
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = true;
184
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = true;
185
186
const Intermediate = ({children}) => children;
187
const Parent = ({children}) => (
191
);
192
class Child extends React.Component<any> {
193
componentDidMount() {
313
- fakeConsole.error('didMount error');
314
- fakeConsole.log('didMount log');
315
- fakeConsole.warn('didMount warn');
194
+ console.error('didMount error');
195
+ console.log('didMount log');
196
+ console.warn('didMount warn');
197
}
198
componentDidUpdate() {
318
- fakeConsole.error('didUpdate error');
319
- fakeConsole.log('didUpdate log');
320
- fakeConsole.warn('didUpdate warn');
199
+ console.error('didUpdate error');
200
+ console.log('didUpdate log');
201
+ console.warn('didUpdate warn');
202
}
203
render() {
204
return null;
208
act(() => render(<Parent />));
209
act(() => render(<Parent />));
210
330
- expect(mockLog).toHaveBeenCalledTimes(2);
331
- expect(mockLog.mock.calls[0]).toHaveLength(1);
332
- expect(mockLog.mock.calls[0][0]).toBe('didMount log');
333
- expect(mockLog.mock.calls[1]).toHaveLength(1);
334
- expect(mockLog.mock.calls[1][0]).toBe('didUpdate log');
335
- expect(mockWarn).toHaveBeenCalledTimes(2);
336
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
337
- expect(mockWarn.mock.calls[0][0]).toBe('didMount warn');
338
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
211
+ expect(global.consoleLogMock.mock.calls).toEqual([
212
+ ['didMount log'],
213
+ ['didUpdate log'],
214
+ ]);
215
+
216
+ expect(
217
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
218
+ ).toEqual([
219
+ 'didMount warn',
220
supportsOwnerStacks
221
? '\n in Child.componentDidMount (at **)\n in Parent (at **)'
222
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
342
- );
343
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
344
- expect(mockWarn.mock.calls[1][0]).toBe('didUpdate warn');
345
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
223
+ ]);
224
+ expect(
225
+ global.consoleWarnMock.mock.calls[1].map(normalizeCodeLocInfo),
226
+ ).toEqual([
227
+ 'didUpdate warn',
228
supportsOwnerStacks
229
? '\n in Child.componentDidUpdate (at **)\n in Parent (at **)'
230
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
349
- );
350
- expect(mockError).toHaveBeenCalledTimes(2);
351
- expect(mockError.mock.calls[0]).toHaveLength(2);
352
- expect(mockError.mock.calls[0][0]).toBe('didMount error');
353
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
231
+ ]);
232
+
233
+ expect(
234
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
235
+ ).toEqual([
236
+ 'didMount error',
237
supportsOwnerStacks
238
? '\n in Child.componentDidMount (at **)\n in Parent (at **)'
239
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
357
- );
358
- expect(mockError.mock.calls[1]).toHaveLength(2);
359
- expect(mockError.mock.calls[1][0]).toBe('didUpdate error');
360
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
240
+ ]);
241
+ expect(
242
+ global.consoleErrorMock.mock.calls[1].map(normalizeCodeLocInfo),
243
+ ).toEqual([
244
+ 'didUpdate error',
245
supportsOwnerStacks
246
? '\n in Child.componentDidUpdate (at **)\n in Parent (at **)'
247
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
364
- );
248
+ ]);
249
});
250
367
- // @reactVersion >=18.0
251
+ // @reactVersion >= 18.0
252
it('should append component stacks to errors and warnings logged from gDSFP', () => {
253
const Intermediate = ({children}) => children;
254
const Parent = ({children}) => (
259
class Child extends React.Component<any, any> {
260
state = {};
261
static getDerivedStateFromProps() {
378
- fakeConsole.error('error');
379
- fakeConsole.log('log');
380
- fakeConsole.warn('warn');
262
+ console.error('error');
263
+ console.log('log');
264
+ console.warn('warn');
265
return null;
266
}
267
render() {
271
272
act(() => render(<Parent />));
273
390
- expect(mockLog).toHaveBeenCalledTimes(1);
391
- expect(mockLog.mock.calls[0]).toHaveLength(1);
392
- expect(mockLog.mock.calls[0][0]).toBe('log');
393
- expect(mockWarn).toHaveBeenCalledTimes(1);
394
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
395
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
396
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
274
+ expect(global.consoleLogMock.mock.calls).toEqual([['log']]);
275
+ expect(
276
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
277
+ ).toEqual([
278
+ 'warn',
279
supportsOwnerStacks
280
? '\n in Parent (at **)'
281
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
400
- );
401
- expect(mockError).toHaveBeenCalledTimes(1);
402
- expect(mockError.mock.calls[0]).toHaveLength(2);
403
- expect(mockError.mock.calls[0][0]).toBe('error');
404
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
282
+ ]);
283
+ expect(
284
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
285
+ ).toEqual([
286
+ 'error',
287
supportsOwnerStacks
288
? '\n in Parent (at **)'
289
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
408
- );
409
- });
410
-
411
- // @reactVersion >=18.0
412
- it('should append stacks after being uninstalled and reinstalled', () => {
413
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
414
-
415
- const Child = ({children}) => {
416
- fakeConsole.warn('warn');
417
- fakeConsole.error('error');
418
- return null;
419
- };
420
-
421
- act(() => render(<Child />));
422
-
423
- expect(mockWarn).toHaveBeenCalledTimes(1);
424
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
425
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
426
- expect(mockError).toHaveBeenCalledTimes(1);
427
- expect(mockError.mock.calls[0]).toHaveLength(1);
428
- expect(mockError.mock.calls[0][0]).toBe('error');
429
-
430
- patchConsole({
431
- appendComponentStack: true,
432
- breakOnConsoleErrors: false,
433
- showInlineWarningsAndErrors: false,
434
- });
435
- act(() => render(<Child />));
436
-
437
- expect(mockWarn).toHaveBeenCalledTimes(2);
438
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
439
- expect(mockWarn.mock.calls[1][0]).toBe('warn');
440
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][1])).toEqual(
441
- '\n in Child (at **)',
442
- );
443
- expect(mockError).toHaveBeenCalledTimes(2);
444
- expect(mockError.mock.calls[1]).toHaveLength(2);
445
- expect(mockError.mock.calls[1][0]).toBe('error');
446
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][1])).toBe(
447
- '\n in Child (at **)',
448
- );
290
+ ]);
291
});
292
451
- // @reactVersion >=18.0
293
+ // @reactVersion >= 18.0
294
it('should be resilient to prepareStackTrace', () => {
453
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = true;
454
-
295
Error.prepareStackTrace = function (error, callsites) {
296
const stack = ['An error occurred:', error.message];
297
for (let i = 0; i < callsites.length; i++) {
313
</Intermediate>
314
);
315
const Child = ({children}) => {
476
- fakeConsole.error('error');
477
- fakeConsole.log('log');
478
- fakeConsole.warn('warn');
316
+ console.error('error');
317
+ console.log('log');
318
+ console.warn('warn');
319
return null;
320
};
321
322
act(() => render(<Parent />));
323
484
- expect(mockLog).toHaveBeenCalledTimes(1);
485
- expect(mockLog.mock.calls[0]).toHaveLength(1);
486
- expect(mockLog.mock.calls[0][0]).toBe('log');
487
- expect(mockWarn).toHaveBeenCalledTimes(1);
488
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
489
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
490
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
324
+ expect(global.consoleLogMock.mock.calls).toEqual([['log']]);
325
+ expect(
326
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
327
+ ).toEqual([
328
+ 'warn',
329
supportsOwnerStacks
330
? '\n in Child (at **)\n in Parent (at **)'
331
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
494
- );
495
- expect(mockError).toHaveBeenCalledTimes(1);
496
- expect(mockError.mock.calls[0]).toHaveLength(2);
497
- expect(mockError.mock.calls[0][0]).toBe('error');
498
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
332
+ ]);
333
+ expect(
334
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
335
+ ).toEqual([
336
+ 'error',
337
supportsOwnerStacks
338
? '\n in Child (at **)\n in Parent (at **)'
339
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
502
- );
340
+ ]);
341
});
342
505
- // @reactVersion >=18.0
343
+ // @reactVersion >= 18.0
344
it('should correctly log Symbols', () => {
345
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
346
+
347
const Component = ({children}) => {
508
- fakeConsole.warn('Symbol:', Symbol(''));
348
+ console.warn('Symbol:', Symbol(''));
349
return null;
350
};
351
352
act(() => render(<Component />));
353
514
- expect(mockWarn).toHaveBeenCalledTimes(1);
515
- expect(mockWarn.mock.calls[0][0]).toBe('Symbol:');
354
+ expect(global.consoleWarnMock.mock.calls).toMatchInlineSnapshot(`
355
+ [
356
+ [
357
+ "Symbol:",
358
+ Symbol(),
359
+ ],
360
+ ]
361
+ `);
362
});
363
364
it('should double log if hideConsoleLogsInStrictMode is disabled in Strict mode', () => {
519
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
520
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = false;
365
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
366
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
367
+ false;
368
369
const container = document.createElement('div');
370
const root = ReactDOMClient.createRoot(container);
371
372
function App() {
526
- fakeConsole.log('log');
527
- fakeConsole.warn('warn');
528
- fakeConsole.error('error');
529
- fakeConsole.info('info');
530
- fakeConsole.group('group');
531
- fakeConsole.groupCollapsed('groupCollapsed');
373
+ console.log('log');
374
+ console.warn('warn');
375
+ console.error('error');
376
return <div />;
377
}
378
383
</React.StrictMode>,
384
),
385
);
542
- expect(mockLog.mock.calls[0]).toHaveLength(1);
543
- expect(mockLog.mock.calls[0][0]).toBe('log');
544
- expect(mockLog.mock.calls[1]).toEqual([
386
+
387
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(2);
388
+ expect(global.consoleLogMock.mock.calls[1]).toEqual([
389
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
390
'log',
391
]);
392
549
- expect(mockWarn).toHaveBeenCalledTimes(2);
550
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
551
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
552
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
553
- expect(mockWarn.mock.calls[1]).toEqual([
393
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(2);
394
+ expect(global.consoleWarnMock.mock.calls[1]).toEqual([
395
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
396
'warn',
397
]);
398
558
- expect(mockError).toHaveBeenCalledTimes(2);
559
- expect(mockError.mock.calls[0]).toHaveLength(1);
560
- expect(mockError.mock.calls[0][0]).toBe('error');
561
- expect(mockError.mock.calls[1]).toHaveLength(2);
562
- expect(mockError.mock.calls[1]).toEqual([
399
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(2);
400
+ expect(global.consoleErrorMock.mock.calls[1]).toEqual([
401
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
402
'error',
403
]);
566
-
567
- expect(mockInfo).toHaveBeenCalledTimes(2);
568
- expect(mockInfo.mock.calls[0]).toHaveLength(1);
569
- expect(mockInfo.mock.calls[0][0]).toBe('info');
570
- expect(mockInfo.mock.calls[1]).toHaveLength(2);
571
- expect(mockInfo.mock.calls[1]).toEqual([
572
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
573
- 'info',
574
- ]);
575
-
576
- expect(mockGroup).toHaveBeenCalledTimes(2);
577
- expect(mockGroup.mock.calls[0]).toHaveLength(1);
578
- expect(mockGroup.mock.calls[0][0]).toBe('group');
579
- expect(mockGroup.mock.calls[1]).toHaveLength(2);
580
- expect(mockGroup.mock.calls[1]).toEqual([
581
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
582
- 'group',
583
- ]);
584
-
585
- expect(mockGroupCollapsed).toHaveBeenCalledTimes(2);
586
- expect(mockGroupCollapsed.mock.calls[0]).toHaveLength(1);
587
- expect(mockGroupCollapsed.mock.calls[0][0]).toBe('groupCollapsed');
588
- expect(mockGroupCollapsed.mock.calls[1]).toHaveLength(2);
589
- expect(mockGroupCollapsed.mock.calls[1]).toEqual([
590
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
591
- 'groupCollapsed',
592
- ]);
404
});
405
406
it('should not double log if hideConsoleLogsInStrictMode is enabled in Strict mode', () => {
596
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
597
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = true;
407
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
408
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
409
+ true;
410
411
const container = document.createElement('div');
412
const root = ReactDOMClient.createRoot(container);
413
414
function App() {
603
- console.log(
604
- 'CALL',
605
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__,
606
- );
607
- fakeConsole.log('log');
608
- fakeConsole.warn('warn');
609
- fakeConsole.error('error');
610
- fakeConsole.info('info');
611
- fakeConsole.group('group');
612
- fakeConsole.groupCollapsed('groupCollapsed');
415
+ console.log('log');
416
+ console.warn('warn');
417
+ console.error('error');
418
return <div />;
419
}
420
426
),
427
);
428
624
- expect(mockLog).toHaveBeenCalledTimes(1);
625
- expect(mockLog.mock.calls[0]).toHaveLength(1);
626
- expect(mockLog.mock.calls[0][0]).toBe('log');
627
-
628
- expect(mockWarn).toHaveBeenCalledTimes(1);
629
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
630
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
631
-
632
- expect(mockError).toHaveBeenCalledTimes(1);
633
- expect(mockError.mock.calls[0]).toHaveLength(1);
634
- expect(mockError.mock.calls[0][0]).toBe('error');
635
-
636
- expect(mockInfo).toHaveBeenCalledTimes(1);
637
- expect(mockInfo.mock.calls[0]).toHaveLength(1);
638
- expect(mockInfo.mock.calls[0][0]).toBe('info');
639
-
640
- expect(mockGroup).toHaveBeenCalledTimes(1);
641
- expect(mockGroup.mock.calls[0]).toHaveLength(1);
642
- expect(mockGroup.mock.calls[0][0]).toBe('group');
643
-
644
- expect(mockGroupCollapsed).toHaveBeenCalledTimes(1);
645
- expect(mockGroupCollapsed.mock.calls[0]).toHaveLength(1);
646
- expect(mockGroupCollapsed.mock.calls[0][0]).toBe('groupCollapsed');
429
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(1);
430
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(1);
431
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(1);
432
});
433
434
it('should double log from Effects if hideConsoleLogsInStrictMode is disabled in Strict mode', () => {
650
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
651
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = false;
435
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
436
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
437
+ false;
438
439
const container = document.createElement('div');
440
const root = ReactDOMClient.createRoot(container);
441
442
function App() {
443
React.useEffect(() => {
658
- fakeConsole.log('log effect create');
659
- fakeConsole.warn('warn effect create');
660
- fakeConsole.error('error effect create');
661
- fakeConsole.info('info effect create');
662
- fakeConsole.group('group effect create');
663
- fakeConsole.groupCollapsed('groupCollapsed effect create');
444
+ console.log('log effect create');
445
+ console.warn('warn effect create');
446
+ console.error('error effect create');
447
448
return () => {
666
- fakeConsole.log('log effect cleanup');
667
- fakeConsole.warn('warn effect cleanup');
668
- fakeConsole.error('error effect cleanup');
669
- fakeConsole.info('info effect cleanup');
670
- fakeConsole.group('group effect cleanup');
671
- fakeConsole.groupCollapsed('groupCollapsed effect cleanup');
449
+ console.log('log effect cleanup');
450
+ console.warn('warn effect cleanup');
451
+ console.error('error effect cleanup');
452
};
453
});
454
462
</React.StrictMode>,
463
),
464
);
685
- expect(mockLog.mock.calls).toEqual([
465
+ expect(global.consoleLogMock.mock.calls).toEqual([
466
['log effect create'],
467
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'log effect cleanup'],
468
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'log effect create'],
469
]);
690
- expect(mockWarn.mock.calls).toEqual([
470
+ expect(global.consoleWarnMock.mock.calls).toEqual([
471
['warn effect create'],
472
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'warn effect cleanup'],
473
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'warn effect create'],
474
]);
695
- expect(mockError.mock.calls).toEqual([
475
+ expect(global.consoleErrorMock.mock.calls).toEqual([
476
['error effect create'],
477
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'error effect cleanup'],
478
['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'error effect create'],
479
]);
700
- expect(mockInfo.mock.calls).toEqual([
701
- ['info effect create'],
702
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'info effect cleanup'],
703
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'info effect create'],
704
- ]);
705
- expect(mockGroup.mock.calls).toEqual([
706
- ['group effect create'],
707
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'group effect cleanup'],
708
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'group effect create'],
709
- ]);
710
- expect(mockGroupCollapsed.mock.calls).toEqual([
711
- ['groupCollapsed effect create'],
712
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'groupCollapsed effect cleanup'],
713
- ['\x1b[2;38;2;124;124;124m%s\x1b[0m', 'groupCollapsed effect create'],
714
- ]);
480
});
481
482
it('should not double log from Effects if hideConsoleLogsInStrictMode is enabled in Strict mode', () => {
718
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
719
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = true;
483
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
484
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
485
+ true;
486
487
const container = document.createElement('div');
488
const root = ReactDOMClient.createRoot(container);
489
490
function App() {
491
React.useEffect(() => {
726
- fakeConsole.log('log effect create');
727
- fakeConsole.warn('warn effect create');
728
- fakeConsole.error('error effect create');
729
- fakeConsole.info('info effect create');
730
- fakeConsole.group('group effect create');
731
- fakeConsole.groupCollapsed('groupCollapsed effect create');
492
+ console.log('log effect create');
493
+ console.warn('warn effect create');
494
+ console.error('error effect create');
495
496
return () => {
734
- fakeConsole.log('log effect cleanup');
735
- fakeConsole.warn('warn effect cleanup');
736
- fakeConsole.error('error effect cleanup');
737
- fakeConsole.info('info effect cleanup');
738
- fakeConsole.group('group effect cleanup');
739
- fakeConsole.groupCollapsed('groupCollapsed effect cleanup');
497
+ console.log('log effect cleanup');
498
+ console.warn('warn effect cleanup');
499
+ console.error('error effect cleanup');
500
};
501
});
502
510
</React.StrictMode>,
511
),
512
);
753
- expect(mockLog.mock.calls).toEqual([['log effect create']]);
754
- expect(mockWarn.mock.calls).toEqual([['warn effect create']]);
755
- expect(mockError.mock.calls).toEqual([['error effect create']]);
756
- expect(mockInfo.mock.calls).toEqual([['info effect create']]);
757
- expect(mockGroup.mock.calls).toEqual([['group effect create']]);
758
- expect(mockGroupCollapsed.mock.calls).toEqual([
759
- ['groupCollapsed effect create'],
760
- ]);
513
+
514
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(1);
515
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(1);
516
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(1);
517
});
518
519
it('should double log from useMemo if hideConsoleLogsInStrictMode is disabled in Strict mode', () => {
764
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
765
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = false;
520
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
521
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
522
+ false;
523
524
const container = document.createElement('div');
525
const root = ReactDOMClient.createRoot(container);
526
527
function App() {
528
React.useMemo(() => {
772
- fakeConsole.log('log');
773
- fakeConsole.warn('warn');
774
- fakeConsole.error('error');
775
- fakeConsole.info('info');
776
- fakeConsole.group('group');
777
- fakeConsole.groupCollapsed('groupCollapsed');
529
+ console.log('log');
530
+ console.warn('warn');
531
+ console.error('error');
532
}, []);
533
return <div />;
534
}
540
</React.StrictMode>,
541
),
542
);
789
- expect(mockLog.mock.calls[0]).toHaveLength(1);
790
- expect(mockLog.mock.calls[0][0]).toBe('log');
791
- expect(mockLog.mock.calls[1]).toEqual([
543
+
544
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(2);
545
+ expect(global.consoleLogMock.mock.calls[1]).toEqual([
546
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
547
'log',
548
]);
549
796
- expect(mockWarn).toHaveBeenCalledTimes(2);
797
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
798
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
799
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
800
- expect(mockWarn.mock.calls[1]).toEqual([
550
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(2);
551
+ expect(global.consoleWarnMock.mock.calls[1]).toEqual([
552
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
553
'warn',
554
]);
555
805
- expect(mockError).toHaveBeenCalledTimes(2);
806
- expect(mockError.mock.calls[0]).toHaveLength(1);
807
- expect(mockError.mock.calls[0][0]).toBe('error');
808
- expect(mockError.mock.calls[1]).toHaveLength(2);
809
- expect(mockError.mock.calls[1]).toEqual([
556
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(2);
557
+ expect(global.consoleErrorMock.mock.calls[1]).toEqual([
558
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
559
'error',
560
]);
813
-
814
- expect(mockInfo).toHaveBeenCalledTimes(2);
815
- expect(mockInfo.mock.calls[0]).toHaveLength(1);
816
- expect(mockInfo.mock.calls[0][0]).toBe('info');
817
- expect(mockInfo.mock.calls[1]).toHaveLength(2);
818
- expect(mockInfo.mock.calls[1]).toEqual([
819
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
820
- 'info',
821
- ]);
822
-
823
- expect(mockGroup).toHaveBeenCalledTimes(2);
824
- expect(mockGroup.mock.calls[0]).toHaveLength(1);
825
- expect(mockGroup.mock.calls[0][0]).toBe('group');
826
- expect(mockGroup.mock.calls[1]).toHaveLength(2);
827
- expect(mockGroup.mock.calls[1]).toEqual([
828
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
829
- 'group',
830
- ]);
831
-
832
- expect(mockGroupCollapsed).toHaveBeenCalledTimes(2);
833
- expect(mockGroupCollapsed.mock.calls[0]).toHaveLength(1);
834
- expect(mockGroupCollapsed.mock.calls[0][0]).toBe('groupCollapsed');
835
- expect(mockGroupCollapsed.mock.calls[1]).toHaveLength(2);
836
- expect(mockGroupCollapsed.mock.calls[1]).toEqual([
837
- '\x1b[2;38;2;124;124;124m%s\x1b[0m',
838
- 'groupCollapsed',
839
- ]);
561
});
562
563
it('should not double log from useMemo fns if hideConsoleLogsInStrictMode is enabled in Strict mode', () => {
843
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
844
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = true;
564
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
565
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
566
+ true;
567
568
const container = document.createElement('div');
569
const root = ReactDOMClient.createRoot(container);
570
571
function App() {
572
React.useMemo(() => {
851
- console.log(
852
- 'CALL',
853
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__,
854
- );
855
- fakeConsole.log('log');
856
- fakeConsole.warn('warn');
857
- fakeConsole.error('error');
858
- fakeConsole.info('info');
859
- fakeConsole.group('group');
860
- fakeConsole.groupCollapsed('groupCollapsed');
573
+ console.log('log');
574
+ console.warn('warn');
575
+ console.error('error');
576
}, []);
577
return <div />;
578
}
585
),
586
);
587
873
- expect(mockLog).toHaveBeenCalledTimes(1);
874
- expect(mockLog.mock.calls[0]).toHaveLength(1);
875
- expect(mockLog.mock.calls[0][0]).toBe('log');
876
-
877
- expect(mockWarn).toHaveBeenCalledTimes(1);
878
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
879
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
880
-
881
- expect(mockError).toHaveBeenCalledTimes(1);
882
- expect(mockError.mock.calls[0]).toHaveLength(1);
883
- expect(mockError.mock.calls[0][0]).toBe('error');
884
-
885
- expect(mockInfo).toHaveBeenCalledTimes(1);
886
- expect(mockInfo.mock.calls[0]).toHaveLength(1);
887
- expect(mockInfo.mock.calls[0][0]).toBe('info');
888
-
889
- expect(mockGroup).toHaveBeenCalledTimes(1);
890
- expect(mockGroup.mock.calls[0]).toHaveLength(1);
891
- expect(mockGroup.mock.calls[0][0]).toBe('group');
892
-
893
- expect(mockGroupCollapsed).toHaveBeenCalledTimes(1);
894
- expect(mockGroupCollapsed.mock.calls[0]).toHaveLength(1);
895
- expect(mockGroupCollapsed.mock.calls[0][0]).toBe('groupCollapsed');
588
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(1);
589
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(1);
590
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(1);
591
});
592
593
it('should double log in Strict mode initial render for extension', () => {
899
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
900
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = false;
594
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
595
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
596
+ false;
597
598
// This simulates a render that happens before React DevTools have finished
599
// their handshake to attach the React DOM renderer functions to DevTools
600
// In this case, we should still be able to mock the console in Strict mode
905
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__.rendererInterfaces.set(
906
- rendererID,
907
- null,
908
- );
601
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.rendererInterfaces.delete(rendererID);
602
const container = document.createElement('div');
603
const root = ReactDOMClient.createRoot(container);
604
605
function App() {
913
- fakeConsole.log('log');
914
- fakeConsole.warn('warn');
915
- fakeConsole.error('error');
606
+ console.log('log');
607
+ console.warn('warn');
608
+ console.error('error');
609
return <div />;
610
}
611
617
),
618
);
619
927
- expect(mockLog).toHaveBeenCalledTimes(2);
928
- expect(mockLog.mock.calls[0]).toHaveLength(1);
929
- expect(mockLog.mock.calls[0][0]).toBe('log');
930
- expect(mockLog.mock.calls[1]).toHaveLength(2);
931
- expect(mockLog.mock.calls[1]).toEqual([
620
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(2);
621
+ expect(global.consoleLogMock.mock.calls[1]).toEqual([
622
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
623
'log',
624
]);
625
936
- expect(mockWarn).toHaveBeenCalledTimes(2);
937
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
938
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
939
- expect(mockWarn.mock.calls[1]).toHaveLength(2);
940
- expect(mockWarn.mock.calls[1]).toEqual([
626
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(2);
627
+ expect(global.consoleWarnMock.mock.calls[1]).toEqual([
628
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
629
'warn',
630
]);
631
945
- expect(mockError).toHaveBeenCalledTimes(2);
946
- expect(mockError.mock.calls[0]).toHaveLength(1);
947
- expect(mockError.mock.calls[0][0]).toBe('error');
948
- expect(mockError.mock.calls[1]).toHaveLength(2);
949
- expect(mockError.mock.calls[1]).toEqual([
632
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(2);
633
+ expect(global.consoleErrorMock.mock.calls[1]).toEqual([
634
'\x1b[2;38;2;124;124;124m%s\x1b[0m',
635
'error',
636
]);
637
});
638
639
it('should not double log in Strict mode initial render for extension', () => {
956
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = false;
957
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = true;
640
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = false;
641
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
642
+ true;
643
644
// This simulates a render that happens before React DevTools have finished
645
// their handshake to attach the React DOM renderer functions to DevTools
646
// In this case, we should still be able to mock the console in Strict mode
962
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__.rendererInterfaces.set(
963
- rendererID,
964
- null,
965
- );
647
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.rendererInterfaces.delete(rendererID);
648
const container = document.createElement('div');
649
const root = ReactDOMClient.createRoot(container);
650
651
function App() {
970
- fakeConsole.log('log');
971
- fakeConsole.warn('warn');
972
- fakeConsole.error('error');
652
+ console.log('log');
653
+ console.warn('warn');
654
+ console.error('error');
655
return <div />;
656
}
657
662
</React.StrictMode>,
663
),
664
);
983
- expect(mockLog).toHaveBeenCalledTimes(1);
984
- expect(mockLog.mock.calls[0]).toHaveLength(1);
985
- expect(mockLog.mock.calls[0][0]).toBe('log');
665
987
- expect(mockWarn).toHaveBeenCalledTimes(1);
988
- expect(mockWarn.mock.calls[0]).toHaveLength(1);
989
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
990
-
991
- expect(mockError).toHaveBeenCalledTimes(1);
992
- expect(mockError.mock.calls[0]).toHaveLength(1);
993
- expect(mockError.mock.calls[0][0]).toBe('error');
666
+ expect(global.consoleLogMock).toHaveBeenCalledTimes(1);
667
+ expect(global.consoleWarnMock).toHaveBeenCalledTimes(1);
668
+ expect(global.consoleErrorMock).toHaveBeenCalledTimes(1);
669
});
670
671
it('should properly dim component stacks during strict mode double log', () => {
997
- global.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = true;
998
- global.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = false;
672
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.appendComponentStack = true;
673
+ global.__REACT_DEVTOOLS_GLOBAL_HOOK__.settings.hideConsoleLogsInStrictMode =
674
+ false;
675
676
const container = document.createElement('div');
677
const root = ReactDOMClient.createRoot(container);
683
</Intermediate>
684
);
685
const Child = ({children}) => {
1010
- fakeConsole.error('error');
1011
- fakeConsole.warn('warn');
686
+ console.error('error');
687
+ console.warn('warn');
688
return null;
689
};
690
696
),
697
);
698
1023
- expect(mockWarn).toHaveBeenCalledTimes(2);
1024
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
1025
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[0][1])).toEqual(
699
+ expect(
700
+ global.consoleWarnMock.mock.calls[0].map(normalizeCodeLocInfo),
701
+ ).toEqual([
702
+ 'warn',
703
supportsOwnerStacks
704
? '\n in Child (at **)\n in Parent (at **)'
705
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
1029
- );
1030
- expect(mockWarn.mock.calls[1]).toHaveLength(3);
1031
- expect(mockWarn.mock.calls[1][0]).toEqual(
706
+ ]);
707
+
708
+ expect(
709
+ global.consoleWarnMock.mock.calls[1].map(normalizeCodeLocInfo),
710
+ ).toEqual([
711
'\x1b[2;38;2;124;124;124m%s %o\x1b[0m',
1033
- );
1034
- expect(mockWarn.mock.calls[1][1]).toMatch('warn');
1035
- expect(normalizeCodeLocInfo(mockWarn.mock.calls[1][2]).trim()).toEqual(
712
+ 'warn',
713
supportsOwnerStacks
1037
- ? 'in Object.overrideMethod (at **)' + // TODO: This leading frame is due to our extra wrapper that shouldn't exist.
1038
- '\n in Child (at **)\n in Parent (at **)'
714
+ ? '\n in Child (at **)\n in Parent (at **)'
715
: 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
1040
- );
716
+ ]);
717
1042
- expect(mockError).toHaveBeenCalledTimes(2);
1043
- expect(mockError.mock.calls[0]).toHaveLength(2);
1044
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toEqual(
718
+ expect(
719
+ global.consoleErrorMock.mock.calls[0].map(normalizeCodeLocInfo),
720
+ ).toEqual([
721
+ 'error',
722
supportsOwnerStacks
723
? '\n in Child (at **)\n in Parent (at **)'
724
: '\n in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
1048
- );
1049
- expect(mockError.mock.calls[1]).toHaveLength(3);
1050
- expect(mockError.mock.calls[1][0]).toEqual(
725
+ ]);
726
+ expect(
727
+ global.consoleErrorMock.mock.calls[1].map(normalizeCodeLocInfo),
728
+ ).toEqual([
729
'\x1b[2;38;2;124;124;124m%s %o\x1b[0m',
1052
- );
1053
- expect(mockError.mock.calls[1][1]).toEqual('error');
1054
- expect(normalizeCodeLocInfo(mockError.mock.calls[1][2]).trim()).toEqual(
730
+ 'error',
731
supportsOwnerStacks
1056
- ? 'in Object.overrideMethod (at **)' + // TODO: This leading frame is due to our extra wrapper that shouldn't exist.
1057
- '\n in Child (at **)\n in Parent (at **)'
732
+ ? '\n in Child (at **)\n in Parent (at **)'
733
: 'in Child (at **)\n in Intermediate (at **)\n in Parent (at **)',
1059
- );
1060
- });
1061
-});
1062
-
1063
-describe('console error', () => {
1064
- beforeEach(() => {
1065
- jest.resetModules();
1066
-
1067
- const Console = require('react-devtools-shared/src/backend/console');
1068
- patchConsole = Console.patch;
1069
- unpatchConsole = Console.unpatch;
1070
-
1071
- // Patch a fake console so we can verify with tests below.
1072
- // Patching the real console is too complicated,
1073
- // because Jest itself has hooks into it as does our test env setup.
1074
- mockError = jest.fn();
1075
- mockInfo = jest.fn();
1076
- mockGroup = jest.fn();
1077
- mockGroupCollapsed = jest.fn();
1078
- mockLog = jest.fn();
1079
- mockWarn = jest.fn();
1080
- fakeConsole = {
1081
- error: mockError,
1082
- info: mockInfo,
1083
- log: mockLog,
1084
- warn: mockWarn,
1085
- group: mockGroup,
1086
- groupCollapsed: mockGroupCollapsed,
1087
- };
1088
-
1089
- Console.dangerous_setTargetConsoleForTesting(fakeConsole);
1090
-
1091
- const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject;
1092
- global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => {
1093
- inject(internals);
1094
-
1095
- Console.registerRenderer(
1096
- () => {
1097
- throw Error('foo');
1098
- },
1099
- () => {
1100
- return {
1101
- enableOwnerStacks: true,
1102
- componentStack: '\n at FakeStack (fake-file)',
1103
- };
1104
- },
1105
- );
1106
- };
1107
-
1108
- React = require('react');
1109
- ReactDOMClient = require('react-dom/client');
1110
-
1111
- const utils = require('./utils');
1112
- act = utils.act;
1113
- });
1114
-
1115
- // @reactVersion >=18.0
1116
- it('error in console log throws without interfering with logging', () => {
1117
- const container = document.createElement('div');
1118
- const root = ReactDOMClient.createRoot(container);
1119
-
1120
- function App() {
1121
- fakeConsole.log('log');
1122
- fakeConsole.warn('warn');
1123
- fakeConsole.error('error');
1124
- return <div />;
1125
- }
1126
-
1127
- patchConsole({
1128
- appendComponentStack: true,
1129
- breakOnConsoleErrors: false,
1130
- showInlineWarningsAndErrors: true,
1131
- hideConsoleLogsInStrictMode: false,
1132
- });
1133
-
1134
- expect(() => {
1135
- act(() => {
1136
- root.render(<App />);
1137
- });
1138
- }).toThrowError('foo');
1139
-
1140
- expect(mockLog).toHaveBeenCalledTimes(1);
1141
- expect(mockLog.mock.calls[0]).toHaveLength(1);
1142
- expect(mockLog.mock.calls[0][0]).toBe('log');
1143
-
1144
- expect(mockWarn).toHaveBeenCalledTimes(1);
1145
- expect(mockWarn.mock.calls[0]).toHaveLength(2);
1146
- expect(mockWarn.mock.calls[0][0]).toBe('warn');
1147
- // An error in showInlineWarningsAndErrors doesn't need to break component stacks.
1148
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
1149
- '\n in FakeStack (at **)',
1150
- );
1151
-
1152
- expect(mockError).toHaveBeenCalledTimes(1);
1153
- expect(mockError.mock.calls[0]).toHaveLength(2);
1154
- expect(mockError.mock.calls[0][0]).toBe('error');
1155
- expect(normalizeCodeLocInfo(mockError.mock.calls[0][1])).toBe(
1156
- '\n in FakeStack (at **)',
1157
- );
734
+ ]);
735
});
736
});