import { assert, describe, it } from "@effect/vitest"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import { beforeEach, vi } from "vite-plus/test"; const { autoUpdaterMock } = vi.hoisted(() => ({ autoUpdaterMock: { allowDowngrade: false, allowPrerelease: false, autoDownload: true, autoInstallOnAppQuit: true, channel: "latest", disableDifferentialDownload: false, checkForUpdates: vi.fn(() => Promise.resolve(null)), downloadUpdate: vi.fn(() => Promise.resolve([])), on: vi.fn(), quitAndInstall: vi.fn(), removeListener: vi.fn(), setFeedURL: vi.fn(), }, })); vi.mock("electron-updater", () => ({ autoUpdater: autoUpdaterMock, })); import * as ElectronUpdater from "./ElectronUpdater.ts"; describe("ElectronUpdater", () => { beforeEach(() => { autoUpdaterMock.allowDowngrade = false; autoUpdaterMock.allowPrerelease = false; autoUpdaterMock.autoDownload = true; autoUpdaterMock.autoInstallOnAppQuit = true; autoUpdaterMock.channel = "latest"; autoUpdaterMock.disableDifferentialDownload = false; autoUpdaterMock.checkForUpdates.mockClear(); autoUpdaterMock.checkForUpdates.mockImplementation(() => Promise.resolve(null)); autoUpdaterMock.downloadUpdate.mockClear(); autoUpdaterMock.downloadUpdate.mockImplementation(() => Promise.resolve([])); autoUpdaterMock.on.mockClear(); autoUpdaterMock.quitAndInstall.mockClear(); autoUpdaterMock.removeListener.mockClear(); autoUpdaterMock.setFeedURL.mockClear(); }); it.effect("scopes updater event listeners", () => Effect.gen(function* () { const listener = vi.fn(); yield* Effect.scoped( Effect.gen(function* () { const updater = yield* ElectronUpdater.ElectronUpdater; yield* updater.on("update-available", listener); }), ); assert.deepEqual(autoUpdaterMock.on.mock.calls, [["update-available", listener]]); assert.deepEqual(autoUpdaterMock.removeListener.mock.calls, [["update-available", listener]]); }).pipe(Effect.provide(ElectronUpdater.layer)), ); it.effect("wraps rejected update checks in the method-specific typed error", () => Effect.gen(function* () { const cause = new Error("network unavailable"); autoUpdaterMock.checkForUpdates.mockImplementationOnce(() => Promise.reject(cause)); const updater = yield* ElectronUpdater.ElectronUpdater; const exit = yield* Effect.exit(updater.checkForUpdates); assert.equal(exit._tag, "Failure"); if (exit._tag === "Failure") { const error = Cause.squash(exit.cause); assert.instanceOf(error, ElectronUpdater.ElectronUpdaterCheckForUpdatesError); assert.equal(error.cause, cause); assert.equal(error.message, "Electron updater failed to check for updates."); } }).pipe(Effect.provide(ElectronUpdater.layer)), ); });