@@ -6,7 +6,12 @@ import * as path from 'path';
6
6
import { SemVer } from 'semver' ;
7
7
import * as TypeMoq from 'typemoq' ;
8
8
import { Disposable , Uri , WorkspaceFolder } from 'vscode' ;
9
- import { ICommandManager , IDocumentManager , IWorkspaceService } from '../../../client/common/application/types' ;
9
+ import {
10
+ IApplicationShell ,
11
+ ICommandManager ,
12
+ IDocumentManager ,
13
+ IWorkspaceService ,
14
+ } from '../../../client/common/application/types' ;
10
15
import { IFileSystem , IPlatformService } from '../../../client/common/platform/types' ;
11
16
import { createCondaEnv } from '../../../client/common/process/pythonEnvironment' ;
12
17
import { createPythonProcessService } from '../../../client/common/process/pythonProcess' ;
@@ -47,6 +52,7 @@ suite('Terminal - Code Execution', () => {
47
52
let pythonExecutionFactory : TypeMoq . IMock < IPythonExecutionFactory > ;
48
53
let interpreterService : TypeMoq . IMock < IInterpreterService > ;
49
54
let isDjangoRepl : boolean ;
55
+ let applicationShell : TypeMoq . IMock < IApplicationShell > ;
50
56
51
57
teardown ( ( ) => {
52
58
disposables . forEach ( ( disposable ) => {
@@ -71,6 +77,7 @@ suite('Terminal - Code Execution', () => {
71
77
fileSystem = TypeMoq . Mock . ofType < IFileSystem > ( ) ;
72
78
pythonExecutionFactory = TypeMoq . Mock . ofType < IPythonExecutionFactory > ( ) ;
73
79
interpreterService = TypeMoq . Mock . ofType < IInterpreterService > ( ) ;
80
+ applicationShell = TypeMoq . Mock . ofType < IApplicationShell > ( ) ;
74
81
settings = TypeMoq . Mock . ofType < IPythonSettings > ( ) ;
75
82
settings . setup ( ( s ) => s . terminal ) . returns ( ( ) => terminalSettings . object ) ;
76
83
configService . setup ( ( c ) => c . getSettings ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => settings . object ) ;
@@ -85,6 +92,7 @@ suite('Terminal - Code Execution', () => {
85
92
platform . object ,
86
93
interpreterService . object ,
87
94
commandManager . object ,
95
+ applicationShell . object ,
88
96
) ;
89
97
break ;
90
98
}
@@ -97,6 +105,7 @@ suite('Terminal - Code Execution', () => {
97
105
platform . object ,
98
106
interpreterService . object ,
99
107
commandManager . object ,
108
+ applicationShell . object ,
100
109
) ;
101
110
expectedTerminalTitle = 'REPL' ;
102
111
break ;
@@ -120,6 +129,7 @@ suite('Terminal - Code Execution', () => {
120
129
fileSystem . object ,
121
130
disposables ,
122
131
interpreterService . object ,
132
+ applicationShell . object ,
123
133
) ;
124
134
expectedTerminalTitle = 'Django Shell' ;
125
135
break ;
@@ -590,7 +600,7 @@ suite('Terminal - Code Execution', () => {
590
600
) ;
591
601
} ) ;
592
602
593
- test ( 'Ensure repl is re-initialized when terminal is closed ' , async ( ) => {
603
+ test ( 'Ensure REPL launches after reducing risk of command being ignored or duplicated ' , async ( ) => {
594
604
const pythonPath = 'usr/bin/python1234' ;
595
605
const terminalArgs = [ '-a' , 'b' , 'c' ] ;
596
606
platform . setup ( ( p ) => p . isWindows ) . returns ( ( ) => false ) ;
@@ -599,43 +609,27 @@ suite('Terminal - Code Execution', () => {
599
609
. returns ( ( ) => Promise . resolve ( ( { path : pythonPath } as unknown ) as PythonEnvironment ) ) ;
600
610
terminalSettings . setup ( ( t ) => t . launchArgs ) . returns ( ( ) => terminalArgs ) ;
601
611
602
- let closeTerminalCallback : undefined | ( ( ) => void ) ;
603
- terminalService
604
- . setup ( ( t ) => t . onDidCloseTerminal ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
605
- . returns ( ( callback ) => {
606
- closeTerminalCallback = callback ;
607
- return {
608
- dispose : noop ,
609
- } ;
610
- } ) ;
611
-
612
612
await executor . execute ( 'cmd1' ) ;
613
613
await executor . execute ( 'cmd2' ) ;
614
614
await executor . execute ( 'cmd3' ) ;
615
615
616
- const expectedTerminalArgs = isDjangoRepl ? terminalArgs . concat ( [ 'manage.py' , 'shell' ] ) : terminalArgs ;
617
-
618
- expect ( closeTerminalCallback ) . not . to . be . an ( 'undefined' , 'Callback not initialized' ) ;
619
- terminalService . verify (
620
- async ( t ) =>
621
- t . sendCommand ( TypeMoq . It . isValue ( pythonPath ) , TypeMoq . It . isValue ( expectedTerminalArgs ) ) ,
622
- TypeMoq . Times . once ( ) ,
616
+ // Now check if sendCommand from the initializeRepl is called atLeastOnce.
617
+ // This is due to newly added Promise race and fallback to lower risk of swollen first command.
618
+ applicationShell . verify (
619
+ async ( t ) => t . onDidWriteTerminalData ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) ,
620
+ TypeMoq . Times . atLeastOnce ( ) ,
623
621
) ;
624
622
625
- closeTerminalCallback ! . call ( terminalService . object ) ;
626
623
await executor . execute ( 'cmd4' ) ;
627
- terminalService . verify (
628
- async ( t ) =>
629
- t . sendCommand ( TypeMoq . It . isValue ( pythonPath ) , TypeMoq . It . isValue ( expectedTerminalArgs ) ) ,
630
- TypeMoq . Times . exactly ( 2 ) ,
624
+ applicationShell . verify (
625
+ async ( t ) => t . onDidWriteTerminalData ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) ,
626
+ TypeMoq . Times . atLeastOnce ( ) ,
631
627
) ;
632
628
633
- closeTerminalCallback ! . call ( terminalService . object ) ;
634
629
await executor . execute ( 'cmd5' ) ;
635
- terminalService . verify (
636
- async ( t ) =>
637
- t . sendCommand ( TypeMoq . It . isValue ( pythonPath ) , TypeMoq . It . isValue ( expectedTerminalArgs ) ) ,
638
- TypeMoq . Times . exactly ( 3 ) ,
630
+ applicationShell . verify (
631
+ async ( t ) => t . onDidWriteTerminalData ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) ,
632
+ TypeMoq . Times . atLeastOnce ( ) ,
639
633
) ;
640
634
} ) ;
641
635
0 commit comments