import { assert, describe, it } from "@effect/vitest"; import * as Effect from "effect/Effect"; import { beforeEach, vi } from "vite-plus/test"; const { appendSwitchMock, exitMock, getAppPathMock, getVersionMock, isDefaultProtocolClientMock, onMock, quitMock, relaunchMock, removeListenerMock, requestSingleInstanceLockMock, setAboutPanelOptionsMock, setAppUserModelIdMock, setAsDefaultProtocolClientMock, setDesktopNameMock, setDockIconMock, setNameMock, setPathMock, whenReadyMock, } = vi.hoisted(() => ({ appendSwitchMock: vi.fn(), exitMock: vi.fn(), getAppPathMock: vi.fn(() => "/app"), getVersionMock: vi.fn(() => "1.2.3"), isDefaultProtocolClientMock: vi.fn(() => false), onMock: vi.fn(), quitMock: vi.fn(), relaunchMock: vi.fn(), removeListenerMock: vi.fn(), requestSingleInstanceLockMock: vi.fn(() => true), setAboutPanelOptionsMock: vi.fn(), setAppUserModelIdMock: vi.fn(), setAsDefaultProtocolClientMock: vi.fn(() => true), setDesktopNameMock: vi.fn(), setDockIconMock: vi.fn(), setNameMock: vi.fn(), setPathMock: vi.fn(), whenReadyMock: vi.fn(() => Promise.resolve()), })); vi.mock("electron", () => ({ app: { commandLine: { appendSwitch: appendSwitchMock, }, dock: { setIcon: setDockIconMock, }, getAppPath: getAppPathMock, getVersion: getVersionMock, isDefaultProtocolClient: isDefaultProtocolClientMock, isPackaged: true, name: "T3 Code", on: onMock, quit: quitMock, relaunch: relaunchMock, removeListener: removeListenerMock, requestSingleInstanceLock: requestSingleInstanceLockMock, runningUnderARM64Translation: false, setAboutPanelOptions: setAboutPanelOptionsMock, setAsDefaultProtocolClient: setAsDefaultProtocolClientMock, setAppUserModelId: setAppUserModelIdMock, setDesktopName: setDesktopNameMock, setName: setNameMock, setPath: setPathMock, whenReady: whenReadyMock, exit: exitMock, }, })); import * as ElectronApp from "./ElectronApp.ts"; describe("ElectronApp", () => { beforeEach(() => { appendSwitchMock.mockClear(); exitMock.mockClear(); onMock.mockClear(); quitMock.mockClear(); relaunchMock.mockClear(); removeListenerMock.mockClear(); setPathMock.mockClear(); }); it.effect("reads app metadata through the service", () => Effect.gen(function* () { const electronApp = yield* ElectronApp.ElectronApp; const metadata = yield* electronApp.metadata; assert.deepEqual(metadata, { appVersion: "1.2.3", appPath: "/app", isPackaged: true, resourcesPath: process.resourcesPath, runningUnderArm64Translation: false, }); }).pipe(Effect.provide(ElectronApp.layer)), ); it.effect("reports which app metadata property failed", () => Effect.gen(function* () { const cause = new Error("version unavailable"); getVersionMock.mockImplementationOnce(() => { throw cause; }); const electronApp = yield* ElectronApp.ElectronApp; const error = yield* electronApp.metadata.pipe(Effect.flip); assert.instanceOf(error, ElectronApp.ElectronAppMetadataReadError); assert.strictEqual(error.property, "app-version"); assert.strictEqual(error.cause, cause); assert.strictEqual( error.message, 'Failed to read Electron app metadata property "app-version".', ); }).pipe(Effect.provide(ElectronApp.layer)), ); it.effect("preserves Electron readiness failures", () => Effect.gen(function* () { const cause = new Error("ready failed"); whenReadyMock.mockRejectedValueOnce(cause); const electronApp = yield* ElectronApp.ElectronApp; const error = yield* electronApp.whenReady.pipe(Effect.flip); assert.instanceOf(error, ElectronApp.ElectronAppWhenReadyError); assert.strictEqual(error.isPackaged, true); assert.strictEqual(error.cause, cause); assert.strictEqual( error.message, "Failed to wait for the Electron app to become ready (packaged: true).", ); }).pipe(Effect.provide(ElectronApp.layer)), ); it.effect("scopes app event listeners", () => Effect.gen(function* () { const listener = vi.fn(); yield* Effect.scoped( Effect.gen(function* () { const electronApp = yield* ElectronApp.ElectronApp; yield* electronApp.on("activate", listener); }), ); assert.deepEqual(onMock.mock.calls, [["activate", listener]]); assert.deepEqual(removeListenerMock.mock.calls, [["activate", listener]]); }).pipe(Effect.provide(ElectronApp.layer)), ); });