syntaxai/tdd.md · main · src / a31_commits.test.ts
import { test, expect } from "bun:test";
import { parseCommit, computeProgress } from "./a31_commits.ts";
test("parseCommit reads a phase prefix", () => {
expect(parseCommit("red: failing test for empty")).toEqual({
phase: "red",
step: null,
subject: "failing test for empty",
});
});
test("parseCommit extracts step from phase(step): form", () => {
expect(parseCommit("green(single-number): return n for one number")).toEqual({
phase: "green",
step: "single-number",
subject: "return n for one number",
});
});
test("parseCommit recognizes 'Initial commit' as init", () => {
expect(parseCommit("Initial commit").phase).toBe("init");
});
test("parseCommit returns untagged for unknown messages", () => {
expect(parseCommit("wip — fixing something").phase).toBe("untagged");
});
test("parseCommit recognizes spike: prefix", () => {
expect(parseCommit("spike: try the regex approach").phase).toBe("spike");
});
test("parseCommit extracts step from spike(step):", () => {
const p = parseCommit("spike(custom-separator): explore Forge regex");
expect(p.phase).toBe("spike");
expect(p.step).toBe("custom-separator");
});
test("computeProgress verifies a step after red→green for the same step", () => {
const commits = [
{ commit: { message: "green(empty): returns 0" } },
{ commit: { message: "red(empty): empty string returns 0" } },
]; // newest first, like Forgejo
const p = computeProgress(commits);
expect(p.verifiedSteps).toEqual(new Set(["empty"]));
expect(p.redCount).toBe(1);
expect(p.greenCount).toBe(1);
});
test("computeProgress does not verify green-without-prior-red", () => {
const commits = [{ commit: { message: "green(empty): returns 0" } }];
expect(computeProgress(commits).verifiedSteps.size).toBe(0);
});