import { assert, assertEquals, assertStringIncludes } from "@std/assert"; import { join } from "node:path"; import { tempDir, until } from "@berry/util"; import { extension, fixture, open, put } from "./loader-fixture.ts"; Deno.test("duplicate names fail without choosing a directory and recover when the collision is removed", () => fixture({ "same/mod.ts": extension("same"), "same/version.ts": 'export const VERSION = "shipped";', }, async (root) => { await using user = await tempDir(); await put(user.path, { "same/mod.ts": extension("same"), "same/version.ts": 'export const VERSION = "personal";', }); const shipped = join(root, "extensions"); const { loader, close, describe } = await open(root, [shipped, user.path]); try { await loader.loadAll(); const [entry] = loader.entries(); assertEquals(entry.status, "failed"); assertEquals(entry.running, false); assertEquals(entry.directory, null); assertEquals(describe("same"), undefined); assertStringIncludes(entry.error!, join(shipped, "same")); assertStringIncludes(entry.error!, join(user.path, "same")); await Deno.remove(join(user.path, "same"), { recursive: true }); assertEquals((await loader.reload("same")).status, "loaded"); assertEquals(describe("same"), "shipped"); } finally { await close(); } })); Deno.test("both roots hot-reload additions, edits, collisions, and removals even if a root starts absent", () => fixture({}, async (root) => { await using user = await tempDir(); const personal = join(user.path, "extensions"); const shipped = join(root, "extensions"); const { loader, close, describe } = await open(root, [shipped, personal]); try { await loader.loadAll(); loader.watch(); await put(personal, { "added/mod.ts": extension("added"), "added/version.ts": 'export const VERSION = "one";', }); await until(() => describe("added") === "one", { timeout: 10_000 }); await Deno.writeTextFile(join(personal, "added/version.ts"), 'export const VERSION = "two";'); await until(() => describe("added") === "two", { timeout: 10_000 }); await put(shipped, { "added/mod.ts": extension("added"), "added/version.ts": 'export const VERSION = "shadow";', }); await until(() => loader.entries()[0]?.status === "failed", { timeout: 10_000 }); assertEquals(describe("added"), "two"); assert(loader.entries()[0].running); await Deno.remove(join(shipped, "added"), { recursive: true }); await until(() => loader.entries()[0]?.status === "loaded", { timeout: 10_000 }); await Deno.remove(join(personal, "added"), { recursive: true }); await until(() => describe("added") === undefined, { timeout: 10_000 }); assertEquals(loader.entries(), []); } finally { await close(); } }));