@@ -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,29 +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
+ 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 ) ;
68
74
service = new EnvironmentActivationService (
69
75
instance ( helper ) ,
70
76
instance ( platform ) ,
71
77
instance ( processServiceFactory ) ,
72
78
instance ( currentProcess ) ,
79
+ instance ( workspace ) ,
80
+ instance ( interpreterService ) ,
73
81
instance ( envVarsService )
74
82
) ;
75
-
76
- const cfg = typemoq . Mock . ofType < WorkspaceConfiguration > ( ) ;
77
- workspace
78
- . setup ( w => w . getConfiguration ( typemoq . It . isValue ( 'python' ) , typemoq . It . isAny ( ) ) )
79
- . returns ( ( ) => cfg . object ) ;
80
- workspace . setup ( w => w . workspaceFolders ) . returns ( ( ) => [ ] ) ;
81
- cfg . setup ( c => c . inspect ( typemoq . It . isValue ( 'pythonPath' ) ) ) . returns ( ( ) => {
82
- return { globalValue : 'GlobalValuepython' } as any ;
83
- } ) ;
84
- clearCache ( ) ;
85
83
}
86
- teardown ( ( ) => {
87
- mockedVSCodeNamespaces . workspace ! . reset ( ) ;
88
- } ) ;
89
84
90
85
function title ( resource ?: Uri , interpreter ?: PythonInterpreter ) {
91
86
return `${ resource ? 'With a resource' : 'Without a resource' } ${ interpreter ? ' and an interpreter' : '' } ` ;
@@ -262,6 +257,72 @@ suite('Interpreters Activation - Python Environment Variables', () => {
262
257
verify ( envVarsService . getEnvironmentVariables ( resource ) ) . once ( ) ;
263
258
verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . once ( ) ;
264
259
} ) ;
260
+ test ( 'Cache Variables' , async ( ) => {
261
+ const cmd = [ '1' , '2' ] ;
262
+ const varsFromEnv = { one : '11' , two : '22' , HELLO : 'xxx' } ;
263
+ const stdout = `${ getEnvironmentPrefix } ${ EOL } ${ JSON . stringify ( varsFromEnv ) } ` ;
264
+ when ( platform . osType ) . thenReturn ( osType . value ) ;
265
+ when (
266
+ helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter )
267
+ ) . thenResolve ( cmd ) ;
268
+ when ( processServiceFactory . create ( resource ) ) . thenResolve ( instance ( processService ) ) ;
269
+ when ( envVarsService . getEnvironmentVariables ( resource ) ) . thenResolve ( { } ) ;
270
+ when ( processService . shellExec ( anything ( ) , anything ( ) ) ) . thenResolve ( { stdout : stdout } ) ;
271
+
272
+ const env = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
273
+ const env2 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
274
+ const env3 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
275
+
276
+ expect ( env ) . to . deep . equal ( varsFromEnv ) ;
277
+ // All same objects.
278
+ expect ( env )
279
+ . to . equal ( env2 )
280
+ . to . equal ( env3 ) ;
281
+
282
+ // All methods invoked only once.
283
+ verify (
284
+ helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter )
285
+ ) . once ( ) ;
286
+ verify ( processServiceFactory . create ( resource ) ) . once ( ) ;
287
+ verify ( envVarsService . getEnvironmentVariables ( resource ) ) . once ( ) ;
288
+ verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . once ( ) ;
289
+ } ) ;
290
+ async function testClearingCache ( bustCache : Function ) {
291
+ const cmd = [ '1' , '2' ] ;
292
+ const varsFromEnv = { one : '11' , two : '22' , HELLO : 'xxx' } ;
293
+ const stdout = `${ getEnvironmentPrefix } ${ EOL } ${ JSON . stringify ( varsFromEnv ) } ` ;
294
+ when ( platform . osType ) . thenReturn ( osType . value ) ;
295
+ when (
296
+ helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter )
297
+ ) . thenResolve ( cmd ) ;
298
+ when ( processServiceFactory . create ( resource ) ) . thenResolve ( instance ( processService ) ) ;
299
+ when ( envVarsService . getEnvironmentVariables ( resource ) ) . thenResolve ( { } ) ;
300
+ when ( processService . shellExec ( anything ( ) , anything ( ) ) ) . thenResolve ( { stdout : stdout } ) ;
301
+
302
+ const env = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
303
+ bustCache ( ) ;
304
+ const env2 = await service . getActivatedEnvironmentVariables ( resource , interpreter ) ;
305
+
306
+ expect ( env ) . to . deep . equal ( varsFromEnv ) ;
307
+ // Objects are different (not same reference).
308
+ expect ( env ) . to . not . equal ( env2 ) ;
309
+ // However variables are the same.
310
+ expect ( env ) . to . deep . equal ( env2 ) ;
311
+
312
+ // All methods invoked twice as cache was blown.
313
+ verify (
314
+ helper . getEnvironmentActivationShellCommands ( resource , anything ( ) , interpreter )
315
+ ) . twice ( ) ;
316
+ verify ( processServiceFactory . create ( resource ) ) . twice ( ) ;
317
+ verify ( envVarsService . getEnvironmentVariables ( resource ) ) . twice ( ) ;
318
+ verify ( processService . shellExec ( anything ( ) , anything ( ) ) ) . twice ( ) ;
319
+ }
320
+ test ( 'Cache Variables get cleared when changing interpreter' , async ( ) => {
321
+ await testClearingCache ( onDidChangeInterpreter . fire . bind ( onDidChangeInterpreter ) ) ;
322
+ } ) ;
323
+ test ( 'Cache Variables get cleared when changing env variables file' , async ( ) => {
324
+ await testClearingCache ( onDidChangeEnvVariables . fire . bind ( onDidChangeEnvVariables ) ) ;
325
+ } ) ;
265
326
} ) ;
266
327
} ) ;
267
328
} ) ;
0 commit comments