daemon.test.ts
1 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; 2 3 const { 4 fetchDaemonStatusMock, 5 requestDaemonShutdownMock, 6 } = vi.hoisted(() => ({ 7 fetchDaemonStatusMock: vi.fn(), 8 requestDaemonShutdownMock: vi.fn(), 9 })); 10 11 vi.mock('../browser/daemon-client.js', () => ({ 12 fetchDaemonStatus: fetchDaemonStatusMock, 13 requestDaemonShutdown: requestDaemonShutdownMock, 14 })); 15 16 import { daemonStatus, daemonStop } from './daemon.js'; 17 18 describe('daemonStatus', () => { 19 let stdoutSpy: ReturnType<typeof vi.spyOn>; 20 21 beforeEach(() => { 22 stdoutSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined); 23 fetchDaemonStatusMock.mockReset(); 24 requestDaemonShutdownMock.mockReset(); 25 }); 26 27 afterEach(() => { 28 vi.restoreAllMocks(); 29 }); 30 31 it('reports "not running" when daemon is unreachable', async () => { 32 fetchDaemonStatusMock.mockResolvedValue(null); 33 34 await daemonStatus(); 35 36 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('not running')); 37 }); 38 39 it('shows daemon info when running', async () => { 40 fetchDaemonStatusMock.mockResolvedValue({ 41 ok: true, 42 pid: 12345, 43 uptime: 3661, 44 extensionConnected: true, 45 extensionVersion: '1.6.8', 46 pending: 0, 47 memoryMB: 64, 48 port: 19825, 49 }); 50 51 await daemonStatus(); 52 53 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('running')); 54 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('PID 12345')); 55 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('1h 1m')); 56 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('connected')); 57 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('v1.6.8')); 58 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('64 MB')); 59 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('19825')); 60 }); 61 62 it('shows disconnected when extension is not connected', async () => { 63 fetchDaemonStatusMock.mockResolvedValue({ 64 ok: true, 65 pid: 99, 66 uptime: 120, 67 extensionConnected: false, 68 pending: 0, 69 memoryMB: 32, 70 port: 19825, 71 }); 72 73 await daemonStatus(); 74 75 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('disconnected')); 76 }); 77 78 it('shows version unknown when the connected extension does not report one', async () => { 79 fetchDaemonStatusMock.mockResolvedValue({ 80 ok: true, 81 pid: 99, 82 uptime: 120, 83 extensionConnected: true, 84 extensionVersion: undefined, 85 pending: 0, 86 memoryMB: 32, 87 port: 19825, 88 }); 89 90 await daemonStatus(); 91 92 expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('version unknown')); 93 }); 94 }); 95 96 describe('daemonStop', () => { 97 let stderrSpy: ReturnType<typeof vi.spyOn>; 98 99 beforeEach(() => { 100 stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true); 101 fetchDaemonStatusMock.mockReset(); 102 requestDaemonShutdownMock.mockReset(); 103 }); 104 105 afterEach(() => { 106 vi.restoreAllMocks(); 107 }); 108 109 it('reports "not running" when daemon is unreachable', async () => { 110 fetchDaemonStatusMock.mockResolvedValue(null); 111 112 await daemonStop(); 113 114 expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('not running')); 115 }); 116 117 it('sends shutdown and reports success', async () => { 118 fetchDaemonStatusMock.mockResolvedValue({ 119 ok: true, 120 pid: 12345, 121 uptime: 100, 122 extensionConnected: true, 123 pending: 0, 124 memoryMB: 50, 125 port: 19825, 126 }); 127 requestDaemonShutdownMock.mockResolvedValue(true); 128 129 await daemonStop(); 130 131 expect(requestDaemonShutdownMock).toHaveBeenCalledTimes(1); 132 expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('Daemon stopped')); 133 }); 134 135 it('reports failure when shutdown request fails', async () => { 136 fetchDaemonStatusMock.mockResolvedValue({ 137 ok: true, 138 pid: 12345, 139 uptime: 100, 140 extensionConnected: true, 141 pending: 0, 142 memoryMB: 50, 143 port: 19825, 144 }); 145 requestDaemonShutdownMock.mockResolvedValue(false); 146 147 await daemonStop(); 148 149 expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to stop daemon')); 150 }); 151 });