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)), );});
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)),
);
});