import { ProcessService, CBProcess } from '../../src/node/process'; // Mock the Node.js process module const mockProcess = { chdir: jest.fn(), cwd: jest.fn(), exit: jest.fn(), on: jest.fn(), env: { NODE_ENV: 'test' } as NodeJS.ProcessEnv }; // Mock the global process object global.process = mockProcess as any; describe('ProcessService', () => { let processService: ProcessService; beforeEach(() => { jest.clearAllMocks(); processService = new ProcessService(); }); describe('chdir', () => { it('should call process.chdir with the provided path', () => { const testPath = '/test/directory'; processService.chdir(testPath); expect(mockProcess.chdir).toHaveBeenCalledWith(testPath); }); it('should handle different path types', () => { const paths = ['/absolute/path', './relative/path', '../parent/path']; paths.forEach(path => { processService.chdir(path); expect(mockProcess.chdir).toHaveBeenCalledWith(path); }); expect(mockProcess.chdir).toHaveBeenCalledTimes(3); }); }); describe('cwd', () => { it('should return the current working directory', () => { const expectedCwd = '/current/working/directory'; mockProcess.cwd.mockReturnValue(expectedCwd); const result = processService.cwd(); expect(mockProcess.cwd).toHaveBeenCalled(); expect(result).toBe(expectedCwd); }); it('should handle different working directories', () => { const directories = ['/home/user', '/var/www', '/tmp']; directories.forEach(dir => { mockProcess.cwd.mockReturnValue(dir); const result = processService.cwd(); expect(result).toBe(dir); }); }); }); describe('exit', () => { it('should call process.exit with default code undefined', () => { // Mock process.exit to prevent actual exit during tests const mockExit = jest.fn(); mockProcess.exit = mockExit; processService.exit(); expect(mockExit).toHaveBeenCalledWith(undefined); }); it('should call process.exit with provided exit code', () => { const mockExit = jest.fn(); mockProcess.exit = mockExit; processService.exit(1); expect(mockExit).toHaveBeenCalledWith(1); }); it('should handle different exit codes', () => { const mockExit = jest.fn(); mockProcess.exit = mockExit; const exitCodes = [0, 1, 2, 130]; exitCodes.forEach(code => { processService.exit(code); expect(mockExit).toHaveBeenCalledWith(code); }); expect(mockExit).toHaveBeenCalledTimes(4); }); }); describe('on', () => { it('should register event listeners', () => { const eventName = 'SIGINT'; const mockListener = jest.fn(); processService.on(eventName, mockListener); expect(mockProcess.on).toHaveBeenCalledWith(eventName, mockListener); }); it('should handle multiple event types', () => { const events = ['SIGINT', 'SIGTERM', 'uncaughtException']; const mockListener = jest.fn(); events.forEach(event => { processService.on(event, mockListener); expect(mockProcess.on).toHaveBeenCalledWith(event, mockListener); }); expect(mockProcess.on).toHaveBeenCalledTimes(3); }); }); describe('env', () => { it('should provide access to environment variables', () => { const env = processService.env; expect(env).toBe(mockProcess.env); expect(env['NODE_ENV']).toBe('test'); }); it('should reflect changes in environment variables', () => { mockProcess.env['TEST_VAR'] = 'test_value'; expect(processService.env['TEST_VAR']).toBe('test_value'); }); }); describe('interface compliance', () => { it('should implement CBProcess interface', () => { const processInstance: CBProcess = processService; expect(typeof processInstance.chdir).toBe('function'); expect(typeof processInstance.cwd).toBe('function'); expect(typeof processInstance.exit).toBe('function'); expect(typeof processInstance.on).toBe('function'); expect(typeof processInstance.env).toBe('object'); }); }); describe('error handling', () => { it('should handle chdir errors gracefully', () => { const testPath = '/nonexistent/directory'; mockProcess.chdir.mockImplementation(() => { throw new Error('Directory not found'); }); expect(() => processService.chdir(testPath)).toThrow('Directory not found'); expect(mockProcess.chdir).toHaveBeenCalledWith(testPath); }); it('should handle cwd errors gracefully', () => { mockProcess.cwd.mockImplementation(() => { throw new Error('Cannot get current directory'); }); expect(() => processService.cwd()).toThrow('Cannot get current directory'); }); }); });