@@ -14,8 +14,9 @@ import {
1414 Uri ,
1515 Terminal as VSCodeTerminal ,
1616 WorkspaceConfiguration ,
17+ TerminalDataWriteEvent ,
1718} from 'vscode' ;
18- import { ITerminalManager , IWorkspaceService } from '../../../client/common/application/types' ;
19+ import { IApplicationShell , ITerminalManager , IWorkspaceService } from '../../../client/common/application/types' ;
1920import { EXTENSION_ROOT_DIR } from '../../../client/common/constants' ;
2021import { IPlatformService } from '../../../client/common/platform/types' ;
2122import { TerminalService } from '../../../client/common/terminal/service' ;
@@ -56,6 +57,9 @@ suite('Terminal Service', () => {
5657 let useEnvExtensionStub : sinon . SinonStub ;
5758 let interpreterService : TypeMoq . IMock < IInterpreterService > ;
5859 let options : TypeMoq . IMock < TerminalCreationOptions > ;
60+ let applicationShell : TypeMoq . IMock < IApplicationShell > ;
61+ let onDidWriteTerminalDataEmitter : EventEmitter < TerminalDataWriteEvent > ;
62+ let onDidChangeTerminalStateEmitter : EventEmitter < VSCodeTerminal > ;
5963
6064 setup ( ( ) => {
6165 useEnvExtensionStub = sinon . stub ( extapi , 'useEnvExtension' ) ;
@@ -118,6 +122,17 @@ suite('Terminal Service', () => {
118122 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalActivator ) ) . returns ( ( ) => terminalActivator . object ) ;
119123 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalAutoActivation ) ) . returns ( ( ) => terminalAutoActivator . object ) ;
120124 mockServiceContainer . setup ( ( c ) => c . get ( IInterpreterService ) ) . returns ( ( ) => interpreterService . object ) ;
125+
126+ applicationShell = TypeMoq . Mock . ofType < IApplicationShell > ( ) ;
127+ onDidWriteTerminalDataEmitter = new EventEmitter < TerminalDataWriteEvent > ( ) ;
128+ applicationShell . setup ( ( a ) => a . onDidWriteTerminalData ) . returns ( ( ) => onDidWriteTerminalDataEmitter . event ) ;
129+ mockServiceContainer . setup ( ( c ) => c . get ( IApplicationShell ) ) . returns ( ( ) => applicationShell . object ) ;
130+
131+ onDidChangeTerminalStateEmitter = new EventEmitter < VSCodeTerminal > ( ) ;
132+ terminalManager
133+ . setup ( ( t ) => t . onDidChangeTerminalState ( TypeMoq . It . isAny ( ) ) )
134+ . returns ( ( handler ) => onDidChangeTerminalStateEmitter . event ( handler ) ) ;
135+
121136 getConfigurationStub = sinon . stub ( workspaceApis , 'getConfiguration' ) ;
122137 isWindowsStub = sinon . stub ( platform , 'isWindows' ) ;
123138 pythonConfig = TypeMoq . Mock . ofType < WorkspaceConfiguration > ( ) ;
@@ -230,8 +245,10 @@ suite('Terminal Service', () => {
230245 terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
231246 terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
232247
233- service . ensureTerminal ( ) ;
234- service . executeCommand ( textToSend , true ) ;
248+ await service . ensureTerminal ( ) ;
249+ const executePromise = service . executeCommand ( textToSend , true ) ;
250+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
251+ await executePromise ;
235252
236253 terminal . verify ( ( t ) => t . show ( TypeMoq . It . isValue ( true ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
237254 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
@@ -251,8 +268,10 @@ suite('Terminal Service', () => {
251268 terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
252269 terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
253270
254- service . ensureTerminal ( ) ;
255- service . executeCommand ( textToSend , true ) ;
271+ await service . ensureTerminal ( ) ;
272+ const executePromise = service . executeCommand ( textToSend , true ) ;
273+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
274+ await executePromise ;
256275
257276 terminal . verify ( ( t ) => t . show ( TypeMoq . It . isValue ( true ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
258277 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
@@ -273,8 +292,10 @@ suite('Terminal Service', () => {
273292 terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
274293 terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
275294
276- service . ensureTerminal ( ) ;
277- service . executeCommand ( textToSend , true ) ;
295+ await service . ensureTerminal ( ) ;
296+ const executePromise = service . executeCommand ( textToSend , true ) ;
297+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
298+ await executePromise ;
278299
279300 terminal . verify ( ( t ) => t . show ( TypeMoq . It . isValue ( true ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
280301 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
@@ -305,7 +326,9 @@ suite('Terminal Service', () => {
305326 terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
306327
307328 await service . ensureTerminal ( ) ;
308- await service . executeCommand ( textToSend , true ) ;
329+ const executePromise = service . executeCommand ( textToSend , true ) ;
330+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
331+ await executePromise ;
309332
310333 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . once ( ) ) ;
311334 } ) ;
@@ -325,13 +348,39 @@ suite('Terminal Service', () => {
325348 terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
326349 terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
327350
328- service . ensureTerminal ( ) ;
329- service . executeCommand ( textToSend , true ) ;
351+ await service . ensureTerminal ( ) ;
352+ const executePromise = service . executeCommand ( textToSend , true ) ;
353+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
354+ await executePromise ;
330355
331356 terminal . verify ( ( t ) => t . show ( TypeMoq . It . isValue ( true ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
332357 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
333358 } ) ;
334359
360+ test ( 'Ensure REPL ready when onDidChangeTerminalState fires with python shell' , async ( ) => {
361+ pythonConfig
362+ . setup ( ( p ) => p . get ( 'terminal.shellIntegration.enabled' ) )
363+ . returns ( ( ) => false )
364+ . verifiable ( TypeMoq . Times . once ( ) ) ;
365+
366+ terminalHelper
367+ . setup ( ( helper ) => helper . getEnvironmentActivationCommands ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
368+ . returns ( ( ) => Promise . resolve ( undefined ) ) ;
369+ service = new TerminalService ( mockServiceContainer . object ) ;
370+ const textToSend = 'Some Text' ;
371+ terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
372+
373+ terminal . setup ( ( t ) => t . state ) . returns ( ( ) => ( { isInteractedWith : true , shell : 'python' } ) ) ;
374+ terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
375+
376+ await service . ensureTerminal ( ) ;
377+ const executePromise = service . executeCommand ( textToSend , true ) ;
378+ onDidChangeTerminalStateEmitter . fire ( terminal . object ) ;
379+ await executePromise ;
380+
381+ terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
382+ } ) ;
383+
335384 test ( 'Ensure terminal is not shown if `hideFromUser` option is set to `true`' , async ( ) => {
336385 terminalHelper
337386 . setup ( ( helper ) => helper . getEnvironmentActivationCommands ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
0 commit comments