diff --git a/tests/acceptance/cliFormattingCapacity.test.ts b/tests/acceptance/cliFormattingCapacity.test.ts index 6e91dc0dea..1b6582764c 100644 --- a/tests/acceptance/cliFormattingCapacity.test.ts +++ b/tests/acceptance/cliFormattingCapacity.test.ts @@ -20,7 +20,7 @@ const formatterFailure = ` throw new RangeError("Invalid string length"); } `; -const formatterCapacityHook = `data:text/javascript,${encodeURIComponent(` +const incurCapacityHook = `data:text/javascript,${encodeURIComponent(` import { registerHooks } from "node:module"; registerHooks({ load(url, context, next) { @@ -34,9 +34,33 @@ registerHooks({ }); `)}`; -for (const scenario of [ +// REA owns Markdown rendering. Fail one scalar's string materialization in the +// CLI child, restoring String before the recovery document uses that formatter. +// This does not depend on generated bundle names or compiled function text. +const markdownCapacityHook = `data:text/javascript,${encodeURIComponent(` +globalThis.String = new Proxy(String, { + apply(target, receiver, args) { + if (["inspect_managed_artifact", "target_unavailable"].includes(args[0])) { + globalThis.String = target; + process.stderr.write("REA_AUTHORED_FORMAT_CAPACITY\\n"); + throw new RangeError("Invalid string length"); + } + return Reflect.apply(target, receiver, args); + }, +}); +`)}`; + +type FormattingScenario = { + readonly name: string; + readonly arguments: readonly string[]; + readonly full: boolean; + readonly format?: "yaml" | "md"; + readonly human?: boolean; +}; + +const scenarios: readonly FormattingScenario[] = [ { name: "default TOON", arguments: [], full: false }, - { name: "human TOON", arguments: [], full: false }, + { name: "human TOON", arguments: [], full: false, human: true }, { name: "full TOON", arguments: ["--full-output"], full: true }, { name: "TOON token count", arguments: ["--token-count"], full: false }, { name: "TOON token window", arguments: ["--token-limit", "3"], full: false }, @@ -45,14 +69,29 @@ for (const scenario of [ arguments: ["--full-output", "--token-limit", "3"], full: true, }, - { name: "YAML", arguments: ["--format", "yaml"], full: false }, + { name: "YAML", format: "yaml", arguments: [], full: false }, { name: "full YAML", - arguments: ["--format", "yaml", "--full-output"], + format: "yaml", + arguments: ["--full-output"], full: true, }, - { name: "Markdown", arguments: ["--format", "md"], full: false }, -] as const) + { name: "Markdown", format: "md", arguments: [], full: false }, + { + name: "full Markdown", + format: "md", + arguments: ["--full-output"], + full: true, + }, + { + name: "Markdown token window", + format: "md", + arguments: ["--token-limit", "3"], + full: false, + }, +]; + +for (const scenario of scenarios) for (const outcome of ["success", "failure"] as const) workspaceCliTest( `${scenario.name} returns a typed formatting constraint after ${outcome}`, @@ -64,14 +103,15 @@ for (const scenario of [ process.execPath, [ "--import", - scenario.name === "human TOON" + scenario.human ? `data:text/javascript,${encodeURIComponent('Object.defineProperty(process.stdout, "isTTY", { value: true });')}` : "data:text/javascript,", "--import", - formatterCapacityHook, + scenario.format === "md" ? markdownCapacityHook : incurCapacityHook, resolve("scripts/rea.mjs"), "inspect-managed-artifact", target, + ...(scenario.format ? ["--format", scenario.format] : []), ...scenario.arguments, ], { cwd: workspace.root, env: { PATH: process.env.PATH ?? "" } }, @@ -85,7 +125,16 @@ for (const scenario of [ expect(result.stdout).not.toContain("UNKNOWN"); if (outcome === "failure") expect(result.stdout).toContain("target_unavailable"); - if (scenario.name.includes("YAML")) { + if (scenario.format === "md" && scenario.full) { + expect(result.stdout).toMatch(/^## ok\n\nfalse$/m); + expect(result.stdout).toMatch( + /^## error\.code\n\nresource_constraint$/m, + ); + expect(result.stdout).toMatch( + /^## meta\n\n(?:\|[^\n]*\|\n)*\| command +\| inspect-managed-artifact +\|$/m, + ); + } + if (scenario.format === "yaml") { const document = parseYaml(result.stdout); const error = scenario.full ? document.error : document; expect(analysisErrorProjectionSchema.parse(error)).toMatchObject({ @@ -112,7 +161,7 @@ workspaceCliTest.skipIf(process.platform === "win32")( process.execPath, [ "--import", - formatterCapacityHook, + incurCapacityHook, resolve("scripts/rea.mjs"), "inspect-managed-artifact", workspace.path("missing.dll"),