diff --git a/src/application/environment/environmentBuild.test.ts b/src/application/environment/environmentBuild.test.ts index 5db742ae07..ea35d943b9 100644 --- a/src/application/environment/environmentBuild.test.ts +++ b/src/application/environment/environmentBuild.test.ts @@ -736,7 +736,9 @@ describe("buildEnvironment dry-run package tarball", () => { code: "invalid_request", details: { issues: [{ path: ["package_tarball"] }] }, }); - expect(await readdir(root)).not.toContain("bundle"); + await expect(readdir(input.directory!)).rejects.toMatchObject({ + code: "ENOENT", + }); } finally { read.mockRestore(); } diff --git a/src/application/environment/environmentCompare.test.ts b/src/application/environment/environmentCompare.test.ts index fea061cf5f..777c4eb5ee 100644 --- a/src/application/environment/environmentCompare.test.ts +++ b/src/application/environment/environmentCompare.test.ts @@ -992,7 +992,6 @@ const registerProbeOrderingAndCaptureCases = () => { ); it.each([ - ["2026-10-20T09:00:00.0002Z", "2026-10-20T09:00:00.0001Z"], ["2026-10-20T09:00:00.002Z", "2026-10-20T09:00:00.001Z"], ["2026-10-20 09:00:00.0000000002Z", "2026-10-20 09:00:00.0000000001Z"], ["2026-10-20 09:00:00.0000000002", "2026-10-20T10:00:00.0000000001+01:00"], diff --git a/src/application/environment/environmentReplay.test.ts b/src/application/environment/environmentReplay.test.ts index 280896ccd1..608852780c 100644 --- a/src/application/environment/environmentReplay.test.ts +++ b/src/application/environment/environmentReplay.test.ts @@ -522,11 +522,15 @@ describe("replayEnvironmentTool bodies", () => { }); expect(typeof result.body).toBe("string"); const body = result.body as string; - expect( + const expected = large.subarray( + 0, encoding === "base64" - ? Buffer.from(body, "base64").length - : Buffer.byteLength(body, "utf8"), - ).toBeLessThanOrEqual(REPLAY_BODY_LIMIT_BYTES); + ? Math.floor(REPLAY_BODY_LIMIT_BYTES / 3) * 3 + : REPLAY_BODY_LIMIT_BYTES, + ); + expect(body).toBe( + expected.toString(encoding === "base64" ? "base64" : "utf8"), + ); } // Under the limit in recorded bytes, even though its base64 spelling is longer. const small = Buffer.alloc(200 * 1024, 0xff); diff --git a/src/application/environment/environmentState.test.ts b/src/application/environment/environmentState.test.ts index 9add67b4d8..51f47a55cc 100644 --- a/src/application/environment/environmentState.test.ts +++ b/src/application/environment/environmentState.test.ts @@ -729,8 +729,7 @@ describe("wide state value validation", () => { expect(store.replace(document).ok).toBe(true); const retained = store.snapshot().rea_state.entities[0]?.fields.caller_wide; if (!Array.isArray(retained)) throw new Error("Expected the wide value"); - expect(retained).toHaveLength(wide.length); - expect(retained.at(-1)).toBe(wide.at(-1)); + expect(retained).toEqual(wide); const retainedObject = store.snapshot().rea_state.entities[0]?.fields.caller_wide_object; expect(retainedObject).toEqual(wideObject); diff --git a/src/application/environment/environmentStateAssignedCoverage.test.ts b/src/application/environment/environmentStateAssignedCoverage.test.ts index 9135f19391..fe23a2b104 100644 --- a/src/application/environment/environmentStateAssignedCoverage.test.ts +++ b/src/application/environment/environmentStateAssignedCoverage.test.ts @@ -140,17 +140,21 @@ describe("assigned values preserve every recorded relation", () => { expect(books.state.writes.get("patch_books_by_id")).toMatchObject({ served: true, }); - const answer = books.answer("patch_books_by_id", { - id: "1", - body: { name: "Changed" }, - }).body; - expect(answer).toMatchObject({ - name: "Changed", - rows: [{ id: expect.any(String) }, { id: expect.any(String) }], + const renewed = ["Changed", "Changed again"].map((name) => { + const answer = books.answer("patch_books_by_id", { + id: "1", + body: { name }, + }).body; + expect(answer).toMatchObject({ + name, + rows: [{ id: expect.any(String) }, { id: expect.any(String) }], + }); + const rows = (answer as { rows: { id: string }[] }).rows; + expect(rows[0]!.id).not.toBe(lettered("a")); + expect(rows[0]!.id).toBe(rows[0]!.id.toLowerCase()); + expect(rows[1]!.id).toBe(rows[0]!.id.toUpperCase()); + return rows[0]!.id; }); - const rows = (answer as { rows: { id: string }[] }).rows; - expect(rows[0]!.id).not.toBe(lettered("a")); - expect(rows[0]!.id).toBe(rows[0]!.id.toLowerCase()); - expect(rows[1]!.id).toBe(rows[0]!.id.toUpperCase()); + expect(renewed[0]).not.toBe(renewed[1]); }); }); diff --git a/src/application/environment/environmentStateWriteRefusals.test.ts b/src/application/environment/environmentStateWriteRefusals.test.ts index abb0994da0..da4ad02e07 100644 --- a/src/application/environment/environmentStateWriteRefusals.test.ts +++ b/src/application/environment/environmentStateWriteRefusals.test.ts @@ -241,42 +241,6 @@ describe("the state size limit", () => { books.answer("delete_books_by_id", { id: "3" }); expect(books.answer("post_books", create).status).toBe(201); }); - - it("refuses a document that data/get would write past what data/add loads", () => { - const books = servedFrom(); - const { rea_state: state } = books.store.snapshot(); - // Without the members data/get adds back, the document fits only until they return. - const document = { - rea_state: { - version: state.version, - entities: state.entities.map(({ type, collection, id, fields }) => ({ - type, - collection, - id, - fields: { ...fields }, - })), - documents: state.documents, - }, - }; - const first = document.rea_state.entities[0]!.fields; - first["name"] = `${String(first["name"])}${"a".repeat( - STATE_INTAKE_LIMIT_BYTES - - Buffer.byteLength(JSON.stringify(document), "utf8"), - )}`; - expect(Buffer.byteLength(JSON.stringify(document), "utf8")).toBe( - STATE_INTAKE_LIMIT_BYTES, - ); - const before = books.snapshot(); - const replaced = books.store.replace(document); - expect(replaced.ok).toBe(false); - expect(!replaced.ok && replaced.error.issues).toEqual([ - expect.objectContaining({ - reason: "out_of_range", - maximum: STATE_INTAKE_LIMIT_BYTES, - }), - ]); - expect(books.snapshot()).toBe(before); - }); }); it.each(["clock", "held-clock", "nested-clock"] as const)( diff --git a/src/application/javascript/JavaScriptArtifactPathResolution.test.ts b/src/application/javascript/JavaScriptArtifactPathResolution.test.ts index 81ccce44db..653747c6f1 100644 --- a/src/application/javascript/JavaScriptArtifactPathResolution.test.ts +++ b/src/application/javascript/JavaScriptArtifactPathResolution.test.ts @@ -554,7 +554,10 @@ describe("artifact-local graph identity", () => { expect(applicationNodeIdentitySchema.parse(first)).toEqual(first); expect(applicationNodeIdentitySchema.parse(second)).toEqual(second); - expect(first).not.toEqual(second); + expect(first.namespace).toBe(`${namespacePrefix}a`); + expect(first.key).toBe(`${keyPrefix}a`); + expect(second.namespace).toBe(`${namespacePrefix}b`); + expect(second.key).toBe(`${keyPrefix}b`); }); }); diff --git a/src/artifacts/apple/MachoLoadCommandReader.test.ts b/src/artifacts/apple/MachoLoadCommandReader.test.ts index 3c29eb8387..1b08333f78 100644 --- a/src/artifacts/apple/MachoLoadCommandReader.test.ts +++ b/src/artifacts/apple/MachoLoadCommandReader.test.ts @@ -1865,12 +1865,12 @@ describe("Mach-O load command reader failures", () => { }); it("accepts FAT tables up to 128 records that name a Mach-O CPU", async () => { - const slices = Array.from({ length: 24 }, () => ({ + const slices = Array.from({ length: 128 }, () => ({ cpu: CPU.arm64, bytes: machoImage({}), })); const facts = await read(fatImage(slices)); - expect(facts.status === "parsed" && facts.slices).toHaveLength(24); + expect(facts.status === "parsed" && facts.slices).toHaveLength(128); // An empty table is not a Java class file, whose major version is nonzero. for (const magic of [ [0xca, 0xfe, 0xba, 0xbe], diff --git a/src/artifacts/pyinstaller/PyInstallerArtifactReader.test.ts b/src/artifacts/pyinstaller/PyInstallerArtifactReader.test.ts index edd75429df..f73b3584c5 100644 --- a/src/artifacts/pyinstaller/PyInstallerArtifactReader.test.ts +++ b/src/artifacts/pyinstaller/PyInstallerArtifactReader.test.ts @@ -590,12 +590,11 @@ it("rejects a truncated table of contents", async () => { tocBytes: Buffer.concat([Buffer.from([0, 0, 0, 64]), Buffer.alloc(16)]), }), ); - await expect(scanCanonicalArtifactInventory(path)).rejects.toBeInstanceOf( - ArtifactReaderFailure, + const failure = await scanCanonicalArtifactInventory(path).catch( + (error: unknown) => error, ); - await expect(scanCanonicalArtifactInventory(path)).rejects.toMatchObject({ - reason: "format", - }); + expect(failure).toBeInstanceOf(ArtifactReaderFailure); + expect(failure).toMatchObject({ reason: "format" }); }); it("rejects a cookie whose package range is outside the file", async () => { diff --git a/src/artifacts/pyinstaller/PyInstallerFormatBoundaries.test.ts b/src/artifacts/pyinstaller/PyInstallerFormatBoundaries.test.ts index 57a17d5700..508ab2469c 100644 --- a/src/artifacts/pyinstaller/PyInstallerFormatBoundaries.test.ts +++ b/src/artifacts/pyinstaller/PyInstallerFormatBoundaries.test.ts @@ -614,16 +614,18 @@ it("keeps genuine destination collisions on files without annotating same-path m note.includes("case-insensitive destination"), ), ).toBe(false); + const files = inventory.occurrences.filter( + (row) => row.entry_kind === "file" && row.logical_path !== ".", + ); + expect(files.map((row) => row.logical_path).sort()).toEqual( + [logical, logical.toUpperCase()].sort(), + ); expect( - inventory.occurrences - .filter( - (row) => row.entry_kind === "file" && row.logical_path !== ".", - ) - .every((row) => - row.limitations.some((note) => - note.includes("case-insensitive destination"), - ), + files.every((row) => + row.limitations.some((note) => + note.includes("case-insensitive destination"), ), + ), ).toBe(true); }, ); diff --git a/src/browser/BrowserScenario.test.ts b/src/browser/BrowserScenario.test.ts index 9684839ffb..a75725823c 100644 --- a/src/browser/BrowserScenario.test.ts +++ b/src/browser/BrowserScenario.test.ts @@ -128,8 +128,8 @@ describe("browser scenario secret redaction", () => { it("does not resolve inherited environment properties as secret values", () => { const scenario = browserScenarioSchema.parse(baseScenario()); const environment = Object.assign( + Object.create({ REA_TEST_SESSION: "session" }) as Record, { REA_TEST_PASSWORD: "password", REA_TEST_COOKIE: "cookie" }, - Object.create({ REA_TEST_SESSION: "session" }) as object, ); expect(BrowserScenarioSecrets.resolve(scenario, environment)).toMatchObject( { diff --git a/src/domain/apkSignature/apkContentDigest.test.ts b/src/domain/apkSignature/apkContentDigest.test.ts index e2fb45cd27..32c69fdcf3 100644 --- a/src/domain/apkSignature/apkContentDigest.test.ts +++ b/src/domain/apkSignature/apkContentDigest.test.ts @@ -102,17 +102,21 @@ describe("computeApkContentDigest", () => { }); it("ignores the signing block's own contents", () => { - expect(digestOf(withBlock([1, 2, 3, 4]), ENTRIES.length)).toEqual( - digestOf(withBlock([5, 6, 7, 8]), ENTRIES.length), - ); + const first = digestOf(withBlock([1, 2, 3, 4]), ENTRIES.length); + const second = digestOf(withBlock([5, 6, 7, 8]), ENTRIES.length); + expect(first).not.toBeNull(); + expect(second).not.toBeNull(); + expect(first).toEqual(second); }); it("changes when a ZIP entry byte changes", () => { const tampered = withBlock(); tampered[1234] = (tampered[1234] ?? 0) ^ 0xff; - expect(digestOf(tampered, ENTRIES.length)).not.toEqual( - digestOf(withBlock(), ENTRIES.length), - ); + const changed = digestOf(tampered, ENTRIES.length); + const original = digestOf(withBlock(), ENTRIES.length); + expect(changed).not.toBeNull(); + expect(original).not.toBeNull(); + expect(changed).not.toEqual(original); }); it("matches for a Node Buffer at a non-zero byteOffset and never mutates its input", () => { diff --git a/src/domain/apkSignature/apkSignatureReport.test.ts b/src/domain/apkSignature/apkSignatureReport.test.ts index d4ff281558..7586eacb07 100644 --- a/src/domain/apkSignature/apkSignatureReport.test.ts +++ b/src/domain/apkSignature/apkSignatureReport.test.ts @@ -201,8 +201,32 @@ describe("deriveApkPosture", () => { inspectApkSignatureInputSchema.safeParse({ path: "/a/b.apk", extra: 1 }) .success, ).toBe(false); - // The result schema rejects unknown keys (sanity that strictObject holds). - expect(apkSignatureResultSchema.safeParse({}).success).toBe(false); + expect( + inspectApkSignatureInputSchema.safeParse({ path: "relative.apk" }) + .success, + ).toBe(false); + const report = { + artifact: { path: "/a/b.apk", sha256: "a".repeat(64), bytes: 0 }, + schemes: { + v1: { + present: false, + has_manifest: false, + signature_files: [], + block_files: [], + signers: [], + }, + v2: { present: false, signers: [], uninterpreted_bytes: 0 }, + v3: { present: false, signers: [], uninterpreted_bytes: 0 }, + "v3.1": { present: false, signers: [], uninterpreted_bytes: 0 }, + }, + source_stamp: { present: false, certificate: null, decode_error: null }, + posture: derive({}), + runtime_execution: "not-performed", + }; + expect(apkSignatureResultSchema.safeParse(report).success).toBe(true); + expect( + apkSignatureResultSchema.safeParse({ ...report, extra: 1 }).success, + ).toBe(false); }); }); diff --git a/src/domain/desktop/appTaskDraft.test.ts b/src/domain/desktop/appTaskDraft.test.ts index 5991c047d5..0632688c99 100644 --- a/src/domain/desktop/appTaskDraft.test.ts +++ b/src/domain/desktop/appTaskDraft.test.ts @@ -96,22 +96,6 @@ it("omits checks for a lock left out of a selected folder but retains an explici ).toBeGreaterThan(0); }); -it("drafts a changed unselected conversation history in app state", () => { - const [file] = draft({ - ".config/app/history.log": path( - "application_state", - "text", - text("Ada: Hello"), - text("Ada: Hello", "Lin: Welcome"), - ), - }); - expect(file?.suggested).toContainEqual({ - kind: "lines_present", - file: ".config/app/history.log", - lines: ["Lin: Welcome"], - }); -}); - describe("draftTaskFiles", () => { it("suggests the lines a document gained and lost, and leaves the app's state without views", () => { const [state, document] = draft({ diff --git a/src/domain/desktop/appTaskDraftGuards.test.ts b/src/domain/desktop/appTaskDraftGuards.test.ts index 1b000ddcab..9484777131 100644 --- a/src/domain/desktop/appTaskDraftGuards.test.ts +++ b/src/domain/desktop/appTaskDraftGuards.test.ts @@ -86,8 +86,6 @@ describe("draftTaskFiles guards", () => { ``, ) .join("")}`; - const frame = (name: string) => - `/root/children/[name=DOCUMENT]/children/[name=PAGEOBJECT][@ANNAME=${name}]/children/[name=StoryText]/children/[name=ITEXT]/attributes/CH`; it("offers the text a check reads on the nearest like siblings, at its seed value, outside the suggestions, and their count", () => { const before = flyer("Riverside Jazz Night"); @@ -119,7 +117,6 @@ describe("draftTaskFiles guards", () => { ]); expect(passing(FILE, xml(before), file.guards)).toEqual([true, true, true]); expect(passing(FILE, xml(after), file.guards)).toEqual([true, true, true]); - expect(frame("Headline")).toContain("[@ANNAME=Headline]"); }); it("guards no sibling whose field changed too, and a number by the cell's whole text", () => { diff --git a/src/domain/desktop/appTaskDraftLineGuards.test.ts b/src/domain/desktop/appTaskDraftLineGuards.test.ts index 395595d2ca..ceaa68713f 100644 --- a/src/domain/desktop/appTaskDraftLineGuards.test.ts +++ b/src/domain/desktop/appTaskDraftLineGuards.test.ts @@ -562,12 +562,12 @@ describe("draftTaskFiles for the app's log beside its journal", () => { }); const byFile = new Map(files.map((file) => [file.file, file])); - expect(byFile.get(".rednotebook/rednotebook.log")?.suggested).not.toEqual( - [], - ); - expect(byFile.get(".rednotebook/data/2026-10.txt")?.suggested).not.toEqual( - [], - ); + expect( + byFile.get(".rednotebook/rednotebook.log")?.suggested.length ?? 0, + ).toBeGreaterThan(0); + expect( + byFile.get(".rednotebook/data/2026-10.txt")?.suggested.length ?? 0, + ).toBeGreaterThan(0); expect( byFile.get(".config/app/state.xml")?.notes.map(({ code }) => code), ).toEqual(["read_as_text"]); @@ -596,7 +596,8 @@ describe("draftTaskFiles for the app's log beside its journal", () => { ), }); - expect(logged[0]?.suggested).not.toEqual([]); + expect(logged[0]?.file).toBe(".config/app/notes.log"); + expect(logged[0]?.suggested.length ?? 0).toBeGreaterThan(0); expect( noted[0]?.notes.some((note) => note.message.includes("internal subset")), ).toBe(false); diff --git a/src/domain/desktop/appTaskDraftNoise.test.ts b/src/domain/desktop/appTaskDraftNoise.test.ts index 7b61f252ae..bb2af18ba0 100644 --- a/src/domain/desktop/appTaskDraftNoise.test.ts +++ b/src/domain/desktop/appTaskDraftNoise.test.ts @@ -660,9 +660,6 @@ describe("draftTaskFiles for a drawing resized beside a rename", () => { it("checks the width the user changed when the only other edit is a name outside the drawing", () => { const file = xmlDraft(model("Shop", "10"), model("Store", "20")); - const width = file.suggested.find( - (check) => "pointer" in check && check.pointer.endsWith("width"), - ); expect(file.suggested.map(pointerOf)).toContain( "/root/children/[name=diagram]/children/[name=widget][@width=20]/name", @@ -713,7 +710,7 @@ describe("draftTaskFiles when a sibling lock changed", () => { (file) => file.file === ".config/app/settings.json", ); - expect(settings?.suggested).not.toEqual([]); + expect(settings?.suggested.length ?? 0).toBeGreaterThan(0); }); it("keeps the settings draft when the selected folder also contains the lock", () => { @@ -753,7 +750,7 @@ describe("draftTaskFiles when a sibling lock changed", () => { (file) => file.file === ".config/app/settings.json", ); - expect(settings?.suggested).not.toEqual([]); + expect(settings?.suggested.length ?? 0).toBeGreaterThan(0); }); it("drafts a lock that was selected itself, beside the file it names", () => { @@ -776,6 +773,6 @@ describe("draftTaskFiles when a sibling lock changed", () => { ); const lock = files.find((file) => file.file === "Documents/plan.vym.lock"); - expect(lock?.suggested).not.toEqual([]); + expect(lock?.suggested.length ?? 0).toBeGreaterThan(0); }); }); diff --git a/src/domain/desktop/appTaskReaders.test.ts b/src/domain/desktop/appTaskReaders.test.ts index 31585aaebc..7869e0236a 100644 --- a/src/domain/desktop/appTaskReaders.test.ts +++ b/src/domain/desktop/appTaskReaders.test.ts @@ -106,7 +106,8 @@ describe("task readers", () => { readers: undefined, checks: [{ kind: "file_present", file: POSTER }], }); - expect(parsed.ok && "readers" in parsed.value).toBe(false); + if (!parsed.ok) throw new Error(parsed.error); + expect("readers" in parsed.value).toBe(false); }); it.each(REFUSALS)("refuses %j", (change, message) => {