fix(scripts): exempt Storybook stories from coverage:diff gate
Story files are excluded from vitest by design (they run in Storybook
runner, not vitest). Add *.stories.{ts,tsx} to ALLOWED_GLOBS so the
L1 diff gate doesn't flag them as "new untested file".
Also add error-handling test for useOptionalConsent rethrow path
(cookie-consent-banner lines 52-53) achieving 100% statement coverage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"generatedAt": "2026-05-19T21:20:25.856Z",
|
"generatedAt": "2026-05-19T21:23:46.645Z",
|
||||||
"commit": "de17803",
|
"commit": "1b6f2d1",
|
||||||
"repo": {
|
"repo": {
|
||||||
"statements": 97.34,
|
"statements": 97.38,
|
||||||
"branches": 91.98,
|
"branches": 92.08,
|
||||||
"functions": 97.09,
|
"functions": 97.09,
|
||||||
"lines": 97.34,
|
"lines": 97.38,
|
||||||
"counts": {
|
"counts": {
|
||||||
"lf": 5742,
|
"lf": 5758,
|
||||||
"lh": 5589,
|
"lh": 5607,
|
||||||
"brf": 1147,
|
"brf": 1149,
|
||||||
"brh": 1055,
|
"brh": 1058,
|
||||||
"fnf": 344,
|
"fnf": 344,
|
||||||
"fnh": 334
|
"fnh": 334
|
||||||
}
|
}
|
||||||
@@ -115,15 +115,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@repo/core-ui": {
|
"@repo/core-ui": {
|
||||||
"statements": 99.49,
|
"statements": 100,
|
||||||
"branches": 90.2,
|
"branches": 91.35,
|
||||||
"functions": 100,
|
"functions": 100,
|
||||||
"lines": 99.49,
|
"lines": 100,
|
||||||
"counts": {
|
"counts": {
|
||||||
"lf": 396,
|
"lf": 412,
|
||||||
"lh": 394,
|
"lh": 412,
|
||||||
"brf": 102,
|
"brf": 104,
|
||||||
"brh": 92,
|
"brh": 95,
|
||||||
"fnf": 18,
|
"fnf": 18,
|
||||||
"fnh": 18
|
"fnh": 18
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Isolated test file for the error-re-throw path in useOptionalConsent.
|
||||||
|
* Uses vi.mock to make useConsent throw a non-ConsentContextError so that
|
||||||
|
* lines 52-53 (the `throw e` branch) are exercised.
|
||||||
|
*/
|
||||||
|
import { describe, it, expect, vi } from "vitest";
|
||||||
|
import { Component, type ReactNode } from "react";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
|
||||||
|
vi.mock("@repo/core-consent/react", () => ({
|
||||||
|
useConsent: vi.fn(() => {
|
||||||
|
throw new Error("unexpected-non-consent-error");
|
||||||
|
}),
|
||||||
|
ConsentContextError: class ConsentContextError extends Error {
|
||||||
|
constructor() {
|
||||||
|
super("no provider");
|
||||||
|
this.name = "ConsentContextError";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { CookieConsentBanner } from "./cookie-consent-banner";
|
||||||
|
|
||||||
|
class ErrorBoundary extends Component<
|
||||||
|
{ children: ReactNode },
|
||||||
|
{ caught: string | null }
|
||||||
|
> {
|
||||||
|
constructor(props: { children: ReactNode }) {
|
||||||
|
super(props);
|
||||||
|
this.state = { caught: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromError(error: Error) {
|
||||||
|
return { caught: error.message };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.caught) {
|
||||||
|
return <div data-testid="caught">{this.state.caught}</div>;
|
||||||
|
}
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("CookieConsentBanner — useOptionalConsent rethrows non-ConsentContextError", () => {
|
||||||
|
it("surfaces unexpected render errors through an error boundary", () => {
|
||||||
|
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||||
|
|
||||||
|
render(
|
||||||
|
<ErrorBoundary>
|
||||||
|
<CookieConsentBanner variant="modal" />
|
||||||
|
</ErrorBoundary>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByTestId("caught")).toHaveTextContent(
|
||||||
|
"unexpected-non-consent-error",
|
||||||
|
);
|
||||||
|
|
||||||
|
consoleSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -32,6 +32,8 @@ import { execSync } from "node:child_process";
|
|||||||
const ALLOWED_GLOBS = [
|
const ALLOWED_GLOBS = [
|
||||||
// Test artifacts
|
// Test artifacts
|
||||||
/\.test\.(ts|tsx|js|mjs)$/,
|
/\.test\.(ts|tsx|js|mjs)$/,
|
||||||
|
// Storybook story files — excluded from vitest by design; tested in Storybook runner
|
||||||
|
/\.stories\.(ts|tsx)$/,
|
||||||
/\/__factories__\//,
|
/\/__factories__\//,
|
||||||
/\/__contracts__\//,
|
/\/__contracts__\//,
|
||||||
/\/__fixtures__\//,
|
/\/__fixtures__\//,
|
||||||
|
|||||||
@@ -210,6 +210,21 @@ describe("computeDiffCoverage", () => {
|
|||||||
assert.equal(result.summary.filesChanged, 3);
|
assert.equal(result.summary.filesChanged, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("skips Storybook story files (.stories.ts/.stories.tsx — excluded from vitest coverage)", () => {
|
||||||
|
const lcov = parseLcov(lcovText);
|
||||||
|
const diff = new Map([
|
||||||
|
[
|
||||||
|
"packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.stories.tsx",
|
||||||
|
new Set([1, 2, 3, 4, 5]),
|
||||||
|
],
|
||||||
|
["packages/core-ui/src/atoms/button/button.stories.ts", new Set([1, 2])],
|
||||||
|
]);
|
||||||
|
const result = computeDiffCoverage(diff, lcov);
|
||||||
|
assert.equal(result.status, "pass");
|
||||||
|
assert.equal(result.summary.filesGated, 0);
|
||||||
|
assert.equal(result.summary.filesChanged, 2);
|
||||||
|
});
|
||||||
|
|
||||||
test("skips packages/core-testing/ (tooling package, no lcov generated)", () => {
|
test("skips packages/core-testing/ (tooling package, no lcov generated)", () => {
|
||||||
const lcov = parseLcov(lcovText);
|
const lcov = parseLcov(lcovText);
|
||||||
const diff = new Map([
|
const diff = new Map([
|
||||||
|
|||||||
Reference in New Issue
Block a user