fancive_obsidian-parallel-r.../tests/coverage-sourcemap.js
wujunchen 606593e39b test: add c8 coverage harness with source-map remapping
- npm run coverage runs the full suite under c8
- Wire inline source maps into the esbuild test bundles
- Redirect bundles into repo (.test-bundles) under coverage so c8
  processes them; cleaned automatically after the run
- Fix esbuild->v8-to-istanbul source path remap (tests/coverage-sourcemap.js)
- .c8rc.json, .gitignore, dev-dep c8

Note: statement/function totals are degenerate under esbuild bundling;
branch coverage + HTML report are the reliable signals.

Change-Id: I880f5ee1e9a8e5368e27a8e274825f917d972269
2026-05-16 00:22:31 +08:00

42 lines
1.7 KiB
JavaScript

'use strict';
// esbuild emits inline source maps whose `sources` are relative to the bundle
// file (deep under .test-bundles/) with a `sourceRoot`. v8-to-istanbul / the
// source-map library resolve those inconsistently and produce wrong paths like
// `/Users/.../github.com/src/batch.ts`, so c8 finds nothing to report.
//
// This rewrites the inline map in-place so every `source` is an absolute path
// to the real repo file and `sourceRoot` is cleared — making the remap exact.
// No-op when coverage is not active.
const fs = require('fs');
const path = require('path');
const MARKER = '//# sourceMappingURL=data:application/json;base64,';
function fixInlineSourceMap(outfile, repoRoot) {
if (!process.env.NODE_V8_COVERAGE) return;
const code = fs.readFileSync(outfile, 'utf8');
const idx = code.lastIndexOf(MARKER);
if (idx === -1) return;
const b64 = code.slice(idx + MARKER.length).trim();
const map = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));
// esbuild keeps `sources` relative to the bundle file's directory regardless
// of `sourceRoot`; resolving against sourceRoot double-counts and corrupts
// the path. Always resolve against the bundle directory.
const base = path.dirname(outfile);
map.sources = map.sources.map((src) => {
if (src.startsWith('stub:') || src.includes('obsidian-stub')) return src;
const abs = path.resolve(base, src);
// Strip any leftover climbing artifacts; keep the real repo path.
const i = abs.indexOf(repoRoot);
return i === -1 ? abs : abs.slice(i);
});
delete map.sourceRoot;
const fixed = Buffer.from(JSON.stringify(map), 'utf8').toString('base64');
fs.writeFileSync(outfile, code.slice(0, idx) + MARKER + fixed);
}
module.exports = { fixInlineSourceMap };