Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/sessions/services/configuration/test/browser/configurationService.test.ts
13406 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { URI } from '../../../../../base/common/uri.js';
8
import { Registry } from '../../../../../platform/registry/common/platform.js';
9
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../../../../platform/configuration/common/configurationRegistry.js';
10
import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';
11
import { FileService } from '../../../../../platform/files/common/fileService.js';
12
import { NullLogService } from '../../../../../platform/log/common/log.js';
13
import { NullPolicyService } from '../../../../../platform/policy/common/policy.js';
14
import { VSBuffer } from '../../../../../base/common/buffer.js';
15
import { UriIdentityService } from '../../../../../platform/uriIdentity/common/uriIdentityService.js';
16
import { InMemoryFileSystemProvider } from '../../../../../platform/files/common/inMemoryFilesystemProvider.js';
17
import { joinPath } from '../../../../../base/common/resources.js';
18
import { Schemas } from '../../../../../base/common/network.js';
19
import { UserDataProfilesService } from '../../../../../platform/userDataProfile/common/userDataProfile.js';
20
import { UserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfileService.js';
21
import { FileUserDataProvider } from '../../../../../platform/userData/common/fileUserDataProvider.js';
22
import { TestEnvironmentService } from '../../../../../workbench/test/browser/workbenchTestServices.js';
23
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
24
import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';
25
import { ConfigurationService } from '../../browser/configurationService.js';
26
import { SessionsWorkspaceContextService } from '../../../workspace/browser/workspaceContextService.js';
27
import { getWorkspaceIdentifier } from '../../../../../workbench/services/workspaces/browser/workspaces.js';
28
import { Event } from '../../../../../base/common/event.js';
29
import { IUserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfile.js';
30
31
const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });
32
33
suite('Sessions ConfigurationService', () => {
34
35
let testObject: ConfigurationService;
36
let workspaceService: SessionsWorkspaceContextService;
37
let fileService: FileService;
38
let userDataProfileService: IUserDataProfileService;
39
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
40
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
41
42
suiteSetup(() => {
43
configurationRegistry.registerConfiguration({
44
'id': '_test_sessions',
45
'type': 'object',
46
'properties': {
47
'sessionsConfigurationService.testSetting': {
48
'type': 'string',
49
'default': 'defaultValue',
50
scope: ConfigurationScope.RESOURCE
51
},
52
'sessionsConfigurationService.machineSetting': {
53
'type': 'string',
54
'default': 'defaultValue',
55
scope: ConfigurationScope.MACHINE
56
},
57
'sessionsConfigurationService.applicationSetting': {
58
'type': 'string',
59
'default': 'defaultValue',
60
scope: ConfigurationScope.APPLICATION
61
},
62
}
63
});
64
});
65
66
setup(async () => {
67
const logService = new NullLogService();
68
fileService = disposables.add(new FileService(logService));
69
const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
70
disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider));
71
72
const environmentService = TestEnvironmentService;
73
const uriIdentityService = disposables.add(new UriIdentityService(fileService));
74
const userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService));
75
disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))));
76
userDataProfileService = disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile));
77
78
const configResource = joinPath(ROOT, 'agent-sessions.code-workspace');
79
await fileService.writeFile(configResource, VSBuffer.fromString(JSON.stringify({ folders: [] })));
80
81
workspaceService = disposables.add(new SessionsWorkspaceContextService(getWorkspaceIdentifier(configResource), uriIdentityService));
82
testObject = disposables.add(new ConfigurationService(userDataProfileService, workspaceService, uriIdentityService, fileService, new NullPolicyService(), logService));
83
await testObject.initialize();
84
});
85
86
// #region Reading
87
88
test('defaults', () => {
89
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
90
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'defaultValue');
91
assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting'), 'defaultValue');
92
});
93
94
test('user settings override defaults', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
95
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
96
await testObject.reloadConfiguration();
97
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');
98
}));
99
100
test('workspace folder settings override user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
101
const folder = joinPath(ROOT, 'myFolder');
102
await fileService.createFolder(folder);
103
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
104
await testObject.reloadConfiguration();
105
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
106
await workspaceService.addFolders([{ uri: folder }]);
107
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
108
}));
109
110
test('folder settings are read when folders are added', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
111
const folder = joinPath(ROOT, 'addedFolder');
112
await fileService.createFolder(folder);
113
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
114
await workspaceService.addFolders([{ uri: folder }]);
115
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
116
}));
117
118
test('folder settings are removed when folders are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
119
const folder = joinPath(ROOT, 'removedFolder');
120
await fileService.createFolder(folder);
121
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
122
await workspaceService.addFolders([{ uri: folder }]);
123
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
124
await workspaceService.removeFolders([folder]);
125
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
126
}));
127
128
test('configuration change event is fired when folders with settings are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
129
const folder = joinPath(ROOT, 'removedFolder2');
130
await fileService.createFolder(folder);
131
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
132
await workspaceService.addFolders([{ uri: folder }]);
133
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
134
135
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
136
await workspaceService.removeFolders([folder]);
137
const event = await promise;
138
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
139
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
140
}));
141
142
test('configuration change event is fired on user settings change', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
143
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
144
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
145
await testObject.reloadConfiguration();
146
const event = await promise;
147
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
148
}));
149
150
test('inspect returns correct values per layer', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
151
const folder = joinPath(ROOT, 'inspectFolder');
152
await fileService.createFolder(folder);
153
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
154
await testObject.reloadConfiguration();
155
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
156
await workspaceService.addFolders([{ uri: folder }]);
157
158
const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });
159
assert.strictEqual(inspection.defaultValue, 'defaultValue');
160
assert.strictEqual(inspection.userValue, 'userValue');
161
assert.strictEqual(inspection.workspaceFolderValue, 'folderValue');
162
}));
163
164
test('application settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
165
const folder = joinPath(ROOT, 'appFolder');
166
await fileService.createFolder(folder);
167
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.applicationSetting": "folderValue" }'));
168
await workspaceService.addFolders([{ uri: folder }]);
169
assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting', { resource: folder }), 'defaultValue');
170
}));
171
172
test('machine settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
173
const folder = joinPath(ROOT, 'machineFolder');
174
await fileService.createFolder(folder);
175
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.machineSetting": "folderValue" }'));
176
await workspaceService.addFolders([{ uri: folder }]);
177
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting', { resource: folder }), 'defaultValue');
178
}));
179
180
test('folder settings change fires configuration change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
181
const folder = joinPath(ROOT, 'changeFolder');
182
await fileService.createFolder(folder);
183
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "initialValue" }'));
184
await workspaceService.addFolders([{ uri: folder }]);
185
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'initialValue');
186
187
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
188
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "updatedValue" }'));
189
const event = await promise;
190
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
191
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'updatedValue');
192
}));
193
194
// #endregion
195
196
// #region Writing
197
198
test('updateValue writes to user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
199
await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenValue');
200
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'writtenValue');
201
}));
202
203
test('updateValue persists to settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
204
await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedValue');
205
206
const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();
207
assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));
208
assert.ok(content.includes('persistedValue'));
209
}));
210
211
test('updateValue fires change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
212
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
213
await testObject.updateValue('sessionsConfigurationService.testSetting', 'eventValue');
214
const event = await promise;
215
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
216
}));
217
218
test('updateValue removes setting when value equals default', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
219
await testObject.updateValue('sessionsConfigurationService.testSetting', 'nonDefault');
220
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'nonDefault');
221
222
await testObject.updateValue('sessionsConfigurationService.testSetting', 'defaultValue');
223
const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();
224
assert.ok(!content.includes('sessionsConfigurationService.testSetting'));
225
}));
226
227
test('updateValue can update multiple settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
228
await testObject.updateValue('sessionsConfigurationService.testSetting', 'value1');
229
await testObject.updateValue('sessionsConfigurationService.machineSetting', 'value2');
230
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'value1');
231
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'value2');
232
}));
233
234
test('updateValue with language override', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
235
await testObject.updateValue('sessionsConfigurationService.testSetting', 'langValue', { overrideIdentifier: 'jsonc' });
236
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { overrideIdentifier: 'jsonc' }), 'langValue');
237
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
238
}));
239
240
test('updateValue is reflected in inspect', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
241
await testObject.updateValue('sessionsConfigurationService.testSetting', 'inspectedValue');
242
const inspection = testObject.inspect('sessionsConfigurationService.testSetting');
243
assert.strictEqual(inspection.defaultValue, 'defaultValue');
244
assert.strictEqual(inspection.userValue, 'inspectedValue');
245
}));
246
247
// #endregion
248
249
// #region Workspace Folder - Read and Write
250
251
test('read setting from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
252
const folder = joinPath(ROOT, 'readFolder');
253
await fileService.createFolder(folder);
254
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
255
256
await workspaceService.addFolders([{ uri: folder }]);
257
258
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
259
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
260
}));
261
262
test('write setting to workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
263
const folder = joinPath(ROOT, 'writeFolder');
264
await fileService.createFolder(folder);
265
266
await workspaceService.addFolders([{ uri: folder }]);
267
268
await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
269
270
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'writtenFolderValue');
271
}));
272
273
test('write setting to workspace folder persists to folder settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
274
const folder = joinPath(ROOT, 'persistFolder');
275
await fileService.createFolder(folder);
276
277
await workspaceService.addFolders([{ uri: folder }]);
278
279
await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
280
281
const content = (await fileService.readFile(joinPath(folder, '.vscode', 'settings.json'))).value.toString();
282
assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));
283
assert.ok(content.includes('persistedFolderValue'));
284
}));
285
286
test('write setting to workspace folder does not affect user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
287
const folder = joinPath(ROOT, 'isolateFolder');
288
await fileService.createFolder(folder);
289
290
await workspaceService.addFolders([{ uri: folder }]);
291
292
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderOnly', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
293
294
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderOnly');
295
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
296
}));
297
298
test('workspace folder setting overrides user setting for resource', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
299
const folder = joinPath(ROOT, 'overrideFolder');
300
await fileService.createFolder(folder);
301
302
await workspaceService.addFolders([{ uri: folder }]);
303
304
await testObject.updateValue('sessionsConfigurationService.testSetting', 'userValue');
305
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
306
307
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
308
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');
309
}));
310
311
test('inspect shows workspace folder value after write', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
312
const folder = joinPath(ROOT, 'inspectWriteFolder');
313
await fileService.createFolder(folder);
314
315
await workspaceService.addFolders([{ uri: folder }]);
316
317
await testObject.updateValue('sessionsConfigurationService.testSetting', 'userVal');
318
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderVal', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
319
320
const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });
321
assert.strictEqual(inspection.defaultValue, 'defaultValue');
322
assert.strictEqual(inspection.userValue, 'userVal');
323
assert.strictEqual(inspection.workspaceFolderValue, 'folderVal');
324
}));
325
326
test('removing folder clears its written settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
327
const folder = joinPath(ROOT, 'clearFolder');
328
await fileService.createFolder(folder);
329
330
await workspaceService.addFolders([{ uri: folder }]);
331
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
332
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
333
334
await workspaceService.removeFolders([folder]);
335
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
336
}));
337
338
// #endregion
339
});
340
341