syntaxai/tdd.md · main · src / a31_commits.test.ts

a31_commits.test.ts 53 lines · 1798 bytes raw
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);
});