mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-06 19:58:43 +02:00
tests: some additional tests
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { describe, expect, mock, test } from 'bun:test';
|
||||
|
||||
import type { SidecarCapabilities } from '@shared/contracts/sidecar';
|
||||
|
||||
mock.module('electron', () => ({
|
||||
app: {
|
||||
isPackaged: false,
|
||||
getAppPath: () => 'C:\\workspace\\personal\\repositories\\eryx',
|
||||
getPath: () => 'C:\\workspace\\personal\\repositories\\eryx\\tests\\fixtures',
|
||||
},
|
||||
dialog: {
|
||||
showOpenDialog: async () => ({ canceled: true, filePaths: [] }),
|
||||
},
|
||||
shell: {
|
||||
openPath: async () => '',
|
||||
},
|
||||
}));
|
||||
|
||||
mock.module('keytar', () => ({
|
||||
default: {
|
||||
getPassword: async () => null,
|
||||
setPassword: async () => undefined,
|
||||
deletePassword: async () => false,
|
||||
},
|
||||
}));
|
||||
|
||||
const { EryxAppService } = await import('@main/EryxAppService');
|
||||
|
||||
const SIDECAR_STOPPED_BEFORE_COMPLETION_MESSAGE =
|
||||
'The .NET sidecar was stopped before the command completed.';
|
||||
|
||||
const CAPABILITIES_FIXTURE: SidecarCapabilities = {
|
||||
runtime: 'dotnet-maf',
|
||||
modes: {
|
||||
single: { available: true },
|
||||
sequential: { available: true },
|
||||
concurrent: { available: true },
|
||||
handoff: { available: true },
|
||||
magentic: { available: false, reason: 'Not yet supported.' },
|
||||
'group-chat': { available: true },
|
||||
},
|
||||
models: [],
|
||||
runtimeTools: [],
|
||||
connection: {
|
||||
status: 'ready',
|
||||
summary: 'Connected',
|
||||
checkedAt: '2026-03-25T00:00:00.000Z',
|
||||
},
|
||||
};
|
||||
|
||||
function setSidecar(
|
||||
service: InstanceType<typeof EryxAppService>,
|
||||
describeCapabilities: () => Promise<SidecarCapabilities>,
|
||||
): void {
|
||||
(
|
||||
service as unknown as {
|
||||
sidecar: {
|
||||
describeCapabilities: () => Promise<SidecarCapabilities>;
|
||||
dispose: () => Promise<void>;
|
||||
};
|
||||
}
|
||||
).sidecar = {
|
||||
describeCapabilities,
|
||||
dispose: async () => undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function createDeferred<T>() {
|
||||
let resolve!: (value: T) => void;
|
||||
const promise = new Promise<T>((resolvePromise) => {
|
||||
resolve = resolvePromise;
|
||||
});
|
||||
|
||||
return { promise, resolve };
|
||||
}
|
||||
|
||||
describe('EryxAppService sidecar capabilities', () => {
|
||||
test('retries describe-capabilities after an intentional sidecar stop', async () => {
|
||||
const service = new EryxAppService();
|
||||
let attempts = 0;
|
||||
|
||||
setSidecar(service, async () => {
|
||||
attempts += 1;
|
||||
if (attempts === 1) {
|
||||
throw new Error(SIDECAR_STOPPED_BEFORE_COMPLETION_MESSAGE);
|
||||
}
|
||||
|
||||
return CAPABILITIES_FIXTURE;
|
||||
});
|
||||
|
||||
await expect(service.describeSidecarCapabilities()).resolves.toEqual(CAPABILITIES_FIXTURE);
|
||||
expect(attempts).toBe(2);
|
||||
});
|
||||
|
||||
test('coalesces concurrent capability requests while the cache is empty', async () => {
|
||||
const service = new EryxAppService();
|
||||
const deferred = createDeferred<SidecarCapabilities>();
|
||||
let calls = 0;
|
||||
|
||||
setSidecar(service, async () => {
|
||||
calls += 1;
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
const first = service.describeSidecarCapabilities();
|
||||
const second = service.describeSidecarCapabilities();
|
||||
|
||||
expect(calls).toBe(1);
|
||||
|
||||
deferred.resolve(CAPABILITIES_FIXTURE);
|
||||
|
||||
await expect(first).resolves.toEqual(CAPABILITIES_FIXTURE);
|
||||
await expect(second).resolves.toEqual(CAPABILITIES_FIXTURE);
|
||||
await expect(service.describeSidecarCapabilities()).resolves.toEqual(CAPABILITIES_FIXTURE);
|
||||
|
||||
expect(calls).toBe(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user