mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add data tests for LogBox
Summary: Adds tests for `LogBox/Data` Changelog: [Internal] Reviewed By: cpojer Differential Revision: D17965799 fbshipit-source-id: 708c62c1c886e65f4cc48f5fd22aaea3190f5512
This commit is contained in:
committed by
Facebook Github Bot
parent
7d4121da02
commit
c2832f2355
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {StackFrame} from '../../../Core/NativeExceptionsManager';
|
||||
|
||||
jest.mock('../LogBoxSymbolication', () => {
|
||||
return {__esModule: true, symbolicate: jest.fn(), deleteStack: jest.fn()};
|
||||
});
|
||||
|
||||
function getLogBoxLog() {
|
||||
return new (require('../LogBoxLog')).default(
|
||||
{content: '...', substitutions: []},
|
||||
createStack(['A', 'B', 'C']),
|
||||
'Message category...',
|
||||
[{component: 'LogBoxLog', location: 'LogBoxLog.js:1'}],
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
function getLogBoxSymbolication(): {|
|
||||
symbolicate: JestMockFn<
|
||||
$ReadOnlyArray<Array<StackFrame>>,
|
||||
Promise<Array<StackFrame>>,
|
||||
>,
|
||||
|} {
|
||||
return (require('../LogBoxSymbolication'): any);
|
||||
}
|
||||
|
||||
const createStack = methodNames =>
|
||||
methodNames.map(methodName => ({
|
||||
column: null,
|
||||
file: 'file://path/to/file.js',
|
||||
lineNumber: 1,
|
||||
methodName,
|
||||
}));
|
||||
|
||||
describe('LogBoxLog', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
getLogBoxSymbolication().symbolicate.mockImplementation(async stack =>
|
||||
createStack(stack.map(frame => `S(${frame.methodName})`)),
|
||||
);
|
||||
});
|
||||
|
||||
it('creates a LogBoxLog object', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
expect(log.message).toEqual({content: '...', substitutions: []});
|
||||
expect(log.stack).toEqual(createStack(['A', 'B', 'C']));
|
||||
expect(log.category).toEqual('Message category...');
|
||||
expect(log.componentStack).toEqual([
|
||||
{component: 'LogBoxLog', location: 'LogBoxLog.js:1'},
|
||||
]);
|
||||
expect(log.ignored).toEqual(true);
|
||||
});
|
||||
|
||||
it('increments LogBoxLog count', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
expect(log.count).toEqual(1);
|
||||
|
||||
log.incrementCount();
|
||||
|
||||
expect(log.count).toEqual(2);
|
||||
});
|
||||
|
||||
it('starts without a symbolicated stack', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
expect(log.symbolicated).toEqual({
|
||||
error: null,
|
||||
stack: null,
|
||||
status: 'NONE',
|
||||
});
|
||||
});
|
||||
|
||||
it('updates when symbolication is in progress', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
const callback = jest.fn();
|
||||
log.symbolicate(callback);
|
||||
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
expect(log.symbolicated).toEqual({
|
||||
error: null,
|
||||
stack: null,
|
||||
status: 'PENDING',
|
||||
});
|
||||
});
|
||||
|
||||
it('updates when symbolication finishes', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
const callback = jest.fn();
|
||||
log.symbolicate(callback);
|
||||
|
||||
jest.runAllTicks();
|
||||
|
||||
expect(callback.mock.calls.length).toBe(2);
|
||||
expect(log.symbolicated).toEqual({
|
||||
error: null,
|
||||
stack: createStack(['S(A)', 'S(B)', 'S(C)']),
|
||||
status: 'COMPLETE',
|
||||
});
|
||||
});
|
||||
|
||||
it('updates when symbolication fails', () => {
|
||||
const error = new Error('...');
|
||||
getLogBoxSymbolication().symbolicate.mockImplementation(async stack => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
const log = getLogBoxLog();
|
||||
|
||||
const callback = jest.fn();
|
||||
log.symbolicate(callback);
|
||||
|
||||
jest.runAllTicks();
|
||||
|
||||
expect(callback.mock.calls.length).toBe(2);
|
||||
expect(log.symbolicated).toEqual({
|
||||
error,
|
||||
stack: null,
|
||||
status: 'FAILED',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not update aborted requests', () => {
|
||||
const log = getLogBoxLog();
|
||||
|
||||
const callback = jest.fn();
|
||||
const request = log.symbolicate(callback);
|
||||
request.abort();
|
||||
|
||||
jest.runAllTicks();
|
||||
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
jest.mock('../../../Core/Devtools/parseErrorStack', () => {
|
||||
return {__esModule: true, default: jest.fn(() => [])};
|
||||
});
|
||||
|
||||
const LogBoxLogData = require('../LogBoxLogData');
|
||||
|
||||
const registry = () => {
|
||||
const observer = jest.fn();
|
||||
LogBoxLogData.observe(observer).unsubscribe();
|
||||
return observer.mock.calls[0][0];
|
||||
};
|
||||
|
||||
const filteredRegistry = () => {
|
||||
const observer = jest.fn();
|
||||
LogBoxLogData.observe(observer).unsubscribe();
|
||||
return observer.mock.calls[0][0].filter(log => !log.ignored);
|
||||
};
|
||||
|
||||
const observe = () => {
|
||||
const observer = jest.fn();
|
||||
return {
|
||||
observer,
|
||||
subscription: LogBoxLogData.observe(observer),
|
||||
};
|
||||
};
|
||||
|
||||
describe('LogBoxLogData', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
});
|
||||
|
||||
it('adds and dismisses logs', () => {
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
|
||||
expect(registry().length).toBe(1);
|
||||
expect(registry()[0]).toBeDefined();
|
||||
|
||||
LogBoxLogData.dismiss(registry()[0]);
|
||||
expect(registry().length).toBe(0);
|
||||
expect(registry()[0]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('clears all logs', () => {
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
LogBoxLogData.add({args: ['C']});
|
||||
|
||||
expect(registry().length).toBe(3);
|
||||
|
||||
LogBoxLogData.clear();
|
||||
expect(registry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('keeps logs in chronological order', () => {
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
LogBoxLogData.add({args: ['C']});
|
||||
|
||||
let logs = registry();
|
||||
expect(logs.length).toBe(3);
|
||||
expect(logs[0].category).toEqual('A');
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[2].category).toEqual('C');
|
||||
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
|
||||
// Expect `A` to be added to the end of the registry.
|
||||
logs = registry();
|
||||
expect(logs.length).toBe(4);
|
||||
expect(logs[0].category).toEqual('A');
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[2].category).toEqual('C');
|
||||
expect(logs[3].category).toEqual('A');
|
||||
});
|
||||
|
||||
it('increments the count of previous log with matching category', () => {
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
|
||||
let logs = registry();
|
||||
expect(logs.length).toBe(2);
|
||||
expect(logs[0].category).toEqual('A');
|
||||
expect(logs[0].count).toBe(1);
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[1].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
|
||||
// Expect `B` to be rolled into the last log.
|
||||
logs = registry();
|
||||
expect(logs.length).toBe(2);
|
||||
expect(logs[0].category).toEqual('A');
|
||||
expect(logs[0].count).toBe(1);
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[1].count).toBe(2);
|
||||
});
|
||||
|
||||
it('ignores logs matching patterns', () => {
|
||||
LogBoxLogData.add({args: ['A!']});
|
||||
LogBoxLogData.add({args: ['B?']});
|
||||
LogBoxLogData.add({args: ['C!']});
|
||||
expect(filteredRegistry().length).toBe(3);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['!']);
|
||||
expect(filteredRegistry().length).toBe(1);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['?']);
|
||||
expect(filteredRegistry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('ignores logs matching regexs or pattern', () => {
|
||||
LogBoxLogData.add({args: ['There are 4 dogs']});
|
||||
LogBoxLogData.add({args: ['There are 3 cats']});
|
||||
LogBoxLogData.add({args: ['There are H cats']});
|
||||
expect(filteredRegistry().length).toBe(3);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['dogs']);
|
||||
expect(filteredRegistry().length).toBe(2);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns([/There are \d+ cats/]);
|
||||
expect(filteredRegistry().length).toBe(1);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['cats']);
|
||||
expect(filteredRegistry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('ignores all logs when disabled', () => {
|
||||
LogBoxLogData.add({args: ['A!']});
|
||||
LogBoxLogData.add({args: ['B?']});
|
||||
LogBoxLogData.add({args: ['C!']});
|
||||
expect(registry().length).toBe(3);
|
||||
|
||||
LogBoxLogData.setDisabled(true);
|
||||
expect(registry().length).toBe(0);
|
||||
|
||||
LogBoxLogData.setDisabled(false);
|
||||
expect(registry().length).toBe(3);
|
||||
});
|
||||
|
||||
it('groups consecutive logs by format string categories', () => {
|
||||
LogBoxLogData.add({args: ['%s', 'A']});
|
||||
expect(registry().length).toBe(1);
|
||||
expect(registry()[0].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['%s', 'B']});
|
||||
expect(registry().length).toBe(1);
|
||||
expect(registry()[0].count).toBe(2);
|
||||
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
expect(registry().length).toBe(2);
|
||||
expect(registry()[1].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
expect(registry().length).toBe(3);
|
||||
expect(registry()[2].count).toBe(1);
|
||||
});
|
||||
|
||||
it('groups warnings with consideration for arguments', () => {
|
||||
LogBoxLogData.add({args: ['A', 'B']});
|
||||
expect(registry().length).toBe(1);
|
||||
expect(registry()[0].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['A', 'B']});
|
||||
expect(registry().length).toBe(1);
|
||||
expect(registry()[0].count).toBe(2);
|
||||
|
||||
LogBoxLogData.add({args: ['A', 'C']});
|
||||
expect(registry().length).toBe(2);
|
||||
expect(registry()[1].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['%s', 'A', 'A']});
|
||||
expect(registry().length).toBe(3);
|
||||
expect(registry()[2].count).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['%s', 'B', 'A']});
|
||||
expect(registry().length).toBe(3);
|
||||
expect(registry()[2].count).toBe(2);
|
||||
|
||||
LogBoxLogData.add({args: ['%s', 'B', 'B']});
|
||||
expect(registry().length).toBe(4);
|
||||
expect(registry()[3].count).toBe(1);
|
||||
});
|
||||
|
||||
it('ignores logs starting with "(ADVICE)"', () => {
|
||||
LogBoxLogData.add({args: ['(ADVICE) ...']});
|
||||
expect(registry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('does not ignore logs formatted to start with "(ADVICE)"', () => {
|
||||
LogBoxLogData.add({args: ['%s ...', '(ADVICE)']});
|
||||
expect(registry().length).toBe(1);
|
||||
});
|
||||
|
||||
it('immediately updates new observers', () => {
|
||||
const {observer} = observe();
|
||||
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
expect(observer.mock.calls[0][0]).toEqual(registry());
|
||||
});
|
||||
|
||||
it('sends batched updates asynchronously', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
LogBoxLogData.add({args: ['B']});
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
});
|
||||
|
||||
it('stops sending updates to unsubscribed observers', () => {
|
||||
const {observer, subscription} = observe();
|
||||
subscription.unsubscribe();
|
||||
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
expect(observer.mock.calls[0][0]).toEqual(registry());
|
||||
});
|
||||
|
||||
it('updates observers when a log is added or dismissed', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
const lastLog = observer.mock.calls[1][0][0];
|
||||
LogBoxLogData.dismiss(lastLog);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
|
||||
// Does nothing when category does not exist.
|
||||
LogBoxLogData.dismiss(lastLog);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
it('updates observers when cleared', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
LogBoxLogData.add({args: ['A']});
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
LogBoxLogData.clear();
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
|
||||
// Does nothing when already empty.
|
||||
LogBoxLogData.clear();
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
it('updates observers when an ignore pattern is added', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['?']);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
LogBoxLogData.addIgnorePatterns(['!']);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
|
||||
// Does nothing for an existing ignore pattern.
|
||||
LogBoxLogData.addIgnorePatterns(['!']);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
it('updates observers when disabled or enabled', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
LogBoxLogData.setDisabled(true);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
// Does nothing when already disabled.
|
||||
LogBoxLogData.setDisabled(true);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
LogBoxLogData.setDisabled(false);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
|
||||
// Does nothing when already enabled.
|
||||
LogBoxLogData.setDisabled(false);
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
jest.mock('../../../Core/Devtools/parseErrorStack', () => {
|
||||
return {__esModule: true, default: jest.fn(() => [])};
|
||||
});
|
||||
|
||||
const LogBoxLogParser = require('../LogBoxLogParser').default;
|
||||
|
||||
describe('LogBoxLogParser', () => {
|
||||
it('parses strings', () => {
|
||||
expect(LogBoxLogParser({args: ['A']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: 'A',
|
||||
message: {
|
||||
content: 'A',
|
||||
substitutions: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('parses strings with arguments', () => {
|
||||
expect(LogBoxLogParser({args: ['A', 'B', 'C']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: 'A B C',
|
||||
message: {
|
||||
content: 'A B C',
|
||||
substitutions: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('parses formatted strings', () => {
|
||||
expect(LogBoxLogParser({args: ['%s', 'A']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: '\ufeff%s',
|
||||
message: {
|
||||
content: 'A',
|
||||
substitutions: [
|
||||
{
|
||||
length: 1,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('parses formatted strings with insufficient arguments', () => {
|
||||
expect(LogBoxLogParser({args: ['%s %s', 'A']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: '\ufeff%s %s',
|
||||
message: {
|
||||
content: 'A %s',
|
||||
substitutions: [
|
||||
{
|
||||
length: 1,
|
||||
offset: 0,
|
||||
},
|
||||
{
|
||||
length: 2,
|
||||
offset: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('parses formatted strings with excess arguments', () => {
|
||||
expect(LogBoxLogParser({args: ['%s', 'A', 'B']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: '\ufeff%s B',
|
||||
message: {
|
||||
content: 'A B',
|
||||
substitutions: [
|
||||
{
|
||||
length: 1,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('treats "%s" in arguments as literals', () => {
|
||||
expect(LogBoxLogParser({args: ['%s', '%s', 'A']})).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category: '\ufeff%s A',
|
||||
message: {
|
||||
content: '%s A',
|
||||
substitutions: [
|
||||
{
|
||||
length: 2,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('detects a component stack in the second argument', () => {
|
||||
expect(
|
||||
LogBoxLogParser({
|
||||
args: [
|
||||
'Some kind of message',
|
||||
'\n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)',
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
componentStack: [
|
||||
{component: 'MyComponent', location: 'filename.js:1'},
|
||||
{component: 'MyOtherComponent', location: 'filename2.js:1'},
|
||||
],
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('does not detect a component stack in the third argument', () => {
|
||||
expect(
|
||||
LogBoxLogParser({
|
||||
args: [
|
||||
'Some kind of message',
|
||||
'Some other kind of message',
|
||||
'\n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)',
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
componentStack: [],
|
||||
stack: [],
|
||||
category:
|
||||
'Some kind of message Some other kind of message \n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)',
|
||||
message: {
|
||||
content:
|
||||
'Some kind of message Some other kind of message \n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)',
|
||||
substitutions: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {StackFrame} from '../../../Core/NativeExceptionsManager';
|
||||
|
||||
jest.mock('../../../Core/Devtools/symbolicateStackTrace');
|
||||
|
||||
const LogBoxSymbolication = require('../LogBoxSymbolication');
|
||||
|
||||
const symbolicateStackTrace: JestMockFn<
|
||||
$ReadOnlyArray<Array<StackFrame>>,
|
||||
Promise<Array<StackFrame>>,
|
||||
> = (require('../../../Core/Devtools/symbolicateStackTrace'): any);
|
||||
|
||||
const createStack = methodNames =>
|
||||
methodNames.map(methodName => ({
|
||||
column: null,
|
||||
file: 'file://path/to/file.js',
|
||||
lineNumber: 1,
|
||||
methodName,
|
||||
}));
|
||||
|
||||
describe('LogBoxSymbolication', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
symbolicateStackTrace.mockImplementation(async stack => stack);
|
||||
});
|
||||
|
||||
it('symbolicates different stacks', () => {
|
||||
LogBoxSymbolication.symbolicate(createStack(['A', 'B', 'C']));
|
||||
LogBoxSymbolication.symbolicate(createStack(['D', 'E', 'F']));
|
||||
|
||||
expect(symbolicateStackTrace.mock.calls.length).toBe(2);
|
||||
});
|
||||
|
||||
it('batch symbolicates equivalent stacks', () => {
|
||||
const stack = createStack(['A', 'B', 'C']);
|
||||
LogBoxSymbolication.symbolicate(stack);
|
||||
LogBoxSymbolication.symbolicate(stack);
|
||||
|
||||
expect(symbolicateStackTrace.mock.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const LogBox = require('../LogBox');
|
||||
const LogBoxLogData = require('../Data/LogBoxLogData');
|
||||
|
||||
declare var console: any;
|
||||
|
||||
describe('LogBox', () => {
|
||||
const {error, warn} = console;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
console.error = jest.fn();
|
||||
console.warn = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
LogBox.uninstall();
|
||||
console.error = error;
|
||||
console.warn = warn;
|
||||
});
|
||||
|
||||
it('can set `disableLogBox` after installing', () => {
|
||||
expect(console.disableLogBox).toBe(undefined);
|
||||
|
||||
LogBox.install();
|
||||
|
||||
expect(console.disableLogBox).toBe(false);
|
||||
expect(LogBoxLogData.isDisabled()).toBe(false);
|
||||
|
||||
console.disableLogBox = true;
|
||||
|
||||
expect(console.disableLogBox).toBe(true);
|
||||
expect(LogBoxLogData.isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
it('can set `disableLogBox` before installing', () => {
|
||||
expect(console.disableLogBox).toBe(undefined);
|
||||
|
||||
console.disableLogBox = true;
|
||||
LogBox.install();
|
||||
|
||||
expect(console.disableLogBox).toBe(true);
|
||||
expect(LogBoxLogData.isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
it('registers warnings', () => {
|
||||
jest.mock('../Data/LogBoxLogData');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
expect(LogBoxLogData.add).not.toBeCalled();
|
||||
console.warn('...');
|
||||
expect(LogBoxLogData.add).toBeCalled();
|
||||
});
|
||||
|
||||
it('registers errors beginning with "Warning: " as warnings', () => {
|
||||
jest.mock('../Data/LogBoxLogData');
|
||||
|
||||
LogBox.install();
|
||||
|
||||
console.error('...');
|
||||
expect(LogBoxLogData.add).not.toBeCalled();
|
||||
|
||||
console.error('Warning: ...');
|
||||
expect(LogBoxLogData.add).toBeCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user