import { describe, expect, test } from "bun:test"; import { type DetectEnv, detectEmulator, emulatorById, } from "../src/domain/emulators.js"; import type { Os } from "../src/domain/quote.js"; const env = (o: { os?: Os; which?: Record; files?: string[]; flatpaks?: string[]; dirs?: Record; }): DetectEnv => ({ os: o.os ?? "linux", which: (c) => o.which?.[c] ?? null, fileExists: (p) => (o.files ?? []).includes(p), flatpakInstalled: (id) => (o.flatpaks ?? []).includes(id), listDir: (p) => o.dirs?.[p] ?? [], expandPath: (p) => p .replace(/^~/, "/home/u") .replace(/%APPDATA%/, "C:\\Users\\u\\AppData\\Roaming") .replace(/%LOCALAPPDATA%/, "C:\\Users\\u\\AppData\\Local"), }); const retroarch = emulatorById("retroarch")!; const ppsspp = emulatorById("ppsspp")!; const dolphin = emulatorById("dolphin")!; describe("detectEmulator", () => { test("RetroArch on PATH, cores scanned + quoted exe token", () => { const d = detectEmulator( retroarch, env({ which: { retroarch: "/usr/bin/retroarch" }, dirs: { "/home/u/.config/retroarch/cores": [ "snes9x_libretro.so", "mgba_libretro.so", "notes.txt", ], }, }), ); expect(d?.via).toBe("path"); expect(d?.exeToken).toBe("'/usr/bin/retroarch'"); expect(d?.coresDir).toBe("/home/u/.config/retroarch/cores"); expect(d?.cores).toEqual(["mgba", "snes9x"]); }); test("RetroArch via Flatpak when not on PATH", () => { const d = detectEmulator( retroarch, env({ flatpaks: ["org.libretro.RetroArch"], dirs: { "/home/u/.var/app/org.libretro.RetroArch/config/retroarch/cores": [ "snes9x_libretro.so", ], }, }), ); expect(d?.via).toBe("flatpak"); expect(d?.exeToken).toBe("flatpak run org.libretro.RetroArch"); expect(d?.appId).toBe("org.libretro.RetroArch"); expect(d?.cores).toEqual(["snes9x"]); }); test("Windows path with spaces is double-quoted", () => { const d = detectEmulator( ppsspp, env({ os: "windows", files: ["C:\\Program Files\\PPSSPP\\PPSSPPWindows64.exe"], }), ); expect(d?.via).toBe("file"); expect(d?.exeToken).toBe( '"C:\\Program Files\\PPSSPP\\PPSSPPWindows64.exe"', ); }); test("returns null when not installed", () => { expect(detectEmulator(dolphin, env({}))).toBeNull(); }); });