supercov 4.15.0 → 4.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/cli.md +12 -1
- package/package.json +9 -9
- package/runtime/javascript/register.mjs +83 -15
package/docs/cli.md
CHANGED
|
@@ -246,6 +246,7 @@ after source changes.
|
|
|
246
246
|
npx supercov runs <run-id> assertions assess --dry-run
|
|
247
247
|
npx supercov runs <run-id> assertions assess
|
|
248
248
|
npx supercov runs <run-id> assertions assess --refresh # ask again instead of reusing saved answers
|
|
249
|
+
npx supercov runs <run-id> assertions assess --tag @e2e --dry-run
|
|
249
250
|
npx supercov runs <run-id> assertions
|
|
250
251
|
npx supercov runs <run-id> assertions --all --json
|
|
251
252
|
```
|
|
@@ -258,6 +259,13 @@ and JSON reports expose it under `data.assertionCoverage`. See
|
|
|
258
259
|
[Assertion coverage](assertions.md) for what counts as asserted and how answers
|
|
259
260
|
are reused across runs.
|
|
260
261
|
|
|
262
|
+
`--kind`, `--runner`, `--tag`, `--title` and `--test-file` assess or read some of
|
|
263
|
+
the tests, as they narrow every query. `assess --tag @e2e` asks only those tests
|
|
264
|
+
about the statements they ran and saves the result apart from the run's whole
|
|
265
|
+
assessment; its answers are kept, so a later `assess` asks only what is left.
|
|
266
|
+
`assertions --tag @e2e` reads what those tests assert: a statement that only
|
|
267
|
+
other tests catch is not asserted there.
|
|
268
|
+
|
|
261
269
|
## Fail CI below a coverage floor
|
|
262
270
|
|
|
263
271
|
```sh supercov-example
|
|
@@ -621,7 +629,10 @@ pass in the run is listed regardless.
|
|
|
621
629
|
per line, for a runner's filter. A Vitest, Playwright or node:test test inside
|
|
622
630
|
`describe` blocks is printed as the blocks and the test joined by spaces
|
|
623
631
|
(`small charges`), which is what `vitest -t`, `--grep` and
|
|
624
|
-
`--test-name-pattern` match.
|
|
632
|
+
`--test-name-pattern` match. `--kind`, `--runner`, `--tag`, `--title` and
|
|
633
|
+
`--test-file` list only the affected tests they pick: from a run that merged two
|
|
634
|
+
runners' suites, `tests affected --names --runner playwright` gives Playwright
|
|
635
|
+
only its own tests. A helper beside the tests, or source outside what is
|
|
625
636
|
measured, that changed affects the tests whose files import it (a JavaScript or
|
|
626
637
|
TypeScript helper that only gained functions affects none), and every test
|
|
627
638
|
where Supercov cannot read the imports. A dependency,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supercov",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.0",
|
|
4
4
|
"description": "Coverage, security and code quality for coding agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"coverage",
|
|
@@ -119,14 +119,14 @@
|
|
|
119
119
|
"test:windows-tls": "node scripts/windows-tls-test.mjs"
|
|
120
120
|
},
|
|
121
121
|
"optionalDependencies": {
|
|
122
|
-
"@supercov/cli-darwin-arm64": "4.
|
|
123
|
-
"@supercov/cli-darwin-x64": "4.
|
|
124
|
-
"@supercov/cli-linux-arm64-gnu": "4.
|
|
125
|
-
"@supercov/cli-linux-arm64-musl": "4.
|
|
126
|
-
"@supercov/cli-linux-x64-gnu": "4.
|
|
127
|
-
"@supercov/cli-linux-x64-musl": "4.
|
|
128
|
-
"@supercov/cli-win32-arm64": "4.
|
|
129
|
-
"@supercov/cli-win32-x64": "4.
|
|
122
|
+
"@supercov/cli-darwin-arm64": "4.17.0",
|
|
123
|
+
"@supercov/cli-darwin-x64": "4.17.0",
|
|
124
|
+
"@supercov/cli-linux-arm64-gnu": "4.17.0",
|
|
125
|
+
"@supercov/cli-linux-arm64-musl": "4.17.0",
|
|
126
|
+
"@supercov/cli-linux-x64-gnu": "4.17.0",
|
|
127
|
+
"@supercov/cli-linux-x64-musl": "4.17.0",
|
|
128
|
+
"@supercov/cli-win32-arm64": "4.17.0",
|
|
129
|
+
"@supercov/cli-win32-x64": "4.17.0"
|
|
130
130
|
},
|
|
131
131
|
"peerDependencies": {
|
|
132
132
|
"@playwright/test": ">=1.55.0",
|
|
@@ -604,13 +604,57 @@ else {
|
|
|
604
604
|
return print.apply(this, [kept.join("\\n"), ...message.slice(1)]);
|
|
605
605
|
})(warnOnce)); } catch {}
|
|
606
606
|
`.replace(/\n\s*/g, " ");
|
|
607
|
+
// A project's `turbopack.root`, set to its own directory, names the copy
|
|
608
|
+
// here, while the copy's dependencies are links into the project's
|
|
609
|
+
// node_modules. Turbopack resolves no package outside its root and
|
|
610
|
+
// panicked "Next.js package not found". The root Next settles on is
|
|
611
|
+
// widened to the nearest directory that holds the real `next` package
|
|
612
|
+
// too -- the project, which holds the copy; one that holds it is kept.
|
|
613
|
+
const widened = `
|
|
614
|
+
;try { loadConfig = ((load) => async function loadConfig(...args) {
|
|
615
|
+
const config = await load.apply(this, args);
|
|
616
|
+
try {
|
|
617
|
+
const path = require("path"), fs = require("fs");
|
|
618
|
+
const root = config && config.turbopack && config.turbopack.root;
|
|
619
|
+
if (typeof root === "string") {
|
|
620
|
+
const dir = path.resolve(args[1] || process.cwd());
|
|
621
|
+
const held = [fs.realpathSync(path.dirname(require.resolve("next/package.json", { paths: [dir] })))];
|
|
622
|
+
for (let at = dir; at.includes(path.sep + ".supercov" + path.sep); at = path.dirname(at)) {
|
|
623
|
+
try { held.push(fs.realpathSync(path.join(at, "node_modules"))); } catch {}
|
|
624
|
+
}
|
|
625
|
+
let common = fs.realpathSync(root).split(path.sep);
|
|
626
|
+
for (const target of held) {
|
|
627
|
+
const parts = target.split(path.sep);
|
|
628
|
+
let i = 0;
|
|
629
|
+
while (i < common.length && i < parts.length && common[i] === parts[i]) i++;
|
|
630
|
+
common = common.slice(0, i);
|
|
631
|
+
}
|
|
632
|
+
const widened = common.join(path.sep) || path.sep;
|
|
633
|
+
if (widened !== fs.realpathSync(root)) {
|
|
634
|
+
config.turbopack.root = widened;
|
|
635
|
+
config.outputFileTracingRoot = widened;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
} catch {}
|
|
639
|
+
return config;
|
|
640
|
+
})(loadConfig); } catch {}
|
|
641
|
+
`.replace(/\n\s*/g, " ");
|
|
642
|
+
const append = (content, code) => {
|
|
643
|
+
// After the last statement, before the source map's line.
|
|
644
|
+
const map = content.lastIndexOf("\n//# sourceMappingURL=");
|
|
645
|
+
return map < 0 ? `${content}${code}` : `${content.slice(0, map)}${code}${content.slice(map)}`;
|
|
646
|
+
};
|
|
607
647
|
const compile = Module.prototype._compile;
|
|
608
648
|
Module.prototype._compile = function _compile(content, filename, ...rest) {
|
|
609
|
-
if (typeof content === "string" && typeof filename === "string"
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
649
|
+
if (typeof content === "string" && typeof filename === "string") {
|
|
650
|
+
if (filename.endsWith("log.js") &&
|
|
651
|
+
/[\\/]next[\\/]dist[\\/]build[\\/]output[\\/]log\.js$/.test(filename)) {
|
|
652
|
+
content = append(content, quieted);
|
|
653
|
+
}
|
|
654
|
+
else if (filename.endsWith("config.js") &&
|
|
655
|
+
/[\\/]next[\\/]dist[\\/]server[\\/]config\.js$/.test(filename)) {
|
|
656
|
+
content = append(content, widened);
|
|
657
|
+
}
|
|
614
658
|
}
|
|
615
659
|
return Reflect.apply(compile, this, [content, filename, ...rest]);
|
|
616
660
|
};
|
|
@@ -1096,12 +1140,38 @@ if (process.env.SUPERCOV_CJS_INTERCEPT === "1") {
|
|
|
1096
1140
|
// Avoid paying to import three runner adapters in every launcher.
|
|
1097
1141
|
}
|
|
1098
1142
|
else {
|
|
1099
|
-
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1143
|
+
// Node's module mocks keep the CJS resolver they find when node:test first
|
|
1144
|
+
// loads (`const { _resolveFilename } = Module` in its mock loader). This
|
|
1145
|
+
// preload runs before the command's own `--import`s, so loading node:test
|
|
1146
|
+
// here handed the mock loader the resolver from before `--import tsx`
|
|
1147
|
+
// mapped tsconfig paths: every `@/` import failed in a test that mocked a
|
|
1148
|
+
// module. Where Node requires an ES module without a warning, each adapter
|
|
1149
|
+
// loads on its first request instead, after every preload; elsewhere, as
|
|
1150
|
+
// before, now.
|
|
1151
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
1152
|
+
const lazily = process.features?.require_module === true &&
|
|
1153
|
+
(major > 23 || (major === 23 && minor >= 5) || (major === 22 && minor >= 13) || (major === 20 && minor >= 19));
|
|
1154
|
+
const requireAdapter = Module.createRequire(import.meta.url);
|
|
1155
|
+
const adapters = new Map();
|
|
1156
|
+
const shapes = [
|
|
1157
|
+
["test", nodeTestWrapper, (module) => module.test],
|
|
1158
|
+
["assert", nodeAssertWrapper, (module) => module.default],
|
|
1159
|
+
["assert/strict", nodeAssertStrictWrapper, (module) => module.default],
|
|
1160
|
+
];
|
|
1161
|
+
const adapter = (name) => {
|
|
1162
|
+
if (!adapters.has(name)) {
|
|
1163
|
+
const [, url, main] = shapes.find(([shape]) => shape === name);
|
|
1164
|
+
const module = requireAdapter(fileURLToPath(url));
|
|
1165
|
+
adapters.set(name, Object.assign(main(module), module));
|
|
1166
|
+
}
|
|
1167
|
+
return adapters.get(name);
|
|
1168
|
+
};
|
|
1169
|
+
if (!lazily) {
|
|
1170
|
+
for (const [name, url, main] of shapes) {
|
|
1171
|
+
const module = await import(__rewriteRelativeImportExtension(url));
|
|
1172
|
+
adapters.set(name, Object.assign(main(module), module));
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1105
1175
|
const originalLoad = Module._load;
|
|
1106
1176
|
Module._load = function supercovNodeTestLoad(request, parent, isMain) {
|
|
1107
1177
|
const parentFile = parent?.filename?.replaceAll("\\", "/");
|
|
@@ -1113,12 +1183,10 @@ if (process.env.SUPERCOV_CJS_INTERCEPT === "1") {
|
|
|
1113
1183
|
(request === "node:test" || request === "test"))
|
|
1114
1184
|
console.error("[supercov] node:test CJS request", { parentFile, projectRoot, belongsToProject });
|
|
1115
1185
|
if ((request === "node:test" || request === "test") && belongsToProject)
|
|
1116
|
-
return
|
|
1186
|
+
return adapter("test");
|
|
1117
1187
|
if (["assert", "node:assert", "assert/strict", "node:assert/strict"].includes(request) &&
|
|
1118
1188
|
belongsToProject)
|
|
1119
|
-
return request.endsWith("/strict")
|
|
1120
|
-
? cjsNodeAssertStrictAdapter
|
|
1121
|
-
: cjsNodeAssertAdapter;
|
|
1189
|
+
return adapter(request.endsWith("/strict") ? "assert/strict" : "assert");
|
|
1122
1190
|
return originalLoad.call(this, request, parent, isMain);
|
|
1123
1191
|
};
|
|
1124
1192
|
}
|