From 5e5f02c67d0c165dd93f8277a3815d51a540d996 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 5 Sep 2026 04:42:20 +0900 Subject: feat(layout): plan 03 — frontend plugin ABI + handshake + load lifecycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/plugin-abi/version.test.ts | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/core/plugin-abi/version.test.ts (limited to 'src/core/plugin-abi/version.test.ts') diff --git a/src/core/plugin-abi/version.test.ts b/src/core/plugin-abi/version.test.ts new file mode 100644 index 0000000..2620847 --- /dev/null +++ b/src/core/plugin-abi/version.test.ts @@ -0,0 +1,54 @@ +import { describe, expect, it } from "vitest"; +import { FRONTEND_ABI_VERSION, isFrontendCompatible } from "./version.js"; + +describe("FRONTEND_ABI_VERSION", () => { + it("is 1 (plan 03)", () => { + expect(FRONTEND_ABI_VERSION).toBe("1"); + }); +}); + +describe("isFrontendCompatible — handshake accept/reject matrix", () => { + it("accepts the canonical authoring range ^1", () => { + expect(isFrontendCompatible("^1")).toBe(true); + expect(isFrontendCompatible("^1.0")).toBe(true); + expect(isFrontendCompatible("^1.0.0")).toBe(true); + }); + + it("accepts the bare major version and exact matches", () => { + expect(isFrontendCompatible("1")).toBe(true); + expect(isFrontendCompatible("1.0.0")).toBe(true); + }); + + it("accepts wildcard and >= ranges", () => { + expect(isFrontendCompatible("*")).toBe(true); + expect(isFrontendCompatible(">=1.0.0")).toBe(true); + }); + + it("rejects a next-major caret range", () => { + expect(isFrontendCompatible("^2")).toBe(false); + expect(isFrontendCompatible("^2.0.0")).toBe(false); + }); + + it("rejects an older pinned range", () => { + expect(isFrontendCompatible("0.9.0")).toBe(false); + expect(isFrontendCompatible("^0.1.0")).toBe(false); + }); + + it("rejects a tilde range of an older minor", () => { + expect(isFrontendCompatible("~0.9.0")).toBe(false); + expect(isFrontendCompatible("~1.0.0")).toBe(true); + }); + + it("rejects malformed ranges (fail closed, never throws)", () => { + expect(isFrontendCompatible("")).toBe(false); + expect(isFrontendCompatible("banana")).toBe(false); + expect(isFrontendCompatible("^abc")).toBe(false); + expect(isFrontendCompatible("1.0.0.0")).toBe(false); + }); + + it("rejects a future patch-level host (the host version pins the answer)", () => { + // The host version defaults to "1.0.0"; "~1.0.0" includes it. + expect(isFrontendCompatible("~1.0.0", "1.0.0")).toBe(true); + expect(isFrontendCompatible("~1.0.0", "1.1.0")).toBe(false); + }); +}); -- cgit v1.2.3