11import 'dart:async' ;
22import 'dart:convert' ;
3+ import 'dart:io' as io;
34
45import 'package:args/command_runner.dart' ;
56import 'package:dart_mcp/server.dart' ;
@@ -373,35 +374,44 @@ void main() {
373374 ]);
374375 });
375376
376- test ('passes directory as positional argument' , () async {
377+ test ('does not pass directory as a positional argument' , () async {
378+ final tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_' );
379+ addTearDown (() => tempDir.deleteSync (recursive: true ));
380+
377381 await sendRequest (
378382 CallToolRequest .methodName,
379383 _params (
380- CallToolRequest (name: 'test' , arguments: {'directory' : 'my_dir' }),
384+ CallToolRequest (
385+ name: 'test' ,
386+ arguments: {'directory' : tempDir.path},
387+ ),
381388 ),
382389 );
383390
384391 final capturedArgs =
385392 verify (() => mockCommandRunner.run (captureAny ())).captured.first
386393 as List <String >;
387- expect (capturedArgs, ['test' , 'my_dir' ]);
394+ expect (capturedArgs, ['test' ]);
388395 });
389396
390- test ('passes directory as positional argument with dart flag' , () async {
397+ test ('does not pass directory positionally with dart flag' , () async {
398+ final tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_' );
399+ addTearDown (() => tempDir.deleteSync (recursive: true ));
400+
391401 await sendRequest (
392402 CallToolRequest .methodName,
393403 _params (
394404 CallToolRequest (
395405 name: 'test' ,
396- arguments: {'directory' : 'my_dir' , 'dart' : true },
406+ arguments: {'directory' : tempDir.path , 'dart' : true },
397407 ),
398408 ),
399409 );
400410
401411 final capturedArgs =
402412 verify (() => mockCommandRunner.run (captureAny ())).captured.first
403413 as List <String >;
404- expect (capturedArgs, ['dart' , 'test' , 'my_dir' ]);
414+ expect (capturedArgs, ['dart' , 'test' ]);
405415 });
406416
407417 test ('handles command failure' , () async {
@@ -456,13 +466,16 @@ void main() {
456466 });
457467
458468 test ('handles all arguments (with split "ignore")' , () async {
469+ final tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_' );
470+ addTearDown (() => tempDir.deleteSync (recursive: true ));
471+
459472 await sendRequest (
460473 CallToolRequest .methodName,
461474 _params (
462475 CallToolRequest (
463476 name: 'packages_get' ,
464477 arguments: {
465- 'directory' : 'my_dir' ,
478+ 'directory' : tempDir.path ,
466479 'recursive' : true ,
467480 'ignore' : 'pkg1, pkg2' ,
468481 },
@@ -476,7 +489,6 @@ void main() {
476489 expect (capturedArgs, [
477490 'packages' ,
478491 'get' ,
479- 'my_dir' ,
480492 '--recursive' ,
481493 '--ignore' ,
482494 'pkg1' ,
@@ -488,37 +500,43 @@ void main() {
488500
489501 group ('Tool: packages_check_licenses' , () {
490502 test ('handles basic case (licenses=true)' , () async {
503+ final tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_' );
504+ addTearDown (() => tempDir.deleteSync (recursive: true ));
505+
491506 await sendRequest (
492507 CallToolRequest .methodName,
493508 _params (
494509 CallToolRequest (
495510 name: 'packages_check_licenses' ,
496- arguments: {'licenses' : true , 'directory' : 'my_dir' },
511+ arguments: {'licenses' : true , 'directory' : tempDir.path },
497512 ),
498513 ),
499514 );
500515
501516 final capturedArgs =
502517 verify (() => mockCommandRunner.run (captureAny ())).captured.first
503518 as List <String >;
504- expect (capturedArgs, ['packages' , 'check' , 'licenses' , 'my_dir' ]);
519+ expect (capturedArgs, ['packages' , 'check' , 'licenses' ]);
505520 });
506521
507522 test ('defaults to licenses=true if not provided' , () async {
523+ final tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_' );
524+ addTearDown (() => tempDir.deleteSync (recursive: true ));
525+
508526 await sendRequest (
509527 CallToolRequest .methodName,
510528 _params (
511529 CallToolRequest (
512530 name: 'packages_check_licenses' ,
513- arguments: {'directory' : 'my_dir' },
531+ arguments: {'directory' : tempDir.path },
514532 ),
515533 ),
516534 );
517535
518536 final capturedArgs =
519537 verify (() => mockCommandRunner.run (captureAny ())).captured.first
520538 as List <String >;
521- expect (capturedArgs, ['packages' , 'check' , 'licenses' , 'my_dir' ]);
539+ expect (capturedArgs, ['packages' , 'check' , 'licenses' ]);
522540 });
523541
524542 test ('returns error if licenses=false' , () async {
@@ -597,5 +615,70 @@ void main() {
597615 expect (text, contains ('Command: very_good' ));
598616 });
599617 });
618+
619+ group ('directory (working directory)' , () {
620+ late io.Directory tempDir;
621+ late String originalCwd;
622+
623+ setUp (() {
624+ originalCwd = io.Directory .current.path;
625+ tempDir = io.Directory .systemTemp.createTempSync ('vgmcp_cwd_' );
626+ addTearDown (() {
627+ // Always restore the cwd so a failure cannot leak into other tests.
628+ io.Directory .current = originalCwd;
629+ if (tempDir.existsSync ()) tempDir.deleteSync (recursive: true );
630+ });
631+ });
632+
633+ for (final toolName in const [
634+ 'test' ,
635+ 'packages_get' ,
636+ 'packages_check_licenses' ,
637+ ]) {
638+ test ('"$toolName " runs in the requested directory' , () async {
639+ String ? cwdDuringRun;
640+ when (() => mockCommandRunner.run (any ())).thenAnswer ((_) async {
641+ cwdDuringRun = io.Directory .current.resolveSymbolicLinksSync ();
642+ return ExitCode .success.code;
643+ });
644+
645+ final response = await sendRequest (
646+ CallToolRequest .methodName,
647+ _params (
648+ CallToolRequest (
649+ name: toolName,
650+ arguments: {'directory' : tempDir.path},
651+ ),
652+ ),
653+ );
654+
655+ final result = CallToolResult .fromMap (
656+ response['result' ] as Map <String , Object ?>,
657+ );
658+ expect (result.isError, isFalse);
659+ expect (cwdDuringRun, tempDir.resolveSymbolicLinksSync ());
660+ // The working directory is restored after the command completes.
661+ expect (io.Directory .current.path, originalCwd);
662+ });
663+ }
664+
665+ test ('returns an error when the directory does not exist' , () async {
666+ final missing = '${tempDir .path }/does-not-exist' ;
667+
668+ final response = await sendRequest (
669+ CallToolRequest .methodName,
670+ _params (
671+ CallToolRequest (name: 'test' , arguments: {'directory' : missing}),
672+ ),
673+ );
674+
675+ final result = CallToolResult .fromMap (
676+ response['result' ] as Map <String , Object ?>,
677+ );
678+ expect (result.isError, isTrue);
679+ // The cwd is left unchanged when switching to it fails.
680+ expect (io.Directory .current.path, originalCwd);
681+ });
682+ });
600683 });
601684}
0 commit comments