Refactor types + tests of parseHermesStack

Summary:
Changelog: [Internal]

* Migrate `parseHermesStack.js` to modern Flow syntax
* Use inline snapshots in `parseHermesStack-test.js`

Reviewed By: jacdebug

Differential Revision: D42367093

fbshipit-source-id: 854b11283729ce9f3c2ea6e3b0c46c7f7a767a56
This commit is contained in:
Moti Zilberman
2023-01-05 07:28:22 -08:00
committed by Facebook GitHub Bot
parent cb9eaa6db0
commit b4d4e85aa8
3 changed files with 159 additions and 170 deletions
@@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`parseHermesStack bytecode location 1`] = `
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"line1Based": 1,
"sourceUrl": "unknown",
"type": "BYTECODE",
"virtualOffset0Based": 9,
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"line1Based": 10,
"sourceUrl": "/js/foo.hbc",
"type": "BYTECODE",
"virtualOffset0Based": 1234,
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`;
exports[`parseHermesStack ignore frames that are part of message 1`] = `
Object {
"entries": Array [
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "The next line is not a stack frame
at bogus (filename:1:2)
but the real stack trace follows below.",
}
`;
exports[`parseHermesStack skipped frames 1`] = `
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"count": 50,
"type": "SKIPPED",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`;
exports[`parseHermesStack source location 1`] = `
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`;
exports[`parseHermesStack tolerate empty filename 1`] = `
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`;
@@ -23,7 +23,33 @@ describe('parseHermesStack', () => {
' at foo$bar (address at /js/foo.hbc:10:1234)',
].join('\n'),
),
).toMatchSnapshot();
).toMatchInlineSnapshot(`
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"line1Based": 1,
"sourceUrl": "unknown",
"type": "BYTECODE",
"virtualOffset0Based": 9,
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"line1Based": 10,
"sourceUrl": "/js/foo.hbc",
"type": "BYTECODE",
"virtualOffset0Based": 1234,
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`);
});
test('source location', () => {
@@ -35,7 +61,33 @@ describe('parseHermesStack', () => {
' at foo$bar (/js/foo.js:10:1234)',
].join('\n'),
),
).toMatchSnapshot();
).toMatchInlineSnapshot(`
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`);
});
test('tolerate empty filename', () => {
@@ -47,7 +99,33 @@ describe('parseHermesStack', () => {
' at foo$bar (:10:1234)',
].join('\n'),
),
).toMatchSnapshot();
).toMatchInlineSnapshot(`
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`);
});
test('skipped frames', () => {
@@ -60,7 +138,37 @@ describe('parseHermesStack', () => {
' at foo$bar (/js/foo.js:10:1234)',
].join('\n'),
),
).toMatchSnapshot();
).toMatchInlineSnapshot(`
Object {
"entries": Array [
Object {
"functionName": "global",
"location": Object {
"column1Based": 9,
"line1Based": 1,
"sourceUrl": "unknown",
"type": "SOURCE",
},
"type": "FRAME",
},
Object {
"count": 50,
"type": "SKIPPED",
},
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "TypeError: undefined is not a function",
}
`);
});
test('ignore frames that are part of message', () => {
@@ -73,6 +181,24 @@ describe('parseHermesStack', () => {
' at foo$bar (/js/foo.js:10:1234)',
].join('\n'),
),
).toMatchSnapshot();
).toMatchInlineSnapshot(`
Object {
"entries": Array [
Object {
"functionName": "foo$bar",
"location": Object {
"column1Based": 1234,
"line1Based": 10,
"sourceUrl": "/js/foo.js",
"type": "SOURCE",
},
"type": "FRAME",
},
],
"message": "The next line is not a stack frame
at bogus (filename:1:2)
but the real stack trace follows below.",
}
`);
});
});
+28 -28
View File
@@ -10,46 +10,46 @@
'use strict';
type HermesStackLocationNative = {|
+type: 'NATIVE',
|};
type HermesStackLocationNative = $ReadOnly<{
type: 'NATIVE',
}>;
type HermesStackLocationSource = {|
+type: 'SOURCE',
+sourceUrl: string,
+line1Based: number,
+column1Based: number,
|};
type HermesStackLocationSource = $ReadOnly<{
type: 'SOURCE',
sourceUrl: string,
line1Based: number,
column1Based: number,
}>;
type HermesStackLocationBytecode = {|
+type: 'BYTECODE',
+sourceUrl: string,
+line1Based: number,
+virtualOffset0Based: number,
|};
type HermesStackLocationBytecode = $ReadOnly<{
type: 'BYTECODE',
sourceUrl: string,
line1Based: number,
virtualOffset0Based: number,
}>;
type HermesStackLocation =
| HermesStackLocationNative
| HermesStackLocationSource
| HermesStackLocationBytecode;
type HermesStackEntryFrame = {|
+type: 'FRAME',
+location: HermesStackLocation,
+functionName: string,
|};
type HermesStackEntryFrame = $ReadOnly<{
type: 'FRAME',
location: HermesStackLocation,
functionName: string,
}>;
type HermesStackEntrySkipped = {|
+type: 'SKIPPED',
+count: number,
|};
type HermesStackEntrySkipped = $ReadOnly<{
type: 'SKIPPED',
count: number,
}>;
type HermesStackEntry = HermesStackEntryFrame | HermesStackEntrySkipped;
export type HermesParsedStack = {|
+message: string,
+entries: $ReadOnlyArray<HermesStackEntry>,
|};
export type HermesParsedStack = $ReadOnly<{
message: string,
entries: $ReadOnlyArray<HermesStackEntry>,
}>;
// Capturing groups:
// 1. function name