Files
buzz/scripts/check-file-sizes-core.test.mjs
Duncan 20609f1815 feat(manifest): model-capability manifest — single source of truth for efforts, routes, labels
Rebased onto origin/main (5bf78671f4).

Conflict resolved in crates/buzz-agent/src/config.rs: kept our generated
anthropic_thinking_config_generated as the sole authority; absorbed main's
thinking shapes, ThinkingSummary enum + parse_thinking_summary, and the
thinking_summary field in Config wired through from_env / for_discovery.

Fixed CI job (model-capabilities): actions/checkout comment v6 → v6.0.3,
Swatinem/rust-cache SHA bumped to tagged v2.9.1 (c1937114) to resolve
zizmor ref-version-mismatch finding (r3730151005).

  62ebc9431 fix(model-capabilities): collapse empty segments in Rust gpt-version-segment matcher
  817b88790 test(file-size): fix fileOverrides integration test under GITHUB_ACTIONS
  1e9df5568 fix(manifest): enforce registry_label exclusion on family rules; test fileOverrides boundary
  0e6aacfd2 fix(buzz-agent): curate display name in configured_model_fallback
  77c24ef32 chore(manifest): remove dead registry_labels key

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-08-10 11:10:45 -04:00

170 lines
5.7 KiB
JavaScript

import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import {
allowedLineCount,
countLines,
evaluateFileSize,
parseChangedFiles,
resolveBaseRef,
runFileSizeCheck,
} from "./check-file-sizes-core.mjs";
function git(repo, ...args) {
return execFileSync("git", args, { cwd: repo, encoding: "utf8" }).trim();
}
test("local base resolution uses the branch merge-base and fails without origin/main", () => {
const repo = mkdtempSync(path.join(tmpdir(), "file-size-base-"));
git(repo, "init", "-b", "main");
git(repo, "config", "user.name", "Test");
git(repo, "config", "user.email", "test@example.com");
git(repo, "commit", "--allow-empty", "-m", "base");
git(repo, "remote", "add", "origin", repo);
git(repo, "fetch", "origin", "main:refs/remotes/origin/main");
const base = git(repo, "rev-parse", "HEAD");
git(repo, "switch", "-c", "feature");
git(repo, "commit", "--allow-empty", "-m", "first branch commit");
git(repo, "commit", "--allow-empty", "-m", "second branch commit");
assert.equal(resolveBaseRef(repo, {}), base);
git(repo, "update-ref", "-d", "refs/remotes/origin/main");
assert.throws(
() => resolveBaseRef(repo, {}),
/Fetch origin\/main or set CHECK_FILE_SIZES_BASE/,
);
});
test("counts empty, LF, and CRLF content with the existing semantics", () => {
assert.equal(countLines(""), 0);
assert.equal(countLines("one\n"), 2);
assert.equal(countLines("one\r\ntwo"), 2);
});
test("new files use the configured ceiling", () => {
assert.equal(allowedLineCount(null, 1000), 1000);
assert.deepEqual(
evaluateFileSize({ baseLines: null, candidateLines: 1000, maxLines: 1000 }),
{
limit: 1000,
violates: false,
},
);
assert.equal(
evaluateFileSize({ baseLines: null, candidateLines: 1001, maxLines: 1000 })
.violates,
true,
);
});
test("a compliant file may not cross the ceiling", () => {
assert.equal(
evaluateFileSize({ baseLines: 996, candidateLines: 1000, maxLines: 1000 })
.violates,
false,
);
assert.equal(
evaluateFileSize({ baseLines: 996, candidateLines: 1003, maxLines: 1000 })
.violates,
true,
);
});
test("parses modifications, deletions, and renames from Git's NUL format", () => {
assert.deepEqual(
parseChangedFiles(
"M\0desktop/src/a.ts\0D\0desktop/src/b.ts\0R100\0desktop/src/old.ts\0desktop/src/new.ts\0",
),
[
{ status: "M", path: "desktop/src/a.ts" },
{ status: "D", path: "desktop/src/b.ts" },
{
status: "R",
oldPath: "desktop/src/old.ts",
path: "desktop/src/new.ts",
},
],
);
});
test("an inherited oversized file may hold or shrink but not grow", () => {
assert.equal(allowedLineCount(1026, 1000), 1026);
assert.equal(
evaluateFileSize({ baseLines: 1026, candidateLines: 1026, maxLines: 1000 })
.violates,
false,
);
assert.equal(
evaluateFileSize({ baseLines: 1026, candidateLines: 1001, maxLines: 1000 })
.violates,
false,
);
assert.equal(
evaluateFileSize({ baseLines: 1026, candidateLines: 1027, maxLines: 1000 })
.violates,
true,
);
});
test("fileOverrides raises the ceiling for a named path without leaking to other files", async () => {
// Build a minimal temp git repo:
// repo/
// desktop/ ← projectRoot
// src/
// governed.ts ← 1 line over the 1000-line default ceiling
// exempted.ts ← same size, but named in fileOverrides (ceiling 1200)
// origin/main at the initial empty commit ← base for diff
const repoRoot = mkdtempSync(path.join(tmpdir(), "file-size-override-"));
const projectRoot = path.join(repoRoot, "desktop");
const srcDir = path.join(projectRoot, "src");
mkdirSync(srcDir, { recursive: true });
function gitRepo(...args) {
return execFileSync("git", args, { cwd: repoRoot, encoding: "utf8" });
}
gitRepo("init", "-b", "main");
gitRepo("config", "user.name", "Test");
gitRepo("config", "user.email", "test@example.com");
gitRepo("commit", "--allow-empty", "-m", "base");
gitRepo("remote", "add", "origin", repoRoot);
gitRepo("fetch", "origin", "main:refs/remotes/origin/main");
// Add a second commit so HEAD^1 resolves (the CI path uses HEAD^1 as base,
// and a parentless HEAD causes git cat-file -e HEAD^1^{commit} to throw).
gitRepo("commit", "--allow-empty", "-m", "branch commit");
// Write both files: 1001 lines each (1 over the 1000-line default ceiling)
const content = "x\n".repeat(1001);
writeFileSync(path.join(srcDir, "governed.ts"), content);
writeFileSync(path.join(srcDir, "exempted.ts"), content);
gitRepo("add", ".");
const prevExitCode = process.exitCode;
const errors = [];
const origConsoleError = console.error;
console.error = (...args) => errors.push(args.join(" "));
try {
await runFileSizeCheck({
projectRoot,
rules: [{ root: "src", extensions: new Set([".ts"]), maxLines: 1000 }],
label: "test",
fileOverrides: { "src/exempted.ts": 1200 },
});
// governed.ts (1001 lines, ceiling 1000) must violate
assert.equal(process.exitCode, 1, "governed.ts over default ceiling should fail");
const combined = errors.join("\n");
assert.ok(combined.includes("governed.ts"), "violation message should name governed.ts");
// exempted.ts (1001 lines, override ceiling 1200) must NOT be in the violation list
assert.ok(!combined.includes("exempted.ts"), "exempted.ts under override ceiling should not appear");
} finally {
process.exitCode = prevExitCode;
console.error = origConsoleError;
}
});