Files
bun.sh/test/cli/run/enable-source-maps.test.ts
Claude Bot 1f06b43d30 WIP: implement --enable-source-maps flag
- Add --enable-source-maps CLI flag to Arguments.zig
- Set JSSourceMap flag when --enable-source-maps is passed
- Add tryLoadExternalSourceMap to load external and inline sourcemaps
- Add test for --enable-source-maps functionality

Status: CLI flag works, findSourceMap API works, but stack traces not yet remapped.
Next: Debug why stack traces aren't being remapped despite code being in place.
2025-10-09 15:06:07 +00:00

177 lines
6.8 KiB
TypeScript

import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDir } from "harness";
test("--enable-source-maps should use user-provided inline source maps in stack traces", async () => {
// Create a transpiled file with an inline source map
// Original source:
// function throwError() {
// throw new Error("original error");
// }
// throwError();
const originalSource = `function throwError() {
throw new Error("original error");
}
throwError();`;
// Transpiled (minified) version with inline sourcemap
const transpiledWithSourceMap = `function a(){throw new Error("original error")}a();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIHRocm93RXJyb3IoKSB7XG4gIHRocm93IG5ldyBFcnJvcihcIm9yaWdpbmFsIGVycm9yXCIpO1xufVxudGhyb3dFcnJvcigpOyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBQUEsSUFDRSxNQUFNLElBQUksTUFBTSxnQkFDbEIsQ0FDQUEsR0FBQSIsIm5hbWVzIjpbInRocm93RXJyb3IiXX0=`;
using dir = tempDir("enable-source-maps", {
"input.js": transpiledWithSourceMap,
});
// Test WITHOUT --enable-source-maps: should show transpiled locations
{
await using proc = Bun.spawn({
cmd: [bunExe(), "input.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(1);
// Without --enable-source-maps, the error should reference the transpiled file
// The error occurs at function 'a()' not 'throwError()'
expect(stderr).toContain("input.js");
// Stack trace should NOT show the original function name
expect(stderr).not.toContain("throwError");
}
// Test WITH --enable-source-maps: should show original source locations
{
await using proc = Bun.spawn({
cmd: [bunExe(), "--enable-source-maps", "input.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(1);
// With --enable-source-maps, the error should reference the original source
expect(stderr).toContain("input.ts");
// Stack trace SHOULD show the original function name
expect(stderr).toContain("throwError");
}
});
test("--enable-source-maps should use external source map files", async () => {
// Create a file with an external source map reference
const transpiledCode = `function a(){throw new Error("test error")}a();
//# sourceMappingURL=output.js.map`;
// Create the external source map file
const sourceMap = {
version: 3,
sources: ["original.ts"],
sourcesContent: ['function throwError() {\n throw new Error("test error");\n}\nthrowError();'],
mappings: "AAAA,SAASA,IACE,MAAM,IAAI,MAAM,aAClB,CACAA,GAAA",
names: ["throwError"],
};
using dir = tempDir("enable-source-maps-external", {
"output.js": transpiledCode,
"output.js.map": JSON.stringify(sourceMap),
});
// Test WITHOUT --enable-source-maps
{
await using proc = Bun.spawn({
cmd: [bunExe(), "output.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(1);
expect(stderr).toContain("output.js");
expect(stderr).not.toContain("original.ts");
}
// Test WITH --enable-source-maps
{
await using proc = Bun.spawn({
cmd: [bunExe(), "--enable-source-maps", "output.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(1);
// With --enable-source-maps, should reference original source
expect(stderr).toContain("original.ts");
expect(stderr).toContain("throwError");
}
});
test("--enable-source-maps should work with findSourceMap from node:module", async () => {
const code = `import { findSourceMap } from "node:module";
const sourceMap = findSourceMap(import.meta.path);
if (!sourceMap) {
console.error("No source map found");
process.exit(1);
}
console.log("Source map found!");
console.log("Has payload:", !!sourceMap.payload);
console.log("Has findEntry:", typeof sourceMap.findEntry === "function");
process.exit(0);
`;
const transpiledWithSourceMap = `import{findSourceMap as a}from"node:module";const b=a(import.meta.path);if(!b){console.error("No source map found");process.exit(1)}console.log("Source map found!");console.log("Has payload:",!!b.payload);console.log("Has findEntry:",typeof b.findEntry==="function");process.exit(0);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZmluZFNvdXJjZU1hcCB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuXG5jb25zdCBzb3VyY2VNYXAgPSBmaW5kU291cmNlTWFwKGltcG9ydC5tZXRhLnBhdGgpO1xuXG5pZiAoIXNvdXJjZU1hcCkge1xuICBjb25zb2xlLmVycm9yKFwiTm8gc291cmNlIG1hcCBmb3VuZFwiKTtcbiAgcHJvY2Vzcy5leGl0KDEpO1xufVxuXG5jb25zb2xlLmxvZyhcIlNvdXJjZSBtYXAgZm91bmQhXCIpO1xuY29uc29sZS5sb2coXCJIYXMgcGF5bG9hZDpcIiwgISFzb3VyY2VNYXAucGF5bG9hZCk7XG5jb25zb2xlLmxvZyhcIkhhcyBmaW5kRW50cnk6XCIsIHR5cGVvZiBzb3VyY2VNYXAuZmluZEVudHJ5ID09PSBcImZ1bmN0aW9uXCIpO1xucHJvY2Vzcy5leGl0KDApOyJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsT0FBQUEsZUFBQUEsS0FBQSxlQUFBLENBRVAsTUFBTUMsRUFBQUQsRUFBQUEsT0FBQUEsS0FBQUEsS0FBQSxLQUFBLENBRUEsR0FBQSxDQUFBQyxFQUFBLENBQ0EsUUFBQSxNQUFBLHFCQUFBLEVBQ0EsUUFBQSxLQUFBLEVBQUEsQ0FDQSxDQUVBLFFBQUEsSUFBQSxvQkFBQSxFQUNBLFFBQUEsSUFBQSxlQUFBLENBQUEsQ0FBQUEsRUFBQSxRQUFBLEVBQ0EsUUFBQSxJQUFBLGdCQUFBLE9BQU9BLEVBQUEsV0FBQSxXQUFBLEVBQ1AsUUFBQSxLQUFBLEVBQUEiLCJuYW1lcyI6WyJmaW5kU291cmNlTWFwIiwic291cmNlTWFwIl19`;
using dir = tempDir("enable-source-maps-api", {
"test.js": transpiledWithSourceMap,
});
// Test WITHOUT --enable-source-maps: should not find source map
{
await using proc = Bun.spawn({
cmd: [bunExe(), "test.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(1);
expect(stderr).toContain("No source map found");
}
// Test WITH --enable-source-maps: should find source map
{
await using proc = Bun.spawn({
cmd: [bunExe(), "--enable-source-maps", "test.js"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(exitCode).toBe(0);
expect(stdout).toContain("Source map found!");
expect(stdout).toContain("Has payload: true");
expect(stdout).toContain("Has findEntry: function");
}
});