UNPKG

@wonderwhy-er/desktop-commander

Version:

MCP server for terminal operations and file editing

76 lines (75 loc) 3.98 kB
import { expect } from 'chai'; import { describe, it } from 'mocha'; import { REPLSessionManager } from './REPLSessionManager'; import * as sinon from 'sinon'; describe('REPLSessionManager', () => { // Create a mock terminal manager for testing const createMockTerminalManager = () => { return { executeCommand: sinon.stub().resolves({ pid: 12345 }), sendInputToProcess: sinon.stub().returns(true), getNewOutput: sinon.stub().returns('test output\n> '), terminateProcess: sinon.stub().resolves(true) }; }; it('should create a new instance', () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); expect(manager).to.be.an.instanceOf(REPLSessionManager); }); it('should create a new session', async () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); const pid = await manager.createSession('node'); expect(pid).to.equal(12345); expect(terminalManager.executeCommand.calledOnce).to.be.true; }); it('should send and read REPL output', async () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); const result = await manager.sendAndReadREPL(12345, 'console.log("hello")', 'node', 1000); expect(result.success).to.be.true; expect(terminalManager.sendInputToProcess.calledOnce).to.be.true; expect(terminalManager.getNewOutput.called).to.be.true; }); it('should detect when output is complete', () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); // Node.js prompt expect(manager.isOutputComplete('test\n> ', 'node')).to.be.true; // Python prompt expect(manager.isOutputComplete('test\n>>> ', 'python')).to.be.true; // Incomplete output expect(manager.isOutputComplete('test\n', 'node')).to.be.false; }); it('should calculate timeout based on code complexity', () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); const simpleTimeout = manager.calculateTimeout('x = 1'); const loopTimeout = manager.calculateTimeout('for (let i = 0; i < 10; i++) { console.log(i); }'); const importTimeout = manager.calculateTimeout('import math\nimport os\nimport sys'); expect(loopTimeout).to.be.greaterThan(simpleTimeout); expect(importTimeout).to.be.greaterThan(simpleTimeout); }); it('should clean output', () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); const nodeOutput = manager.cleanOutput('x = 1\n> ', 'x = 1', 'node'); const pythonOutput = manager.cleanOutput('>>> x = 1\n>>> ', 'x = 1', 'python'); expect(nodeOutput).to.not.include('>'); expect(pythonOutput).to.not.include('>>>'); }); it('should handle multi-line code', async () => { const terminalManager = createMockTerminalManager(); const manager = new REPLSessionManager(terminalManager); // Mock implementation for Python indentation terminalManager.getNewOutput.onFirstCall().returns('>>> '); terminalManager.getNewOutput.onSecondCall().returns('... '); terminalManager.getNewOutput.onThirdCall().returns('... '); terminalManager.getNewOutput.onCall(3).returns('result\n>>> '); const multilineCode = 'for i in range(5):\n print(i)'; const result = await manager.handleMultilineCode(12345, multilineCode, 'python', 1000); expect(result.success).to.be.true; expect(terminalManager.sendInputToProcess.callCount).to.be.at.least(2); }); });