syntaxai/tdd.md · main · src / c14_working_set_walker.test.ts
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
import {
collectPolyglotFiles,
measureWorkingSetForRepo,
} from "./c14_working_set_walker.ts";
// Hermetic fixture: build a tiny fake repo in a tmpdir, walk it,
// assert what comes back. The CLI script's real-world use against
// /tmp/dive and /tmp/ripgrep is exercised via the measurement step
// in this PR, not via unit tests; this file pins the algorithm.
const FIXTURE_ROOT = mkdtempSync(resolve(tmpdir(), "tdd-md-wswalker-"));
const writeFile = (relPath: string, lineCount: number): void => {
const abs = resolve(FIXTURE_ROOT, relPath);
mkdirSync(abs.split("/").slice(0, -1).join("/"), { recursive: true });
const lines = Array.from({ length: lineCount }, (_, i) => `// line ${i}`);
writeFileSync(abs, lines.join("\n"));
};
beforeAll(() => {
// Top-level Go sources (one in-band, one out-of-band, one test file).
writeFile("a.go", 100); // in band
writeFile("b.go", 600); // out (over)
writeFile("c_test.go", 200); // excluded for Go
// Nested.
writeFile("pkg/inner.go", 60); // in band, inside subdir
writeFile("pkg/tiny.go", 10); // out (under)
// Rust sources (separate sub-tree).
writeFile("rs/src/lib.rs", 120); // in band
writeFile("rs/src/big.rs", 700); // out (over)
writeFile("rs/src/tests.rs", 75); // included (Rust has no path test rule)
// Skip directories that should NOT be walked.
writeFile(".git/HEAD.go", 100); // .git is skipped
writeFile("target/build.rs", 100); // target/ is skipped
writeFile("vendor/pkg.go", 100); // vendor/ is skipped
writeFile("node_modules/dep.go", 100); // node_modules/ skipped
});
afterAll(() => {
rmSync(FIXTURE_ROOT, { recursive: true, force: true });
});
describe("collectPolyglotFiles — Go", () => {
test("walks recursively and finds the right .go files", () => {
const files = collectPolyglotFiles(FIXTURE_ROOT, "go");
const paths = files.map((f) => f.path);
// Excluded: .git/*, target/*, vendor/*, node_modules/*.
// Included: a.go, b.go, c_test.go (the helper RETURNS it; the
// metric helper drops it during the count — separation of concerns).
expect(paths).toContain("a.go");
expect(paths).toContain("b.go");
expect(paths).toContain("c_test.go");
expect(paths).toContain("pkg/inner.go");
expect(paths).toContain("pkg/tiny.go");
expect(paths).not.toContain(".git/HEAD.go");
expect(paths).not.toContain("vendor/pkg.go");
expect(paths).not.toContain("node_modules/dep.go");
});
test("LOC counts match content.split('\\n').length", () => {
const files = collectPolyglotFiles(FIXTURE_ROOT, "go");
const a = files.find((f) => f.path === "a.go");
// We wrote 100 lines joined by "\n" → split("\n").length === 100.
expect(a?.locCount).toBe(100);
});
test("returns files in deterministic sorted order", () => {
const a = collectPolyglotFiles(FIXTURE_ROOT, "go").map((f) => f.path);
const b = collectPolyglotFiles(FIXTURE_ROOT, "go").map((f) => f.path);
expect(a).toEqual(b);
const sorted = [...a].sort((x, y) => x.localeCompare(y));
expect(a).toEqual(sorted);
});
});
describe("collectPolyglotFiles — Rust", () => {
test("finds only .rs files; ignores .go", () => {
const files = collectPolyglotFiles(FIXTURE_ROOT, "rust");
const paths = files.map((f) => f.path);
expect(paths).toContain("rs/src/lib.rs");
expect(paths).toContain("rs/src/big.rs");
expect(paths).toContain("rs/src/tests.rs");
expect(paths.every((p) => p.endsWith(".rs"))).toBe(true);
});
test("target/build.rs is excluded (skipped dir)", () => {
const files = collectPolyglotFiles(FIXTURE_ROOT, "rust");
const paths = files.map((f) => f.path);
expect(paths).not.toContain("target/build.rs");
});
});
describe("measureWorkingSetForRepo — end-to-end", () => {
test("Go fixture: 2 in band (a.go=100, pkg/inner.go=60) of 4 source files (excluding c_test.go) = 0.5", () => {
const r = measureWorkingSetForRepo(FIXTURE_ROOT, "go");
expect(r.total).toBe(4); // a, b, pkg/inner, pkg/tiny (c_test excluded)
expect(r.included).toBe(2); // a, pkg/inner
expect(r.ratio).toBe(0.5);
});
test("Rust fixture: 2 in band (lib.rs=120, tests.rs=75) of 3 .rs files = 2/3", () => {
const r = measureWorkingSetForRepo(FIXTURE_ROOT, "rust");
expect(r.total).toBe(3);
expect(r.included).toBe(2);
expect(r.ratio).toBeCloseTo(2 / 3, 6);
});
test("echoes the bounds back so callers can audit which numbers produced the ratio", () => {
const r = measureWorkingSetForRepo(FIXTURE_ROOT, "go");
expect(r.minLoc).toBe(50);
expect(r.maxLoc).toBe(500);
});
});