Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/configuration/test/common/configurationService.test.ts
5243 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 { VSBuffer } from '../../../../base/common/buffer.js';
8
import { Event } from '../../../../base/common/event.js';
9
import { Schemas } from '../../../../base/common/network.js';
10
import { URI } from '../../../../base/common/uri.js';
11
import { runWithFakedTimers } from '../../../../base/test/common/timeTravelScheduler.js';
12
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
13
import { ConfigurationTarget, isConfigured } from '../../common/configuration.js';
14
import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from '../../common/configurationRegistry.js';
15
import { ConfigurationService } from '../../common/configurationService.js';
16
import { IFileService } from '../../../files/common/files.js';
17
import { FileService } from '../../../files/common/fileService.js';
18
import { InMemoryFileSystemProvider } from '../../../files/common/inMemoryFilesystemProvider.js';
19
import { NullLogService } from '../../../log/common/log.js';
20
import { FilePolicyService } from '../../../policy/common/filePolicyService.js';
21
import { NullPolicyService } from '../../../policy/common/policy.js';
22
import { Registry } from '../../../registry/common/platform.js';
23
import { PolicyCategory } from '../../../../base/common/policy.js';
24
25
suite('ConfigurationService.test.ts', () => {
26
27
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
28
29
let fileService: IFileService;
30
let settingsResource: URI;
31
32
setup(async () => {
33
fileService = disposables.add(new FileService(new NullLogService()));
34
const diskFileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
35
disposables.add(fileService.registerProvider(Schemas.file, diskFileSystemProvider));
36
settingsResource = URI.file('settings.json');
37
});
38
39
test('simple', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
40
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
41
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
42
await testObject.initialize();
43
const config = testObject.getValue<{
44
foo: string;
45
}>();
46
47
assert.ok(config);
48
assert.strictEqual(config.foo, 'bar');
49
}));
50
51
test('config gets flattened', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
52
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }'));
53
54
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
55
await testObject.initialize();
56
const config = testObject.getValue<{
57
testworkbench: {
58
editor: {
59
tabs: boolean;
60
};
61
};
62
}>();
63
64
assert.ok(config);
65
assert.ok(config.testworkbench);
66
assert.ok(config.testworkbench.editor);
67
assert.strictEqual(config.testworkbench.editor.tabs, true);
68
}));
69
70
test('error case does not explode', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
71
await fileService.writeFile(settingsResource, VSBuffer.fromString(',,,,'));
72
73
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
74
await testObject.initialize();
75
const config = testObject.getValue<{
76
foo: string;
77
}>();
78
79
assert.ok(config);
80
}));
81
82
test('missing file does not explode', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
83
const testObject = disposables.add(new ConfigurationService(URI.file('__testFile'), fileService, new NullPolicyService(), new NullLogService()));
84
await testObject.initialize();
85
86
const config = testObject.getValue<{ foo: string }>();
87
88
assert.ok(config);
89
}));
90
91
test('trigger configuration change event when file does not exist', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
92
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
93
await testObject.initialize();
94
return new Promise<void>((c, e) => {
95
disposables.add(Event.filter(testObject.onDidChangeConfiguration, e => e.source === ConfigurationTarget.USER)(() => {
96
assert.strictEqual(testObject.getValue('foo'), 'bar');
97
c();
98
}));
99
fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')).catch(e);
100
});
101
102
}));
103
104
test('trigger configuration change event when file exists', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
105
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
106
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
107
await testObject.initialize();
108
109
return new Promise<void>((c) => {
110
disposables.add(Event.filter(testObject.onDidChangeConfiguration, e => e.source === ConfigurationTarget.USER)(async (e) => {
111
assert.strictEqual(testObject.getValue('foo'), 'barz');
112
c();
113
}));
114
fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "barz" }'));
115
});
116
}));
117
118
test('reloadConfiguration', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
119
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
120
121
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
122
await testObject.initialize();
123
let config = testObject.getValue<{
124
foo: string;
125
}>();
126
assert.ok(config);
127
assert.strictEqual(config.foo, 'bar');
128
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "changed" }'));
129
130
// force a reload to get latest
131
await testObject.reloadConfiguration();
132
config = testObject.getValue<{
133
foo: string;
134
}>();
135
assert.ok(config);
136
assert.strictEqual(config.foo, 'changed');
137
}));
138
139
test('model defaults', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
140
interface ITestSetting {
141
configuration: {
142
service: {
143
testSetting: string;
144
};
145
};
146
}
147
148
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
149
configurationRegistry.registerConfiguration({
150
'id': '_test',
151
'type': 'object',
152
'properties': {
153
'configuration.service.testSetting': {
154
'type': 'string',
155
'default': 'isSet'
156
}
157
}
158
});
159
160
let testObject = disposables.add(new ConfigurationService(URI.file('__testFile'), fileService, new NullPolicyService(), new NullLogService()));
161
await testObject.initialize();
162
let setting = testObject.getValue<ITestSetting>();
163
164
assert.ok(setting);
165
assert.strictEqual(setting.configuration.service.testSetting, 'isSet');
166
167
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "testworkbench.editor.tabs": true }'));
168
testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
169
await testObject.initialize();
170
171
setting = testObject.getValue<ITestSetting>();
172
173
assert.ok(setting);
174
assert.strictEqual(setting.configuration.service.testSetting, 'isSet');
175
176
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "configuration.service.testSetting": "isChanged" }'));
177
178
await testObject.reloadConfiguration();
179
setting = testObject.getValue<ITestSetting>();
180
assert.ok(setting);
181
assert.strictEqual(setting.configuration.service.testSetting, 'isChanged');
182
}));
183
184
test('lookup', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
185
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
186
configurationRegistry.registerConfiguration({
187
'id': '_test',
188
'type': 'object',
189
'properties': {
190
'lookup.service.testSetting': {
191
'type': 'string',
192
'default': 'isSet'
193
}
194
}
195
});
196
197
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
198
await testObject.initialize();
199
200
let res = testObject.inspect('something.missing');
201
assert.strictEqual(res.value, undefined);
202
assert.strictEqual(res.defaultValue, undefined);
203
assert.strictEqual(res.userValue, undefined);
204
assert.strictEqual(isConfigured(res), false);
205
206
res = testObject.inspect('lookup.service.testSetting');
207
assert.strictEqual(res.defaultValue, 'isSet');
208
assert.strictEqual(res.value, 'isSet');
209
assert.strictEqual(res.userValue, undefined);
210
assert.strictEqual(isConfigured(res), false);
211
212
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "lookup.service.testSetting": "bar" }'));
213
214
await testObject.reloadConfiguration();
215
res = testObject.inspect('lookup.service.testSetting');
216
assert.strictEqual(res.defaultValue, 'isSet');
217
assert.strictEqual(res.userValue, 'bar');
218
assert.strictEqual(res.value, 'bar');
219
assert.strictEqual(isConfigured(res), true);
220
221
}));
222
223
test('lookup with null', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
224
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
225
configurationRegistry.registerConfiguration({
226
'id': '_testNull',
227
'type': 'object',
228
'properties': {
229
'lookup.service.testNullSetting': {
230
'type': 'null',
231
}
232
}
233
});
234
235
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
236
await testObject.initialize();
237
238
let res = testObject.inspect('lookup.service.testNullSetting');
239
assert.strictEqual(res.defaultValue, null);
240
assert.strictEqual(res.value, null);
241
assert.strictEqual(res.userValue, undefined);
242
243
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "lookup.service.testNullSetting": null }'));
244
245
await testObject.reloadConfiguration();
246
247
res = testObject.inspect('lookup.service.testNullSetting');
248
assert.strictEqual(res.defaultValue, null);
249
assert.strictEqual(res.value, null);
250
assert.strictEqual(res.userValue, null);
251
}));
252
253
test('update configuration', async () => {
254
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
255
configurationRegistry.registerConfiguration({
256
'id': '_test',
257
'type': 'object',
258
'properties': {
259
'configurationService.testSetting': {
260
'type': 'string',
261
'default': 'isSet'
262
}
263
}
264
});
265
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
266
await testObject.initialize();
267
268
await testObject.updateValue('configurationService.testSetting', 'value');
269
assert.strictEqual(testObject.getValue('configurationService.testSetting'), 'value');
270
});
271
272
test('update configuration when exist', async () => {
273
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
274
configurationRegistry.registerConfiguration({
275
'id': '_test',
276
'type': 'object',
277
'properties': {
278
'configurationService.testSetting': {
279
'type': 'string',
280
'default': 'isSet'
281
}
282
}
283
});
284
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
285
await testObject.initialize();
286
287
await testObject.updateValue('configurationService.testSetting', 'value');
288
await testObject.updateValue('configurationService.testSetting', 'updatedValue');
289
assert.strictEqual(testObject.getValue('configurationService.testSetting'), 'updatedValue');
290
});
291
292
test('update configuration to default value should remove', async () => {
293
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
294
configurationRegistry.registerConfiguration({
295
'id': '_test',
296
'type': 'object',
297
'properties': {
298
'configurationService.testSetting': {
299
'type': 'string',
300
'default': 'isSet'
301
}
302
}
303
});
304
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
305
await testObject.initialize();
306
307
await testObject.updateValue('configurationService.testSetting', 'value');
308
await testObject.updateValue('configurationService.testSetting', 'isSet');
309
const inspect = testObject.inspect('configurationService.testSetting');
310
311
assert.strictEqual(inspect.userValue, undefined);
312
});
313
314
test('update configuration should remove when undefined is passed', async () => {
315
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
316
configurationRegistry.registerConfiguration({
317
'id': '_test',
318
'type': 'object',
319
'properties': {
320
'configurationService.testSetting': {
321
'type': 'string',
322
'default': 'isSet'
323
}
324
}
325
});
326
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
327
await testObject.initialize();
328
329
await testObject.updateValue('configurationService.testSetting', 'value');
330
await testObject.updateValue('configurationService.testSetting', undefined);
331
const inspect = testObject.inspect('configurationService.testSetting');
332
333
assert.strictEqual(inspect.userValue, undefined);
334
});
335
336
test('update unknown configuration', async () => {
337
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
338
await testObject.initialize();
339
340
await testObject.updateValue('configurationService.unknownSetting', 'value');
341
assert.strictEqual(testObject.getValue('configurationService.unknownSetting'), 'value');
342
});
343
344
test('update configuration in non user target throws error', async () => {
345
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
346
configurationRegistry.registerConfiguration({
347
'id': '_test',
348
'type': 'object',
349
'properties': {
350
'configurationService.testSetting': {
351
'type': 'string',
352
'default': 'isSet'
353
}
354
}
355
});
356
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, new NullPolicyService(), new NullLogService()));
357
await testObject.initialize();
358
359
try {
360
await testObject.updateValue('configurationService.testSetting', 'value', ConfigurationTarget.WORKSPACE);
361
assert.fail('Should fail with error');
362
} catch (e) {
363
// succeess
364
}
365
});
366
367
test('update configuration throws error for policy setting', async () => {
368
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
369
configurationRegistry.registerConfiguration({
370
'id': '_test',
371
'type': 'object',
372
'properties': {
373
'configurationService.policySetting': {
374
'type': 'string',
375
'default': 'isSet',
376
policy: {
377
name: 'configurationService.policySetting',
378
category: PolicyCategory.Extensions,
379
minimumVersion: '1.0.0',
380
localization: { description: { key: '', value: '' }, }
381
}
382
}
383
}
384
});
385
386
const logService = new NullLogService();
387
const policyFile = URI.file('policies.json');
388
await fileService.writeFile(policyFile, VSBuffer.fromString('{ "configurationService.policySetting": "policyValue" }'));
389
const policyService = disposables.add(new FilePolicyService(policyFile, fileService, logService));
390
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService, policyService, logService));
391
await testObject.initialize();
392
393
try {
394
await testObject.updateValue('configurationService.policySetting', 'value');
395
assert.fail('Should throw error');
396
} catch (error) {
397
// succeess
398
}
399
});
400
});
401
402