@@ -24,6 +24,7 @@ import { NoneLSExtensionManager } from '../../client/languageServer/noneLSExtens
2424import { PylanceLSExtensionManager } from '../../client/languageServer/pylanceLSExtensionManager' ;
2525import { LanguageServerWatcher } from '../../client/languageServer/watcher' ;
2626import * as Logging from '../../client/logging' ;
27+ import { PythonEnvironment } from '../../client/pythonEnvironments/info' ;
2728
2829suite ( 'Language server watcher' , ( ) => {
2930 let watcher : LanguageServerWatcher ;
@@ -47,6 +48,9 @@ suite('Language server watcher', () => {
4748 } as unknown ) as IInterpreterPathService ,
4849 ( {
4950 getActiveInterpreter : ( ) => 'python' ,
51+ onDidChangeInterpreterInformation : ( ) => {
52+ /* do nothing */
53+ } ,
5054 } as unknown ) as IInterpreterService ,
5155 { } as IEnvironmentVariablesProvider ,
5256 ( {
@@ -95,7 +99,11 @@ suite('Language server watcher', () => {
9599 /* do nothing */
96100 } ,
97101 } as unknown ) as IInterpreterPathService ,
98- { } as IInterpreterService ,
102+ ( {
103+ onDidChangeInterpreterInformation : ( ) => {
104+ /* do nothing */
105+ } ,
106+ } as unknown ) as IInterpreterService ,
99107 { } as IEnvironmentVariablesProvider ,
100108 ( {
101109 isTrusted : true ,
@@ -138,7 +146,11 @@ suite('Language server watcher', () => {
138146 /* do nothing */
139147 } ,
140148 } as unknown ) as IInterpreterPathService ,
141- { } as IInterpreterService ,
149+ ( {
150+ onDidChangeInterpreterInformation : ( ) => {
151+ /* do nothing */
152+ } ,
153+ } as unknown ) as IInterpreterService ,
142154 { } as IEnvironmentVariablesProvider ,
143155 ( {
144156 isTrusted : false ,
@@ -180,6 +192,9 @@ suite('Language server watcher', () => {
180192
181193 const interpreterService = ( {
182194 getActiveInterpreter : getActiveInterpreterStub ,
195+ onDidChangeInterpreterInformation : ( ) => {
196+ /* do nothing */
197+ } ,
183198 } as unknown ) as IInterpreterService ;
184199
185200 watcher = new LanguageServerWatcher (
@@ -277,6 +292,9 @@ suite('Language server watcher', () => {
277292 } as unknown ) as IInterpreterPathService ,
278293 ( {
279294 getActiveInterpreter : ( ) => 'python' ,
295+ onDidChangeInterpreterInformation : ( ) => {
296+ /* do nothing */
297+ } ,
280298 } as unknown ) as IInterpreterService ,
281299 { } as IEnvironmentVariablesProvider ,
282300 ( {
@@ -360,6 +378,9 @@ suite('Language server watcher', () => {
360378 } as unknown ) as IInterpreterPathService ,
361379 ( {
362380 getActiveInterpreter : ( ) => 'python' ,
381+ onDidChangeInterpreterInformation : ( ) => {
382+ /* do nothing */
383+ } ,
363384 } as unknown ) as IInterpreterService ,
364385 { } as IEnvironmentVariablesProvider ,
365386 workspaceService ,
@@ -426,6 +447,9 @@ suite('Language server watcher', () => {
426447 } as unknown ) as IInterpreterPathService ,
427448 ( {
428449 getActiveInterpreter : ( ) => 'python' ,
450+ onDidChangeInterpreterInformation : ( ) => {
451+ /* do nothing */
452+ } ,
429453 } as unknown ) as IInterpreterService ,
430454 { } as IEnvironmentVariablesProvider ,
431455 workspaceService ,
@@ -477,6 +501,9 @@ suite('Language server watcher', () => {
477501 } as unknown ) as IInterpreterPathService ,
478502 ( {
479503 getActiveInterpreter : ( ) => ( { version : { major : 2 , minor : 7 } } ) ,
504+ onDidChangeInterpreterInformation : ( ) => {
505+ /* do nothing */
506+ } ,
480507 } as unknown ) as IInterpreterService ,
481508 { } as IEnvironmentVariablesProvider ,
482509 ( {
@@ -535,6 +562,9 @@ suite('Language server watcher', () => {
535562 } as unknown ) as IInterpreterPathService ,
536563 ( {
537564 getActiveInterpreter : ( ) => ( { version : { major : 2 , minor : 7 } } ) ,
565+ onDidChangeInterpreterInformation : ( ) => {
566+ /* do nothing */
567+ } ,
538568 } as unknown ) as IInterpreterService ,
539569 { } as IEnvironmentVariablesProvider ,
540570 ( {
@@ -590,6 +620,9 @@ suite('Language server watcher', () => {
590620 } as unknown ) as IInterpreterPathService ,
591621 ( {
592622 getActiveInterpreter : ( ) => ( { version : { major : 2 , minor : 7 } } ) ,
623+ onDidChangeInterpreterInformation : ( ) => {
624+ /* do nothing */
625+ } ,
593626 } as unknown ) as IInterpreterService ,
594627 { } as IEnvironmentVariablesProvider ,
595628 ( {
@@ -673,6 +706,9 @@ suite('Language server watcher', () => {
673706 } as unknown ) as IInterpreterPathService ,
674707 ( {
675708 getActiveInterpreter : getActiveInterpreterStub ,
709+ onDidChangeInterpreterInformation : ( ) => {
710+ /* do nothing */
711+ } ,
676712 } as unknown ) as IInterpreterService ,
677713 { } as IEnvironmentVariablesProvider ,
678714 ( {
@@ -757,6 +793,9 @@ suite('Language server watcher', () => {
757793 } as unknown ) as IInterpreterPathService ,
758794 ( {
759795 getActiveInterpreter : ( ) => ( { version : { major : 3 , minor : 7 } } ) ,
796+ onDidChangeInterpreterInformation : ( ) => {
797+ /* do nothing */
798+ } ,
760799 } as unknown ) as IInterpreterService ,
761800 { } as IEnvironmentVariablesProvider ,
762801 workspaceService ,
@@ -792,4 +831,165 @@ suite('Language server watcher', () => {
792831 assert . ok ( stopLanguageServerStub . notCalled === ! multiLS ) ;
793832 } ) ;
794833 } ) ;
834+
835+ test ( 'The language server should be restarted if the interpreter info changed' , async ( ) => {
836+ const info = ( {
837+ envPath : 'foo' ,
838+ path : 'path/to/foo/bin/python' ,
839+ } as unknown ) as PythonEnvironment ;
840+
841+ let onDidChangeInfoListener : ( event : PythonEnvironment ) => Promise < void > = ( ) => Promise . resolve ( ) ;
842+
843+ const interpreterService = ( {
844+ onDidChangeInterpreterInformation : (
845+ listener : ( event : PythonEnvironment ) => Promise < void > ,
846+ thisArg : unknown ,
847+ ) : void => {
848+ onDidChangeInfoListener = listener . bind ( thisArg ) ;
849+ } ,
850+ getActiveInterpreter : ( ) => ( {
851+ envPath : 'foo' ,
852+ path : 'path/to/foo' ,
853+ } ) ,
854+ } as unknown ) as IInterpreterService ;
855+
856+ watcher = new LanguageServerWatcher (
857+ ( {
858+ get : ( ) => {
859+ /* do nothing */
860+ } ,
861+ } as unknown ) as IServiceContainer ,
862+ { } as ILanguageServerOutputChannel ,
863+ {
864+ getSettings : ( ) => ( { languageServer : LanguageServerType . None } ) ,
865+ } as IConfigurationService ,
866+ { } as IExperimentService ,
867+ ( {
868+ getActiveWorkspaceUri : ( ) => undefined ,
869+ } as unknown ) as IInterpreterHelper ,
870+ ( {
871+ onDidChange : ( ) => {
872+ /* do nothing */
873+ } ,
874+ } as unknown ) as IInterpreterPathService ,
875+ interpreterService ,
876+ ( {
877+ onDidEnvironmentVariablesChange : ( ) => {
878+ /* do nothing */
879+ } ,
880+ } as unknown ) as IEnvironmentVariablesProvider ,
881+ ( {
882+ isTrusted : true ,
883+ getWorkspaceFolder : ( uri : Uri ) => ( { uri } ) ,
884+ onDidChangeConfiguration : ( ) => {
885+ /* do nothing */
886+ } ,
887+ onDidChangeWorkspaceFolders : ( ) => {
888+ /* do nothing */
889+ } ,
890+ } as unknown ) as IWorkspaceService ,
891+ ( {
892+ registerCommand : ( ) => {
893+ /* do nothing */
894+ } ,
895+ } as unknown ) as ICommandManager ,
896+ { } as IFileSystem ,
897+ ( {
898+ getExtension : ( ) => undefined ,
899+ onDidChange : ( ) => {
900+ /* do nothing */
901+ } ,
902+ } as unknown ) as IExtensions ,
903+ { } as IApplicationShell ,
904+ [ ] as Disposable [ ] ,
905+ ) ;
906+
907+ const startLanguageServerSpy = sandbox . spy ( watcher , 'startLanguageServer' ) ;
908+
909+ await watcher . startLanguageServer ( LanguageServerType . None ) ;
910+
911+ await onDidChangeInfoListener ( info ) ;
912+
913+ // Check that startLanguageServer was called twice: Once above, and once after the interpreter info changed.
914+ assert . ok ( startLanguageServerSpy . calledTwice ) ;
915+ } ) ;
916+
917+ test ( 'The language server should not be restarted if the interpreter info did not change' , async ( ) => {
918+ const info = ( {
919+ envPath : 'foo' ,
920+ path : 'path/to/foo' ,
921+ } as unknown ) as PythonEnvironment ;
922+
923+ let onDidChangeInfoListener : ( event : PythonEnvironment ) => Promise < void > = ( ) => Promise . resolve ( ) ;
924+
925+ const interpreterService = ( {
926+ onDidChangeInterpreterInformation : (
927+ listener : ( event : PythonEnvironment ) => Promise < void > ,
928+ thisArg : unknown ,
929+ ) : void => {
930+ onDidChangeInfoListener = listener . bind ( thisArg ) ;
931+ } ,
932+ getActiveInterpreter : ( ) => info ,
933+ } as unknown ) as IInterpreterService ;
934+
935+ watcher = new LanguageServerWatcher (
936+ ( {
937+ get : ( ) => {
938+ /* do nothing */
939+ } ,
940+ } as unknown ) as IServiceContainer ,
941+ { } as ILanguageServerOutputChannel ,
942+ {
943+ getSettings : ( ) => ( { languageServer : LanguageServerType . None } ) ,
944+ } as IConfigurationService ,
945+ { } as IExperimentService ,
946+ ( {
947+ getActiveWorkspaceUri : ( ) => undefined ,
948+ } as unknown ) as IInterpreterHelper ,
949+ ( {
950+ onDidChange : ( ) => {
951+ /* do nothing */
952+ } ,
953+ } as unknown ) as IInterpreterPathService ,
954+ interpreterService ,
955+ ( {
956+ onDidEnvironmentVariablesChange : ( ) => {
957+ /* do nothing */
958+ } ,
959+ } as unknown ) as IEnvironmentVariablesProvider ,
960+ ( {
961+ isTrusted : true ,
962+ getWorkspaceFolder : ( uri : Uri ) => ( { uri } ) ,
963+ onDidChangeConfiguration : ( ) => {
964+ /* do nothing */
965+ } ,
966+ onDidChangeWorkspaceFolders : ( ) => {
967+ /* do nothing */
968+ } ,
969+ } as unknown ) as IWorkspaceService ,
970+ ( {
971+ registerCommand : ( ) => {
972+ /* do nothing */
973+ } ,
974+ } as unknown ) as ICommandManager ,
975+ { } as IFileSystem ,
976+ ( {
977+ getExtension : ( ) => undefined ,
978+ onDidChange : ( ) => {
979+ /* do nothing */
980+ } ,
981+ } as unknown ) as IExtensions ,
982+ { } as IApplicationShell ,
983+ [ ] as Disposable [ ] ,
984+ ) ;
985+
986+ const startLanguageServerSpy = sandbox . spy ( watcher , 'startLanguageServer' ) ;
987+
988+ await watcher . startLanguageServer ( LanguageServerType . None ) ;
989+
990+ await onDidChangeInfoListener ( info ) ;
991+
992+ // Check that startLanguageServer was called once: Only when startLanguageServer() was called above.
993+ assert . ok ( startLanguageServerSpy . calledOnce ) ;
994+ } ) ;
795995} ) ;
0 commit comments