coverage-check 0.2.2 → 0.2.3

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.
@@ -35,6 +35,7 @@ export async function runCheck(args) {
35
35
  const stripPrefixes = buildStripPrefixes(args.stripPrefixes);
36
36
  const reports = [];
37
37
  const suiteSources = [];
38
+ const parsedSources = [];
38
39
  if (args.store !== null) {
39
40
  const suites = await args.store.list();
40
41
  for (const suite of suites) {
@@ -45,6 +46,7 @@ export async function runCheck(args) {
45
46
  const lcov = parseLcov(buf.toString("utf8"), stripPrefixes);
46
47
  reports.push(lcov);
47
48
  suiteSources.push({ suite, source: "store", lcov });
49
+ parsedSources.push({ name: `suite '${suite}'`, lcov });
48
50
  }
49
51
  }
50
52
  }
@@ -54,6 +56,7 @@ export async function runCheck(args) {
54
56
  const lcov = parseLcov(readFileSync(f, "utf8"), stripPrefixes);
55
57
  reports.push(lcov);
56
58
  freshLcovs.push(lcov);
59
+ parsedSources.push({ name: `file '${f}'`, lcov });
57
60
  }
58
61
  if (freshLcovs.length > 0) {
59
62
  suiteSources.push({
@@ -75,6 +78,27 @@ export async function runCheck(args) {
75
78
  stderr(`coverage-check: git diff failed: ${err}`);
76
79
  return 2;
77
80
  }
81
+ if (diff.size > 0) {
82
+ for (const { name, lcov: sourceLcov } of parsedSources) {
83
+ let contributes = false;
84
+ for (const [file, changedLines] of diff) {
85
+ const fileLines = sourceLcov.get(file);
86
+ if (fileLines) {
87
+ for (const lineNo of changedLines) {
88
+ if (fileLines.has(lineNo)) {
89
+ contributes = true;
90
+ break;
91
+ }
92
+ }
93
+ }
94
+ if (contributes)
95
+ break;
96
+ }
97
+ if (!contributes) {
98
+ stderr(`coverage-check: warning: coverage from ${name} contributed 0 coverable lines to the patch result. This may indicate a path prefix mismatch.`);
99
+ }
100
+ }
101
+ }
78
102
  const { buckets, informational } = computePatchCoverage(diff, lcov, rules);
79
103
  const passed = buckets.every((b) => b.passed);
80
104
  const result = { buckets, informational, passed };
@@ -11,13 +11,21 @@ export function parseLcov(text, stripPrefixes = []) {
11
11
  const line = raw.trimEnd();
12
12
  if (line.startsWith("SF:")) {
13
13
  let path = line.slice(3);
14
+ let stripped = false;
14
15
  for (const prefix of stripPrefixes) {
15
16
  if (path.startsWith(prefix)) {
16
17
  path = path.slice(prefix.length);
18
+ stripped = true;
17
19
  break;
18
20
  }
19
21
  }
20
22
  path = normalizePath(path);
23
+ if (!stripped && (path.startsWith("/") || /^[A-Z]:\//i.test(path))) {
24
+ const match = path.match(/^.*?\/_?work\/([^/]+)\/\1\//);
25
+ if (match) {
26
+ path = path.slice(match[0].length);
27
+ }
28
+ }
21
29
  currentLines = result.get(path) ?? new Map();
22
30
  result.set(path, currentLines);
23
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coverage-check",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Patch-coverage gate: checks that newly added lines meet per-path coverage thresholds. Supports per-suite LCOV accumulation for conditional CI.",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Ong",