@@ -361,6 +361,28 @@ export class LogtalkTestsExplorerProvider implements Disposable {
361361 // Track whether any tests failed for openOnTestFailure setting
362362 let hasFailures = false ;
363363
364+ // Link cancellation from the VS Code token and Logtalk terminal close events.
365+ const linkedCancellationSource = new vscode . CancellationTokenSource ( ) ;
366+ const linkedToken = linkedCancellationSource . token ;
367+ const cancellationDisposables : Disposable [ ] = [ ] ;
368+
369+ if ( token ) {
370+ cancellationDisposables . push (
371+ token . onCancellationRequested ( ( ) => {
372+ linkedCancellationSource . cancel ( ) ;
373+ } )
374+ ) ;
375+ }
376+
377+ cancellationDisposables . push (
378+ vscode . window . onDidCloseTerminal ( ( terminal ) => {
379+ if ( LogtalkTerminal . isLogtalkTerminal ( terminal ) || terminal . name === 'Logtalk' ) {
380+ this . logger . info ( 'Logtalk terminal was closed while tests were running; cancelling test run' ) ;
381+ linkedCancellationSource . cancel ( ) ;
382+ }
383+ } )
384+ ) ;
385+
364386 try {
365387 // If no specific tests are selected, run all tests via the tester file
366388 if ( ! request . include ) {
@@ -369,7 +391,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
369391 // If URI is provided (from ViaProfile methods), use it directly
370392 if ( uri ) {
371393 this . logger . info ( `Running tests for provided URI: ${ uri . fsPath } ` ) ;
372- await LogtalkTerminal . runAllTests ( uri , this . linter , this . testsReporter ) ;
394+ await LogtalkTerminal . runAllTests ( uri , this . linter , this . testsReporter , linkedToken ) ;
373395
374396 // Parse results
375397 // Check if URI is a directory or file
@@ -411,7 +433,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
411433 const workspacePath = workspaceFolder . uri . fsPath ;
412434 testDirectories . add ( workspacePath ) ;
413435 this . logger . info ( `Running all tests in workspace folder: ${ workspacePath } ` ) ;
414- await LogtalkTerminal . runAllTests ( workspaceFolder . uri , this . linter , this . testsReporter ) ;
436+ await LogtalkTerminal . runAllTests ( workspaceFolder . uri , this . linter , this . testsReporter , linkedToken ) ;
415437
416438 // Parse results - look in tester directory
417439 const testerFile = LogtalkTerminal . findTesterFile ( workspacePath , workspaceFolder . uri ) ;
@@ -449,7 +471,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
449471 directoriesProcessed . add ( dirPath ) ;
450472 testDirectories . add ( dirPath ) ;
451473 this . logger . info ( `Running all tests in directory: ${ dirPath } ` ) ;
452- await LogtalkTerminal . runAllTests ( metadata . directoryUri ! , this . linter , this . testsReporter ) ;
474+ await LogtalkTerminal . runAllTests ( metadata . directoryUri ! , this . linter , this . testsReporter , linkedToken ) ;
453475
454476 // Parse results - look in tester directory
455477 const testerFile = LogtalkTerminal . findTesterFile ( dirPath , metadata . directoryUri ! ) ;
@@ -470,7 +492,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
470492 directoriesProcessed . add ( dirPath ) ;
471493 testDirectories . add ( dirPath ) ;
472494 this . logger . info ( `Running all tests in workspace root directory: ${ dirPath } ` ) ;
473- await LogtalkTerminal . runAllTests ( Uri . file ( dirPath ) , this . linter , this . testsReporter ) ;
495+ await LogtalkTerminal . runAllTests ( Uri . file ( dirPath ) , this . linter , this . testsReporter , linkedToken ) ;
474496
475497 // Parse results - look in tester directory
476498 const testerFile = LogtalkTerminal . findTesterFile ( dirPath , Uri . file ( dirPath ) ) ;
@@ -503,7 +525,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
503525
504526 // Process each test item
505527 for ( const test of queue ) {
506- if ( token ? .isCancellationRequested ) {
528+ if ( linkedToken . isCancellationRequested ) {
507529 break ;
508530 }
509531
@@ -527,7 +549,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
527549 // Run all tests in the directory
528550 this . logger . info ( `Running all tests in directory: ${ metadata . directoryUri ! . fsPath } ` ) ;
529551 testDirectories . add ( metadata . directoryUri ! . fsPath ) ;
530- await LogtalkTerminal . runAllTests ( metadata . directoryUri ! , this . linter , this . testsReporter ) ;
552+ await LogtalkTerminal . runAllTests ( metadata . directoryUri ! , this . linter , this . testsReporter , linkedToken ) ;
531553
532554 // Parse results - look in tester directory
533555 const dirTesterFile = LogtalkTerminal . findTesterFile ( metadata . directoryUri ! . fsPath , metadata . directoryUri ! ) ;
@@ -545,7 +567,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
545567 case 'file' :
546568 // Run all tests in the file
547569 this . logger . info ( `Running all tests in file: ${ metadata . fileUri . fsPath } ` ) ;
548- await LogtalkTerminal . runFileTests ( metadata . fileUri , this . linter , this . testsReporter ) ;
570+ await LogtalkTerminal . runFileTests ( metadata . fileUri , this . linter , this . testsReporter , linkedToken ) ;
549571
550572 // Parse results
551573 if ( fs . existsSync ( resultsFilePath ) ) {
@@ -557,7 +579,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
557579 case 'object' :
558580 // Run all tests in the object (test suite)
559581 this . logger . info ( `Running all tests for object: ${ metadata . objectName } in file: ${ metadata . fileUri . fsPath } ` ) ;
560- await LogtalkTerminal . runObjectTests ( metadata . fileUri , metadata . objectName ! , this . linter , this . testsReporter ) ;
582+ await LogtalkTerminal . runObjectTests ( metadata . fileUri , metadata . objectName ! , this . linter , this . testsReporter , linkedToken ) ;
561583
562584 // Parse results
563585 if ( fs . existsSync ( resultsFilePath ) ) {
@@ -569,7 +591,7 @@ export class LogtalkTestsExplorerProvider implements Disposable {
569591 case 'test' :
570592 // Run a specific test
571593 this . logger . info ( `Running test: ${ metadata . testName } in object: ${ metadata . objectName } ` ) ;
572- await LogtalkTerminal . runTest ( metadata . fileUri , metadata . objectName ! , metadata . testName ! , this . linter , this . testsReporter ) ;
594+ await LogtalkTerminal . runTest ( metadata . fileUri , metadata . objectName ! , metadata . testName ! , this . linter , this . testsReporter , linkedToken ) ;
573595
574596 // Parse results
575597 if ( fs . existsSync ( resultsFilePath ) ) {
@@ -598,6 +620,9 @@ export class LogtalkTestsExplorerProvider implements Disposable {
598620 }
599621 this . runAllureReportIfEnabled ( testDirectories ) ;
600622 testRun . end ( ) ;
623+ } finally {
624+ linkedCancellationSource . dispose ( ) ;
625+ cancellationDisposables . forEach ( disposable => disposable . dispose ( ) ) ;
601626 }
602627 }
603628
0 commit comments