feat(roadmap): checklist-derived completion percentage
This commit is contained in:
parent
1c24687dae
commit
b164f3273c
2 changed files with 49 additions and 0 deletions
32
src/lib/roadmap/progress.test.ts
Normal file
32
src/lib/roadmap/progress.test.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { checklistPercent } from "@/lib/roadmap/progress";
|
||||
|
||||
describe("checklistPercent", () => {
|
||||
it("returns null when there is no checklist", () => {
|
||||
// A card with no subtasks has no honest completion figure. Showing 0%
|
||||
// would claim nothing has been done, which is a different statement.
|
||||
expect(checklistPercent(0, 0)).toBeNull();
|
||||
});
|
||||
|
||||
it("computes a whole percentage", () => {
|
||||
expect(checklistPercent(3, 4)).toBe(75);
|
||||
expect(checklistPercent(1, 3)).toBe(33);
|
||||
});
|
||||
|
||||
it("returns 0 for an untouched checklist", () => {
|
||||
expect(checklistPercent(0, 5)).toBe(0);
|
||||
});
|
||||
|
||||
it("returns 100 for a complete one", () => {
|
||||
expect(checklistPercent(5, 5)).toBe(100);
|
||||
});
|
||||
|
||||
it("clamps impossible input rather than exceeding 100", () => {
|
||||
expect(checklistPercent(9, 5)).toBe(100);
|
||||
expect(checklistPercent(-1, 5)).toBe(0);
|
||||
});
|
||||
|
||||
it("returns null for a negative total", () => {
|
||||
expect(checklistPercent(0, -3)).toBeNull();
|
||||
});
|
||||
});
|
||||
17
src/lib/roadmap/progress.ts
Normal file
17
src/lib/roadmap/progress.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Checklist completion for a card.
|
||||
*
|
||||
* The per-row percentage from the developer's Gantt reference, mapped onto the
|
||||
* one thing in this product that honestly supports it: subtasks the developer
|
||||
* ticked themselves. Nothing is inferred.
|
||||
*
|
||||
* Returns null rather than 0 for a card with no checklist. "0%" asserts that
|
||||
* nothing has been done; "no figure" says nobody has broken this down. They are
|
||||
* different statements and the second one is true.
|
||||
*/
|
||||
export function checklistPercent(done: number, total: number): number | null {
|
||||
if (!Number.isFinite(total) || total <= 0) return null;
|
||||
|
||||
const completed = Math.min(Math.max(done, 0), total);
|
||||
return Math.round((completed / total) * 100);
|
||||
}
|
||||
Loading…
Reference in a new issue