Files
reverse-engineering-anything/tests/boundary/cli/referenceSourceImportStatus.test.ts
T
morluto 53e7fadbd0 fix(reference)!: retain source and metadata cleanup owners
Require a caller-owned artifact resource scope for source traversal and Git metadata reads. Preserve cancellation, filesystem reasons, partial entries and bytes, and cleanup observations through import and the CLI. Transfer exact failed file owners at regular-file admission and close boundaries, including multiple failures encountered by Git reference resolution.

Validation: 169 focused tests passed across 26 files; two Windows-only cases skipped. Build, typecheck, lint, formatting, knip, architecture guards, discovery and docs checks passed.

BREAKING CHANGE: Reference source readers and imports require an ArtifactResourceScope. VCS metadata reads return Result, and CLI import failures include observed details and partial evidence.
2026-10-11 06:10:10 +08:00

183 lines
6.2 KiB
TypeScript

import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const unsupportedHostOutput = {
error: "Import failed",
category: "unsupported_host",
message: expect.stringContaining(
"Safe no-follow file opens are unavailable on this host.",
),
};
const permissionChecksUnavailable =
process.platform === "win32" || process.getuid?.() === 0;
describe("compiled Windows reference-source import", () => {
for (const scenario of [
{ fullOutput: false, logging: false },
{ fullOutput: true, logging: true },
]) {
cliTest.runIf(process.platform === "win32")(
`readable root, ${scenario.fullOutput ? "full-output" : "JSON"}, logging ${String(scenario.logging)}`,
async ({ cli }) => {
const root = await createTestTempDirectory("rea-reference-host-");
const source = join(root, "source.js");
const bytes = "export const answer = 42;\n";
await writeFile(source, bytes);
const result = await cli.run({
arguments: [
"import-reference-source",
root,
"--json",
...(scenario.fullOutput ? ["--full-output"] : []),
],
cwd: root,
environment: {
USERPROFILE: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
...(scenario.logging ? { REA_LOG_LEVEL: "info" } : {}),
},
});
expect(result.json).toEqual(
scenario.fullOutput
? expect.objectContaining({
ok: true,
data: unsupportedHostOutput,
})
: unsupportedHostOutput,
);
expect.soft(result.exitCode).toBe(1);
expect(await readFile(source, "utf8")).toBe(bytes);
if (scenario.logging) {
expect(JSON.parse(result.stderr.trim())).toMatchObject({
command: "import-reference-source",
status: "error",
level: 50,
msg: "CLI command failed",
});
} else expect(result.stderr).toBe("");
},
);
}
});
describe("compiled reference-source import preflight failures", () => {
for (const scenario of [
{ rootKind: "missing", fullOutput: false, logging: false },
{ rootKind: "missing", fullOutput: true, logging: true },
{ rootKind: "regular-file", fullOutput: false, logging: true },
{ rootKind: "regular-file", fullOutput: true, logging: false },
] as const) {
cliTest(
`${scenario.rootKind} root, ${scenario.fullOutput ? "full-output" : "JSON"}, logging ${String(scenario.logging)}`,
async ({ cli }) => {
const directory = await createTestTempDirectory(
"rea-reference-cli-status-",
);
const root = join(directory, "input");
if (scenario.rootKind === "regular-file")
await writeFile(root, "inert input\n");
const result = await cli.run({
arguments: [
"import-reference-source",
root,
"--json",
...(scenario.fullOutput ? ["--full-output"] : []),
],
cwd: directory,
environment: {
HOME: directory,
USERPROFILE: directory,
XDG_CONFIG_HOME: directory,
XDG_CACHE_HOME: directory,
...(scenario.logging ? { REA_LOG_LEVEL: "info" } : {}),
},
});
const rootReason =
scenario.rootKind === "missing"
? "Reference source root could not be resolved"
: "Reference source root is not a directory";
const invalidRootOutput = {
error: "Import failed",
category: "invalid_input",
message: expect.stringContaining(rootReason),
};
if (scenario.fullOutput) {
// Incur's legacy wrapper remains unchanged; operation status is
// conveyed by the exit code and command log, not this `ok` field.
expect(result.json).toMatchObject({
ok: true,
data: invalidRootOutput,
});
} else {
expect(result.json).toMatchObject(invalidRootOutput);
}
expect(JSON.stringify(result.json)).toContain(
"Check that the path exists, is readable, and points to a directory.",
);
expect(JSON.stringify(result.json)).toContain(root);
expect.soft(result.exitCode).toBe(1);
if (scenario.logging) {
const records: unknown[] = result.stderr
.trim()
.split("\n")
.map((line) => JSON.parse(line) as unknown);
expect(records).toEqual([
expect.objectContaining({
command: "import-reference-source",
status: "error",
level: 50,
msg: "CLI command failed",
}),
]);
} else {
expect(result.stderr).toBe("");
}
},
);
}
cliTest.skipIf(permissionChecksUnavailable)(
"classifies a blocked parent directory as an execution failure",
async ({ cli }) => {
const directory = await createTestTempDirectory(
"rea-reference-cli-blocked-root-",
);
const parent = join(directory, "blocked-parent");
const root = join(parent, "input");
await mkdir(root, { recursive: true });
await chmod(parent, 0);
try {
const result = await cli.run({
arguments: ["import-reference-source", root, "--json"],
cwd: directory,
environment: {
HOME: directory,
USERPROFILE: directory,
XDG_CONFIG_HOME: directory,
XDG_CACHE_HOME: directory,
},
});
expect(result.json).toMatchObject({
error: "Import failed",
category: "execution_failure",
message: expect.stringContaining("EACCES: permission denied"),
});
expect(JSON.stringify(result.json)).toContain(root);
expect(JSON.stringify(result.json)).toContain(
"Check directory permissions and try again.",
);
expect(result.exitCode).toBe(1);
} finally {
await chmod(parent, 0o700);
}
},
);
});