@@ -106,13 +106,12 @@ describe("PortManager", () => {
106106 }
107107 } ) ;
108108
109- // Try to allocate again - should get next port
110- const port2 = await portManager . allocatePort ( 3141 ) ;
111- expect ( port2 ) . not . toBe ( 3141 ) ;
112- expect ( port2 ) . toBe ( 4310 ) ; // Next preferred port
109+ await expect ( portManager . allocatePort ( 3141 ) ) . rejects . toThrow (
110+ "Port 3141 is already in use or unavailable. Configure your server provider with a different port, for example: { port: 4310 }" ,
111+ ) ;
113112 } ) ;
114113
115- it ( "should handle port in use (EADDRINUSE)" , async ( ) => {
114+ it ( "should throw with guidance when preferred port is in use (EADDRINUSE)" , async ( ) => {
116115 let portBeingTested : number | undefined ;
117116
118117 ( createNetServer as any ) . mockImplementation ( ( ) => {
@@ -145,9 +144,44 @@ describe("PortManager", () => {
145144 return mockServer ;
146145 } ) ;
147146
148- const port = await portManager . allocatePort ( 3141 ) ;
149- expect ( port ) . not . toBe ( 3141 ) ;
150- expect ( port ) . toBe ( 4310 ) ; // Should try next port after skipping duplicate 3141
147+ await expect ( portManager . allocatePort ( 3141 ) ) . rejects . toThrow (
148+ "Port 3141 is already in use or unavailable. Configure your server provider with a different port, for example: { port: 4310 }" ,
149+ ) ;
150+ } ) ;
151+
152+ it ( "should fall through to the next available port when default port is in use" , async ( ) => {
153+ let portBeingTested : number | undefined ;
154+
155+ ( createNetServer as any ) . mockImplementation ( ( ) => {
156+ const mockServer = {
157+ once : vi . fn ( ) ,
158+ listen : vi . fn ( ( port : number ) => {
159+ portBeingTested = port ;
160+ } ) ,
161+ close : vi . fn ( ( callback ?: ( ) => void ) => callback ?.( ) ) ,
162+ } ;
163+
164+ const handlers : Record < string , ( ...args : any [ ] ) => void > = { } ;
165+ mockServer . once . mockImplementation ( ( event : string , handler : ( ...args : any [ ] ) => void ) => {
166+ handlers [ event ] = handler ;
167+ if ( Object . keys ( handlers ) . length === 2 ) {
168+ setTimeout ( ( ) => {
169+ if ( portBeingTested === 3141 ) {
170+ handlers . error ( { code : "EADDRINUSE" } ) ;
171+ } else {
172+ handlers . listening ( ) ;
173+ }
174+ } , 0 ) ;
175+ }
176+ return mockServer ;
177+ } ) ;
178+
179+ return mockServer ;
180+ } ) ;
181+
182+ const port = await portManager . allocatePort ( ) ;
183+ expect ( port ) . toBe ( 4310 ) ;
184+ expect ( portManager . isPortAllocated ( 4310 ) ) . toBe ( true ) ;
151185 } ) ;
152186
153187 it ( "should handle permission denied (EACCES)" , async ( ) => {
@@ -183,9 +217,9 @@ describe("PortManager", () => {
183217 return mockServer ;
184218 } ) ;
185219
186- const port = await portManager . allocatePort ( 80 ) ; // Low port, likely EACCES
187- expect ( port ) . not . toBe ( 80 ) ;
188- expect ( port ) . toBe ( 3141 ) ; // Should try next port
220+ await expect ( portManager . allocatePort ( 80 ) ) . rejects . toThrow (
221+ "Port 80 is already in use or unavailable. Configure your server provider with a different port, for example: { port: 3141 }" ,
222+ ) ;
189223 } ) ;
190224
191225 it ( "should throw error when no ports are available" , async ( ) => {
@@ -226,13 +260,11 @@ describe("PortManager", () => {
226260 } ) ;
227261
228262 // Start multiple allocations concurrently
229- const promises = [
263+ const results = await Promise . all ( [
230264 portManager . allocatePort ( ) ,
231265 portManager . allocatePort ( ) ,
232266 portManager . allocatePort ( ) ,
233- ] ;
234-
235- const results = await Promise . all ( promises ) ;
267+ ] ) ;
236268
237269 // All ports should be different
238270 expect ( new Set ( results ) . size ) . toBe ( 3 ) ;
@@ -269,12 +301,13 @@ describe("PortManager", () => {
269301 await delay ( 10 ) ; // Small delay to ensure first check is in progress
270302 const promise2 = portManager . allocatePort ( 5000 ) ;
271303
272- const [ port1 , port2 ] = await Promise . all ( [ promise1 , promise2 ] ) ;
304+ const port1 = await promise1 ;
305+ await expect ( promise2 ) . rejects . toThrow (
306+ "Port 5000 is already in use or unavailable. Configure your server provider with a different port, for example: { port: 3141 }" ,
307+ ) ;
273308
274309 // First should get the requested port
275310 expect ( port1 ) . toBe ( 5000 ) ;
276- // Second should get a different port (since first is checking/allocated)
277- expect ( port2 ) . not . toBe ( 5000 ) ;
278311 expect ( checkCompleted ) . toBe ( true ) ;
279312 } ) ;
280313 } ) ;
@@ -443,9 +476,9 @@ describe("PortManager", () => {
443476 return mockServer ;
444477 } ) ;
445478
446- const port = await portManager . allocatePort ( 3000 ) ;
447- expect ( port ) . not . toBe ( 3000 ) ;
448- expect ( port ) . toBe ( 3141 ) ; // Should try the first preferred port
479+ await expect ( portManager . allocatePort ( 3000 ) ) . rejects . toThrow (
480+ "Port 3000 is already in use or unavailable. Configure your server provider with a different port, for example: { port: 3141 }" ,
481+ ) ;
449482 } ) ;
450483
451484 it ( "should cleanup promises map even on error" , async ( ) => {
0 commit comments