forked from microsoft/vscode-python-environments
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcondaUtils.unit.test.ts
More file actions
179 lines (141 loc) · 6.61 KB
/
condaUtils.unit.test.ts
File metadata and controls
179 lines (141 loc) · 6.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import assert from 'assert';
import * as os from 'os';
import * as sinon from 'sinon';
import {
getCondaPathSetting,
trimVersionToMajorMinor,
generateName,
getName,
} from '../../../managers/conda/condaUtils';
import * as workspaceApis from '../../../common/workspace.apis';
import { Uri } from 'vscode';
import { PythonEnvironmentApi } from '../../../api';
/**
* Tests for condaUtils.ts
*
* Note: This test suite focuses on pure functions that don't require mocking Node.js modules.
* Functions that directly interact with file system (fse) or child processes (ch.spawn)
* are challenging to test in unit tests without wrapper abstractions.
*
* Based on the test plan in docs/condaUtils-test-plan.md, we're testing:
* - getCondaPathSetting: Configuration reading with tilde expansion
* - trimVersionToMajorMinor: Version string parsing
* - generateName: Unique name generation logic
* - getName: URI to name conversion
*/
suite('condaUtils - Configuration and Settings', () => {
let getConfigurationStub: sinon.SinonStub;
setup(() => {
getConfigurationStub = sinon.stub(workspaceApis, 'getConfiguration');
});
teardown(() => {
sinon.restore();
});
suite('getCondaPathSetting', () => {
test('should return conda path from python.condaPath setting', () => {
const mockConfig = { get: sinon.stub().withArgs('condaPath').returns('/custom/conda') };
getConfigurationStub.withArgs('python').returns(mockConfig);
const result = getCondaPathSetting();
assert.strictEqual(result, '/custom/conda');
});
test('should untildify conda path with tilde', () => {
const mockConfig = { get: sinon.stub().withArgs('condaPath').returns('~/miniconda3/bin/conda') };
getConfigurationStub.withArgs('python').returns(mockConfig);
const result = getCondaPathSetting();
assert.ok(result);
assert.ok(!result.includes('~'), 'Should expand tilde');
assert.ok(result.includes(os.homedir()), 'Should include home directory');
});
test('should return undefined when condaPath not set', () => {
const mockConfig = { get: sinon.stub().withArgs('condaPath').returns(undefined) };
getConfigurationStub.withArgs('python').returns(mockConfig);
const result = getCondaPathSetting();
assert.strictEqual(result, undefined);
});
test('should return value as-is when non-string value provided', () => {
const mockConfig = { get: sinon.stub().withArgs('condaPath').returns(123) };
getConfigurationStub.withArgs('python').returns(mockConfig);
const result = getCondaPathSetting();
assert.strictEqual(result, 123);
});
});
});
suite('condaUtils - Version Utilities', () => {
suite('trimVersionToMajorMinor', () => {
test('should trim version to major.minor.patch', () => {
const result = trimVersionToMajorMinor('3.11.5');
assert.strictEqual(result, '3.11.5');
});
test('should trim version with extra segments', () => {
const result = trimVersionToMajorMinor('3.11.5.post1+abc123');
assert.strictEqual(result, '3.11.5');
});
test('should handle two-part versions', () => {
const result = trimVersionToMajorMinor('3.11');
assert.strictEqual(result, '3.11');
});
test('should return original for single-part versions', () => {
const result = trimVersionToMajorMinor('3');
assert.strictEqual(result, '3');
});
test('should return original for non-standard versions', () => {
const result = trimVersionToMajorMinor('latest');
assert.strictEqual(result, 'latest');
});
test('should handle version with leading v', () => {
const result = trimVersionToMajorMinor('v3.11.5');
assert.strictEqual(result, 'v3.11.5');
});
});
});
suite('condaUtils - Name and Path Utilities', () => {
suite('getName', () => {
let mockApi: { getPythonProject: sinon.SinonStub };
setup(() => {
mockApi = {
getPythonProject: sinon.stub(),
};
});
test('should return undefined when no URIs provided', () => {
const result = getName(mockApi as unknown as PythonEnvironmentApi, undefined);
assert.strictEqual(result, undefined);
});
test('should return undefined when empty array provided', () => {
const result = getName(mockApi as unknown as PythonEnvironmentApi, []);
assert.strictEqual(result, undefined);
});
test('should return undefined when multiple URIs provided', () => {
const uris = [Uri.file('/path1'), Uri.file('/path2')];
const result = getName(mockApi as unknown as PythonEnvironmentApi, uris);
assert.strictEqual(result, undefined);
});
test('should return project name for single URI', () => {
const uri = Uri.file('/workspace/project');
mockApi.getPythonProject.withArgs(uri).returns({ name: 'my-project', uri });
const result = getName(mockApi as unknown as PythonEnvironmentApi, uri);
assert.strictEqual(result, 'my-project');
});
test('should return project name for single-element array', () => {
const uri = Uri.file('/workspace/project');
mockApi.getPythonProject.withArgs(uri).returns({ name: 'my-project', uri });
const result = getName(mockApi as unknown as PythonEnvironmentApi, [uri]);
assert.strictEqual(result, 'my-project');
});
test('should return undefined when project not found', () => {
const uri = Uri.file('/workspace/project');
mockApi.getPythonProject.withArgs(uri).returns(undefined);
const result = getName(mockApi as unknown as PythonEnvironmentApi, uri);
assert.strictEqual(result, undefined);
});
});
suite('generateName', () => {
test('should generate unique name with env_ prefix', async () => {
// This is an integration-style test since we can't easily mock fs.exists
// We just verify the format and that it returns a string
const result = await generateName('/some/path');
assert.ok(result, 'Should return a name');
assert.ok(result!.startsWith('env_'), 'Should start with env_ prefix');
assert.ok(result!.length > 4, 'Should have random suffix');
});
});
});