27 new tests: detectAgentClis/requireAtLeastOneAgentCli/NoAgentCliError with mocked commandExists, plus identity-restore run() covering all skip conditions (missing .env, no Supabase config, fetch errors) and happy path (canonical + legacy paths, no-overwrite guard, blank file overwrite, header verification, quoted .env values). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --- Build: FAIL | Tests: pass — Tests 1390 passed (1390)
151 lines
5.1 KiB
TypeScript
151 lines
5.1 KiB
TypeScript
/**
|
|
* setup/agent-cli-check.test.ts — agent CLI detection tests.
|
|
*
|
|
* Tests AGENT_CLIS, detectAgentClis(), NoAgentCliError, and
|
|
* requireAtLeastOneAgentCli() with mocked commandExists.
|
|
*
|
|
* Run with: npx vitest run setup/agent-cli-check.test.ts
|
|
*/
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Mock commandExists from platform.js
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const platformMock = vi.hoisted(() => ({
|
|
commandExists: vi.fn<[string], boolean>(() => false),
|
|
}));
|
|
|
|
vi.mock('./platform.js', () => platformMock);
|
|
|
|
import {
|
|
AGENT_CLIS,
|
|
detectAgentClis,
|
|
NoAgentCliError,
|
|
requireAtLeastOneAgentCli,
|
|
} from './agent-cli-check.js';
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// AGENT_CLIS
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe('AGENT_CLIS', () => {
|
|
it('contains pi, aider, claude, codex, gemini', () => {
|
|
const commands = AGENT_CLIS.map((c) => c.command);
|
|
expect(commands).toContain('pi');
|
|
expect(commands).toContain('aider');
|
|
expect(commands).toContain('claude');
|
|
expect(commands).toContain('codex');
|
|
expect(commands).toContain('gemini');
|
|
});
|
|
|
|
it('each entry has name and command fields', () => {
|
|
for (const cli of AGENT_CLIS) {
|
|
expect(typeof cli.name).toBe('string');
|
|
expect(typeof cli.command).toBe('string');
|
|
}
|
|
});
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// detectAgentClis
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe('detectAgentClis', () => {
|
|
beforeEach(() => {
|
|
platformMock.commandExists.mockReset().mockReturnValue(false);
|
|
});
|
|
|
|
it('returns one entry per AGENT_CLIS entry', () => {
|
|
const result = detectAgentClis();
|
|
expect(result).toHaveLength(AGENT_CLIS.length);
|
|
});
|
|
|
|
it('marks all as not present when commandExists returns false', () => {
|
|
const result = detectAgentClis();
|
|
expect(result.every((c) => !c.present)).toBe(true);
|
|
});
|
|
|
|
it('marks all as present when commandExists returns true', () => {
|
|
platformMock.commandExists.mockReturnValue(true);
|
|
const result = detectAgentClis();
|
|
expect(result.every((c) => c.present)).toBe(true);
|
|
});
|
|
|
|
it('marks only "pi" as present when only pi is available', () => {
|
|
platformMock.commandExists.mockImplementation((cmd) => cmd === 'pi');
|
|
const result = detectAgentClis();
|
|
const piEntry = result.find((c) => c.command === 'pi');
|
|
const aiderEntry = result.find((c) => c.command === 'aider');
|
|
expect(piEntry?.present).toBe(true);
|
|
expect(aiderEntry?.present).toBe(false);
|
|
});
|
|
|
|
it('passes the command string to commandExists', () => {
|
|
detectAgentClis();
|
|
const calledCommands = platformMock.commandExists.mock.calls.map((c) => c[0]);
|
|
expect(calledCommands).toContain('pi');
|
|
expect(calledCommands).toContain('aider');
|
|
});
|
|
|
|
it('returned entries include name and command from AGENT_CLIS', () => {
|
|
const result = detectAgentClis();
|
|
for (let i = 0; i < AGENT_CLIS.length; i++) {
|
|
expect(result[i].name).toBe(AGENT_CLIS[i].name);
|
|
expect(result[i].command).toBe(AGENT_CLIS[i].command);
|
|
}
|
|
});
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// NoAgentCliError
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe('NoAgentCliError', () => {
|
|
it('is an instance of Error', () => {
|
|
expect(new NoAgentCliError()).toBeInstanceOf(Error);
|
|
});
|
|
|
|
it('has name "NoAgentCliError"', () => {
|
|
expect(new NoAgentCliError().name).toBe('NoAgentCliError');
|
|
});
|
|
|
|
it('message mentions agent CLI and install guidance', () => {
|
|
const msg = new NoAgentCliError().message;
|
|
expect(msg).toContain('No agent CLI found');
|
|
expect(msg.toLowerCase()).toContain('pi');
|
|
expect(msg.toLowerCase()).toContain('aider');
|
|
});
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// requireAtLeastOneAgentCli
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe('requireAtLeastOneAgentCli', () => {
|
|
beforeEach(() => {
|
|
platformMock.commandExists.mockReset().mockReturnValue(false);
|
|
});
|
|
|
|
it('throws NoAgentCliError when no CLI is present', () => {
|
|
expect(() => requireAtLeastOneAgentCli()).toThrow(NoAgentCliError);
|
|
});
|
|
|
|
it('does not throw when at least one CLI is present', () => {
|
|
platformMock.commandExists.mockImplementation((cmd) => cmd === 'claude');
|
|
expect(() => requireAtLeastOneAgentCli()).not.toThrow();
|
|
});
|
|
|
|
it('returns the full list of CLIs', () => {
|
|
platformMock.commandExists.mockReturnValue(true);
|
|
const result = requireAtLeastOneAgentCli();
|
|
expect(result).toHaveLength(AGENT_CLIS.length);
|
|
});
|
|
|
|
it('returned list includes present=true for available CLIs', () => {
|
|
platformMock.commandExists.mockImplementation((cmd) => cmd === 'aider');
|
|
const result = requireAtLeastOneAgentCli();
|
|
const aider = result.find((c) => c.command === 'aider');
|
|
expect(aider?.present).toBe(true);
|
|
});
|
|
});
|