Files
nexu-io__open-design/apps/closure/tests/closure.test.ts
PerishFire 8ab7c3d5f1 feat(standalone): establish the exact lifecycle and Terminal carrier (#7716)
* feat(standalone): add shell-neutral exact lifecycle

* feat(terminal): add native exact cold-start carrier

* test(terminal): exercise mutable exact channel heads

* feat(standalone): model synced blobs and Shell updates

* feat(terminal): exercise the complete Shell lifecycle

* feat(release): add the independent exact Terminal line

* test(exact): run the full local Terminal release line

* feat(terminal): harden exact Sidecar lifecycle

* feat(standalone): prove exact update transactions

* refactor(standalone): separate shell lifecycle dimensions

* refactor(e2e): decouple terminal exact drivers

* refactor(terminal): isolate exact sidecar fixture host

* feat(terminal): gate handoff on physical retirement

* refactor(release): gate exact activation on public acceptance

* test(terminal): formalize guarded lifecycle algebra

* fix(terminal): guard shell installer handoff

* feat(terminal): add exact bootloader handoff

* feat(terminal): integrate exact sidecar lifecycle

* refactor(exact): rename validation channels

* test(terminal): harden exact release acceptance

* fix(postinstall): build standalone dependencies first

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

* fix(ci): build the native Terminal scene

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

* test(ci): cover exact convergence handoff routing

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

* fix(exact): isolate terminal validation from main CI

* fix(terminal): complete shell update confirmation

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

* fix(exact): bind acceptance to installed manifest

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

* fix(standalone): block occupied shell installs

Generated-By: looper 0.11.2 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-09-03 03:50:34 +00:00

74 lines
4.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { CLOSURE_FIXTURE_COMPONENT, createClosureFixtureContribution, prepareClosureShellUpdate } from "../src/index.js";
import closureFixture from "../src/fixture.js";
describe("Closure cold-start fixture", () => {
it("declares an intentionally Web/daemon-free content slot", () => {
expect(closureFixture).toEqual({ schemaVersion: 1, capability: "cold-start-lifecycle-fixture", web: false, daemon: false });
const bytes = Buffer.from("fixture");
expect(createClosureFixtureContribution({ artifactUrl: "https://example.invalid/fixture.mjs", artifactBytes: bytes })).toMatchObject({
id: CLOSURE_FIXTURE_COMPONENT,
sync: true,
blob: { size: bytes.byteLength, mediaType: "text/javascript" },
materialization: { type: "file", entrypoint: "fixture.mjs" },
});
});
it("drives a Shell-owned updater through check and download when the Closure floor is not met", async () => {
let revision = 0;
let state: "idle" | "available" | "ready" = "idle";
const snapshots: string[] = [];
const updater = {
shellType: "electron",
readSnapshot: async () => ({ schemaVersion: 3 as const, revision, shellType: "electron", state, actions: [], blockedBy: [] }),
waitForChange: async () => ({ schemaVersion: 3 as const, revision, shellType: "electron", state, actions: [], blockedBy: [] }),
invoke: async (action: string) => {
revision += 1;
state = action === "check" ? "available" : "ready";
return { outcome: "accepted" as const, snapshot: { schemaVersion: 3 as const, revision, shellType: "electron", state, actions: [], blockedBy: [], ...(state === "ready" ? { progress: { completed: 2, total: 2 } } : {}) } };
},
confirmInstalled: async () => ({ outcome: "unsupported" as const, snapshot: { schemaVersion: 3 as const, revision, shellType: "electron", state, actions: [], blockedBy: [] } }),
};
await expect(prepareClosureShellUpdate({
requirement: { type: "electron", minVersion: "2.0.0", buildHash: "b".repeat(64) },
shell: { type: "electron", version: "1.0.0", buildHash: "b".repeat(64), digest: "a".repeat(64) },
updater,
onSnapshot: (snapshot) => { snapshots.push(snapshot.state); },
})).resolves.toMatchObject({ state: "update-required", minimumVersion: "2.0.0", snapshot: { state: "ready", progress: { completed: 2, total: 2 } } });
expect(snapshots).toEqual(["idle", "available", "ready"]);
});
it("does not enter the Shell handler when the current Shell satisfies the fossil floor", async () => {
const updater = {
shellType: "electron",
readSnapshot: async () => { throw new Error("must not read a compatible Shell updater"); },
waitForChange: async () => { throw new Error("must not wait on a compatible Shell updater"); },
invoke: async () => { throw new Error("must not invoke a compatible Shell updater"); },
confirmInstalled: async () => { throw new Error("must not confirm a compatible Shell updater"); },
};
await expect(prepareClosureShellUpdate({
requirement: { type: "electron", minVersion: "1.2.0", buildHash: "b".repeat(64) },
shell: { type: "electron", version: "1.2.0", buildHash: "b".repeat(64), digest: "a".repeat(64) },
updater,
})).resolves.toEqual({ state: "compatible" });
});
it("fails closed when the available updater belongs to another Shell type", async () => {
let invoked = false;
const updater = {
shellType: "terminal",
readSnapshot: async () => { invoked = true; throw new Error("wrong updater must remain isolated"); },
waitForChange: async () => { invoked = true; throw new Error("wrong updater must remain isolated"); },
invoke: async () => { invoked = true; throw new Error("wrong updater must remain isolated"); },
confirmInstalled: async () => { invoked = true; throw new Error("wrong updater must remain isolated"); },
};
await expect(prepareClosureShellUpdate({
requirement: { type: "electron", minVersion: "2.0.0", buildHash: "b".repeat(64) },
shell: { type: "electron", version: "1.0.0", buildHash: "b".repeat(64), digest: "a".repeat(64) },
updater,
})).resolves.toEqual({ state: "update-required", currentVersion: "1.0.0", minimumVersion: "2.0.0", snapshot: null });
expect(invoked).toBe(false);
});
});