From b869fa762a827fb66978067fabe09439ebfef111 Mon Sep 17 00:00:00 2001 From: Kaoru0822 Date: Fri, 23 Oct 2026 22:08:18 -0700 Subject: [PATCH] test: align stale fixtures with recent native and launcher contracts (#6945) * test(native): expect artifact_changed when a bound metadata target is lost 41e10b240 made a bound metadata target that fails the source boundary (`path`) or disappears (`ENOENT`) report AnalysisArtifactChangedError, as its comment and docs/testing.md state, but left the module test expecting AnalysisInputError. The test now asserts the shipped contract, so main's Test shard and Portable tests lanes pass again. Co-Authored-By: Claude Opus 5.5 * test(package): ship the CLI process environment owner in launcher fixtures c2caae88f moved launcher environment preparation into scripts/lib/cli-process-environment.mjs, made scripts/rea.mjs import it and made verifyPackagePack require it in the packed listing, and updated the dispatcher fixtures, but two other fixtures still omit it: - packageTarListing's fake tar listing, so every case stops at "package omitted the CLI process environment owner" before its own assertion; - deferredRuntime's copied compiled package, so the copied launcher fails to resolve its import instead of reporting the corrupted catalog. Both fixtures now include the module, as the package ships it. Co-Authored-By: Claude Opus 5.5 * test(native): expect XML plist validation in typed-value provenance 9f5dd56e2 records a successful `plutil -lint` of an XML plist source in provenance, as docs/native-investigation.md states, but the macOS typed-value CLI test still expected only the `file` step for both formats. XML sources now expect the lint step; binary sources are unchanged. Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 --- src/native/AppleDispatchMetadata.failure.test.ts | 13 +++++++------ tests/boundary/cli/nativePlistCli.test.ts | 12 +++++++++++- tests/boundary/mcp/deferredRuntime.test.ts | 7 ++++++- tests/boundary/process/packageTarListing.test.ts | 1 + 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/native/AppleDispatchMetadata.failure.test.ts b/src/native/AppleDispatchMetadata.failure.test.ts index 11d187ac97..8c9a36141a 100644 --- a/src/native/AppleDispatchMetadata.failure.test.ts +++ b/src/native/AppleDispatchMetadata.failure.test.ts @@ -2,19 +2,18 @@ import { expect, it } from "vitest"; import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js"; import { appleDispatchMetadataFailure } from "./AppleDispatchMetadata.js"; +// The metadata target is already bound, so losing it is a change to that artifact rather than a new input error. it.each(["integrity", "path"] as const)( - "keeps %s source-read refusals distinct from provider execution failures", + "reports a %s source-read refusal as a change to the bound target, not a provider failure", (reason) => { const cause = new ArtifactReaderFailure(reason, "source boundary refused"); expect(appleDispatchMetadataFailure(cause, "/selected")._tag).toBe( - reason === "integrity" - ? "AnalysisArtifactChangedError" - : "AnalysisInputError", + "AnalysisArtifactChangedError", ); }, ); it.each(["EACCES", "EPERM", "ENOENT"])( - "preserves the filesystem outcome %s for a selected metadata target", + "preserves the filesystem outcome %s for a bound metadata target", (code) => { const physical = Object.assign(new Error("selected read refused"), { code, @@ -23,7 +22,9 @@ it.each(["EACCES", "EPERM", "ENOENT"])( cause: physical, }); expect(appleDispatchMetadataFailure(cause, "/selected")._tag).toBe( - code === "ENOENT" ? "AnalysisInputError" : "AnalysisAccessDeniedError", + code === "ENOENT" + ? "AnalysisArtifactChangedError" + : "AnalysisAccessDeniedError", ); }, ); diff --git a/tests/boundary/cli/nativePlistCli.test.ts b/tests/boundary/cli/nativePlistCli.test.ts index 9f0648c802..192f2337ab 100644 --- a/tests/boundary/cli/nativePlistCli.test.ts +++ b/tests/boundary/cli/nativePlistCli.test.ts @@ -281,7 +281,17 @@ describe.skipIf(process.platform !== "darwin")( ], }, bundle: { identifier: "com.example.types", executable: "App" }, - provenance: [{ tool: "file" }], + // An XML source also records its successful native format validation. + provenance: + format === "xml" + ? [ + { tool: "file" }, + { + tool: "plutil", + command: ["/usr/bin/plutil", "-lint", "--", "$PLIST"], + }, + ] + : [{ tool: "file" }], limitations: [expect.stringContaining("2 non-finite real")], }, }); diff --git a/tests/boundary/mcp/deferredRuntime.test.ts b/tests/boundary/mcp/deferredRuntime.test.ts index 3718f20650..14196fe55b 100644 --- a/tests/boundary/mcp/deferredRuntime.test.ts +++ b/tests/boundary/mcp/deferredRuntime.test.ts @@ -619,8 +619,13 @@ it("runs the real static artifact workflow after deferred initialization", async const copyCompiledPackage = async (prefix: string): Promise => { const directory = await createTestTempDirectory(prefix); await cp(resolve("dist"), join(directory, "dist"), { recursive: true }); - await mkdir(join(directory, "scripts")); + await mkdir(join(directory, "scripts/lib"), { recursive: true }); await cp(resolve("scripts/rea.mjs"), join(directory, "scripts/rea.mjs")); + // The launcher imports its process-environment owner, as the package ships it. + await cp( + resolve("scripts/lib/cli-process-environment.mjs"), + join(directory, "scripts/lib/cli-process-environment.mjs"), + ); await cp(resolve("package.json"), join(directory, "package.json")); await symlink( resolve("node_modules"), diff --git a/tests/boundary/process/packageTarListing.test.ts b/tests/boundary/process/packageTarListing.test.ts index e876811bac..02a84327c7 100644 --- a/tests/boundary/process/packageTarListing.test.ts +++ b/tests/boundary/process/packageTarListing.test.ts @@ -25,6 +25,7 @@ const members = [ "package/bridge/ghidra/ReaGhidraAnalysisOptions.java", "package/bridge/ghidra/ReaGhidraNoReturnFix.java", "package/bridge/ghidra/ReaGhidraMipsSoftFloat.java", + "package/scripts/lib/cli-process-environment.mjs", ]; async function verifyListing(listing: string) {