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
7 changes: 5 additions & 2 deletions .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const [major] = process.versions.node.split('.');
/** @type {import("mocha").MochaOptions} */
module.exports = {
require: [
'source-map-support/register',
'ts-node/register',
'test/tools/runner/source_map.cjs',
'test/tools/runner/throw_rejections.cjs',
'test/tools/runner/chai_addons.ts',
'test/tools/runner/ee_checker.ts'
Expand All @@ -18,5 +18,8 @@ module.exports = {
reporter: 'test/tools/reporter/mongodb_reporter.js',
sort: true,
color: true,
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
'node-option':
Number(major) >= 23
? ['enable-source-maps', 'no-experimental-strip-types']
: ['enable-source-maps']
};
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
"build:bundle": "npm run bundle:driver && npm run bundle:types && npm run build:runtime-barrel",
"build:runtime-barrel": "node etc/build-runtime-barrel.mjs",
"bundle:driver": "node etc/bundle-driver.mjs",
"bundle:types": "npx tsc --project ./tsconfig.json --declaration --emitDeclarationOnly --declarationDir test/tools/runner/bundle/types",
"bundle:types": "node ./node_modules/typescript/bin/tsc --project ./tsconfig.json --declaration --emitDeclarationOnly --declarationDir test/tools/runner/bundle/types",
"fix:eslint": "npm run check:eslint -- --fix",
"prepare": "node etc/prepare.js",
"preview:docs": "ts-node etc/docs/preview.ts",
Expand Down
6 changes: 5 additions & 1 deletion test/manual/mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ const [major] = process.versions.node.split('.');
module.exports = {
require: [
'ts-node/register',
'test/tools/runner/source_map.cjs',
'test/tools/runner/throw_rejections.cjs',
'test/tools/runner/chai_addons.ts'
],
reporter: 'test/tools/reporter/mongodb_reporter.js',
failZero: true,
color: true,
timeout: 10000,
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
'node-option':
Number(major) >= 23
? ['enable-source-maps', 'no-experimental-strip-types']
: ['enable-source-maps']
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change is what makes it all working well. If you get source-map-support back - it will produce correct lines and stack traces (so we will cover both: V8 with this flag for debuggers, and source-map-support covers test output).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, spoke over a call with @nbbeeken and I'll be pushing a change with this and/or the require hook back in places.

};
5 changes: 4 additions & 1 deletion test/mocha_lambda.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ module.exports = {
reporter: 'test/tools/reporter/mongodb_reporter.js',
sort: true,
color: true,
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
'node-option':
Number(major) >= 23
? ['enable-source-maps', 'no-experimental-strip-types']
: ['enable-source-maps']
};
7 changes: 5 additions & 2 deletions test/mocha_mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const [major] = process.versions.node.split('.');
/** @type {import("mocha").MochaOptions} */
module.exports = {
require: [
'source-map-support/register',
'ts-node/register',
'test/tools/runner/source_map.cjs',
'test/tools/runner/throw_rejections.cjs',
'test/tools/runner/chai_addons.ts',
'test/tools/runner/ee_checker.ts',
Expand All @@ -31,5 +31,8 @@ module.exports = {
'test/integration/node-specific/examples/transactions.test.js',
'test/integration/node-specific/examples/versioned_api.js'
],
'node-option': Number(major) >= 23 ? ['no-experimental-strip-types'] : undefined
'node-option':
Number(major) >= 23
? ['enable-source-maps', 'no-experimental-strip-types']
: ['enable-source-maps']
};
5 changes: 0 additions & 5 deletions test/tools/runner/hooks/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
/* eslint-disable simple-import-sort/imports */

// eslint-disable-next-line @typescript-eslint/no-require-imports
require('source-map-support').install({
hookRequire: true
});

import * as process from 'process';
import * as os from 'os';

Expand Down
4 changes: 4 additions & 0 deletions test/tools/runner/source_map.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('source-map-support').install({
hookRequire: true
});
3 changes: 2 additions & 1 deletion test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"compilerOptions": {
"strict": false,
"allowJs": true,
"checkJs": false
"checkJs": false,
"sourceMap": true
},
"include": [
"../node_modules/@types/mocha/index.d.ts",
Expand Down
76 changes: 76 additions & 0 deletions test/unit/source_map.test.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the idea of checking programmatically that the correct line is reported. But the current implementation is a bit flaky: we are hard-coding TS_SOURCE_LINE. What if instead we populate that value during test runtime by reading the test file?

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// These import-type lines are completely erased by the TypeScript compiler
// (no blank-line placeholder is left behind), so the compiled JS has fewer
// lines than this source file. That shifts every subsequent line upward in
// the JS output.
import type { Document as _Doc } from 'bson';
import { expect } from 'chai';

import type {
AbstractCursor as _AbC,
AggregationCursor as _AC,
ChangeStream as _CS,
ClientSession as _Sess,
Collection as _Col,
Db as _Db,
FindCursor as _FC,
GridFSBucket as _GB,
MongoClient as _MC
} from '../../mongodb';

// ─── This Error is created at line 31 in the TypeScript source. ───────────
// The twelve `import type` lines above are erased without replacement, so
// in the compiled JS this falls on line 31 − 12 = line 19.
//
// ts-node's bundled `@cspotcode/source-map-support` patches
// Error.prepareStackTrace so `error.stack` already shows the correct TS
// line. We DISABLE that patch to see what V8 reports natively.
//
// OLD commit (no --enable-source-maps): V8 says line 19 ← WRONG
// NEW commit ( --enable-source-maps): V8 says line 31 ← correct
const TS_SOURCE_LINE = 31; // must match the line below
const errorAtKnownLine = new Error('source-map probe'); // ← line 31

/**
* Capture a raw V8 stack frame by temporarily removing
* `@cspotcode/source-map-support`'s prepareStackTrace override (installed
* by ts-node) so we see exactly what V8 reports — with or without its own
* source-map awareness.
*/
function rawV8FrameOf(err: Error): {
file: string | null;
line: number | null;
col: number | null;
} {
const saved = Error.prepareStackTrace;
// Null → V8 uses its built-in formatter (honours --enable-source-maps).
Error.prepareStackTrace = undefined as unknown as typeof Error.prepareStackTrace;
const raw = err.stack ?? ''; // triggers V8 formatting with no hook
Error.prepareStackTrace = saved;

// First "at …" line: " at Object.<anonymous> (/abs/path/file.ts:LINE:COL)"
const match = raw.split('\n')[1]?.match(/\((.+):(\d+):(\d+)\)$/);
if (!match) return { file: null, line: null, col: null };
return { file: match[1], line: Number(match[2]), col: Number(match[3]) };
}

describe('Source maps', function () {
it('report the correct line number when enabled', function () {
const frame = rawV8FrameOf(errorAtKnownLine);

if (process.env.VERBOSE) {
console.error('\n ── raw V8 frame (prepareStackTrace bypassed) ──');
console.error(` file : ${frame.file}`);
console.error(` line : ${frame.line} (TypeScript source line is ${TS_SOURCE_LINE})`);
console.error(` col : ${frame.col}`);
console.error(
` ${frame.line === TS_SOURCE_LINE ? '✔ line matches TS source' : `✘ line ${frame.line} ≠ TS source line ${TS_SOURCE_LINE} — source maps not applied by V8`}`
);
}
expect(frame.line).to.equal(
TS_SOURCE_LINE,
`V8 reported line ${frame.line} but TypeScript source line is ${TS_SOURCE_LINE}. ` +
`This means --enable-source-maps is absent and V8 is reading the compiled-JS ` +
`line number instead of the original TypeScript line.`
);
});
});