mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
LogBox - Rework how fatals and syntax errors are handled
Summary: This diff makes a few changes to how errors and warnings are handled in LogBox: - Soft errors continue to notify the user collapsed. - Fatal errors pop up full screen over the content, but are dismissible. - Syntax errors pop up full screen, and are **not** dismissible. - Removed the "Reload" button on fatals, and added back the dismiss/close. - Removed all buttons from syntax errors so users are encouraged to fix it and safe without reloading. To do this we needed to: - Move the selectedLogIndex state out of the component and up to the rest of the log state. - Change the way popping a log works, it's now done by setting selectedLogIndex at log time instead of deriving it at render time, that means `selectedLogIndex` is now the sole state value for deciding if the log inspector is open or not - Whenever the state is updated, find a syntax error if it's there, instead of doing this at render time Changelog: [Internal] Reviewed By: cpojer Differential Revision: D18421089 fbshipit-source-id: d2c4937f666f1302ed1a7b1b9c6679b0509136c5
This commit is contained in:
1 parent
54bbe1b6ea
commit
fe82f402a9
16 files changed
+547
-876
No files matched your search
@@ -27,7 +27,11 @@ export type LogData = $ReadOnly<{|
|
||||
|}>;
|
||||
|
||||
export type Observer = (
|
||||
$ReadOnly<{|logs: LogBoxLogs, isDisabled: boolean|}>,
|
||||
$ReadOnly<{|
|
||||
logs: LogBoxLogs,
|
||||
isDisabled: boolean,
|
||||
selectedLogIndex: number,
|
||||
|}>,
|
||||
) => void;
|
||||
|
||||
export type IgnorePattern = string | RegExp;
|
||||
@@ -41,10 +45,33 @@ const ignorePatterns: Set<IgnorePattern> = new Set();
|
||||
let logs: LogBoxLogs = new Set();
|
||||
let updateTimeout = null;
|
||||
let _isDisabled = false;
|
||||
let _selectedIndex = -1;
|
||||
|
||||
const LOGBOX_ERROR_MESSAGE =
|
||||
'An error was thrown when attempting to render log messages via LogBox.';
|
||||
|
||||
function getNextState() {
|
||||
const logArray = Array.from(logs);
|
||||
let index = logArray.length - 1;
|
||||
while (index >= 0) {
|
||||
// The latest syntax error is selected and displayed before all other logs.
|
||||
if (logArray[index].level === 'syntax') {
|
||||
return {
|
||||
logs,
|
||||
isDisabled: _isDisabled,
|
||||
selectedLogIndex: index,
|
||||
};
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
|
||||
return {
|
||||
logs,
|
||||
isDisabled: _isDisabled,
|
||||
selectedLogIndex: _selectedIndex,
|
||||
};
|
||||
}
|
||||
|
||||
export function reportLogBoxError(
|
||||
error: ExtendedError,
|
||||
componentStack?: string,
|
||||
@@ -79,9 +106,7 @@ function handleUpdate(): void {
|
||||
if (updateTimeout == null) {
|
||||
updateTimeout = setImmediate(() => {
|
||||
updateTimeout = null;
|
||||
observers.forEach(({observer}) =>
|
||||
observer({logs, isDisabled: _isDisabled}),
|
||||
);
|
||||
observers.forEach(({observer}) => observer(getNextState()));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -172,10 +197,12 @@ export function addException(error: ExceptionData): void {
|
||||
);
|
||||
|
||||
// Start symbolicating now so it's warm when it renders.
|
||||
logs.add(newLog);
|
||||
|
||||
if (level === 'fatal') {
|
||||
_selectedIndex = logs.size - 1;
|
||||
symbolicateLogLazy(newLog);
|
||||
}
|
||||
logs.add(newLog);
|
||||
}
|
||||
|
||||
handleUpdate();
|
||||
@@ -186,12 +213,18 @@ export function addException(error: ExceptionData): void {
|
||||
}
|
||||
|
||||
export function clear(): void {
|
||||
if (logs.size > 0) {
|
||||
logs.clear();
|
||||
const newLogs = Array.from(logs).filter(log => log.level === 'syntax');
|
||||
if (newLogs.length !== logs.size) {
|
||||
logs = new Set(newLogs);
|
||||
handleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
export function setSelectedLog(index: number): void {
|
||||
_selectedIndex = index;
|
||||
handleUpdate();
|
||||
}
|
||||
|
||||
export function clearWarnings(): void {
|
||||
const newLogs = Array.from(logs).filter(log => log.level !== 'warn');
|
||||
if (newLogs.length !== logs.size) {
|
||||
@@ -201,7 +234,9 @@ export function clearWarnings(): void {
|
||||
}
|
||||
|
||||
export function clearErrors(): void {
|
||||
const newLogs = Array.from(logs).filter(log => log.level !== 'error');
|
||||
const newLogs = Array.from(logs).filter(
|
||||
log => log.level !== 'error' && log.level !== 'fatal',
|
||||
);
|
||||
if (newLogs.length !== logs.size) {
|
||||
logs = new Set(newLogs);
|
||||
handleUpdate();
|
||||
@@ -276,7 +311,7 @@ export function observe(observer: Observer): Subscription {
|
||||
const subscription = {observer};
|
||||
observers.add(subscription);
|
||||
|
||||
observer({logs, isDisabled: _isDisabled});
|
||||
observer(getNextState());
|
||||
|
||||
return {
|
||||
unsubscribe(): void {
|
||||
|
||||
@@ -37,6 +37,12 @@ const disabledState = () => {
|
||||
return observer.mock.calls[0][0].isDisabled;
|
||||
};
|
||||
|
||||
const selectedLogIndex = () => {
|
||||
const observer = jest.fn();
|
||||
LogBoxData.observe(observer).unsubscribe();
|
||||
return observer.mock.calls[0][0].selectedLogIndex;
|
||||
};
|
||||
|
||||
const observe = () => {
|
||||
const observer = jest.fn();
|
||||
return {
|
||||
@@ -59,7 +65,7 @@ const addLogs = logs => {
|
||||
});
|
||||
};
|
||||
|
||||
const addExceptions = errors => {
|
||||
const addSoftErrors = errors => {
|
||||
errors.forEach(error => {
|
||||
LogBoxData.addException(
|
||||
Object.assign(
|
||||
@@ -81,8 +87,30 @@ const addExceptions = errors => {
|
||||
});
|
||||
};
|
||||
|
||||
const addFatalErrors = errors => {
|
||||
errors.forEach(error => {
|
||||
LogBoxData.addException(
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
message: '',
|
||||
originalMessage: '',
|
||||
name: 'console.error',
|
||||
componentStack: '',
|
||||
stack: [],
|
||||
id: 0,
|
||||
isFatal: true,
|
||||
},
|
||||
typeof error === 'string'
|
||||
? {message: error, originalMessage: error}
|
||||
: error,
|
||||
),
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const addSyntaxError = () => {
|
||||
addExceptions([
|
||||
addFatalErrors([
|
||||
{
|
||||
message: `
|
||||
|
||||
@@ -109,13 +137,19 @@ beforeEach(() => {
|
||||
describe('LogBoxData', () => {
|
||||
it('adds and dismisses logs', () => {
|
||||
addLogs(['A']);
|
||||
addExceptions(['B']);
|
||||
addSoftErrors(['B']);
|
||||
addFatalErrors(['C']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(registry().length).toBe(2);
|
||||
expect(registry().length).toBe(4);
|
||||
expect(registry()[0]).toBeDefined();
|
||||
expect(registry()[1]).toBeDefined();
|
||||
|
||||
LogBoxData.dismiss(registry()[0]);
|
||||
expect(registry().length).toBe(3);
|
||||
LogBoxData.dismiss(registry()[0]);
|
||||
expect(registry().length).toBe(2);
|
||||
LogBoxData.dismiss(registry()[0]);
|
||||
expect(registry().length).toBe(1);
|
||||
LogBoxData.dismiss(registry()[0]);
|
||||
@@ -123,20 +157,22 @@ describe('LogBoxData', () => {
|
||||
expect(registry()[0]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('clears all logs', () => {
|
||||
it('clears all logs except syntax errors', () => {
|
||||
addLogs(['A', 'B']);
|
||||
addExceptions(['C', 'D']);
|
||||
addSoftErrors(['C', 'D']);
|
||||
addFatalErrors(['E', 'F']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(registry().length).toBe(4);
|
||||
expect(registry().length).toBe(7);
|
||||
|
||||
LogBoxData.clear();
|
||||
expect(registry().length).toBe(0);
|
||||
expect(registry().length).toBe(1);
|
||||
});
|
||||
|
||||
it('clears only warnings', () => {
|
||||
addLogs(['A', 'B']);
|
||||
addExceptions(['C', 'D', 'E']);
|
||||
addSoftErrors(['C', 'D', 'E']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
@@ -146,13 +182,14 @@ describe('LogBoxData', () => {
|
||||
expect(registry().length).toBe(4);
|
||||
});
|
||||
|
||||
it('clears only errors', () => {
|
||||
it('clears errors and fatals, but not syntax errors.', () => {
|
||||
addLogs(['A', 'B']);
|
||||
addExceptions(['C', 'D', 'E']);
|
||||
addSoftErrors(['C', 'D', 'E']);
|
||||
addFatalErrors(['F']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(registry().length).toBe(6);
|
||||
expect(registry().length).toBe(7);
|
||||
|
||||
LogBoxData.clearErrors();
|
||||
expect(registry().length).toBe(3);
|
||||
@@ -160,23 +197,25 @@ describe('LogBoxData', () => {
|
||||
|
||||
it('clears only syntax errors', () => {
|
||||
addLogs(['A', 'B']);
|
||||
addExceptions(['C', 'D', 'E']);
|
||||
addSoftErrors(['C', 'D', 'E']);
|
||||
addFatalErrors(['F']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(registry().length).toBe(6);
|
||||
expect(registry().length).toBe(7);
|
||||
|
||||
LogBoxData.clearSyntaxErrors();
|
||||
expect(registry().length).toBe(5);
|
||||
expect(registry().length).toBe(6);
|
||||
});
|
||||
|
||||
it('clears all types', () => {
|
||||
addLogs(['A', 'B']);
|
||||
addExceptions(['C', 'D', 'E']);
|
||||
addSoftErrors(['C', 'D', 'E']);
|
||||
addFatalErrors(['F']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(registry().length).toBe(6);
|
||||
expect(registry().length).toBe(7);
|
||||
|
||||
LogBoxData.clearErrors();
|
||||
LogBoxData.clearWarnings();
|
||||
@@ -186,26 +225,103 @@ describe('LogBoxData', () => {
|
||||
|
||||
it('keeps logs in chronological order', () => {
|
||||
addLogs(['A']);
|
||||
addExceptions(['B']);
|
||||
addLogs(['C']);
|
||||
addSoftErrors(['B']);
|
||||
addFatalErrors(['C']);
|
||||
addLogs(['D']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
let logs = registry();
|
||||
expect(logs.length).toBe(3);
|
||||
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('D');
|
||||
|
||||
addLogs(['A']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
// Expect `A` to be added to the end of the registry.
|
||||
logs = registry();
|
||||
expect(logs.length).toBe(4);
|
||||
expect(logs.length).toBe(5);
|
||||
expect(logs[0].category).toEqual('A');
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[2].category).toEqual('C');
|
||||
expect(logs[3].category).toEqual('A');
|
||||
expect(logs[3].category).toEqual('D');
|
||||
expect(logs[4].category).toEqual('A');
|
||||
});
|
||||
|
||||
it('sets the selectedLogIndex', () => {
|
||||
expect(selectedLogIndex()).toBe(-1);
|
||||
|
||||
LogBoxData.setSelectedLog(1);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(1);
|
||||
});
|
||||
|
||||
it('does not set the selectedLogIndex for warnings', () => {
|
||||
addLogs(['A']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(-1);
|
||||
});
|
||||
|
||||
it('does not set the selectedLogIndex for soft errors', () => {
|
||||
addSoftErrors(['A']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(-1);
|
||||
});
|
||||
|
||||
it('sets the selectedLogIndex to the last fatal error', () => {
|
||||
addFatalErrors(['A']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
|
||||
addLogs(['B']);
|
||||
addFatalErrors(['C']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(2);
|
||||
});
|
||||
|
||||
it('sets the selectedLogIndex to the last syntax error', () => {
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
|
||||
addLogs(['B']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(2);
|
||||
});
|
||||
|
||||
it('keeps selectedLogIndex set to the syntax error even when a new fatal is added', () => {
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
|
||||
addLogs(['B']);
|
||||
addFatalErrors(['C']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
});
|
||||
|
||||
it('keeps selectedLogIndex set to the syntax error even when explicitly changed', () => {
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
|
||||
LogBoxData.setSelectedLog(1);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(selectedLogIndex()).toBe(0);
|
||||
});
|
||||
|
||||
it('increments the count of previous log with matching category (logs)', () => {
|
||||
@@ -231,8 +347,8 @@ describe('LogBoxData', () => {
|
||||
expect(logs[1].count).toBe(2);
|
||||
});
|
||||
|
||||
it('increments the count of previous log with matching category (exceptions)', () => {
|
||||
addExceptions(['A', 'B']);
|
||||
it('increments the count of previous log with matching category (errors)', () => {
|
||||
addFatalErrors(['A', 'B']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
let logs = registry();
|
||||
@@ -242,7 +358,7 @@ describe('LogBoxData', () => {
|
||||
expect(logs[1].category).toEqual('B');
|
||||
expect(logs[1].count).toBe(1);
|
||||
|
||||
addExceptions(['B']);
|
||||
addSoftErrors(['B']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
// Expect `B` to be rolled into the last log.
|
||||
@@ -283,8 +399,9 @@ describe('LogBoxData', () => {
|
||||
expect(filteredRegistry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('ignores logs matching patterns (exceptions)', () => {
|
||||
addExceptions(['A!', 'B?', 'C!']);
|
||||
it('ignores logs matching patterns (errors)', () => {
|
||||
addSoftErrors(['A!', 'B?']);
|
||||
addFatalErrors(['C!']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(filteredRegistry().length).toBe(3);
|
||||
@@ -312,8 +429,9 @@ describe('LogBoxData', () => {
|
||||
expect(filteredRegistry().length).toBe(0);
|
||||
});
|
||||
|
||||
it('ignores matching regexs or pattern (exceptions)', () => {
|
||||
addExceptions(['There are 4 dogs', 'There are 3 cats', 'There are H cats']);
|
||||
it('ignores matching regexs or pattern (errors)', () => {
|
||||
addSoftErrors(['There are 4 dogs', 'There are 3 cats']);
|
||||
addFatalErrors(['There are H cats']);
|
||||
jest.runAllImmediates();
|
||||
|
||||
expect(filteredRegistry().length).toBe(3);
|
||||
@@ -329,8 +447,9 @@ describe('LogBoxData', () => {
|
||||
});
|
||||
|
||||
it('ignores all logs except fatals when disabled', () => {
|
||||
addLogs(['A!', 'B?']);
|
||||
addExceptions(['C!']);
|
||||
addLogs(['A!']);
|
||||
addSoftErrors(['B?']);
|
||||
addFatalErrors(['C!']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
|
||||
@@ -424,7 +543,9 @@ describe('LogBoxData', () => {
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
addLogs(['A']);
|
||||
addExceptions(['B']);
|
||||
addSoftErrors(['B']);
|
||||
addFatalErrors(['C']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
@@ -443,7 +564,9 @@ describe('LogBoxData', () => {
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
addLogs(['A']);
|
||||
addExceptions(['B']);
|
||||
addSoftErrors(['B']);
|
||||
addFatalErrors(['C']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
@@ -462,6 +585,8 @@ describe('LogBoxData', () => {
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
addLogs(['A']);
|
||||
addSoftErrors(['B']);
|
||||
addFatalErrors(['C']);
|
||||
addSyntaxError();
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
@@ -26,6 +26,7 @@ type State = {|
|
||||
logs: LogBoxLogs,
|
||||
isDisabled: boolean,
|
||||
hasError: boolean,
|
||||
selectedLogIndex: number,
|
||||
|};
|
||||
|
||||
let LogBoxComponent;
|
||||
@@ -109,6 +110,7 @@ if (__DEV__) {
|
||||
logs: new Set(),
|
||||
isDisabled: false,
|
||||
hasError: false,
|
||||
selectedLogIndex: -1,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
@@ -125,6 +127,8 @@ if (__DEV__) {
|
||||
onDismissErrors={LogBoxData.clearErrors}
|
||||
logs={this.state.logs}
|
||||
isDisabled={this.state.isDisabled}
|
||||
selectedLogIndex={this.state.selectedLogIndex}
|
||||
setSelectedLog={this._handleSetSelectedLog}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -144,6 +148,10 @@ if (__DEV__) {
|
||||
_handleDismiss(log: LogBoxLog): void {
|
||||
LogBoxData.dismiss(log);
|
||||
}
|
||||
|
||||
_handleSetSelectedLog(index: number): void {
|
||||
LogBoxData.setSelectedLog(index);
|
||||
}
|
||||
};
|
||||
|
||||
const registerWarning = (...args): void => {
|
||||
|
||||
@@ -23,12 +23,14 @@ type Props = $ReadOnly<{|
|
||||
onDismiss: (log: LogBoxLog) => void,
|
||||
onDismissWarns: () => void,
|
||||
onDismissErrors: () => void,
|
||||
setSelectedLog: number => void,
|
||||
logs: LogBoxLogs,
|
||||
selectedLogIndex: number,
|
||||
isDisabled?: ?boolean,
|
||||
|}>;
|
||||
|
||||
function LogBoxContainer(props: Props): React.Node {
|
||||
const [selectedLogIndex, setSelectedLog] = React.useState(null);
|
||||
const {selectedLogIndex, setSelectedLog} = props;
|
||||
|
||||
const logs = Array.from(props.logs);
|
||||
|
||||
@@ -38,7 +40,7 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
// is now outside the bounds of the log array.
|
||||
if (selectedLogIndex != null) {
|
||||
if (logs.length - 1 <= 0) {
|
||||
setSelectedLog(null);
|
||||
setSelectedLog(-1);
|
||||
} else if (selectedLogIndex >= logs.length - 1) {
|
||||
setSelectedLog(selectedLogIndex - 1);
|
||||
}
|
||||
@@ -47,7 +49,7 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
}
|
||||
|
||||
function handleInspectorMinimize() {
|
||||
setSelectedLog(null);
|
||||
setSelectedLog(-1);
|
||||
}
|
||||
|
||||
function openLog(log: LogBoxLog) {
|
||||
@@ -60,16 +62,7 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
setSelectedLog(index);
|
||||
}
|
||||
|
||||
let fatalIndex = logs.length - 1;
|
||||
while (fatalIndex >= 0) {
|
||||
const level = logs[fatalIndex].level;
|
||||
if (level === 'fatal' || level === 'syntax') {
|
||||
break;
|
||||
}
|
||||
fatalIndex -= 1;
|
||||
}
|
||||
|
||||
if (selectedLogIndex == null && fatalIndex >= 0) {
|
||||
if (selectedLogIndex > -1) {
|
||||
return (
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
<LogBoxInspector
|
||||
@@ -77,22 +70,6 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
onMinimize={handleInspectorMinimize}
|
||||
onChangeSelectedIndex={setSelectedLog}
|
||||
logs={logs}
|
||||
fatalType={logs[fatalIndex].level}
|
||||
selectedIndex={fatalIndex}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedLogIndex != null) {
|
||||
return (
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
<LogBoxInspector
|
||||
onDismiss={handleInspectorDismiss}
|
||||
onMinimize={handleInspectorMinimize}
|
||||
onChangeSelectedIndex={setSelectedLog}
|
||||
logs={logs}
|
||||
fatalType={fatalIndex >= 0 ? logs[fatalIndex].level : null}
|
||||
selectedIndex={selectedLogIndex}
|
||||
/>
|
||||
</View>
|
||||
@@ -104,7 +81,9 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
}
|
||||
|
||||
const warnings = logs.filter(log => log.level === 'warn');
|
||||
const errors = logs.filter(log => log.level === 'error');
|
||||
const errors = logs.filter(
|
||||
log => log.level === 'error' || log.level === 'fatal',
|
||||
);
|
||||
return (
|
||||
<View style={styles.list}>
|
||||
{warnings.length > 0 && (
|
||||
@@ -114,9 +93,6 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
level="warn"
|
||||
totalLogCount={warnings.length}
|
||||
onPressOpen={() => openLog(warnings[warnings.length - 1])}
|
||||
onPressList={() => {
|
||||
/* TODO: open log list */
|
||||
}}
|
||||
onPressDismiss={props.onDismissWarns}
|
||||
/>
|
||||
</View>
|
||||
@@ -128,9 +104,6 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
level="error"
|
||||
totalLogCount={errors.length}
|
||||
onPressOpen={() => openLog(errors[errors.length - 1])}
|
||||
onPressList={() => {
|
||||
/* TODO: open log list */
|
||||
}}
|
||||
onPressDismiss={props.onDismissErrors}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -79,7 +79,7 @@ function LogBoxInspector(props: Props): React.Node {
|
||||
<LogBoxInspectorFooter
|
||||
onDismiss={props.onDismiss}
|
||||
onMinimize={props.onMinimize}
|
||||
fatalType={props.fatalType}
|
||||
level={log.level}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -23,31 +23,16 @@ import * as LogBoxStyle from './LogBoxStyle';
|
||||
type Props = $ReadOnly<{|
|
||||
onDismiss: () => void,
|
||||
onMinimize: () => void,
|
||||
fatalType?: ?LogLevel,
|
||||
level?: ?LogLevel,
|
||||
|}>;
|
||||
|
||||
function LogBoxInspectorFooter(props: Props): React.Node {
|
||||
if (props.fatalType === 'fatal' || props.fatalType === 'syntax') {
|
||||
if (props.level === 'syntax') {
|
||||
return (
|
||||
<View style={[styles.root, fatalStyles.root]}>
|
||||
<LogBoxButton
|
||||
backgroundColor={{
|
||||
default: LogBoxStyle.getFatalColor(),
|
||||
pressed: LogBoxStyle.getFatalDarkColor(),
|
||||
}}
|
||||
onPress={() =>
|
||||
require('../../Utilities/DevSettings').reload('LogBox fatal')
|
||||
}
|
||||
style={fatalStyles.button}>
|
||||
<View style={[fatalStyles.content]}>
|
||||
<Text style={fatalStyles.label}>Reload</Text>
|
||||
<Text style={fatalStyles.subtextLabel}>
|
||||
{{fatal: 'Fatal', syntax: 'Syntax'}[props.fatalType]} errors
|
||||
require a full reload
|
||||
</Text>
|
||||
</View>
|
||||
<SafeAreaView />
|
||||
</LogBoxButton>
|
||||
<View style={styles.root}>
|
||||
<Text style={styles.syntaxErrorText}>
|
||||
This error cannot be dismissed.
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -82,36 +67,6 @@ function FooterButton(props: ButtonProps): React.Node {
|
||||
);
|
||||
}
|
||||
|
||||
const fatalStyles = StyleSheet.create({
|
||||
root: {
|
||||
shadowColor: LogBoxStyle.getBackgroundDarkColor(1),
|
||||
},
|
||||
button: {
|
||||
flex: 1,
|
||||
},
|
||||
content: {
|
||||
alignItems: 'center',
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
subtext: {
|
||||
height: 60,
|
||||
},
|
||||
label: {
|
||||
color: LogBoxStyle.getTextColor(1),
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
includeFontPadding: false,
|
||||
lineHeight: 20,
|
||||
},
|
||||
subtextLabel: {
|
||||
color: LogBoxStyle.getTextColor(0.8),
|
||||
fontSize: 11,
|
||||
includeFontPadding: false,
|
||||
lineHeight: 12,
|
||||
},
|
||||
});
|
||||
|
||||
const buttonStyles = StyleSheet.create({
|
||||
button: {
|
||||
flex: 1,
|
||||
@@ -139,6 +94,15 @@ const styles = StyleSheet.create({
|
||||
elevation: 1,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
syntaxErrorText: {
|
||||
textAlign: 'center',
|
||||
width: '100%',
|
||||
fontSize: 14,
|
||||
paddingTop: 15,
|
||||
paddingBottom: 15,
|
||||
fontStyle: 'italic',
|
||||
color: LogBoxStyle.getTextColor(0.6),
|
||||
},
|
||||
});
|
||||
|
||||
export default LogBoxInspectorFooter;
|
||||
@@ -29,6 +29,18 @@ type Props = $ReadOnly<{|
|
||||
|}>;
|
||||
|
||||
function LogBoxInspectorHeader(props: Props): React.Node {
|
||||
if (props.level === 'syntax') {
|
||||
return (
|
||||
<SafeAreaView style={styles[props.level]}>
|
||||
<View style={styles.header}>
|
||||
<View style={styles.title}>
|
||||
<Text style={styles.titleText}>Failed to compile</Text>
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const prevIndex =
|
||||
props.selectedIndex - 1 < 0 ? props.total - 1 : props.selectedIndex - 1;
|
||||
const nextIndex =
|
||||
|
||||
@@ -27,7 +27,6 @@ type Props = $ReadOnly<{|
|
||||
totalLogCount: number,
|
||||
level: 'warn' | 'error',
|
||||
onPressOpen: () => void,
|
||||
onPressList: () => void,
|
||||
onPressDismiss: () => void,
|
||||
|}>;
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ describe('LogBoxContainer', () => {
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={new Set()}
|
||||
/>,
|
||||
);
|
||||
@@ -30,121 +32,119 @@ describe('LogBoxContainer', () => {
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest warning', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest error', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render both an error and warning', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render null when disabled with non-fatal error and warning', () => {
|
||||
it('should render null with no selected log and disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest error notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render both an error and warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
@@ -175,95 +175,15 @@ describe('LogBoxContainer', () => {
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render fatal before warn and error', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'fatal',
|
||||
{
|
||||
content: 'Some kind of fatal message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of fatal message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'warn',
|
||||
{
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'error',
|
||||
{
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message (latest)',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render most recent fatal', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'fatal',
|
||||
{
|
||||
content: 'Should not be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of fatal message',
|
||||
[],
|
||||
),
|
||||
new LogBoxLog(
|
||||
'fatal',
|
||||
{
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of message',
|
||||
[],
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render fatal error even when disabled', () => {
|
||||
it('should render selected fatal error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={0}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
@@ -284,69 +204,15 @@ describe('LogBoxContainer', () => {
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render most recent syntax error', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
'syntax',
|
||||
{
|
||||
content: 'Should not be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of syntax error message',
|
||||
[],
|
||||
{
|
||||
fileName:
|
||||
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
location: {row: 199, column: 0},
|
||||
content: ` 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |`,
|
||||
},
|
||||
),
|
||||
new LogBoxLog(
|
||||
'syntax',
|
||||
{
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
[],
|
||||
'Some kind of syntax error message',
|
||||
[],
|
||||
{
|
||||
fileName:
|
||||
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
location: {row: 199, column: 0},
|
||||
content: ` 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |`,
|
||||
},
|
||||
),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render syntax error even when disabled', () => {
|
||||
it('should render selected syntax error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={0}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog(
|
||||
|
||||
@@ -16,44 +16,48 @@ const LogBoxInspectorFooter = require('../LogBoxInspectorFooter').default;
|
||||
const render = require('../../../../jest/renderer');
|
||||
|
||||
describe('LogBoxInspectorFooter', () => {
|
||||
it('should render two buttons for warning with no fatal', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorFooter onMinimize={() => {}} onDismiss={() => {}} />,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render fatal for warning with a fatal', () => {
|
||||
it('should render two buttons for warning', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorFooter
|
||||
onMinimize={() => {}}
|
||||
onDismiss={() => {}}
|
||||
fatalType="syntax"
|
||||
level="warn"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render fatal button', () => {
|
||||
it('should render two buttons for error', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorFooter
|
||||
onMinimize={() => {}}
|
||||
onDismiss={() => {}}
|
||||
fatalType="fatal"
|
||||
level="error"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render fatal button for syntax erorr', () => {
|
||||
it('should render two buttons for fatal', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorFooter
|
||||
onMinimize={() => {}}
|
||||
onDismiss={() => {}}
|
||||
fatalType="syntax"
|
||||
level="fatal"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render no buttons and a message for syntax error', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorFooter
|
||||
onMinimize={() => {}}
|
||||
onDismiss={() => {}}
|
||||
level="syntax"
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -54,4 +54,17 @@ describe('LogBoxInspectorHeader', () => {
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render syntax error header', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorHeader
|
||||
onSelectIndex={() => {}}
|
||||
selectedIndex={0}
|
||||
total={1}
|
||||
level="syntax"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -35,7 +35,6 @@ describe('LogBoxLogNotification', () => {
|
||||
totalLogCount={1}
|
||||
level="warn"
|
||||
onPressOpen={() => {}}
|
||||
onPressList={() => {}}
|
||||
onPressDismiss={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxContainer should render both an error and warning 1`] = `
|
||||
exports[`LogBoxContainer should render both an error and warning notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -42,7 +42,6 @@ exports[`LogBoxContainer should render both an error and warning 1`] = `
|
||||
}
|
||||
}
|
||||
onPressDismiss={[Function]}
|
||||
onPressList={[Function]}
|
||||
onPressOpen={[Function]}
|
||||
totalLogCount={1}
|
||||
/>
|
||||
@@ -78,7 +77,6 @@ exports[`LogBoxContainer should render both an error and warning 1`] = `
|
||||
}
|
||||
}
|
||||
onPressDismiss={[Function]}
|
||||
onPressList={[Function]}
|
||||
onPressOpen={[Function]}
|
||||
totalLogCount={1}
|
||||
/>
|
||||
@@ -93,273 +91,53 @@ exports[`LogBoxContainer should render both an error and warning 1`] = `
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render fatal before warn and error 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
fatalType="fatal"
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of fatal message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Some kind of fatal message",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "warn",
|
||||
"message": Object {
|
||||
"content": "Some kind of message",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message (latest)",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "error",
|
||||
"message": Object {
|
||||
"content": "Some kind of message (latest)",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={0}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render fatal error even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
fatalType="fatal"
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={0}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render most recent fatal 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
fatalType="fatal"
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of fatal message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Should not be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={1}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render most recent syntax error 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
fatalType="syntax"
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of syntax error message",
|
||||
"codeFrame": Object {
|
||||
"content": " 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |",
|
||||
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
|
||||
"location": Object {
|
||||
"column": 0,
|
||||
"row": 199,
|
||||
},
|
||||
},
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "syntax",
|
||||
"message": Object {
|
||||
"content": "Should not be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
LogBoxLog {
|
||||
"category": "Some kind of syntax error message",
|
||||
"codeFrame": Object {
|
||||
"content": " 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |",
|
||||
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
|
||||
"location": Object {
|
||||
"column": 0,
|
||||
"row": 199,
|
||||
},
|
||||
},
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "syntax",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={1}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render null when disabled with non-fatal error and warning 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render syntax error even when disabled 1`] = `
|
||||
exports[`LogBoxContainer should render null with no selected log and disabled 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render selected fatal error even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={0}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render selected syntax error even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -372,7 +150,6 @@ exports[`LogBoxContainer should render syntax error even when disabled 1`] = `
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
fatalType="syntax"
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
@@ -413,7 +190,7 @@ exports[`LogBoxContainer should render syntax error even when disabled 1`] = `
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render the latest error 1`] = `
|
||||
exports[`LogBoxContainer should render the latest error notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -455,7 +232,6 @@ exports[`LogBoxContainer should render the latest error 1`] = `
|
||||
}
|
||||
}
|
||||
onPressDismiss={[Function]}
|
||||
onPressList={[Function]}
|
||||
onPressOpen={[Function]}
|
||||
totalLogCount={2}
|
||||
/>
|
||||
@@ -470,7 +246,7 @@ exports[`LogBoxContainer should render the latest error 1`] = `
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render the latest warning 1`] = `
|
||||
exports[`LogBoxContainer should render the latest warning notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -512,7 +288,6 @@ exports[`LogBoxContainer should render the latest warning 1`] = `
|
||||
}
|
||||
}
|
||||
onPressDismiss={[Function]}
|
||||
onPressList={[Function]}
|
||||
onPressOpen={[Function]}
|
||||
totalLogCount={2}
|
||||
/>
|
||||
|
||||
@@ -39,7 +39,7 @@ exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = `
|
||||
onRetry={[Function]}
|
||||
/>
|
||||
<LogBoxInspectorFooter
|
||||
fatalType="fatal"
|
||||
level="fatal"
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
/>
|
||||
@@ -87,6 +87,7 @@ exports[`LogBoxContainer should render warning with selectedIndex 0 1`] = `
|
||||
onRetry={[Function]}
|
||||
/>
|
||||
<LogBoxInspectorFooter
|
||||
level="warn"
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
/>
|
||||
|
||||
@@ -1,243 +1,97 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxInspectorFooter should render fatal button 1`] = `
|
||||
exports[`LogBoxInspectorFooter should render no buttons and a message for syntax error 1`] = `
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
Object {
|
||||
"shadowColor": "rgba(34, 34, 34, 1)",
|
||||
},
|
||||
]
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "rgba(243, 83, 105, 1)",
|
||||
"pressed": "rgba(208, 75, 95, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"color": "rgba(255, 255, 255, 0.6)",
|
||||
"fontSize": 14,
|
||||
"fontStyle": "italic",
|
||||
"paddingBottom": 15,
|
||||
"paddingTop": 15,
|
||||
"textAlign": "center",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"height": 60,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
Reload
|
||||
</Text>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.8)",
|
||||
"fontSize": 11,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
Fatal
|
||||
errors require a full reload
|
||||
</Text>
|
||||
</View>
|
||||
<ForwardRef(SafeAreaView) />
|
||||
</LogBoxButton>
|
||||
This error cannot be dismissed.
|
||||
</Text>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorFooter should render fatal button for syntax erorr 1`] = `
|
||||
exports[`LogBoxInspectorFooter should render two buttons for error 1`] = `
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
Object {
|
||||
"shadowColor": "rgba(34, 34, 34, 1)",
|
||||
},
|
||||
]
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "rgba(243, 83, 105, 1)",
|
||||
"pressed": "rgba(208, 75, 95, 1)",
|
||||
}
|
||||
}
|
||||
<FooterButton
|
||||
onPress={[Function]}
|
||||
text="Dismiss"
|
||||
/>
|
||||
<FooterButton
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"height": 60,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
Reload
|
||||
</Text>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.8)",
|
||||
"fontSize": 11,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
Syntax
|
||||
errors require a full reload
|
||||
</Text>
|
||||
</View>
|
||||
<ForwardRef(SafeAreaView) />
|
||||
</LogBoxButton>
|
||||
text="Close"
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorFooter should render fatal for warning with a fatal 1`] = `
|
||||
exports[`LogBoxInspectorFooter should render two buttons for fatal 1`] = `
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
Object {
|
||||
"backgroundColor": "rgba(51, 51, 51, 1)",
|
||||
"elevation": 1,
|
||||
"flexDirection": "row",
|
||||
"shadowColor": "#000",
|
||||
"shadowOffset": Object {
|
||||
"height": -2,
|
||||
"width": 0,
|
||||
},
|
||||
Object {
|
||||
"shadowColor": "rgba(34, 34, 34, 1)",
|
||||
},
|
||||
]
|
||||
"shadowOpacity": 0.5,
|
||||
"shadowRadius": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "rgba(243, 83, 105, 1)",
|
||||
"pressed": "rgba(208, 75, 95, 1)",
|
||||
}
|
||||
}
|
||||
<FooterButton
|
||||
onPress={[Function]}
|
||||
text="Dismiss"
|
||||
/>
|
||||
<FooterButton
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"height": 60,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
Reload
|
||||
</Text>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.8)",
|
||||
"fontSize": 11,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 12,
|
||||
}
|
||||
}
|
||||
>
|
||||
Syntax
|
||||
errors require a full reload
|
||||
</Text>
|
||||
</View>
|
||||
<ForwardRef(SafeAreaView) />
|
||||
</LogBoxButton>
|
||||
text="Close"
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorFooter should render two buttons for warning with no fatal 1`] = `
|
||||
exports[`LogBoxInspectorFooter should render two buttons for warning 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
|
||||
@@ -110,6 +110,49 @@ exports[`LogBoxInspectorHeader should render no buttons for one total 1`] = `
|
||||
</ForwardRef(SafeAreaView)>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorHeader should render syntax error header 1`] = `
|
||||
<ForwardRef(SafeAreaView)
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(243, 83, 105, 1)",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"height": 44,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 20,
|
||||
}
|
||||
}
|
||||
>
|
||||
Failed to compile
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ForwardRef(SafeAreaView)>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorHeader should render two buttons for three or more total 1`] = `
|
||||
<ForwardRef(SafeAreaView)
|
||||
style={
|
||||
|
||||
Reference in new issue
Block a user