Files
reverse-engineering-anything/tests/boundary/cli/nativeDemangleCli.test.ts
T
Beqa 54146627f0 fix(cli): emit compact JSON validation errors for demangle-swift (#7622)
* fix(cli): emit compact JSON validation errors for demangle-swift

Piped and redirected --json argument diagnostics went through Incur's
always-indented Formatter, bypassing REA's destination-aware writer.
Buffer non-TTY SDK JSON like JSONL and rewrite through writeJsonOutput.

* fix(cli): keep token-count for piped SDK JSON documents

Compact JSON rewrite for non-TTY SDK output returned early before
token controls, so --llms/--schema --format json --token-count printed
the document instead of its count.

* fix(cli): do not token-count non-document JSON captures

Completion hooks and other non-JSON --json pipe output must stay verbatim;
token-count on non-JSON SDK captures applies only with sdkDocumentControls.

* test(cli): assert demangle JSON validation by code, not wording
2026-11-04 19:40:27 +08:00

96 lines
2.8 KiB
TypeScript

import { copyFile } 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 environment = {
REA_LOG_LEVEL: "silent",
REA_ANALYSIS_PROVIDER: "auto",
} as const;
/** Copy a host program to serve as the evidence-identity artifact. */
const evidenceTarget = async () => {
const path = join(await createTestTempDirectory("rea-demangle-"), "tool");
await copyFile("/usr/bin/true", path);
return path;
};
describe("Swift demangling CLI with line-terminator characters", () => {
cliTest.skipIf(process.platform !== "darwin")(
"keeps a carriage return in the symbol",
async ({ cli }) => {
const result = await cli.run({
arguments: [
"demangle-swift",
await evidenceTarget(),
"$s4main3FooV",
"carriage\r",
"--json",
],
environment,
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({
normalized_result: {
symbols: [
{ input: "$s4main3FooV", output: "main.Foo", status: "demangled" },
{ input: "carriage\r", output: "carriage\r", status: "unchanged" },
],
},
});
},
);
cliTest("rejects a symbol spanning lines as input", async ({ cli }) => {
const missingTarget = join(
await createTestTempDirectory("rea-demangle-invalid-input-"),
"absent",
);
const result = await cli.run({
arguments: [
"demangle-swift",
missingTarget,
"$s4main3FooV",
"$s4main\n3FooV",
"--json",
],
environment,
timeoutMs: 20_000,
});
expect(result.signal).toBeNull();
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "VALIDATION_ERROR",
fieldErrors: expect.arrayContaining([
expect.objectContaining({ path: "symbols.1", missing: false }),
]),
});
});
cliTest(
"emits compact JSON for missing-argument validation on piped stdout",
async ({ cli }) => {
const result = await cli.run({
arguments: ["demangle-swift", "--json"],
environment,
timeoutMs: 20_000,
});
expect(result.signal).toBeNull();
expect(result.exitCode).toBe(1);
expect(result.stderr).toBe("");
expect(result.json).toEqual(
expect.objectContaining({
code: "VALIDATION_ERROR",
message: expect.stringMatching(/\S/),
}),
);
// Piped stdout must stay compact; Incur's Formatter always indents.
expect(result.stdout).not.toContain("\n ");
expect(result.stdout).toBe(`${JSON.stringify(result.json)}\n`);
},
);
});