Skip to content

Commit 228897f

Browse files
author
Sean Milligan
committed
test(NODE-7493): enable source maps for accurate unit test debugging
Pass --enable-source-maps to Node for all mocha configs so V8 resolves inline source maps emitted by ts-node, making the debugger show correct TypeScript file/line locations. Also add sourceMap: true to test/tsconfig.json and ensure bundled test runs reset test/mongodb.ts so stale VM-context state does not affect subsequent debug sessions.
1 parent 24e5705 commit 228897f

7 files changed

Lines changed: 94 additions & 7 deletions

File tree

.mocharc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ module.exports = {
1818
reporter: 'test/tools/reporter/mongodb_reporter.js',
1919
sort: true,
2020
color: true,
21-
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
21+
'node-option':
22+
Number(major) >= 23
23+
? ['enable-source-maps', 'no-experimental-strip-types']
24+
: ['enable-source-maps']
2225
};

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@
141141
"check:dts": "npm run build:bundle && node ./node_modules/typescript/bin/tsc --target es2023 --module commonjs --noEmit mongodb.d.ts && tsd",
142142
"check:search-indexes": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/manual/search-index-management.prose.test.ts",
143143
"check:test": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/integration",
144-
"check:test-bundled": "MONGODB_BUNDLED=true npm run check:test",
144+
"check:test-bundled": "MONGODB_BUNDLED=true npm run check:test; npm run build:runtime-barrel",
145145
"check:unit": "npm run build:bundle && nyc mocha test/unit",
146-
"check:unit-bundled": "MONGODB_BUNDLED=true npm run check:unit",
146+
"check:unit-bundled": "MONGODB_BUNDLED=true npm run check:unit; npm run build:runtime-barrel",
147147
"check:ts": "node ./node_modules/typescript/bin/tsc -v && node ./node_modules/typescript/bin/tsc --noEmit",
148148
"check:atlas": "npm run build:bundle && nyc mocha --config test/manual/mocharc.js test/manual/atlas_connectivity.test.ts",
149149
"check:drivers-atlas-testing": "npm run build:bundle && nyc mocha --config test/mocha_mongodb.js test/atlas/drivers_atlas_testing.test.ts",

test/manual/mocharc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ module.exports = {
1414
failZero: true,
1515
color: true,
1616
timeout: 10000,
17-
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
17+
'node-option':
18+
Number(major) >= 23
19+
? ['enable-source-maps', 'no-experimental-strip-types']
20+
: ['enable-source-maps']
1821
};

test/mocha_lambda.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@ module.exports = {
1717
reporter: 'test/tools/reporter/mongodb_reporter.js',
1818
sort: true,
1919
color: true,
20-
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
20+
'node-option':
21+
Number(major) >= 23
22+
? ['enable-source-maps', 'no-experimental-strip-types']
23+
: ['enable-source-maps']
2124
};

test/mocha_mongodb.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@ module.exports = {
3131
'test/integration/node-specific/examples/transactions.test.js',
3232
'test/integration/node-specific/examples/versioned_api.js'
3333
],
34-
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
34+
'node-option':
35+
Number(major) >= 23
36+
? ['enable-source-maps', 'no-experimental-strip-types']
37+
: ['enable-source-maps']
3538
};

test/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"compilerOptions": {
44
"strict": false,
55
"allowJs": true,
6-
"checkJs": false
6+
"checkJs": false,
7+
"sourceMap": true
78
},
89
"include": [
910
"../node_modules/@types/mocha/index.d.ts",

test/unit/sourcemap_demo.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// These import-type lines are completely erased by the TypeScript compiler
2+
// (no blank-line placeholder is left behind), so the compiled JS has fewer
3+
// lines than this source file. That shifts every subsequent line upward in
4+
// the JS output.
5+
import type { Document as _Doc } from 'bson';
6+
import { expect } from 'chai';
7+
8+
import type {
9+
AbstractCursor as _AbC,
10+
AggregationCursor as _AC,
11+
ChangeStream as _CS,
12+
ClientSession as _Sess,
13+
Collection as _Col,
14+
Db as _Db,
15+
FindCursor as _FC,
16+
GridFSBucket as _GB,
17+
MongoClient as _MC
18+
} from '../../mongodb';
19+
20+
// ─── This Error is created at line 31 in the TypeScript source. ───────────
21+
// The twelve `import type` lines above are erased without replacement, so
22+
// in the compiled JS this falls on line 31 − 12 = line 19.
23+
//
24+
// source-map-support patches Error.prepareStackTrace so `error.stack`
25+
// already shows the correct TS line. The demo below DISABLES that patch
26+
// temporarily so we can see what V8 reports natively.
27+
//
28+
// OLD commit (no --enable-source-maps): V8 says line 19 ← WRONG
29+
// NEW commit ( --enable-source-maps): V8 says line 31 ← correct
30+
const TS_SOURCE_LINE = 31; // must match the line below
31+
const errorAtKnownLine = new Error('source-map probe'); // ← line 31
32+
33+
/**
34+
* Capture a raw V8 stack frame by temporarily removing
35+
* source-map-support's prepareStackTrace override so we see exactly what
36+
* V8 reports — with or without its own source-map awareness.
37+
*/
38+
function rawV8FrameOf(err: Error): {
39+
file: string | null;
40+
line: number | null;
41+
col: number | null;
42+
} {
43+
const saved = Error.prepareStackTrace;
44+
// Null → V8 uses its built-in formatter (honours --enable-source-maps).
45+
Error.prepareStackTrace = undefined as unknown as typeof Error.prepareStackTrace;
46+
const raw = err.stack ?? ''; // triggers V8 formatting with no hook
47+
Error.prepareStackTrace = saved;
48+
49+
// First "at …" line: " at Object.<anonymous> (/abs/path/file.ts:LINE:COL)"
50+
const match = raw.split('\n')[1]?.match(/\((.+):(\d+):(\d+)\)$/);
51+
if (!match) return { file: null, line: null, col: null };
52+
return { file: match[1], line: Number(match[2]), col: Number(match[3]) };
53+
}
54+
55+
describe('Source map verification (NODE-7493)', function () {
56+
it('V8 native stack frame reports correct TypeScript line number', function () {
57+
const frame = rawV8FrameOf(errorAtKnownLine);
58+
59+
console.log('\n ── raw V8 frame (prepareStackTrace bypassed) ──');
60+
console.log(` file : ${frame.file}`);
61+
console.log(` line : ${frame.line} (TypeScript source line is ${TS_SOURCE_LINE})`);
62+
console.log(` col : ${frame.col}`);
63+
console.log(
64+
` ${frame.line === TS_SOURCE_LINE ? '✔ line matches TS source' : `✘ line ${frame.line} ≠ TS source line ${TS_SOURCE_LINE} — source maps not applied by V8`}`
65+
);
66+
67+
expect(frame.line).to.equal(
68+
TS_SOURCE_LINE,
69+
`V8 reported line ${frame.line} but TypeScript source line is ${TS_SOURCE_LINE}. ` +
70+
`This means --enable-source-maps is absent and V8 is reading the compiled-JS ` +
71+
`line number instead of the original TypeScript line.`
72+
);
73+
});
74+
});

0 commit comments

Comments
 (0)