singularity-forge/src/tests/tool-bootstrap.test.ts
2026-05-05 14:46:18 +02:00

99 lines
2.9 KiB
TypeScript

import assert from "node:assert/strict";
import {
chmodSync,
existsSync,
lstatSync,
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
symlinkSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, test } from "vitest";
import { ensureManagedTools, resolveToolFromPath } from "../tool-bootstrap.js";
const FD_TARGET = process.platform === "win32" ? "fd.exe" : "fd";
const RG_TARGET = process.platform === "win32" ? "rg.exe" : "rg";
function makeExecutable(
dir: string,
name: string,
content = "#!/bin/sh\nexit 0\n",
): string {
const file = join(dir, name);
writeFileSync(file, content);
chmodSync(file, 0o755);
return file;
}
test("resolveToolFromPath finds fd via fdfind fallback", (_t) => {
const tmp = mkdtempSync(join(tmpdir(), "sf-tool-bootstrap-resolve-"));
afterEach(() => {
rmSync(tmp, { recursive: true, force: true });
});
makeExecutable(tmp, "fdfind");
const resolved = resolveToolFromPath("fd", tmp);
assert.equal(resolved, join(tmp, "fdfind"));
});
test("ensureManagedTools provisions fd and rg into managed bin dir", (_t) => {
const tmp = mkdtempSync(join(tmpdir(), "sf-tool-bootstrap-provision-"));
const sourceBin = join(tmp, "source-bin");
const targetBin = join(tmp, "target-bin");
mkdirSync(sourceBin, { recursive: true });
mkdirSync(targetBin, { recursive: true });
afterEach(() => {
rmSync(tmp, { recursive: true, force: true });
});
makeExecutable(sourceBin, "fdfind");
makeExecutable(sourceBin, "rg");
const provisioned = ensureManagedTools(targetBin, sourceBin);
assert.equal(provisioned.length, 2);
assert.ok(existsSync(join(targetBin, FD_TARGET)));
assert.ok(existsSync(join(targetBin, RG_TARGET)));
assert.ok(
lstatSync(join(targetBin, FD_TARGET)).isSymbolicLink() ||
lstatSync(join(targetBin, FD_TARGET)).isFile(),
);
assert.ok(
lstatSync(join(targetBin, RG_TARGET)).isSymbolicLink() ||
lstatSync(join(targetBin, RG_TARGET)).isFile(),
);
});
test("ensureManagedTools copies executable when symlink target already exists as a broken link", (_t) => {
const tmp = mkdtempSync(join(tmpdir(), "sf-tool-bootstrap-copy-"));
const sourceBin = join(tmp, "source-bin");
const targetBin = join(tmp, "target-bin");
const targetFd = join(targetBin, FD_TARGET);
mkdirSync(sourceBin, { recursive: true });
mkdirSync(targetBin, { recursive: true });
afterEach(() => {
rmSync(tmp, { recursive: true, force: true });
});
makeExecutable(sourceBin, "fdfind", "#!/bin/sh\necho fd\n");
makeExecutable(sourceBin, "rg", "#!/bin/sh\necho rg\n");
symlinkSync(join(tmp, "missing-target"), targetFd);
const provisioned = ensureManagedTools(targetBin, sourceBin);
assert.equal(provisioned.length, 2);
assert.ok(
lstatSync(targetFd).isFile(),
"fd fallback should replace broken symlink with a copied file",
);
assert.match(readFileSync(targetFd, "utf8"), /echo fd/);
});