Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,6 @@ const COMPONENT_CODE_FRAME: CodeCodeFrame = {
content: 'Component',
};

// We can delete this when we delete legacy component stack types.
function getLogBoxLogLegacy() {
return new (require('../LogBoxLog').default)({
level: 'warn',
isComponentError: false,
message: {content: '...', substitutions: []},
stack: createStack(['A', 'B', 'C']),
category: 'Message category...',
componentStack: [
{
content: 'LogBoxLog',
fileName: 'LogBoxLog.js',
location: {column: -1, row: 1},
},
],
codeFrame: {
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: {row: 199, column: 0},
content: '<code frame>',
},
});
}

function getLogBoxLog() {
return new (require('../LogBoxLog').default)({
level: 'warn',
Expand Down Expand Up @@ -148,243 +125,6 @@ describe('LogBoxLog', () => {
);
});

describe('symbolicate legacy component stacks (no symbolication)', () => {
it('creates a LogBoxLog object', () => {
const log = getLogBoxLogLegacy();

expect(log.level).toEqual('warn');
expect(log.message).toEqual({content: '...', substitutions: []});
expect(log.stack).toEqual(createStack(['A', 'B', 'C']));
expect(log.category).toEqual('Message category...');
expect(log.componentStack).toEqual([
{
content: 'LogBoxLog',
fileName: 'LogBoxLog.js',
location: {column: -1, row: 1},
},
]);
expect(log.codeFrame).toEqual({
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: {row: 199, column: 0},
content: '<code frame>',
});
});

it('increments LogBoxLog count', () => {
const log = getLogBoxLogLegacy();

expect(log.count).toEqual(1);

log.incrementCount();

expect(log.count).toEqual(2);
});

it('starts without a symbolicated stack', () => {
const log = getLogBoxLogLegacy();

expect(log.symbolicated).toEqual({
error: null,
stack: null,
status: 'NONE',
});
});

it('updates when symbolication is in progress', () => {
const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.symbolicate(callback);

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalledTimes(1);
expect(log.symbolicated).toEqual({
error: null,
stack: null,
status: 'PENDING',
});

// Symbolicating while pending should not make more requests.
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();

log.symbolicate(callback);
expect(callback).not.toBeCalled();
expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
});

it('updates when symbolication finishes', async () => {
const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.symbolicate(callback);
expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalled();

await runMicrotasks();

expect(callback).toBeCalledTimes(2);
expect(callback).toBeCalledWith('COMPLETE');
expect(log.symbolicated).toEqual({
error: null,
stack: createStack(['S(A)', 'S(B)', 'S(C)']),
status: 'COMPLETE',
});

// Do not symbolicate again.
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();

log.symbolicate(callback);

await runMicrotasks();

expect(callback).toBeCalledTimes(0);
expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
});

it('updates when symbolication fails', async () => {
const error = new Error('...');
getLogBoxSymbolication().symbolicate.mockImplementation(async stack => {
throw error;
});

const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.symbolicate(callback);
expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalled();

await runMicrotasks();

expect(callback).toBeCalledTimes(2);
expect(callback).toBeCalledWith('FAILED');
expect(log.symbolicated).toEqual({
error,
stack: null,
status: 'FAILED',
});

// Do not symbolicate again, retry if needed.
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();

log.symbolicate(callback);

await runMicrotasks();

expect(callback).toBeCalledTimes(0);
expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
});

it('retry updates when symbolication is in progress', () => {
const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.retrySymbolicate(callback);

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalledTimes(1);
expect(log.symbolicated).toEqual({
error: null,
stack: null,
status: 'PENDING',
});

// Symbolicating while pending should not make more requests.
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();

log.symbolicate(callback);
expect(callback).not.toBeCalled();
expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
});

it('retry updates when symbolication finishes', async () => {
const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.retrySymbolicate(callback);
expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalled();

await runMicrotasks();

expect(callback).toBeCalledTimes(2);
expect(callback).toBeCalledWith('COMPLETE');
expect(log.symbolicated).toEqual({
error: null,
stack: createStack(['S(A)', 'S(B)', 'S(C)']),
status: 'COMPLETE',
});

// Do not symbolicate again
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();

log.retrySymbolicate(callback);
jest.runAllTicks();

expect(callback).toBeCalledTimes(0);
expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
});

it('retry updates when symbolication fails', async () => {
const error = new Error('...');
getLogBoxSymbolication().symbolicate.mockImplementation(async stack => {
throw error;
});

const log = getLogBoxLogLegacy();

const callback = jest.fn();
log.retrySymbolicate(callback);
expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalled();

await runMicrotasks();

expect(callback).toBeCalledTimes(2);
expect(callback).toBeCalledWith('FAILED');
expect(log.symbolicated).toEqual({
error,
stack: null,
status: 'FAILED',
});

// Retry to symbolicate again.
callback.mockClear();
getLogBoxSymbolication().symbolicate.mockClear();
getLogBoxSymbolication().symbolicate.mockImplementation(async stack => ({
stack: createStack(stack.map(frame => `S(${frame.methodName})`)),
codeFrame: null,
}));

log.retrySymbolicate(callback);

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith('PENDING');
expect(getLogBoxSymbolication().symbolicate).toBeCalled();

await runMicrotasks();

expect(callback).toBeCalledTimes(2);
expect(callback).toBeCalledWith('COMPLETE');
expect(log.symbolicated).toEqual({
error: null,
stack: createStack(['S(A)', 'S(B)', 'S(C)']),
status: 'COMPLETE',
});
});
});

describe('symbolicate component stacks', () => {
it('creates a LogBoxLog object', () => {
const log = getLogBoxLog();
Expand Down
Loading
Loading