import { afterEach, expect, test } from "bun:test"; import { clearRegistry, NativeUnavailableError, platform, register, run, supports, } from "../src/registry.ts"; import { mobileCapabilities } from "../src/mobile.ts"; afterEach(clearRegistry); test("registers and runs a browser capability", async () => { register("example.echo", { browser: { run: (options) => options } }); expect(supports("example.echo", "browser")).toBe(true); expect(await run<{ value: number }>("example.echo", { value: 3 }, { target: "browser" })).toEqual( { value: 3 }, ); }); test("reports unsupported adapters without invoking them", async () => { register("example.mobile", { mobile: { supported: () => false, run: () => "no" } }); expect(supports("example.mobile", "mobile")).toBe(false); expect(run("example.mobile", undefined, { target: "mobile" })).rejects.toBeInstanceOf( NativeUnavailableError, ); }); test("unregister callback removes a custom capability", () => { const unregister = register("example.temp", { browser: { run: () => true } }); expect(supports("example.temp", "browser")).toBe(true); unregister(); expect(supports("example.temp", "browser")).toBe(false); }); test("reports server rather than browser during SSR", () => { const root = globalThis as typeof globalThis & { window?: Window }; const existing = Object.getOwnPropertyDescriptor(root, "window"); Reflect.deleteProperty(root, "window"); expect(platform()).toBe("server"); if (existing) Object.defineProperty(root, "window", existing); }); test("mirrors custom registration into the declarative browser runtime", () => { const calls: string[] = []; const root = globalThis as typeof globalThis & { WrNexusNative?: object }; root.WrNexusNative = { target: "browser", isMobile: false, register: (name: string) => calls.push(`add:${name}`), unregister: (name: string) => calls.push(`remove:${name}`), supports: () => true, run: async () => undefined, }; const unregister = register("example.mirror", { browser: { run: () => true } }); unregister(); delete root.WrNexusNative; expect(calls).toEqual(["add:example.mirror", "remove:example.mirror"]); }); test("normalizes unified clipboard options for Capacitor", async () => { let received: unknown; const root = globalThis as typeof globalThis & { Capacitor?: object }; root.Capacitor = { Plugins: { Clipboard: { write: (options: unknown) => (received = options) } }, }; await mobileCapabilities["clipboard.write"]!.mobile!.run({ text: "hello" }); delete root.Capacitor; expect(received).toEqual({ string: "hello" }); }); test("normalizes a simple notification into Capacitor's notification list", async () => { let received: unknown; const root = globalThis as typeof globalThis & { Capacitor?: object }; root.Capacitor = { Plugins: { LocalNotifications: { schedule: (options: unknown) => (received = options) } }, }; await mobileCapabilities["notifications.schedule"]!.mobile!.run({ id: 7, title: "Hi", body: "There", }); delete root.Capacitor; expect(received).toEqual({ notifications: [{ id: 7, title: "Hi", body: "There", schedule: undefined }], }); });