@@ -7,8 +7,9 @@ import { EOL } from 'os';
77import * as path from 'path' ;
88import { SemVer } from 'semver' ;
99import { anything , capture , instance , mock , verify , when } from 'ts-mockito' ;
10- import * as typemoq from 'typemoq' ;
11- import { EventEmitter , Uri , workspace as workspaceType , WorkspaceConfiguration } from 'vscode' ;
10+ import { EventEmitter , Uri } from 'vscode' ;
11+ import { IWorkspaceService } from '../../../client/common/application/types' ;
12+ import { WorkspaceService } from '../../../client/common/application/workspace' ;
1213import { PlatformService } from '../../../client/common/platform/platformService' ;
1314import { IPlatformService } from '../../../client/common/platform/types' ;
1415import { CurrentProcess } from '../../../client/common/process/currentProcess' ;
@@ -18,15 +19,14 @@ import { IProcessService, IProcessServiceFactory } from '../../../client/common/
1819import { TerminalHelper } from '../../../client/common/terminal/helper' ;
1920import { ITerminalHelper } from '../../../client/common/terminal/types' ;
2021import { ICurrentProcess } from '../../../client/common/types' ;
21- import { clearCache } from '../../../client/common/utils/cacheUtils' ;
2222import { getNamesAndValues } from '../../../client/common/utils/enum' ;
2323import { Architecture , OSType } from '../../../client/common/utils/platform' ;
2424import { EnvironmentVariablesProvider } from '../../../client/common/variables/environmentVariablesProvider' ;
2525import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types' ;
2626import { EXTENSION_ROOT_DIR } from '../../../client/constants' ;
2727import { EnvironmentActivationService } from '../../../client/interpreter/activation/service' ;
28- import { InterpreterType , PythonInterpreter } from '../../../client/interpreter/contracts' ;
29- import { mockedVSCodeNamespaces } from '../../vscode-mock ' ;
28+ import { IInterpreterService , InterpreterType , PythonInterpreter } from '../../../client/interpreter/contracts' ;
29+ import { InterpreterService } from '../../../client/interpreter/interpreterService ' ;
3030
3131const getEnvironmentPrefix = 'e8b39361-0157-4923-80e1-22d70d46dee6' ;
3232const defaultShells = {
@@ -45,8 +45,10 @@ suite('Interpreters Activation - Python Environment Variables', () => {
4545 let processService : IProcessService ;
4646 let currentProcess : ICurrentProcess ;
4747 let envVarsService : IEnvironmentVariablesProvider ;
48- let workspace : typemoq . IMock < typeof workspaceType > ;
49-
48+ let workspace : IWorkspaceService ;
49+ let interpreterService : IInterpreterService ;
50+ let onDidChangeEnvVariables : EventEmitter < Uri | undefined > ;
51+ let onDidChangeInterpreter : EventEmitter < void > ;
5052 const pythonInterpreter : PythonInterpreter = {
5153 path : '/foo/bar/python.exe' ,
5254 version : new SemVer ( '3.6.6-final' ) ,
@@ -63,21 +65,22 @@ suite('Interpreters Activation - Python Environment Variables', () => {
6365 processService = mock ( ProcessService ) ;
6466 currentProcess = mock ( CurrentProcess ) ;
6567 envVarsService = mock ( EnvironmentVariablesProvider ) ;
66- workspace = mockedVSCodeNamespaces . workspace ! ;
67- when ( envVarsService . onDidEnvironmentVariablesChange ) . thenReturn ( new EventEmitter < Uri | undefined > ( ) . event ) ;
68- service = new EnvironmentActivationService ( instance ( helper ) , instance ( platform ) , instance ( processServiceFactory ) , instance ( currentProcess ) , instance ( envVarsService ) ) ;
69-
70- const cfg = typemoq . Mock . ofType < WorkspaceConfiguration > ( ) ;
71- workspace . setup ( w => w . getConfiguration ( typemoq . It . isValue ( 'python' ) , typemoq . It . isAny ( ) ) ) . returns ( ( ) => cfg . object ) ;
72- workspace . setup ( w => w . workspaceFolders ) . returns ( ( ) => [ ] ) ;
73- cfg . setup ( c => c . inspect ( typemoq . It . isValue ( 'pythonPath' ) ) ) . returns ( ( ) => {
74- return { globalValue : 'GlobalValuepython' } as any ;
75- } ) ;
76- clearCache ( ) ;
68+ interpreterService = mock ( InterpreterService ) ;
69+ workspace = mock ( WorkspaceService ) ;
70+ onDidChangeEnvVariables = new EventEmitter < Uri | undefined > ( ) ;
71+ onDidChangeInterpreter = new EventEmitter < void > ( ) ;
72+ when ( envVarsService . onDidEnvironmentVariablesChange ) . thenReturn ( onDidChangeEnvVariables . event ) ;
73+ when ( interpreterService . onDidChangeInterpreter ) . thenReturn ( onDidChangeInterpreter . event ) ;
74+ service = new EnvironmentActivationService (
75+ instance ( helper ) ,
76+ instance ( platform ) ,
77+ instance ( processServiceFactory ) ,
78+ instance ( currentProcess ) ,
79+ instance ( workspace ) ,
80+ instance ( interpreterService ) ,
81+ instance ( envVarsService )
82+ ) ;
7783 }
78- teardown ( ( ) => {
79- mockedVSCodeNamespaces . workspace ! . reset ( ) ;
80- } ) ;
8184
8285 function title ( resource ?: Uri , interpreter ?: PythonInterpreter ) {
8386 return `${ resource ? 'With a resource' : 'Without a resource' } ${ interpreter ? ' and an interpreter' : '' } ` ;
@@ -218,6 +221,64 @@ suite('Interpreters Activation - Python Environment Variables', () => {
218221 verify ( envVarsService . getEnvironmentVariables ( resource ) ) . once ( ) ;
219222 verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . once ( ) ;
220223 } ) ;
224+ test ( 'Cache Variables' , async ( ) => {
225+ const cmd = [ '1' , '2' ] ;
226+ const varsFromEnv = { one : '11' , two : '22' , HELLO : 'xxx' } ;
227+ const stdout = `${ getEnvironmentPrefix } ${ EOL } ${ JSON . stringify ( varsFromEnv ) } ` ;
228+ when ( platform . osType ) . thenReturn ( osType . value ) ;
229+ when ( helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter ) ) . thenResolve ( cmd ) ;
230+ when ( processServiceFactory . create ( resource ) ) . thenResolve ( instance ( processService ) ) ;
231+ when ( envVarsService . getEnvironmentVariables ( resource ) ) . thenResolve ( { } ) ;
232+ when ( processService . shellExec ( anything ( ) , anything ( ) ) ) . thenResolve ( { stdout : stdout } ) ;
233+
234+ const env = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
235+ const env2 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
236+ const env3 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
237+
238+ expect ( env ) . to . deep . equal ( varsFromEnv ) ;
239+ // All same objects.
240+ expect ( env )
241+ . to . equal ( env2 )
242+ . to . equal ( env3 ) ;
243+
244+ // All methods invoked only once.
245+ verify ( helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter ) ) . once ( ) ;
246+ verify ( processServiceFactory . create ( resource ) ) . once ( ) ;
247+ verify ( envVarsService . getEnvironmentVariables ( resource ) ) . once ( ) ;
248+ verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . once ( ) ;
249+ } ) ;
250+ async function testClearingCache ( bustCache : Function ) {
251+ const cmd = [ '1' , '2' ] ;
252+ const varsFromEnv = { one : '11' , two : '22' , HELLO : 'xxx' } ;
253+ const stdout = `${ getEnvironmentPrefix } ${ EOL } ${ JSON . stringify ( varsFromEnv ) } ` ;
254+ when ( platform . osType ) . thenReturn ( osType . value ) ;
255+ when ( helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter ) ) . thenResolve ( cmd ) ;
256+ when ( processServiceFactory . create ( resource ) ) . thenResolve ( instance ( processService ) ) ;
257+ when ( envVarsService . getEnvironmentVariables ( resource ) ) . thenResolve ( { } ) ;
258+ when ( processService . shellExec ( anything ( ) , anything ( ) ) ) . thenResolve ( { stdout : stdout } ) ;
259+
260+ const env = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
261+ bustCache ( ) ;
262+ const env2 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
263+
264+ expect ( env ) . to . deep . equal ( varsFromEnv ) ;
265+ // Objects are different (not same reference).
266+ expect ( env ) . to . not . equal ( env2 ) ;
267+ // However variables are the same.
268+ expect ( env ) . to . deep . equal ( env2 ) ;
269+
270+ // All methods invoked twice as cache was blown.
271+ verify ( helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter ) ) . twice ( ) ;
272+ verify ( processServiceFactory . create ( resource ) ) . twice ( ) ;
273+ verify ( envVarsService . getEnvironmentVariables ( resource ) ) . twice ( ) ;
274+ verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . twice ( ) ;
275+ }
276+ test ( 'Cache Variables get cleared when changing interpreter' , async ( ) => {
277+ await testClearingCache ( onDidChangeInterpreter . fire . bind ( onDidChangeInterpreter ) ) ;
278+ } ) ;
279+ test ( 'Cache Variables get cleared when changing env variables file' , async ( ) => {
280+ await testClearingCache ( onDidChangeEnvVariables . fire . bind ( onDidChangeEnvVariables ) ) ;
281+ } ) ;
221282 } ) ;
222283 } ) ;
223284 } ) ;
0 commit comments