diff options
Diffstat (limited to 'test/js/node/v8/capture-stack-trace.test.js')
-rw-r--r-- | test/js/node/v8/capture-stack-trace.test.js | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/test/js/node/v8/capture-stack-trace.test.js b/test/js/node/v8/capture-stack-trace.test.js new file mode 100644 index 000000000..789503960 --- /dev/null +++ b/test/js/node/v8/capture-stack-trace.test.js @@ -0,0 +1,303 @@ +import { test, expect } from "bun:test"; + +test("capture stack trace", () => { + function f1() { + f2(); + } + + function f2() { + f3(); + } + + function f3() { + logErrorStackTrace(); + } + + function logErrorStackTrace() { + let error = {}; + Error.captureStackTrace(error); + expect(error.stack !== undefined).toBe(true); + } + + f1(); +}); + +test("capture stack trace with message", () => { + function f1() { + f2(); + } + + function f2() { + f3(); + } + + function f3() { + logErrorStackTrace(); + } + + function logErrorStackTrace() { + let e1 = { message: "bad error!" }; + Error.captureStackTrace(e1); + expect(e1.message === "bad error!").toBe(true); + + let e2 = new Error("bad error!"); + Error.captureStackTrace(e2); + expect(e2.message === "bad error!").toBe(true); + } + + f1(); +}); + +test("capture stack trace with constructor", () => { + class S { + constructor() { + captureStackTrace(); + } + } + + function captureStackTrace() { + let e1 = {}; + Error.captureStackTrace(e1); + expect(e1.stack.split("\n")[2].includes("new S")).toBe(true); + } + + let s = new S(); +}); + +test("capture stack trace limit", () => { + function f1() { + f2(); + } + + function f2() { + f3(); + } + + function f3() { + f4(); + } + + function f4() { + f5(); + } + + function f5() { + f6(); + } + + function f6() { + f7(); + } + + function f7() { + f8(); + } + + function f8() { + f9(); + } + + function f9() { + f10(); + } + + function f10() { + captureStackTrace(); + } + + function captureStackTrace() { + let e1 = {}; + Error.captureStackTrace(e1); + expect(e1.stack.split("\n").length).toBe(11); + + let e2 = new Error(); + Error.captureStackTrace(e2); + expect(e2.stack.split("\n").length).toBe(11); + + let e3 = {}; + Error.stackTraceLimit = 4; + Error.captureStackTrace(e3); + expect(e3.stack.split("\n").length).toBe(5); + + let e4 = new Error(); + Error.captureStackTrace(e4); + expect(e4.stack.split("\n").length).toBe(5); + + let e5 = { stackTraceLimit: 2 }; + Error.captureStackTrace(e5); + expect(e5.stack.split("\n").length).toBe(5); + + let e6 = {}; + Error.stackTraceLimit = Infinity; + Error.captureStackTrace(e6); + expect(e6.stack.split("\n").length).toBe(13); + } + + f1(); +}); + +test("prepare stack trace", () => { + function f1() { + f2(); + } + + function f2() { + let e = {}; + let prevPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (e, stack) => { + return "custom stack trace"; + }; + Error.captureStackTrace(e); + expect(e.stack).toBe("custom stack trace"); + Error.prepareStackTrace = prevPrepareStackTrace; + f3(); + } + + function f3() { + let e = { message: "bad error!" }; + let prevPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (e, s) => { + expect(e.message === "bad error!").toBe(true); + expect(s.length).toBe(4); + }; + Error.stackTraceLimit = 10; + Error.captureStackTrace(e); + expect(e.stack === undefined).toBe(true); + Error.prepareStackTrace = prevPrepareStackTrace; + } + + f1(); +}); + +test("capture stack trace second argument", () => { + function f0() { + let s = new S(); + } + + class S { + constructor() { + f1(); + } + } + + function f1() { + f2(); + } + + function f2() { + f3(); + } + + function f3() { + f4(); + } + + function f4() { + f5(); + } + + function f5() { + f6(); + } + + function f6() { + let e = { message: "bad error!" }; + Error.captureStackTrace(e); + expect(e.stack.split("\n")[1].includes("at f6")).toBe(true); + expect(e.stack.split("\n")[2].includes("at f5")).toBe(true); + + let e2 = {}; + Error.captureStackTrace(e2, f3); + expect(e2.stack.split("\n")[1].includes("at f2")).toBe(true); + expect(e2.stack.split("\n")[2].includes("at f1")).toBe(true); + + let e3 = {}; + Error.captureStackTrace(e3, f9); + expect(e3.stack.split("\n").length).toBe(1); + + let e4 = { message: "exclude constructor!" }; + Error.captureStackTrace(e4, S.constructor); + expect(e4.stack.split("\n").length).toBe(1); + + let e5 = { message: "actually exclude constructor!" }; + Error.captureStackTrace(e5, S); + expect(e5.stack.split("\n")[1].includes("at f0")).toBe(true); + } + + function f9() { + // nothing + } + + f0(); +}); + +test("capture stack trace edge cases", () => { + let e1 = {}; + Error.captureStackTrace(e1, null); + expect(e1.stack !== undefined).toBe(true); + + let e2 = {}; + Error.captureStackTrace(e2, undefined); + expect(e2.stack !== undefined).toBe(true); + + let e3 = {}; + Error.captureStackTrace(e3, 1); + expect(e3.stack !== undefined).toBe(true); + + let e4 = {}; + Error.captureStackTrace(e4, "foo"); + expect(e4.stack !== undefined).toBe(true); + + let e5 = {}; + Error.captureStackTrace(e5, {}); + expect(e5.stack !== undefined).toBe(true); + + expect(Error.captureStackTrace({})).toBe(undefined); + expect(Error.captureStackTrace({}, () => {})).toBe(undefined); + expect(Error.captureStackTrace({}, undefined)).toBe(undefined); + expect(Error.captureStackTrace({}, null)).toBe(undefined); + expect(Error.captureStackTrace({}, 1)).toBe(undefined); + expect(Error.captureStackTrace({}, "foo")).toBe(undefined); + expect(Error.captureStackTrace({}, {})).toBe(undefined); + expect(Error.captureStackTrace({}, [])).toBe(undefined); + expect(Error.captureStackTrace({}, true)).toBe(undefined); +}); + +test("prepare stack trace call sites", () => { + function f1() { + f2(); + } + + function f2() { + f3(); + } + + function f3() { + let e = { message: "bad error!" }; + // let e = new Error("bad error!"); + let prevPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = (e, s) => { + expect(s[0].getThis !== undefined).toBe(true); + expect(s[0].getTypeName !== undefined).toBe(true); + expect(s[0].getFunction !== undefined).toBe(true); + expect(s[0].getFunctionName !== undefined).toBe(true); + expect(s[0].getMethodName !== undefined).toBe(true); + expect(s[0].getFileName !== undefined).toBe(true); + expect(s[0].getLineNumber !== undefined).toBe(true); + expect(s[0].getColumnNumber !== undefined).toBe(true); + expect(s[0].getEvalOrigin !== undefined).toBe(true); + expect(s[0].isToplevel !== undefined).toBe(true); + expect(s[0].isEval !== undefined).toBe(true); + expect(s[0].isNative !== undefined).toBe(true); + expect(s[0].isConstructor !== undefined).toBe(true); + expect(s[0].isAsync !== undefined).toBe(true); + expect(s[0].isPromiseAll !== undefined).toBe(true); + expect(s[0].getPromiseIndex !== undefined).toBe(true); + }; + Error.captureStackTrace(e); + expect(e.stack === undefined).toBe(true); + Error.prepareStackTrace = prevPrepareStackTrace; + } + + f1(); +}); |