mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-13 16:38:56 +02:00
test: final coverage pass — CLI rendering, revert traps, keychain probe, gbrain doc ops
The user-directed third generation pass closes the audit's remaining tail: the code-intelligence CLI's options/status/suggest surfaces get behavioral coverage through the fake-shim chain; brain-context-load gains an argv-logging trap that goes red if anyone reverts the memoized PATH scan back to the spawn probe (receipt: simulated revert failed exactly these tests); the darwin Keychain auth branch (#1890) gets its first free-tier tests via a PATH-shimmed security binary; and the gbrain add/delete/export ops are pinned (body piped byte-for-byte, receipt sha256, stdin-EOF prompt guard, PROVIDER_UNAVAILABLE degradation) — retiring their TODOS entry.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { chmodSync, mkdtempSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
||||
import { chmodSync, mkdtempSync, readFileSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
||||
import { tmpdir } from "os";
|
||||
import { delimiter, join } from "path";
|
||||
import { spawnSync } from "child_process";
|
||||
@@ -52,6 +52,38 @@ fi
|
||||
chmodSync(fakeBin, 0o755);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like writeFakeGbrain, but every invocation appends its argv to `logFile`.
|
||||
* Still answers `--version` successfully ON PURPOSE: a revert from the
|
||||
* memoized PATH stat scan back to the old `gbrain --version` spawn probe
|
||||
* would pass every non-logging test — only the argv log catches it.
|
||||
*/
|
||||
function writeLoggingGbrain(binDir: string, logFile: string): void {
|
||||
if (process.platform === "win32") {
|
||||
writeFileSync(
|
||||
join(binDir, "gbrain.cmd"),
|
||||
`@echo off\r\necho %* >> "${logFile}"\r\nif "%1"=="--version" (\r\n echo gbrain 0.test\r\n) else (\r\n echo fake gbrain %*\r\n)\r\n`,
|
||||
"utf-8",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const fakeBin = join(binDir, "gbrain");
|
||||
writeFileSync(
|
||||
fakeBin,
|
||||
`#!/bin/sh
|
||||
printf '%s\\n' "$*" >> "${logFile}"
|
||||
if [ "$1" = "--version" ]; then
|
||||
echo "gbrain 0.test"
|
||||
else
|
||||
echo "fake gbrain $*"
|
||||
fi
|
||||
`,
|
||||
"utf-8",
|
||||
);
|
||||
chmodSync(fakeBin, 0o755);
|
||||
}
|
||||
|
||||
function prependPath(binDir: string): Record<string, string> {
|
||||
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path") || "PATH";
|
||||
const currentPath = process.env[pathKey] || "";
|
||||
@@ -295,6 +327,55 @@ gbrain:
|
||||
}
|
||||
});
|
||||
|
||||
it("gbrain detection never spawns gbrain — stat-based PATH scan, not a `--version` probe (revert trap)", () => {
|
||||
// The fix replaced a per-query `gbrain --version` spawn probe with a
|
||||
// memoized PATH stat scan. The plain writeFakeGbrain shim still ANSWERS
|
||||
// --version, so a revert to the spawn probe passes every other test in
|
||||
// this file. This fake logs its argv: detection must invoke gbrain zero
|
||||
// times, so the only invocations are the 3 default-manifest list_pages
|
||||
// queries — a revert adds `--version` lines (and re-probing adds one per
|
||||
// query) and fails exactly here.
|
||||
const dir = mkdtempSync(join(tmpdir(), "gstack-bcl-"));
|
||||
const binDir = join(dir, "bin");
|
||||
mkdirSync(binDir);
|
||||
const logFile = join(dir, "gbrain-argv.log");
|
||||
writeLoggingGbrain(binDir, logFile);
|
||||
|
||||
try {
|
||||
const r = runScript(["--repo", "test-repo", "--explain", "--quiet"], prependPath(binDir));
|
||||
expect(r.exitCode).toBe(0);
|
||||
expect(r.stderr).toContain("queries=3");
|
||||
const invocations = readFileSync(logFile, "utf-8").split("\n").filter(Boolean);
|
||||
expect(invocations.some((argv) => argv.includes("--version"))).toBe(false);
|
||||
// Exactly the 3 real queries — no extra availability spawns of any shape.
|
||||
expect(invocations).toHaveLength(3);
|
||||
for (const argv of invocations) expect(argv.startsWith("list_pages")).toBe(true);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("availability survives a 1ms query budget — detection is not subject to GSTACK_BRAIN_TIMEOUT_MS", () => {
|
||||
// The spawn probe ran under the same MCP_TIMEOUT_MS budget as the queries,
|
||||
// so a cold spawn slower than the budget misreported gbrain as MISSING.
|
||||
// With the stat scan, a 1ms budget kills the queries themselves (SKIP)
|
||||
// but detection still sees the CLI — "gbrain CLI missing" must not appear.
|
||||
const dir = mkdtempSync(join(tmpdir(), "gstack-bcl-"));
|
||||
const binDir = join(dir, "bin");
|
||||
mkdirSync(binDir);
|
||||
writeFakeGbrain(binDir);
|
||||
|
||||
try {
|
||||
const env = { ...prependPath(binDir), GSTACK_BRAIN_TIMEOUT_MS: "1" };
|
||||
const r = runScript(["--repo", "test-repo", "--explain", "--quiet"], env);
|
||||
expect(r.exitCode).toBe(0);
|
||||
expect(r.stderr).toContain("SKIP");
|
||||
expect(r.stderr).not.toContain("gbrain CLI missing");
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("vector + list queries still complete (with SKIP) when gbrain CLI is missing", () => {
|
||||
// We can't easily un-install gbrain; rely on the helper's own missing-binary
|
||||
// detection. The default manifest uses kind: list which calls gbrain. If
|
||||
|
||||
Reference in New Issue
Block a user