@@ -231,6 +231,45 @@ afterEach(() => {
231231} ) ;
232232
233233describe ( 'parseArguments' , ( ) => {
234+ afterEach ( ( ) => {
235+ vi . restoreAllMocks ( ) ;
236+ } ) ;
237+ it ( 'should fail if both --resume and --session-id are provided' , async ( ) => {
238+ process . argv = [
239+ 'node' ,
240+ 'script.js' ,
241+ '--resume' ,
242+ '--session-id' ,
243+ 'test-uuid-1234' ,
244+ ] ;
245+ const mockConsoleError = vi
246+ . spyOn ( console , 'error' )
247+ . mockImplementation ( ( ) => { } ) ;
248+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
249+ throw new Error ( 'process.exit called' ) ;
250+ } ) ;
251+
252+ await expect ( parseArguments ( createTestMergedSettings ( ) ) ) . rejects . toThrow (
253+ 'process.exit called' ,
254+ ) ;
255+
256+ expect ( mockConsoleError ) . toHaveBeenCalledWith (
257+ expect . stringContaining (
258+ 'Cannot use both --resume (-r) and --session-id together' ,
259+ ) ,
260+ ) ;
261+ } ) ;
262+
263+ it ( 'should parse --session-id option correctly' , async ( ) => {
264+ process . argv = [ 'node' , 'script.js' , '--session-id' , 'test-uuid-1234' ] ;
265+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
266+ throw new Error ( 'process.exit called' ) ;
267+ } ) ;
268+
269+ const parsedArgs = await parseArguments ( createTestMergedSettings ( ) ) ;
270+ expect ( parsedArgs . sessionId ) . toBe ( 'test-uuid-1234' ) ;
271+ } ) ;
272+
234273 describe ( 'worktree' , ( ) => {
235274 it ( 'should parse --worktree flag when provided with a name' , async ( ) => {
236275 process . argv = [ 'node' , 'script.js' , '--worktree' , 'my-feature' ] ;
@@ -255,7 +294,7 @@ describe('parseArguments', () => {
255294 const settings = createTestMergedSettings ( ) ;
256295 settings . experimental . worktrees = false ;
257296
258- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
297+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
259298 throw new Error ( 'process.exit called' ) ;
260299 } ) ;
261300 const mockConsoleError = vi
@@ -270,9 +309,6 @@ describe('parseArguments', () => {
270309 'The --worktree flag is only available when experimental.worktrees is enabled in your settings.' ,
271310 ) ,
272311 ) ;
273-
274- mockExit . mockRestore ( ) ;
275- mockConsoleError . mockRestore ( ) ;
276312 } ) ;
277313 } ) ;
278314
@@ -304,7 +340,7 @@ describe('parseArguments', () => {
304340 async ( { argv } ) => {
305341 process . argv = argv ;
306342
307- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
343+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
308344 throw new Error ( 'process.exit called' ) ;
309345 } ) ;
310346
@@ -321,9 +357,6 @@ describe('parseArguments', () => {
321357 'Cannot use both --prompt (-p) and --prompt-interactive (-i) together' ,
322358 ) ,
323359 ) ;
324-
325- mockExit . mockRestore ( ) ;
326- mockConsoleError . mockRestore ( ) ;
327360 } ,
328361 ) ;
329362
@@ -560,7 +593,7 @@ describe('parseArguments', () => {
560593 async ( { argv } ) => {
561594 process . argv = argv ;
562595
563- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
596+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
564597 throw new Error ( 'process.exit called' ) ;
565598 } ) ;
566599
@@ -577,9 +610,6 @@ describe('parseArguments', () => {
577610 'Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.' ,
578611 ) ,
579612 ) ;
580-
581- mockExit . mockRestore ( ) ;
582- mockConsoleError . mockRestore ( ) ;
583613 } ,
584614 ) ;
585615
@@ -604,7 +634,7 @@ describe('parseArguments', () => {
604634 it ( 'should reject invalid --approval-mode values' , async ( ) => {
605635 process . argv = [ 'node' , 'script.js' , '--approval-mode' , 'invalid' ] ;
606636
607- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
637+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
608638 throw new Error ( 'process.exit called' ) ;
609639 } ) ;
610640
@@ -623,10 +653,6 @@ describe('parseArguments', () => {
623653 expect . stringContaining ( 'Invalid values:' ) ,
624654 ) ;
625655 expect ( mockConsoleError ) . toHaveBeenCalled ( ) ;
626-
627- mockExit . mockRestore ( ) ;
628- mockConsoleError . mockRestore ( ) ;
629- debugErrorSpy . mockRestore ( ) ;
630656 } ) ;
631657
632658 it ( 'should allow resuming a session without prompt argument in non-interactive mode (expecting stdin)' , async ( ) => {
@@ -870,16 +896,14 @@ describe('loadCliConfig', () => {
870896 } ) ;
871897
872898 it ( 'should skip inaccessible workspace folders from GEMINI_CLI_IDE_WORKSPACE_PATH' , async ( ) => {
873- const resolveToRealPathSpy = vi
874- . spyOn ( ServerConfig , 'resolveToRealPath' )
875- . mockImplementation ( ( p ) => {
876- if ( p . toString ( ) . includes ( 'restricted' ) ) {
877- const err = new Error ( 'EACCES: permission denied' ) ;
878- ( err as NodeJS . ErrnoException ) . code = 'EACCES' ;
879- throw err ;
880- }
881- return p . toString ( ) ;
882- } ) ;
899+ vi . spyOn ( ServerConfig , 'resolveToRealPath' ) . mockImplementation ( ( p ) => {
900+ if ( p . toString ( ) . includes ( 'restricted' ) ) {
901+ const err = new Error ( 'EACCES: permission denied' ) ;
902+ ( err as NodeJS . ErrnoException ) . code = 'EACCES' ;
903+ throw err ;
904+ }
905+ return p . toString ( ) ;
906+ } ) ;
883907 vi . stubEnv (
884908 'GEMINI_CLI_IDE_WORKSPACE_PATH' ,
885909 [ '/project/folderA' , '/nonexistent/restricted/folder' ] . join (
@@ -893,8 +917,6 @@ describe('loadCliConfig', () => {
893917 const dirs = config . getPendingIncludeDirectories ( ) ;
894918 expect ( dirs ) . toContain ( '/project/folderA' ) ;
895919 expect ( dirs ) . not . toContain ( '/nonexistent/restricted/folder' ) ;
896-
897- resolveToRealPathSpy . mockRestore ( ) ;
898920 } ) ;
899921
900922 it ( 'should use default fileFilter options when unconfigured' , async ( ) => {
@@ -3178,7 +3200,7 @@ describe('Output format', () => {
31783200 it ( 'should error on invalid --output-format argument' , async ( ) => {
31793201 process . argv = [ 'node' , 'script.js' , '--output-format' , 'invalid' ] ;
31803202
3181- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
3203+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
31823204 throw new Error ( 'process.exit called' ) ;
31833205 } ) ;
31843206
@@ -3196,10 +3218,6 @@ describe('Output format', () => {
31963218 expect . stringContaining ( 'Invalid values:' ) ,
31973219 ) ;
31983220 expect ( mockConsoleError ) . toHaveBeenCalled ( ) ;
3199-
3200- mockExit . mockRestore ( ) ;
3201- mockConsoleError . mockRestore ( ) ;
3202- debugErrorSpy . mockRestore ( ) ;
32033221 } ) ;
32043222} ) ;
32053223
@@ -3230,13 +3248,11 @@ describe('parseArguments with positional prompt', () => {
32303248 'test prompt' ,
32313249 ] ;
32323250
3233- const mockExit = vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
3251+ vi . spyOn ( process , 'exit' ) . mockImplementation ( ( ) => {
32343252 throw new Error ( 'process.exit called' ) ;
32353253 } ) ;
32363254
3237- const mockConsoleError = vi
3238- . spyOn ( console , 'error' )
3239- . mockImplementation ( ( ) => { } ) ;
3255+ vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
32403256 const debugErrorSpy = vi
32413257 . spyOn ( debugLogger , 'error' )
32423258 . mockImplementation ( ( ) => { } ) ;
@@ -3250,10 +3266,6 @@ describe('parseArguments with positional prompt', () => {
32503266 'Cannot use both a positional prompt and the --prompt (-p) flag together' ,
32513267 ) ,
32523268 ) ;
3253-
3254- mockExit . mockRestore ( ) ;
3255- mockConsoleError . mockRestore ( ) ;
3256- debugErrorSpy . mockRestore ( ) ;
32573269 } ) ;
32583270
32593271 it ( 'should correctly parse a positional prompt to query field' , async ( ) => {
0 commit comments