import { describe, expect, test } from "bun:test"; import { WORKING_SET_MAX_LOC, WORKING_SET_MIN_LOC, } from "./a31_sama_v2.ts"; import { computeWorkingSetFitPolyglot, type PolyglotLanguage, type WorkingSetFile, } from "./b32_working_set_polyglot.ts"; // Mirror the inclusive-bound assertions in b32_sama_v2_metrics.test.ts. // Same algorithm, same constants, same edge behaviour — the polyglot // helper is allowed to compute a different SET of files (Go/Rust source // trees rather than src/*.ts), but the RATIO formula must match the // TS metric byte-for-byte. These tests pin that. const file = (path: string, locCount: number): WorkingSetFile => ({ path, locCount }); describe("computeWorkingSetFitPolyglot — empty input", () => { test("empty list → 1.0 vacuous (matches the TS metric on an empty file map)", () => { const r = computeWorkingSetFitPolyglot([], "go"); expect(r.ratio).toBe(1.0); expect(r.included).toBe(0); expect(r.total).toBe(0); }); test("empty list also vacuous under Rust", () => { const r = computeWorkingSetFitPolyglot([], "rust"); expect(r.ratio).toBe(1.0); }); }); describe("computeWorkingSetFitPolyglot — single-file extremes", () => { test("a single 100-line Go file → 1.0", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", 100)], "go"); expect(r.ratio).toBe(1.0); expect(r.included).toBe(1); expect(r.total).toBe(1); }); test("a single 10-line file falls below the min → 0.0", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", 10)], "go"); expect(r.ratio).toBe(0.0); expect(r.included).toBe(0); expect(r.total).toBe(1); }); test("a single 600-line file exceeds the max → 0.0", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", 600)], "go"); expect(r.ratio).toBe(0.0); expect(r.included).toBe(0); expect(r.total).toBe(1); }); }); describe("computeWorkingSetFitPolyglot — bound-edge inclusivity", () => { // The TS metric uses `lines >= MIN && lines <= MAX`. These tests // mirror b32_sama_v2_metrics.test.ts's "exact bounds are inclusive". test("LOC = 49 → out of band", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", WORKING_SET_MIN_LOC - 1)], "go"); expect(r.included).toBe(0); }); test("LOC = 50 → in band", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", WORKING_SET_MIN_LOC)], "go"); expect(r.included).toBe(1); }); test("LOC = 500 → in band", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", WORKING_SET_MAX_LOC)], "go"); expect(r.included).toBe(1); }); test("LOC = 501 → out of band", () => { const r = computeWorkingSetFitPolyglot([file("pkg/x.go", WORKING_SET_MAX_LOC + 1)], "go"); expect(r.included).toBe(0); }); }); describe("computeWorkingSetFitPolyglot — mixed inputs", () => { test("half in / half out → 0.5", () => { const r = computeWorkingSetFitPolyglot([ file("pkg/a.go", 100), file("pkg/b.go", 10), ], "go"); expect(r.ratio).toBe(0.5); }); test("two in / two out → 0.5", () => { const r = computeWorkingSetFitPolyglot([ file("pkg/a.go", 100), file("pkg/b.go", 300), file("pkg/c.go", 10), file("pkg/d.go", 800), ], "go"); expect(r.ratio).toBe(0.5); }); }); describe("computeWorkingSetFitPolyglot — Go test-file exclusion", () => { test("*_test.go files do NOT count toward total or included", () => { const r = computeWorkingSetFitPolyglot([ file("pkg/x.go", 100), file("pkg/x_test.go", 200), file("pkg/y_test.go", 50), ], "go"); // Only x.go counts; both _test.go files dropped before tallying. expect(r.total).toBe(1); expect(r.included).toBe(1); expect(r.ratio).toBe(1.0); }); test("a 100-line source + a 1-line _test.go sibling → 1.0 (mirrors the TS metric)", () => { const r = computeWorkingSetFitPolyglot([ file("pkg/x.go", 100), file("pkg/x_test.go", 1), ], "go"); expect(r.ratio).toBe(1.0); }); }); describe("computeWorkingSetFitPolyglot — Rust inline-tests asymmetry", () => { test("Rust includes ALL .rs files (no path-based test exclusion)", () => { // Rust convention: tests live inside source files under // #[cfg(test)] mod tests. The polyglot helper preserves that — // it does NOT exclude any .rs path. The asymmetry is documented // in the b32_working_set_polyglot.ts source comment. const r = computeWorkingSetFitPolyglot([ file("src/lib.rs", 100), file("src/tests.rs", 100), file("src/something_test.rs", 100), ], "rust"); expect(r.total).toBe(3); expect(r.included).toBe(3); expect(r.ratio).toBe(1.0); }); }); describe("computeWorkingSetFitPolyglot — reproducibility", () => { test("same input → identical output across runs (deep-equal)", () => { const input: WorkingSetFile[] = [ file("a.go", 100), file("b.go", 60), file("c.go", 480), file("d.go", 20), file("e_test.go", 999), ]; const langs: PolyglotLanguage[] = ["go", "rust"]; for (const l of langs) { const a = computeWorkingSetFitPolyglot(input, l); const b = computeWorkingSetFitPolyglot(input, l); expect(a).toEqual(b); } }); }); describe("computeWorkingSetFitPolyglot — bounds echo", () => { test("result echoes minLoc / maxLoc from a31_sama_v2.ts (auditable)", () => { const r = computeWorkingSetFitPolyglot([], "go"); expect(r.minLoc).toBe(WORKING_SET_MIN_LOC); expect(r.maxLoc).toBe(WORKING_SET_MAX_LOC); }); });