@ng-prism/plugin-coverage 22.2.0-beta.4 → 22.2.0-beta.5
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/dist/coverage-contributions.d.ts +13 -0
- package/dist/coverage-contributions.d.ts.map +1 -0
- package/dist/coverage-contributions.js +41 -0
- package/dist/coverage-header-badge.component.d.ts +1 -3
- package/dist/coverage-header-badge.component.d.ts.map +1 -1
- package/dist/coverage-header-badge.component.js +7 -10
- package/dist/coverage-panel.component.js +1 -1
- package/dist/coverage-plugin.browser.d.ts.map +1 -1
- package/dist/coverage-plugin.browser.js +3 -0
- package/dist/coverage-plugin.d.ts.map +1 -1
- package/dist/coverage-plugin.js +11 -1
- package/dist/coverage-summary.d.ts +13 -0
- package/dist/coverage-summary.d.ts.map +1 -0
- package/dist/coverage-summary.js +21 -0
- package/dist/coverage.types.d.ts +9 -0
- package/dist/coverage.types.d.ts.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NavigationDecorationDefinition, PanelBadge, RuntimeComponent } from '@ng-prism/core/plugin';
|
|
2
|
+
/**
|
|
3
|
+
* The score on the panel's own tab.
|
|
4
|
+
*
|
|
5
|
+
* Declared by the plugin rather than left to the core's built-in badge chain,
|
|
6
|
+
* which graded every score on a fixed 90/70 scale and so could paint the tab
|
|
7
|
+
* red for a component the navigation marker — reading this plugin's configured
|
|
8
|
+
* thresholds — called amber. The `summary` written at build time wins when it
|
|
9
|
+
* is there; deriving from `thresholds` covers the run where it is not.
|
|
10
|
+
*/
|
|
11
|
+
export declare function coverageBadge(component: RuntimeComponent): PanelBadge | null;
|
|
12
|
+
export declare const COVERAGE_NAVIGATION_DECORATION: NavigationDecorationDefinition;
|
|
13
|
+
//# sourceMappingURL=coverage-contributions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-contributions.d.ts","sourceRoot":"","sources":["../src/coverage-contributions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,UAAU,EACV,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAiB/B;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAW5E;AAED,eAAO,MAAM,8BAA8B,EAAE,8BAU5C,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { deriveCoverageSummary } from './coverage-summary.js';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime contributions both entry points declare. `coverage-plugin.ts`
|
|
4
|
+
* carries the build-time hook and must never be reachable from a browser
|
|
5
|
+
* bundle, so the browser entry cannot import through it.
|
|
6
|
+
*/
|
|
7
|
+
function componentMeta(component) {
|
|
8
|
+
return (component.meta?.showcaseConfig?.meta?.['coverage'] ?? null);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The score on the panel's own tab.
|
|
12
|
+
*
|
|
13
|
+
* Declared by the plugin rather than left to the core's built-in badge chain,
|
|
14
|
+
* which graded every score on a fixed 90/70 scale and so could paint the tab
|
|
15
|
+
* red for a component the navigation marker — reading this plugin's configured
|
|
16
|
+
* thresholds — called amber. The `summary` written at build time wins when it
|
|
17
|
+
* is there; deriving from `thresholds` covers the run where it is not.
|
|
18
|
+
*/
|
|
19
|
+
export function coverageBadge(component) {
|
|
20
|
+
const meta = componentMeta(component);
|
|
21
|
+
if (!meta?.found)
|
|
22
|
+
return null;
|
|
23
|
+
const variant = meta.summary?.variant ??
|
|
24
|
+
(meta.thresholds
|
|
25
|
+
? deriveCoverageSummary(meta.score, meta.thresholds).variant
|
|
26
|
+
: 'default');
|
|
27
|
+
return { text: String(meta.score), variant };
|
|
28
|
+
}
|
|
29
|
+
export const COVERAGE_NAVIGATION_DECORATION = {
|
|
30
|
+
id: 'coverage',
|
|
31
|
+
icon: 'shield-check',
|
|
32
|
+
order: 30,
|
|
33
|
+
badge: (component) => {
|
|
34
|
+
const meta = componentMeta(component);
|
|
35
|
+
if (!meta?.found || !meta.summary)
|
|
36
|
+
return null;
|
|
37
|
+
if (meta.summary.variant === 'ok')
|
|
38
|
+
return null;
|
|
39
|
+
return { variant: meta.summary.variant, label: meta.summary.label };
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
type Variant = 'ok' | 'warn' | 'danger';
|
|
3
2
|
export declare class CoverageHeaderBadgeComponent {
|
|
4
3
|
private readonly manifest;
|
|
5
4
|
protected readonly data: import("@angular/core").Signal<{
|
|
6
5
|
score: number;
|
|
7
|
-
variant:
|
|
6
|
+
variant: "ok" | "warn" | "danger";
|
|
8
7
|
title: string;
|
|
9
8
|
} | null>;
|
|
10
9
|
static ɵfac: i0.ɵɵFactoryDeclaration<CoverageHeaderBadgeComponent, never>;
|
|
11
10
|
static ɵcmp: i0.ɵɵComponentDeclaration<CoverageHeaderBadgeComponent, "prism-coverage-header-badge", never, {}, {}, never, never, true, never>;
|
|
12
11
|
}
|
|
13
|
-
export {};
|
|
14
12
|
//# sourceMappingURL=coverage-header-badge.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-header-badge.component.d.ts","sourceRoot":"","sources":["../src/coverage-header-badge.component.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"coverage-header-badge.component.d.ts","sourceRoot":"","sources":["../src/coverage-header-badge.component.ts"],"names":[],"mappings":";AAWA,qBAqFa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IAEpE,SAAS,CAAC,QAAQ,CAAC,IAAI;;;;cAqBpB;yCAxBQ,4BAA4B;2CAA5B,4BAA4B;CAyBxC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, computed, inject, } from '@angular/core';
|
|
2
2
|
import { PRISM_MANIFEST } from '@ng-prism/core/plugin';
|
|
3
|
+
import { deriveCoverageSummary } from './coverage-summary.js';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
function CoverageHeaderBadgeComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
5
6
|
i0.ɵɵdomElementStart(0, "span", 1);
|
|
@@ -26,17 +27,13 @@ export class CoverageHeaderBadgeComponent {
|
|
|
26
27
|
if (!meta?.total?.found)
|
|
27
28
|
return null;
|
|
28
29
|
const score = meta.total.score;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const variant = score
|
|
32
|
-
? 'ok'
|
|
33
|
-
: score >= avgThreshold * 0.75
|
|
34
|
-
? 'warn'
|
|
35
|
-
: 'danger';
|
|
30
|
+
// Both halves come from the one derivation, so the pill's first line and
|
|
31
|
+
// the navigation marker's tooltip cannot name different targets.
|
|
32
|
+
const { variant, label } = deriveCoverageSummary(score, meta.thresholds);
|
|
36
33
|
return {
|
|
37
34
|
score,
|
|
38
35
|
variant,
|
|
39
|
-
title: `Library
|
|
36
|
+
title: `Library ${label}\n` +
|
|
40
37
|
`Lines ${meta.total.lines.pct}% · ` +
|
|
41
38
|
`Branches ${meta.total.branches.pct}% · ` +
|
|
42
39
|
`Functions ${meta.total.functions.pct}% · ` +
|
|
@@ -50,7 +47,7 @@ export class CoverageHeaderBadgeComponent {
|
|
|
50
47
|
} if (rf & 2) {
|
|
51
48
|
let tmp_0_0;
|
|
52
49
|
i0.ɵɵconditional((tmp_0_0 = ctx.data()) ? 0 : -1, tmp_0_0);
|
|
53
|
-
} }, styles: ["[_nghost-%COMP%] { display: inline-flex; align-items: center; }\n\n .cov-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(
|
|
50
|
+
} }, styles: ["[_nghost-%COMP%] { display: inline-flex; align-items: center; }\n\n .cov-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--%NS%font-mono);\n font-size: var(--%NS%fs-xs);\n padding: 2px 10px;\n border-radius: 9999px;\n line-height: 1.4;\n border: 1px solid var(--%NS%prism-border);\n background: var(--%NS%prism-input-bg);\n color: var(--%NS%prism-text-muted);\n white-space: nowrap;\n }\n\n .cov-pill__dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n }\n\n .cov-pill__label[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text-ghost);\n letter-spacing: 0.02em;\n }\n\n .cov-pill__value[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text);\n font-weight: 600;\n }\n .cov-pill__value[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 1px;\n color: var(--%NS%prism-text-muted);\n font-weight: 500;\n }\n\n .cov-pill--ok[_ngcontent-%COMP%] {\n color: var(--%NS%prism-success);\n border-color: color-mix(in srgb, var(--%NS%prism-success) 35%, transparent);\n background: color-mix(in srgb, var(--%NS%prism-success) 12%, transparent);\n }\n .cov-pill--ok[_ngcontent-%COMP%] .cov-pill__label[_ngcontent-%COMP%], \n .cov-pill--ok[_ngcontent-%COMP%] .cov-pill__value[_ngcontent-%COMP%] { color: var(--%NS%prism-success); }\n\n .cov-pill--warn[_ngcontent-%COMP%] {\n color: var(--%NS%prism-warn);\n border-color: color-mix(in srgb, var(--%NS%prism-warn) 35%, transparent);\n background: color-mix(in srgb, var(--%NS%prism-warn) 12%, transparent);\n }\n .cov-pill--warn[_ngcontent-%COMP%] .cov-pill__label[_ngcontent-%COMP%], \n .cov-pill--warn[_ngcontent-%COMP%] .cov-pill__value[_ngcontent-%COMP%] { color: var(--%NS%prism-warn); }\n\n .cov-pill--danger[_ngcontent-%COMP%] {\n color: var(--%NS%prism-danger);\n border-color: color-mix(in srgb, var(--%NS%prism-danger) 35%, transparent);\n background: color-mix(in srgb, var(--%NS%prism-danger) 12%, transparent);\n }\n .cov-pill--danger[_ngcontent-%COMP%] .cov-pill__label[_ngcontent-%COMP%], \n .cov-pill--danger[_ngcontent-%COMP%] .cov-pill__value[_ngcontent-%COMP%] { color: var(--%NS%prism-danger); }"] });
|
|
54
51
|
}
|
|
55
52
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CoverageHeaderBadgeComponent, [{
|
|
56
53
|
type: Component,
|
|
@@ -70,4 +67,4 @@ export class CoverageHeaderBadgeComponent {
|
|
|
70
67
|
}
|
|
71
68
|
`, styles: ["\n :host { display: inline-flex; align-items: center; }\n\n .cov-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: var(--font-mono);\n font-size: var(--fs-xs);\n padding: 2px 10px;\n border-radius: 9999px;\n line-height: 1.4;\n border: 1px solid var(--prism-border);\n background: var(--prism-input-bg);\n color: var(--prism-text-muted);\n white-space: nowrap;\n }\n\n .cov-pill__dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n }\n\n .cov-pill__label {\n color: var(--prism-text-ghost);\n letter-spacing: 0.02em;\n }\n\n .cov-pill__value {\n color: var(--prism-text);\n font-weight: 600;\n }\n .cov-pill__value small {\n font-size: 9px;\n margin-left: 1px;\n color: var(--prism-text-muted);\n font-weight: 500;\n }\n\n .cov-pill--ok {\n color: var(--prism-success);\n border-color: color-mix(in srgb, var(--prism-success) 35%, transparent);\n background: color-mix(in srgb, var(--prism-success) 12%, transparent);\n }\n .cov-pill--ok .cov-pill__label,\n .cov-pill--ok .cov-pill__value { color: var(--prism-success); }\n\n .cov-pill--warn {\n color: var(--prism-warn);\n border-color: color-mix(in srgb, var(--prism-warn) 35%, transparent);\n background: color-mix(in srgb, var(--prism-warn) 12%, transparent);\n }\n .cov-pill--warn .cov-pill__label,\n .cov-pill--warn .cov-pill__value { color: var(--prism-warn); }\n\n .cov-pill--danger {\n color: var(--prism-danger);\n border-color: color-mix(in srgb, var(--prism-danger) 35%, transparent);\n background: color-mix(in srgb, var(--prism-danger) 12%, transparent);\n }\n .cov-pill--danger .cov-pill__label,\n .cov-pill--danger .cov-pill__value { color: var(--prism-danger); }\n "] }]
|
|
72
69
|
}], null, null); })();
|
|
73
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CoverageHeaderBadgeComponent, { className: "CoverageHeaderBadgeComponent", filePath: "coverage-header-badge.component.ts", lineNumber:
|
|
70
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CoverageHeaderBadgeComponent, { className: "CoverageHeaderBadgeComponent", filePath: "coverage-header-badge.component.ts", lineNumber: 97 }); })();
|
|
@@ -145,7 +145,7 @@ export class CoveragePanelComponent {
|
|
|
145
145
|
i0.ɵɵconditionalCreate(0, CoveragePanelComponent_Conditional_0_Template, 5, 1, "div", 0)(1, CoveragePanelComponent_Conditional_1_Template, 3, 0, "div", 1);
|
|
146
146
|
} if (rf & 2) {
|
|
147
147
|
i0.ɵɵconditional(ctx.coverage()?.found ? 0 : 1);
|
|
148
|
-
} }, styles: ["[_nghost-%COMP%] { display: block; height: 100%; overflow: auto; }\n\n .cov-body[_ngcontent-%COMP%] { padding: 20px 24px; }\n\n .cov-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 18px;\n }\n\n .cov-stat[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(
|
|
148
|
+
} }, styles: ["[_nghost-%COMP%] { display: block; height: 100%; overflow: auto; }\n\n .cov-body[_ngcontent-%COMP%] { padding: 20px 24px; }\n\n .cov-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 18px;\n }\n\n .cov-stat[_ngcontent-%COMP%] {\n padding: 12px 14px;\n background: var(--%NS%prism-bg-surface);\n border: 1px solid var(--%NS%prism-border);\n border-radius: 8px;\n }\n .cov-stat-k[_ngcontent-%COMP%] {\n font-size: 10.5px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--%NS%prism-text-ghost);\n font-weight: 700;\n margin-bottom: 6px;\n }\n .cov-stat-v[_ngcontent-%COMP%] {\n font-family: var(--%NS%font-mono);\n font-size: 22px;\n font-weight: 700;\n color: var(--%NS%prism-text);\n letter-spacing: -0.02em;\n }\n .cov-stat-v[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--%NS%prism-text-muted);\n font-weight: 500;\n }\n .cov-bar[_ngcontent-%COMP%] {\n margin-top: 8px;\n height: 4px;\n background: var(--%NS%prism-input-bg);\n border-radius: 2px;\n overflow: hidden;\n }\n .cov-bar-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: linear-gradient(90deg, var(--%NS%prism-primary-from), var(--%NS%prism-primary-to));\n border-radius: 2px;\n transition: width 0.6s;\n }\n\n .cov-files[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--%NS%prism-bg-surface);\n border: 1px solid var(--%NS%prism-border);\n border-radius: 8px;\n }\n\n .cov-file[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto auto auto auto;\n align-items: center;\n gap: 16px;\n padding: 7px 4px;\n font-family: var(--%NS%font-mono);\n font-size: 12px;\n border-bottom: 1px solid var(--%NS%prism-border);\n }\n .cov-file[_ngcontent-%COMP%]:last-child { border-bottom: 0; }\n\n .cov-file--header[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--%NS%prism-border-strong);\n padding-bottom: 8px;\n color: var(--%NS%prism-text-ghost);\n font-size: 10.5px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n font-weight: 700;\n }\n\n .cov-file-name[_ngcontent-%COMP%] { color: var(--%NS%prism-text-2); }\n .cov-file-val[_ngcontent-%COMP%] {\n color: var(--%NS%prism-text);\n min-width: 54px;\n text-align: right;\n }\n .cov-file-val.bad[_ngcontent-%COMP%] { color: var(--%NS%prism-warn); }\n\n .cov-empty[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n color: var(--%NS%prism-text-muted);\n font-size: 13px;\n text-align: center;\n }"] });
|
|
149
149
|
}
|
|
150
150
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CoveragePanelComponent, [{
|
|
151
151
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-plugin.browser.d.ts","sourceRoot":"","sources":["../src/coverage-plugin.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage-plugin.browser.d.ts","sourceRoot":"","sources":["../src/coverage-plugin.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAMjE,wBAAgB,cAAc,CAC5B,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,aAAa,CA8Bf"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { coverageBadge, COVERAGE_NAVIGATION_DECORATION, } from './coverage-contributions.js';
|
|
1
2
|
export function coveragePlugin(_options) {
|
|
2
3
|
return {
|
|
3
4
|
name: '@ng-prism/plugin-coverage',
|
|
@@ -5,6 +6,7 @@ export function coveragePlugin(_options) {
|
|
|
5
6
|
{
|
|
6
7
|
id: 'coverage',
|
|
7
8
|
label: 'Coverage',
|
|
9
|
+
badge: coverageBadge,
|
|
8
10
|
icon: 'shield-check',
|
|
9
11
|
loadComponent: () => import('./coverage-panel.component.js').then((m) => m.CoveragePanelComponent),
|
|
10
12
|
position: 'bottom',
|
|
@@ -18,5 +20,6 @@ export function coveragePlugin(_options) {
|
|
|
18
20
|
loadComponent: () => import('./coverage-header-badge.component.js').then((m) => m.CoverageHeaderBadgeComponent),
|
|
19
21
|
},
|
|
20
22
|
],
|
|
23
|
+
navigationDecorations: [COVERAGE_NAVIGATION_DECORATION],
|
|
21
24
|
};
|
|
22
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-plugin.d.ts","sourceRoot":"","sources":["../src/coverage-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage-plugin.d.ts","sourceRoot":"","sources":["../src/coverage-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAQ7B,eAAO,MAAM,2BAA2B,EAAE,kBAKzC,CAAC;AAEF,wBAAgB,yBAAyB,CACvC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAC3C,kBAAkB,CAWpB;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAgE7E"}
|
package/dist/coverage-plugin.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { coverageBadge, COVERAGE_NAVIGATION_DECORATION, } from './coverage-contributions.js';
|
|
1
2
|
const DEFAULT_COVERAGE_PATH = 'coverage/coverage-summary.json';
|
|
2
3
|
export const DEFAULT_COVERAGE_THRESHOLDS = {
|
|
3
4
|
lines: 80,
|
|
@@ -25,6 +26,7 @@ export function coveragePlugin(options) {
|
|
|
25
26
|
name: '@ng-prism/plugin-coverage',
|
|
26
27
|
async onComponentScanned(component) {
|
|
27
28
|
const { readCoverageForFile } = await import('./coverage-reader.js');
|
|
29
|
+
const { deriveCoverageSummary } = await import('./coverage-summary.js');
|
|
28
30
|
const coverage = readCoverageForFile(coveragePath, component.filePath);
|
|
29
31
|
return {
|
|
30
32
|
...component,
|
|
@@ -32,7 +34,13 @@ export function coveragePlugin(options) {
|
|
|
32
34
|
...component.showcaseConfig,
|
|
33
35
|
meta: {
|
|
34
36
|
...component.showcaseConfig.meta,
|
|
35
|
-
coverage: {
|
|
37
|
+
coverage: {
|
|
38
|
+
...coverage,
|
|
39
|
+
thresholds,
|
|
40
|
+
...(coverage.found
|
|
41
|
+
? { summary: deriveCoverageSummary(coverage.score, thresholds) }
|
|
42
|
+
: {}),
|
|
43
|
+
},
|
|
36
44
|
},
|
|
37
45
|
},
|
|
38
46
|
};
|
|
@@ -52,6 +60,7 @@ export function coveragePlugin(options) {
|
|
|
52
60
|
{
|
|
53
61
|
id: 'coverage',
|
|
54
62
|
label: 'Coverage',
|
|
63
|
+
badge: coverageBadge,
|
|
55
64
|
loadComponent: () => import('./coverage-panel.component.js').then((m) => m.CoveragePanelComponent),
|
|
56
65
|
position: 'bottom',
|
|
57
66
|
},
|
|
@@ -64,5 +73,6 @@ export function coveragePlugin(options) {
|
|
|
64
73
|
loadComponent: () => import('./coverage-header-badge.component.js').then((m) => m.CoverageHeaderBadgeComponent),
|
|
65
74
|
},
|
|
66
75
|
],
|
|
76
|
+
navigationDecorations: [COVERAGE_NAVIGATION_DECORATION],
|
|
67
77
|
};
|
|
68
78
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CoverageSummary, CoverageThresholds } from './coverage.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Threshold derivation lives in its own module so both sides can reach it:
|
|
4
|
+
* `coverage-plugin.ts` carries the build-time hook that reads the istanbul
|
|
5
|
+
* summary from disk and must never be reachable from a browser bundle, while
|
|
6
|
+
* the header badge and the navigation marker run in the browser.
|
|
7
|
+
*
|
|
8
|
+
* Same motive as `thresholds.ts` in `plugin-visual-regression`.
|
|
9
|
+
*/
|
|
10
|
+
/** The single number the badge compares against — the mean of the four metrics. */
|
|
11
|
+
export declare function avgThreshold(thresholds: CoverageThresholds): number;
|
|
12
|
+
export declare function deriveCoverageSummary(score: number, thresholds: CoverageThresholds): CoverageSummary;
|
|
13
|
+
//# sourceMappingURL=coverage-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-summary.d.ts","sourceRoot":"","sources":["../src/coverage-summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE/E;;;;;;;GAOG;AACH,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CAQnE;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,kBAAkB,GAC7B,eAAe,CAMjB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threshold derivation lives in its own module so both sides can reach it:
|
|
3
|
+
* `coverage-plugin.ts` carries the build-time hook that reads the istanbul
|
|
4
|
+
* summary from disk and must never be reachable from a browser bundle, while
|
|
5
|
+
* the header badge and the navigation marker run in the browser.
|
|
6
|
+
*
|
|
7
|
+
* Same motive as `thresholds.ts` in `plugin-visual-regression`.
|
|
8
|
+
*/
|
|
9
|
+
/** The single number the badge compares against — the mean of the four metrics. */
|
|
10
|
+
export function avgThreshold(thresholds) {
|
|
11
|
+
return Math.round((thresholds.lines +
|
|
12
|
+
thresholds.branches +
|
|
13
|
+
thresholds.functions +
|
|
14
|
+
thresholds.statements) /
|
|
15
|
+
4);
|
|
16
|
+
}
|
|
17
|
+
export function deriveCoverageSummary(score, thresholds) {
|
|
18
|
+
const avg = avgThreshold(thresholds);
|
|
19
|
+
const variant = score >= avg ? 'ok' : score >= avg * 0.75 ? 'warn' : 'danger';
|
|
20
|
+
return { variant, label: `Coverage: ${score}% (target ${avg}%)` };
|
|
21
|
+
}
|
package/dist/coverage.types.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export interface CoverageThresholds {
|
|
|
17
17
|
functions: number;
|
|
18
18
|
statements: number;
|
|
19
19
|
}
|
|
20
|
+
export interface CoverageSummary {
|
|
21
|
+
variant: 'ok' | 'warn' | 'danger';
|
|
22
|
+
label: string;
|
|
23
|
+
}
|
|
20
24
|
export interface CoverageData {
|
|
21
25
|
score: number;
|
|
22
26
|
statements: MetricDetail;
|
|
@@ -26,6 +30,11 @@ export interface CoverageData {
|
|
|
26
30
|
found: boolean;
|
|
27
31
|
files?: FileCoverageDetail[];
|
|
28
32
|
thresholds?: CoverageThresholds;
|
|
33
|
+
/**
|
|
34
|
+
* Pre-derived headline, written by the build-time hook. Optional because a
|
|
35
|
+
* browser-only plugin setup runs no build-time hooks and then has none.
|
|
36
|
+
*/
|
|
37
|
+
summary?: CoverageSummary;
|
|
29
38
|
}
|
|
30
39
|
export interface CoveragePluginOptions {
|
|
31
40
|
coveragePath?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.types.d.ts","sourceRoot":"","sources":["../src/coverage.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage.types.d.ts","sourceRoot":"","sources":["../src/coverage.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACnD;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAAC;CAC1C"}
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { coveragePlugin } from './coverage-plugin.browser.js';
|
|
2
2
|
export { CoveragePanelComponent } from './coverage-panel.component.js';
|
|
3
3
|
export { CoverageHeaderBadgeComponent } from './coverage-header-badge.component.js';
|
|
4
|
-
export type { CoverageData, CoverageManifestMeta, CoveragePluginOptions, CoverageThresholds, MetricDetail, } from './coverage.types.js';
|
|
4
|
+
export type { CoverageData, CoverageManifestMeta, CoveragePluginOptions, CoverageSummary, CoverageThresholds, MetricDetail, } from './coverage.types.js';
|
|
5
5
|
//# sourceMappingURL=index.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { coveragePlugin } from './coverage-plugin.js';
|
|
2
2
|
export { CoveragePanelComponent } from './coverage-panel.component.js';
|
|
3
3
|
export { CoverageHeaderBadgeComponent } from './coverage-header-badge.component.js';
|
|
4
|
-
export type { CoverageData, CoverageManifestMeta, CoveragePluginOptions, CoverageThresholds, MetricDetail, } from './coverage.types.js';
|
|
4
|
+
export type { CoverageData, CoverageManifestMeta, CoveragePluginOptions, CoverageSummary, CoverageThresholds, MetricDetail, } from './coverage.types.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC"}
|