@@ -7,8 +7,9 @@ import { EOL } from 'os';
7
7
import * as path from 'path' ;
8
8
import { SemVer } from 'semver' ;
9
9
import { 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' ;
12
13
import { PlatformService } from '../../../client/common/platform/platformService' ;
13
14
import { IPlatformService } from '../../../client/common/platform/types' ;
14
15
import { CurrentProcess } from '../../../client/common/process/currentProcess' ;
@@ -18,15 +19,14 @@ import { IProcessService, IProcessServiceFactory } from '../../../client/common/
18
19
import { TerminalHelper } from '../../../client/common/terminal/helper' ;
19
20
import { ITerminalHelper } from '../../../client/common/terminal/types' ;
20
21
import { ICurrentProcess } from '../../../client/common/types' ;
21
- import { clearCache } from '../../../client/common/utils/cacheUtils' ;
22
22
import { getNamesAndValues } from '../../../client/common/utils/enum' ;
23
23
import { Architecture , OSType } from '../../../client/common/utils/platform' ;
24
24
import { EnvironmentVariablesProvider } from '../../../client/common/variables/environmentVariablesProvider' ;
25
25
import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types' ;
26
26
import { EXTENSION_ROOT_DIR } from '../../../client/constants' ;
27
27
import { 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 ' ;
30
30
31
31
const getEnvironmentPrefix = 'e8b39361-0157-4923-80e1-22d70d46dee6' ;
32
32
const defaultShells = {
@@ -45,8 +45,10 @@ suite('Interpreters Activation - Python Environment Variables', () => {
45
45
let processService : IProcessService ;
46
46
let currentProcess : ICurrentProcess ;
47
47
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 > ;
50
52
const pythonInterpreter : PythonInterpreter = {
51
53
path : '/foo/bar/python.exe' ,
52
54
version : new SemVer ( '3.6.6-final' ) ,
@@ -63,21 +65,22 @@ suite('Interpreters Activation - Python Environment Variables', () => {
63
65
processService = mock ( ProcessService ) ;
64
66
currentProcess = mock ( CurrentProcess ) ;
65
67
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
+ ) ;
77
83
}
78
- teardown ( ( ) => {
79
- mockedVSCodeNamespaces . workspace ! . reset ( ) ;
80
- } ) ;
81
84
82
85
function title ( resource ?: Uri , interpreter ?: PythonInterpreter ) {
83
86
return `${ resource ? 'With a resource' : 'Without a resource' } ${ interpreter ? ' and an interpreter' : '' } ` ;
@@ -218,6 +221,64 @@ suite('Interpreters Activation - Python Environment Variables', () => {
218
221
verify ( envVarsService . getEnvironmentVariables ( resource ) ) . once ( ) ;
219
222
verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . once ( ) ;
220
223
} ) ;
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
+ } ) ;
221
282
} ) ;
222
283
} ) ;
223
284
} ) ;
0 commit comments