mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 22:21:20 +00:00
- stop mocking the completion backend in root-command-router tests - remove cross-file module poisoning that caused flaky CI ordering failures
130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test';
|
|
|
|
let calls: string[] = [];
|
|
let logLines: string[] = [];
|
|
let originalConsoleLog: typeof console.log;
|
|
let originalProcessExit: typeof process.exit;
|
|
|
|
beforeEach(() => {
|
|
calls = [];
|
|
logLines = [];
|
|
originalConsoleLog = console.log;
|
|
originalProcessExit = process.exit;
|
|
|
|
console.log = (...args: unknown[]) => {
|
|
logLines.push(args.map(String).join(' '));
|
|
};
|
|
|
|
mock.module('../../../src/commands/version-command', () => ({
|
|
handleVersionCommand: async () => {
|
|
calls.push('version');
|
|
},
|
|
}));
|
|
|
|
mock.module('../../../src/commands/update-command', () => ({
|
|
handleUpdateCommand: async (options: Record<string, unknown>) => {
|
|
calls.push(`update:${JSON.stringify(options)}`);
|
|
},
|
|
}));
|
|
|
|
mock.module('../../../src/commands/api-command/index', () => ({
|
|
handleApiCommand: async (args: string[]) => {
|
|
calls.push(`api:${args.join(' ')}`);
|
|
},
|
|
}));
|
|
|
|
mock.module('../../../src/commands/docker-command', () => ({
|
|
handleDockerCommand: async (args: string[]) => {
|
|
calls.push(`docker:${args.join(' ')}`);
|
|
},
|
|
}));
|
|
|
|
mock.module('../../../src/commands/tokens-command', () => ({
|
|
handleTokensCommand: async () => 37,
|
|
}));
|
|
});
|
|
|
|
afterEach(() => {
|
|
console.log = originalConsoleLog;
|
|
process.exit = originalProcessExit;
|
|
mock.restore();
|
|
});
|
|
|
|
async function loadTryHandleRootCommand() {
|
|
const mod = await import(
|
|
`../../../src/commands/root-command-router?test=${Date.now()}-${Math.random()}`
|
|
);
|
|
return mod.tryHandleRootCommand;
|
|
}
|
|
|
|
describe('root-command-router', () => {
|
|
it('routes command aliases to their handlers', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['--version'])).resolves.toBe(true);
|
|
|
|
expect(calls).toEqual(['version']);
|
|
});
|
|
|
|
it('returns false for profile-like tokens that are not root commands', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['glm'])).resolves.toBe(false);
|
|
|
|
expect(calls).toEqual([]);
|
|
});
|
|
|
|
it('does not capture cursor so bare cursor can fall through to profile routing', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['cursor'])).resolves.toBe(false);
|
|
await expect(tryHandleRootCommand(['cursor', 'status'])).resolves.toBe(false);
|
|
|
|
expect(calls).toEqual([]);
|
|
});
|
|
|
|
it('prints update help without invoking the updater', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['update', '--help'])).resolves.toBe(true);
|
|
|
|
expect(calls).toEqual([]);
|
|
expect(logLines.join('\n')).toContain('Usage: ccs update [options]');
|
|
expect(logLines.join('\n')).toContain('ccs update --beta');
|
|
});
|
|
|
|
it('passes remaining args through to nested command handlers', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['api', 'discover', '--register'])).resolves.toBe(true);
|
|
|
|
expect(calls).toEqual(['api:discover --register']);
|
|
});
|
|
|
|
it('routes docker commands through the root router', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['docker', 'status', '--host', 'my-box'])).resolves.toBe(
|
|
true
|
|
);
|
|
|
|
expect(calls).toEqual(['docker:status --host my-box']);
|
|
});
|
|
|
|
it('exits with the nested command exit code when required', async () => {
|
|
process.exit = ((code?: number) => {
|
|
throw new Error(`process.exit(${code ?? 0})`);
|
|
}) as typeof process.exit;
|
|
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['tokens', 'list'])).rejects.toThrow('process.exit(37)');
|
|
});
|
|
|
|
it('routes hidden completion queries through the completion backend', async () => {
|
|
const tryHandleRootCommand = await loadTryHandleRootCommand();
|
|
|
|
await expect(tryHandleRootCommand(['__complete', '--shell', 'bash', '--current', 'do'])).resolves.toBe(true);
|
|
});
|
|
});
|