@@ -2,26 +2,27 @@ import { describe, it, expect, beforeEach } from "bun:test";
22import { BackgroundProcessManager } from "./backgroundProcessManager" ;
33import { BashExecutionService } from "./bashExecutionService" ;
44import { LocalBackgroundExecutor } from "./localBackgroundExecutor" ;
5+ import type { BackgroundExecutor } from "./backgroundExecutor" ;
56
6- // Helper to create manager with executor registered for a workspace
7- function createManagerWithExecutor ( workspaceId : string ) : BackgroundProcessManager {
8- const manager = new BackgroundProcessManager ( ) ;
9- manager . registerExecutor ( workspaceId , new LocalBackgroundExecutor ( new BashExecutionService ( ) ) ) ;
10- return manager ;
7+ // Create a shared executor for tests
8+ function createTestExecutor ( ) : BackgroundExecutor {
9+ return new LocalBackgroundExecutor ( new BashExecutionService ( ) ) ;
1110}
1211
1312describe ( "BackgroundProcessManager" , ( ) => {
1413 let manager : BackgroundProcessManager ;
14+ let executor : BackgroundExecutor ;
1515 const testWorkspaceId = "workspace-1" ;
1616 const testWorkspaceId2 = "workspace-2" ;
1717
1818 beforeEach ( ( ) => {
19- manager = createManagerWithExecutor ( testWorkspaceId ) ;
19+ manager = new BackgroundProcessManager ( ) ;
20+ executor = createTestExecutor ( ) ;
2021 } ) ;
2122
2223 describe ( "spawn" , ( ) => {
2324 it ( "should spawn a background process and return process ID" , async ( ) => {
24- const result = await manager . spawn ( testWorkspaceId , "echo hello" , {
25+ const result = await manager . spawn ( executor , testWorkspaceId , "echo hello" , {
2526 cwd : process . cwd ( ) ,
2627 } ) ;
2728
@@ -31,28 +32,16 @@ describe("BackgroundProcessManager", () => {
3132 }
3233 } ) ;
3334
34- it ( "should return error when no executor is registered" , async ( ) => {
35- const managerNoExecutor = new BackgroundProcessManager ( ) ;
36- const result = await managerNoExecutor . spawn ( "unregistered-workspace" , "echo hello" , {
37- cwd : process . cwd ( ) ,
38- } ) ;
39-
40- expect ( result . success ) . toBe ( false ) ;
41- if ( ! result . success ) {
42- expect ( result . error ) . toContain ( "No executor registered" ) ;
43- }
44- } ) ;
45-
4635 it ( "should return error on spawn failure" , async ( ) => {
47- const result = await manager . spawn ( testWorkspaceId , "echo test" , {
36+ const result = await manager . spawn ( executor , testWorkspaceId , "echo test" , {
4837 cwd : "/nonexistent/path/that/does/not/exist" ,
4938 } ) ;
5039
5140 expect ( result . success ) . toBe ( false ) ;
5241 } ) ;
5342
5443 it ( "should capture stdout and stderr" , async ( ) => {
55- const result = await manager . spawn ( testWorkspaceId , "echo hello; echo world >&2" , {
44+ const result = await manager . spawn ( executor , testWorkspaceId , "echo hello; echo world >&2" , {
5645 cwd : process . cwd ( ) ,
5746 } ) ;
5847
@@ -75,7 +64,7 @@ describe("BackgroundProcessManager", () => {
7564 . map ( ( _ , i ) => `echo line${ i } ` )
7665 . join ( "; " ) ;
7766
78- const result = await manager . spawn ( testWorkspaceId , script , {
67+ const result = await manager . spawn ( executor , testWorkspaceId , script , {
7968 cwd : process . cwd ( ) ,
8069 } ) ;
8170
@@ -93,7 +82,7 @@ describe("BackgroundProcessManager", () => {
9382
9483 describe ( "getProcess" , ( ) => {
9584 it ( "should return process by ID" , async ( ) => {
96- const spawnResult = await manager . spawn ( testWorkspaceId , "sleep 1" , {
85+ const spawnResult = await manager . spawn ( executor , testWorkspaceId , "sleep 1" , {
9786 cwd : process . cwd ( ) ,
9887 } ) ;
9988
@@ -113,22 +102,18 @@ describe("BackgroundProcessManager", () => {
113102
114103 describe ( "list" , ( ) => {
115104 it ( "should list all processes" , async ( ) => {
116- await manager . spawn ( testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
117- await manager . spawn ( testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
105+ await manager . spawn ( executor , testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
106+ await manager . spawn ( executor , testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
118107
119108 const processes = manager . list ( ) ;
120109 expect ( processes . length ) . toBeGreaterThanOrEqual ( 2 ) ;
121110 } ) ;
122111
123112 it ( "should filter by workspace ID" , async ( ) => {
124- // Register second workspace executor
125- manager . registerExecutor (
126- testWorkspaceId2 ,
127- new LocalBackgroundExecutor ( new BashExecutionService ( ) )
128- ) ;
113+ const executor2 = createTestExecutor ( ) ;
129114
130- await manager . spawn ( testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
131- await manager . spawn ( testWorkspaceId2 , "sleep 1" , { cwd : process . cwd ( ) } ) ;
115+ await manager . spawn ( executor , testWorkspaceId , "sleep 1" , { cwd : process . cwd ( ) } ) ;
116+ await manager . spawn ( executor2 , testWorkspaceId2 , "sleep 1" , { cwd : process . cwd ( ) } ) ;
132117
133118 const ws1Processes = manager . list ( testWorkspaceId ) ;
134119 const ws2Processes = manager . list ( testWorkspaceId2 ) ;
@@ -142,7 +127,7 @@ describe("BackgroundProcessManager", () => {
142127
143128 describe ( "terminate" , ( ) => {
144129 it ( "should terminate a running process" , async ( ) => {
145- const spawnResult = await manager . spawn ( testWorkspaceId , "sleep 10" , {
130+ const spawnResult = await manager . spawn ( executor , testWorkspaceId , "sleep 10" , {
146131 cwd : process . cwd ( ) ,
147132 } ) ;
148133
@@ -161,7 +146,7 @@ describe("BackgroundProcessManager", () => {
161146 } ) ;
162147
163148 it ( "should be idempotent (double-terminate succeeds)" , async ( ) => {
164- const spawnResult = await manager . spawn ( testWorkspaceId , "sleep 10" , {
149+ const spawnResult = await manager . spawn ( executor , testWorkspaceId , "sleep 10" , {
165150 cwd : process . cwd ( ) ,
166151 } ) ;
167152
@@ -176,29 +161,19 @@ describe("BackgroundProcessManager", () => {
176161 } ) ;
177162
178163 describe ( "cleanup" , ( ) => {
179- it ( "should kill all processes for a workspace and remove them from memory" , async ( ) => {
180- // Register second workspace executor
181- manager . registerExecutor (
182- testWorkspaceId2 ,
183- new LocalBackgroundExecutor ( new BashExecutionService ( ) )
184- ) ;
164+ it ( "should kill all processes for a workspace and clear cached executor" , async ( ) => {
165+ const executor2 = createTestExecutor ( ) ;
185166
186- await manager . spawn ( testWorkspaceId , "sleep 10" , { cwd : process . cwd ( ) } ) ;
187- await manager . spawn ( testWorkspaceId , "sleep 10" , { cwd : process . cwd ( ) } ) ;
188- await manager . spawn ( testWorkspaceId2 , "sleep 10" , { cwd : process . cwd ( ) } ) ;
167+ await manager . spawn ( executor , testWorkspaceId , "sleep 10" , { cwd : process . cwd ( ) } ) ;
168+ await manager . spawn ( executor , testWorkspaceId , "sleep 10" , { cwd : process . cwd ( ) } ) ;
169+ await manager . spawn ( executor2 , testWorkspaceId2 , "sleep 10" , { cwd : process . cwd ( ) } ) ;
189170
190171 await manager . cleanup ( testWorkspaceId ) ;
191172
192173 const ws1Processes = manager . list ( testWorkspaceId ) ;
193174 const ws2Processes = manager . list ( testWorkspaceId2 ) ;
194175 // All testWorkspaceId processes should be removed from memory
195176 expect ( ws1Processes . length ) . toBe ( 0 ) ;
196- // Executor should also be unregistered - spawning should fail
197- const spawnResult = await manager . spawn ( testWorkspaceId , "echo test" , { cwd : process . cwd ( ) } ) ;
198- expect ( spawnResult . success ) . toBe ( false ) ;
199- if ( ! spawnResult . success ) {
200- expect ( spawnResult . error ) . toContain ( "No executor registered" ) ;
201- }
202177 // workspace-2 processes should still exist and be running
203178 expect ( ws2Processes . length ) . toBeGreaterThanOrEqual ( 1 ) ;
204179 expect ( ws2Processes . some ( ( p ) => p . status === "running" ) ) . toBe ( true ) ;
@@ -207,7 +182,7 @@ describe("BackgroundProcessManager", () => {
207182
208183 describe ( "process state tracking" , ( ) => {
209184 it ( "should track process exit" , async ( ) => {
210- const result = await manager . spawn ( testWorkspaceId , "exit 42" , {
185+ const result = await manager . spawn ( executor , testWorkspaceId , "exit 42" , {
211186 cwd : process . cwd ( ) ,
212187 } ) ;
213188
@@ -223,7 +198,7 @@ describe("BackgroundProcessManager", () => {
223198 } ) ;
224199
225200 it ( "should keep buffer after process exits" , async ( ) => {
226- const result = await manager . spawn ( testWorkspaceId , "echo test; exit 0" , {
201+ const result = await manager . spawn ( executor , testWorkspaceId , "echo test; exit 0" , {
227202 cwd : process . cwd ( ) ,
228203 } ) ;
229204
@@ -238,7 +213,7 @@ describe("BackgroundProcessManager", () => {
238213
239214 it ( "should preserve killed status after onExit callback fires" , async ( ) => {
240215 // Spawn a long-running process
241- const result = await manager . spawn ( testWorkspaceId , "sleep 60" , {
216+ const result = await manager . spawn ( executor , testWorkspaceId , "sleep 60" , {
242217 cwd : process . cwd ( ) ,
243218 } ) ;
244219
0 commit comments