Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/configuration/test/browser/configurationEditing.test.ts
4780 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 * as sinon from 'sinon';
7
import assert from 'assert';
8
import * as json from '../../../../../base/common/json.js';
9
import { Event } from '../../../../../base/common/event.js';
10
import { Registry } from '../../../../../platform/registry/common/platform.js';
11
import { IEnvironmentService } from '../../../../../platform/environment/common/environment.js';
12
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';
13
import { TestEnvironmentService, TestTextFileService, workbenchInstantiationService } from '../../../../test/browser/workbenchTestServices.js';
14
import * as uuid from '../../../../../base/common/uuid.js';
15
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../../../platform/configuration/common/configurationRegistry.js';
16
import { WorkspaceService } from '../../browser/configurationService.js';
17
import { ConfigurationEditing, ConfigurationEditingErrorCode, EditableConfigurationTarget } from '../../common/configurationEditing.js';
18
import { WORKSPACE_STANDALONE_CONFIGURATIONS, FOLDER_SETTINGS_PATH, USER_STANDALONE_CONFIGURATIONS, IConfigurationCache } from '../../common/configuration.js';
19
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
20
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
21
import { ITextFileService } from '../../../textfile/common/textfiles.js';
22
import { ITextModelService } from '../../../../../editor/common/services/resolverService.js';
23
import { TextModelResolverService } from '../../../textmodelResolver/common/textModelResolverService.js';
24
import { INotificationService } from '../../../../../platform/notification/common/notification.js';
25
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
26
import { CommandService } from '../../../commands/common/commandService.js';
27
import { URI } from '../../../../../base/common/uri.js';
28
import { IRemoteAgentService } from '../../../remote/common/remoteAgentService.js';
29
import { FileService } from '../../../../../platform/files/common/fileService.js';
30
import { NullLogService } from '../../../../../platform/log/common/log.js';
31
import { Schemas } from '../../../../../base/common/network.js';
32
import { IFileService } from '../../../../../platform/files/common/files.js';
33
import { KeybindingsEditingService, IKeybindingEditingService } from '../../../keybinding/common/keybindingEditing.js';
34
import { FileUserDataProvider } from '../../../../../platform/userData/common/fileUserDataProvider.js';
35
import { UriIdentityService } from '../../../../../platform/uriIdentity/common/uriIdentityService.js';
36
import { toDisposable } from '../../../../../base/common/lifecycle.js';
37
import { InMemoryFileSystemProvider } from '../../../../../platform/files/common/inMemoryFilesystemProvider.js';
38
import { joinPath } from '../../../../../base/common/resources.js';
39
import { VSBuffer } from '../../../../../base/common/buffer.js';
40
import { RemoteAgentService } from '../../../remote/browser/remoteAgentService.js';
41
import { getSingleFolderWorkspaceIdentifier } from '../../../workspaces/browser/workspaces.js';
42
import { IUserDataProfilesService, UserDataProfilesService } from '../../../../../platform/userDataProfile/common/userDataProfile.js';
43
import { hash } from '../../../../../base/common/hash.js';
44
import { FilePolicyService } from '../../../../../platform/policy/common/filePolicyService.js';
45
import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';
46
import { UserDataProfileService } from '../../../userDataProfile/common/userDataProfileService.js';
47
import { IUserDataProfileService } from '../../../userDataProfile/common/userDataProfile.js';
48
import { IBrowserWorkbenchEnvironmentService } from '../../../environment/browser/environmentService.js';
49
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
50
import { PolicyCategory } from '../../../../../base/common/policy.js';
51
52
const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });
53
54
class ConfigurationCache implements IConfigurationCache {
55
needsCaching(resource: URI): boolean { return false; }
56
async read(): Promise<string> { return ''; }
57
async write(): Promise<void> { }
58
async remove(): Promise<void> { }
59
}
60
61
suite('ConfigurationEditing', () => {
62
63
let instantiationService: TestInstantiationService;
64
let userDataProfileService: IUserDataProfileService;
65
let environmentService: IBrowserWorkbenchEnvironmentService;
66
let fileService: IFileService;
67
let workspaceService: WorkspaceService;
68
let testObject: ConfigurationEditing;
69
70
suiteSetup(() => {
71
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
72
configurationRegistry.registerConfiguration({
73
'id': '_test',
74
'type': 'object',
75
'properties': {
76
'configurationEditing.service.testSetting': {
77
'type': 'string',
78
'default': 'isSet'
79
},
80
'configurationEditing.service.testSettingTwo': {
81
'type': 'string',
82
'default': 'isSet'
83
},
84
'configurationEditing.service.testSettingThree': {
85
'type': 'string',
86
'default': 'isSet'
87
},
88
'configurationEditing.service.policySetting': {
89
'type': 'string',
90
'default': 'isSet',
91
policy: {
92
name: 'configurationEditing.service.policySetting',
93
category: PolicyCategory.Extensions,
94
minimumVersion: '1.0.0',
95
localization: { description: { key: '', value: '' } }
96
}
97
}
98
}
99
});
100
});
101
102
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
103
104
setup(async () => {
105
disposables.add(toDisposable(() => sinon.restore()));
106
const logService = new NullLogService();
107
fileService = disposables.add(new FileService(logService));
108
const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
109
disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider));
110
111
const workspaceFolder = joinPath(ROOT, uuid.generateUuid());
112
await fileService.createFolder(workspaceFolder);
113
114
instantiationService = workbenchInstantiationService(undefined, disposables);
115
environmentService = TestEnvironmentService;
116
environmentService.policyFile = joinPath(workspaceFolder, 'policies.json');
117
instantiationService.stub(IEnvironmentService, environmentService);
118
const uriIdentityService = disposables.add(new UriIdentityService(fileService));
119
const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)));
120
userDataProfileService = disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile));
121
const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService));
122
disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))));
123
instantiationService.stub(IFileService, fileService);
124
instantiationService.stub(IRemoteAgentService, remoteAgentService);
125
workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), disposables.add(new FilePolicyService(environmentService.policyFile, fileService, logService))));
126
await workspaceService.initialize({
127
id: hash(workspaceFolder.toString()).toString(16),
128
uri: workspaceFolder
129
});
130
instantiationService.stub(IWorkspaceContextService, workspaceService);
131
132
await workspaceService.initialize(getSingleFolderWorkspaceIdentifier(workspaceFolder));
133
instantiationService.stub(IConfigurationService, workspaceService);
134
instantiationService.stub(IKeybindingEditingService, disposables.add(instantiationService.createInstance(KeybindingsEditingService)));
135
instantiationService.stub(ITextFileService, disposables.add(instantiationService.createInstance(TestTextFileService)));
136
instantiationService.stub(ITextModelService, <ITextModelService>disposables.add(instantiationService.createInstance(TextModelResolverService)));
137
instantiationService.stub(ICommandService, CommandService);
138
testObject = instantiationService.createInstance(ConfigurationEditing, null);
139
});
140
141
test('errors cases - invalid key', async () => {
142
try {
143
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' }, { donotNotifyError: true });
144
} catch (error) {
145
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY);
146
return;
147
}
148
assert.fail('Should fail with ERROR_UNKNOWN_KEY');
149
});
150
151
test('errors cases - no workspace', async () => {
152
await workspaceService.initialize({ id: uuid.generateUuid() });
153
try {
154
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true });
155
} catch (error) {
156
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_NO_WORKSPACE_OPENED);
157
return;
158
}
159
assert.fail('Should fail with ERROR_NO_WORKSPACE_OPENED');
160
});
161
162
test('errors cases - invalid configuration', async () => {
163
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString(',,,,,,,,,,,,,,'));
164
try {
165
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true });
166
} catch (error) {
167
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION);
168
return;
169
}
170
assert.fail('Should fail with ERROR_INVALID_CONFIGURATION');
171
});
172
173
test('errors cases - invalid global tasks configuration', async () => {
174
const resource = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
175
await fileService.writeFile(resource, VSBuffer.fromString(',,,,,,,,,,,,,,'));
176
try {
177
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks.configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true });
178
} catch (error) {
179
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION);
180
return;
181
}
182
assert.fail('Should fail with ERROR_INVALID_CONFIGURATION');
183
});
184
185
test('errors cases - dirty', async () => {
186
instantiationService.stub(ITextFileService, 'isDirty', true);
187
try {
188
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true });
189
} catch (error) {
190
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_DIRTY);
191
return;
192
}
193
assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.');
194
});
195
196
test('do not notify error', async () => {
197
instantiationService.stub(ITextFileService, 'isDirty', true);
198
const target = sinon.stub();
199
instantiationService.stub(INotificationService, <INotificationService>{ prompt: target, _serviceBrand: undefined, filter: false, onDidChangeFilter: undefined!, notify: null!, error: null!, info: null!, warn: null!, status: null!, setFilter: null!, getFilter: null!, getFilters: null!, removeFilter: null! });
200
try {
201
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true });
202
} catch (error) {
203
assert.strictEqual(false, target.calledOnce);
204
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_DIRTY);
205
return;
206
}
207
assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.');
208
});
209
210
test('errors cases - ERROR_POLICY_CONFIGURATION', async () => {
211
await runWithFakedTimers({ useFakeTimers: true }, async () => {
212
const promise = Event.toPromise(instantiationService.get(IConfigurationService).onDidChangeConfiguration);
213
await fileService.writeFile(environmentService.policyFile!, VSBuffer.fromString('{ "configurationEditing.service.policySetting": "policyValue" }'));
214
await promise;
215
});
216
try {
217
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.policySetting', value: 'value' }, { donotNotifyError: true });
218
} catch (error) {
219
assert.strictEqual(error.code, ConfigurationEditingErrorCode.ERROR_POLICY_CONFIGURATION);
220
return;
221
}
222
assert.fail('Should fail with ERROR_POLICY_CONFIGURATION');
223
});
224
225
test('write policy setting - when not set', async () => {
226
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.policySetting', value: 'value' }, { donotNotifyError: true });
227
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
228
const parsed = json.parse(contents.value.toString());
229
assert.strictEqual(parsed['configurationEditing.service.policySetting'], 'value');
230
});
231
232
test('write one setting - empty file', async () => {
233
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' });
234
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
235
const parsed = json.parse(contents.value.toString());
236
assert.strictEqual(parsed['configurationEditing.service.testSetting'], 'value');
237
});
238
239
test('write one setting - existing file', async () => {
240
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
241
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' });
242
243
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
244
const parsed = json.parse(contents.value.toString());
245
assert.strictEqual(parsed['configurationEditing.service.testSetting'], 'value');
246
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
247
});
248
249
test('remove an existing setting - existing file', async () => {
250
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "my.super.setting": "my.super.value", "configurationEditing.service.testSetting": "value" }'));
251
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: undefined });
252
253
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
254
const parsed = json.parse(contents.value.toString());
255
assert.deepStrictEqual(Object.keys(parsed), ['my.super.setting']);
256
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
257
});
258
259
test('remove non existing setting - existing file', async () => {
260
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
261
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: undefined });
262
263
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
264
const parsed = json.parse(contents.value.toString());
265
assert.deepStrictEqual(Object.keys(parsed), ['my.super.setting']);
266
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
267
});
268
269
test('write overridable settings to user settings', async () => {
270
const key = '[language]';
271
const value = { 'configurationEditing.service.testSetting': 'overridden value' };
272
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key, value });
273
274
const contents = await fileService.readFile(userDataProfileService.currentProfile.settingsResource);
275
const parsed = json.parse(contents.value.toString());
276
assert.deepStrictEqual(parsed[key], value);
277
});
278
279
test('write overridable settings to workspace settings', async () => {
280
const key = '[language]';
281
const value = { 'configurationEditing.service.testSetting': 'overridden value' };
282
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key, value });
283
284
const contents = await fileService.readFile(joinPath(workspaceService.getWorkspace().folders[0].uri, FOLDER_SETTINGS_PATH));
285
const parsed = json.parse(contents.value.toString());
286
assert.deepStrictEqual(parsed[key], value);
287
});
288
289
test('write overridable settings to workspace folder settings', async () => {
290
const key = '[language]';
291
const value = { 'configurationEditing.service.testSetting': 'overridden value' };
292
const folderSettingsFile = joinPath(workspaceService.getWorkspace().folders[0].uri, FOLDER_SETTINGS_PATH);
293
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE_FOLDER, { key, value }, { scopes: { resource: folderSettingsFile } });
294
295
const contents = await fileService.readFile(folderSettingsFile);
296
const parsed = json.parse(contents.value.toString());
297
assert.deepStrictEqual(parsed[key], value);
298
});
299
300
test('write workspace standalone setting - empty file', async () => {
301
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
302
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks.service.testSetting', value: 'value' });
303
304
const contents = await fileService.readFile(target);
305
const parsed = json.parse(contents.value.toString());
306
assert.strictEqual(parsed['service.testSetting'], 'value');
307
});
308
309
test('write user standalone setting - empty file', async () => {
310
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
311
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks.service.testSetting', value: 'value' });
312
313
const contents = await fileService.readFile(target);
314
const parsed = json.parse(contents.value.toString());
315
assert.strictEqual(parsed['service.testSetting'], 'value');
316
});
317
318
test('write workspace standalone setting - existing file', async () => {
319
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
320
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
321
322
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks.service.testSetting', value: 'value' });
323
324
const contents = await fileService.readFile(target);
325
const parsed = json.parse(contents.value.toString());
326
assert.strictEqual(parsed['service.testSetting'], 'value');
327
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
328
});
329
330
test('write user standalone setting - existing file', async () => {
331
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
332
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
333
334
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks.service.testSetting', value: 'value' });
335
336
const contents = await fileService.readFile(target);
337
const parsed = json.parse(contents.value.toString());
338
assert.strictEqual(parsed['service.testSetting'], 'value');
339
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
340
});
341
342
test('write user standalone mcp setting - existing file', async () => {
343
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['mcp']);
344
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
345
346
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'mcp.service.testSetting', value: 'value' });
347
348
const contents = await fileService.readFile(target);
349
const parsed = json.parse(contents.value.toString());
350
assert.strictEqual(parsed['service.testSetting'], 'value');
351
assert.strictEqual(parsed['my.super.setting'], 'my.super.value');
352
});
353
354
test('write workspace standalone setting - empty file - full JSON', async () => {
355
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
356
357
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
358
const contents = await fileService.readFile(target);
359
const parsed = json.parse(contents.value.toString());
360
assert.strictEqual(parsed['version'], '1.0.0');
361
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
362
});
363
364
test('write user standalone setting - empty file - full JSON', async () => {
365
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
366
367
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
368
const contents = await fileService.readFile(target);
369
const parsed = json.parse(contents.value.toString());
370
assert.strictEqual(parsed['version'], '1.0.0');
371
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
372
});
373
374
test('write workspace standalone setting - existing file - full JSON', async () => {
375
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
376
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
377
378
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
379
380
const contents = await fileService.readFile(target);
381
const parsed = json.parse(contents.value.toString());
382
assert.strictEqual(parsed['version'], '1.0.0');
383
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
384
});
385
386
test('write user standalone setting - existing file - full JSON', async () => {
387
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
388
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": "my.super.value" }'));
389
390
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
391
392
const contents = await fileService.readFile(target);
393
const parsed = json.parse(contents.value.toString());
394
assert.strictEqual(parsed['version'], '1.0.0');
395
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
396
});
397
398
test('write workspace standalone setting - existing file with JSON errors - full JSON', async () => {
399
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
400
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": ')); // invalid JSON
401
402
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
403
404
const contents = await fileService.readFile(target);
405
const parsed = json.parse(contents.value.toString());
406
assert.strictEqual(parsed['version'], '1.0.0');
407
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
408
});
409
410
test('write user standalone setting - existing file with JSON errors - full JSON', async () => {
411
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
412
await fileService.writeFile(target, VSBuffer.fromString('{ "my.super.setting": ')); // invalid JSON
413
414
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } });
415
416
const contents = await fileService.readFile(target);
417
const parsed = json.parse(contents.value.toString());
418
assert.strictEqual(parsed['version'], '1.0.0');
419
assert.strictEqual(parsed['tasks'][0]['taskName'], 'myTask');
420
});
421
422
test('write workspace standalone setting should replace complete file', async () => {
423
const target = joinPath(workspaceService.getWorkspace().folders[0].uri, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
424
await fileService.writeFile(target, VSBuffer.fromString(`{
425
"version": "1.0.0",
426
"tasks": [
427
{
428
"taskName": "myTask1"
429
},
430
{
431
"taskName": "myTask2"
432
}
433
]
434
}`));
435
436
await testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] } });
437
438
const actual = await fileService.readFile(target);
439
const expected = JSON.stringify({ 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] }, null, '\t');
440
assert.strictEqual(actual.value.toString(), expected);
441
});
442
443
test('write user standalone setting should replace complete file', async () => {
444
const target = joinPath(environmentService.userRoamingDataHome, USER_STANDALONE_CONFIGURATIONS['tasks']);
445
await fileService.writeFile(target, VSBuffer.fromString(`{
446
"version": "1.0.0",
447
"tasks": [
448
{
449
"taskName": "myTask1"
450
},
451
{
452
"taskName": "myTask2"
453
}
454
]
455
}`));
456
457
await testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] } });
458
459
const actual = await fileService.readFile(target);
460
const expected = JSON.stringify({ 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] }, null, '\t');
461
assert.strictEqual(actual.value.toString(), expected);
462
});
463
});
464
465