Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt standard monorepo conventions (apps/ for runnable apps, packages/ for reusable libraries). Update all config files, shared package imports, test fixtures, and documentation to reflect new paths. Key fixes: - Update workspace config to ["apps/*", "packages/*"] - Update tsconfig.json rootDir/include for apps/server/ - Add apps/web/** to vitest exclude list - Update drizzle.config.ts schema path - Fix ensure-schema.ts migration path detection (3 levels up in dev, 2 levels up in dist) - Fix tests/integration/cli-server.test.ts import paths - Update packages/shared imports to apps/server/ paths - Update all docs/ files with new paths
184 lines
5.0 KiB
TypeScript
184 lines
5.0 KiB
TypeScript
/**
|
|
* ProcessRegistry Tests
|
|
*
|
|
* Tests for the in-memory process registry.
|
|
* Verifies CRUD operations for process metadata.
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { ProcessRegistry } from './registry.js';
|
|
import type { ProcessInfo } from './types.js';
|
|
|
|
describe('ProcessRegistry', () => {
|
|
let registry: ProcessRegistry;
|
|
|
|
// Helper to create a ProcessInfo object
|
|
const createProcessInfo = (id: string, overrides: Partial<ProcessInfo> = {}): ProcessInfo => ({
|
|
id,
|
|
pid: 12345,
|
|
command: 'node',
|
|
args: ['server.js'],
|
|
startedAt: new Date(),
|
|
status: 'running',
|
|
...overrides,
|
|
});
|
|
|
|
beforeEach(() => {
|
|
registry = new ProcessRegistry();
|
|
});
|
|
|
|
describe('register()', () => {
|
|
it('should add process to registry', () => {
|
|
const info = createProcessInfo('proc-1');
|
|
registry.register(info);
|
|
|
|
expect(registry.size).toBe(1);
|
|
expect(registry.get('proc-1')).toBe(info);
|
|
});
|
|
|
|
it('should overwrite process with same ID', () => {
|
|
const info1 = createProcessInfo('proc-1', { pid: 111 });
|
|
const info2 = createProcessInfo('proc-1', { pid: 222 });
|
|
|
|
registry.register(info1);
|
|
registry.register(info2);
|
|
|
|
expect(registry.size).toBe(1);
|
|
expect(registry.get('proc-1')?.pid).toBe(222);
|
|
});
|
|
});
|
|
|
|
describe('get()', () => {
|
|
it('should retrieve registered process', () => {
|
|
const info = createProcessInfo('proc-1');
|
|
registry.register(info);
|
|
|
|
const retrieved = registry.get('proc-1');
|
|
expect(retrieved).toBe(info);
|
|
});
|
|
|
|
it('should return undefined for non-existent process', () => {
|
|
const result = registry.get('non-existent');
|
|
expect(result).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('getAll()', () => {
|
|
it('should return all registered processes', () => {
|
|
const info1 = createProcessInfo('proc-1');
|
|
const info2 = createProcessInfo('proc-2');
|
|
const info3 = createProcessInfo('proc-3');
|
|
|
|
registry.register(info1);
|
|
registry.register(info2);
|
|
registry.register(info3);
|
|
|
|
const all = registry.getAll();
|
|
expect(all).toHaveLength(3);
|
|
expect(all).toContain(info1);
|
|
expect(all).toContain(info2);
|
|
expect(all).toContain(info3);
|
|
});
|
|
|
|
it('should return empty array when registry is empty', () => {
|
|
const all = registry.getAll();
|
|
expect(all).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('updateStatus()', () => {
|
|
it('should change process status correctly', () => {
|
|
const info = createProcessInfo('proc-1', { status: 'running' });
|
|
registry.register(info);
|
|
|
|
const result = registry.updateStatus('proc-1', 'stopped');
|
|
|
|
expect(result).toBe(true);
|
|
expect(registry.get('proc-1')?.status).toBe('stopped');
|
|
});
|
|
|
|
it('should return false for non-existent process', () => {
|
|
const result = registry.updateStatus('non-existent', 'stopped');
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it('should update to crashed status', () => {
|
|
const info = createProcessInfo('proc-1', { status: 'running' });
|
|
registry.register(info);
|
|
|
|
registry.updateStatus('proc-1', 'crashed');
|
|
|
|
expect(registry.get('proc-1')?.status).toBe('crashed');
|
|
});
|
|
});
|
|
|
|
describe('unregister()', () => {
|
|
it('should remove process from registry', () => {
|
|
const info = createProcessInfo('proc-1');
|
|
registry.register(info);
|
|
|
|
expect(registry.size).toBe(1);
|
|
|
|
registry.unregister('proc-1');
|
|
|
|
expect(registry.size).toBe(0);
|
|
expect(registry.get('proc-1')).toBeUndefined();
|
|
});
|
|
|
|
it('should do nothing for non-existent process', () => {
|
|
registry.register(createProcessInfo('proc-1'));
|
|
|
|
registry.unregister('non-existent');
|
|
|
|
expect(registry.size).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('getByPid()', () => {
|
|
it('should find process by OS PID', () => {
|
|
const info = createProcessInfo('proc-1', { pid: 54321 });
|
|
registry.register(info);
|
|
|
|
const found = registry.getByPid(54321);
|
|
expect(found).toBe(info);
|
|
});
|
|
|
|
it('should return undefined for unknown PID', () => {
|
|
registry.register(createProcessInfo('proc-1', { pid: 111 }));
|
|
|
|
const found = registry.getByPid(99999);
|
|
expect(found).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('clear()', () => {
|
|
it('should remove all processes from registry', () => {
|
|
registry.register(createProcessInfo('proc-1'));
|
|
registry.register(createProcessInfo('proc-2'));
|
|
registry.register(createProcessInfo('proc-3'));
|
|
|
|
expect(registry.size).toBe(3);
|
|
|
|
registry.clear();
|
|
|
|
expect(registry.size).toBe(0);
|
|
expect(registry.getAll()).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('size', () => {
|
|
it('should return count of registered processes', () => {
|
|
expect(registry.size).toBe(0);
|
|
|
|
registry.register(createProcessInfo('proc-1'));
|
|
expect(registry.size).toBe(1);
|
|
|
|
registry.register(createProcessInfo('proc-2'));
|
|
expect(registry.size).toBe(2);
|
|
|
|
registry.unregister('proc-1');
|
|
expect(registry.size).toBe(1);
|
|
});
|
|
});
|
|
});
|