ci: scoped 100% coverage gates + policy doc

This commit is contained in:
Kunal
2026-02-07 15:54:42 +00:00
parent 6fe7aaecf3
commit f87cc1f7fb
8 changed files with 240 additions and 4 deletions

View File

@@ -20,6 +20,23 @@ describe("createExponentialBackoff", () => {
expect(backoff.nextDelayMs()).toBe(250); // capped
});
it("clamps invalid numeric options and treats negative jitter as zero", () => {
vi.spyOn(Math, "random").mockReturnValue(0.9999);
// baseMs: NaN should clamp to min (50)
// maxMs: Infinity should clamp to min (= baseMs)
// jitter: negative -> treated as 0 (no extra delay)
const backoff = createExponentialBackoff({
baseMs: Number.NaN,
maxMs: Number.POSITIVE_INFINITY,
jitter: -1,
});
// With maxMs clamped to baseMs, delay will always be baseMs
expect(backoff.nextDelayMs()).toBe(50);
expect(backoff.nextDelayMs()).toBe(50);
});
it("reset brings attempt back to zero", () => {
vi.spyOn(Math, "random").mockReturnValue(0);
@@ -30,4 +47,15 @@ describe("createExponentialBackoff", () => {
backoff.reset();
expect(backoff.attempt()).toBe(0);
});
it("uses defaults when options are omitted", () => {
vi.spyOn(Math, "random").mockReturnValue(0);
const backoff = createExponentialBackoff();
expect(backoff.attempt()).toBe(0);
// Default baseMs is 1000 (clamped within bounds), jitter default is 0.2.
// With Math.random=0, delay should be the normalized base (1000).
expect(backoff.nextDelayMs()).toBe(1000);
});
});

View File

@@ -9,8 +9,16 @@ export default defineConfig({
provider: "v8",
reporter: ["text", "lcov"],
reportsDirectory: "./coverage",
include: ["src/**/*.{ts,tsx}"],
// Policy (scoped gate): require 100% coverage on *explicitly listed* unit-testable modules first.
// We'll expand this include list as we add more unit/component tests.
include: ["src/lib/backoff.ts"],
exclude: ["**/*.d.ts", "src/**/__generated__/**", "src/**/generated/**"],
thresholds: {
lines: 100,
statements: 100,
functions: 100,
branches: 100,
},
},
},
});