configurationEditingService.test.ts 13.1 KB
Newer Older
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

S
Sandeep Somavarapu 已提交
8
import * as sinon from 'sinon';
9 10 11 12 13
import assert = require('assert');
import os = require('os');
import path = require('path');
import fs = require('fs');
import * as json from 'vs/base/common/json';
J
Johannes Rieken 已提交
14
import { TPromise } from 'vs/base/common/winjs.base';
15
import { Registry } from 'vs/platform/registry/common/platform';
S
Sandeep Somavarapu 已提交
16
import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment';
J
Joao Moreno 已提交
17
import { parseArgs } from 'vs/platform/environment/node/argv';
18
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
J
Johannes Rieken 已提交
19
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
20
import extfs = require('vs/base/node/extfs');
S
Sandeep Somavarapu 已提交
21
import { TestTextFileService, TestTextResourceConfigurationService, workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
22
import uuid = require('vs/base/common/uuid');
J
Johannes Rieken 已提交
23
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
24
import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService';
J
Johannes Rieken 已提交
25
import { FileService } from 'vs/workbench/services/files/node/fileService';
S
Sandeep Somavarapu 已提交
26
import { ConfigurationEditingService, ConfigurationEditingError, ConfigurationEditingErrorCode } from 'vs/workbench/services/configuration/node/configurationEditingService';
J
Johannes Rieken 已提交
27
import { IFileService } from 'vs/platform/files/common/files';
28
import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration';
S
Sandeep Somavarapu 已提交
29
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
S
Sandeep Somavarapu 已提交
30 31
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
32
import { ITextModelService } from 'vs/editor/common/services/resolverService';
S
Sandeep Somavarapu 已提交
33
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
S
Sandeep Somavarapu 已提交
34
import { IChoiceService } from 'vs/platform/message/common/message';
B
Benjamin Pasero 已提交
35
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
36
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
37
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
38 39 40 41 42 43 44 45 46 47

class SettingsTestEnvironmentService extends EnvironmentService {

	constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome) {
		super(args, _execPath);
	}

	get appSettingsPath(): string { return this.customAppSettingsHome; }
}

S
Sandeep Somavarapu 已提交
48 49
suite('ConfigurationEditingService', () => {

S
Sandeep Somavarapu 已提交
50
	let instantiationService: TestInstantiationService;
S
Sandeep Somavarapu 已提交
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
	let testObject: ConfigurationEditingService;
	let parentDir;
	let workspaceDir;
	let globalSettingsFile;
	let workspaceSettingsDir;

	suiteSetup(() => {
		const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
		configurationRegistry.registerConfiguration({
			'id': '_test',
			'type': 'object',
			'properties': {
				'configurationEditing.service.testSetting': {
					'type': 'string',
					'default': 'isSet'
				},
				'configurationEditing.service.testSettingTwo': {
					'type': 'string',
					'default': 'isSet'
				},
				'configurationEditing.service.testSettingThree': {
					'type': 'string',
					'default': 'isSet'
				}
			}
		});
	});
78

S
Sandeep Somavarapu 已提交
79 80 81 82
	setup(() => {
		return setUpWorkspace()
			.then(() => setUpServices());
	});
83

S
Sandeep Somavarapu 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97
	function setUpWorkspace(): TPromise<void> {
		return new TPromise<void>((c, e) => {
			const id = uuid.generateUuid();
			parentDir = path.join(os.tmpdir(), 'vsctests', id);
			workspaceDir = path.join(parentDir, 'workspaceconfig', id);
			globalSettingsFile = path.join(workspaceDir, 'config.json');
			workspaceSettingsDir = path.join(workspaceDir, '.vscode');
			extfs.mkdirp(workspaceSettingsDir, 493, (error) => {
				if (error) {
					e(error);
				} else {
					c(null);
				}
			});
98 99 100
		});
	}

S
Sandeep Somavarapu 已提交
101
	function setUpServices(noWorkspace: boolean = false): TPromise<void> {
102 103 104
		// Clear services if they are already created
		clearServices();

S
Sandeep Somavarapu 已提交
105
		instantiationService = <TestInstantiationService>workbenchInstantiationService();
106 107
		const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile);
		instantiationService.stub(IEnvironmentService, environmentService);
108
		const workspacesService = instantiationService.stub(IWorkspacesService, {});
S
Sandeep Somavarapu 已提交
109
		const workspaceService = new WorkspaceService(environmentService, workspacesService);
110
		instantiationService.stub(IWorkspaceContextService, workspaceService);
111
		return workspaceService.initialize(noWorkspace ? <IWindowConfiguration>{} : workspaceDir).then(() => {
112 113 114 115 116 117
			instantiationService.stub(IConfigurationService, workspaceService);
			instantiationService.stub(IFileService, new FileService(workspaceService, new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }));
			instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
			instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
			testObject = instantiationService.createInstance(ConfigurationEditingService);
		});
118 119
	}

S
Sandeep Somavarapu 已提交
120
	teardown(() => {
121
		clearServices();
S
Sandeep Somavarapu 已提交
122
		return clearWorkspace();
123 124
	});

125 126
	function clearServices(): void {
		if (instantiationService) {
127
			const configuraitonService = <WorkspaceService>instantiationService.get(IConfigurationService);
128 129 130 131 132 133 134
			if (configuraitonService) {
				configuraitonService.dispose();
			}
			instantiationService = null;
		}
	}

S
Sandeep Somavarapu 已提交
135 136 137
	function clearWorkspace(): TPromise<void> {
		return new TPromise<void>((c, e) => {
			if (parentDir) {
138
				extfs.del(parentDir, os.tmpdir(), () => c(null), () => c(null));
S
Sandeep Somavarapu 已提交
139 140
			} else {
				c(null);
141
			}
142
		}).then(() => parentDir = null);
S
Sandeep Somavarapu 已提交
143
	}
144

S
Sandeep Somavarapu 已提交
145 146 147
	test('errors cases - invalid key', () => {
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' })
			.then(() => assert.fail('Should fail with ERROR_UNKNOWN_KEY'),
148
			(error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY));
149 150
	});

S
Sandeep Somavarapu 已提交
151 152 153
	test('errors cases - invalid target', () => {
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'tasks.something', value: 'value' })
			.then(() => assert.fail('Should fail with ERROR_INVALID_TARGET'),
S
Sandeep Somavarapu 已提交
154
			(error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_USER_TARGET));
155 156
	});

S
Sandeep Somavarapu 已提交
157 158 159 160
	test('errors cases - no workspace', () => {
		return setUpServices(true)
			.then(() => testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'configurationEditing.service.testSetting', value: 'value' }))
			.then(() => assert.fail('Should fail with ERROR_NO_WORKSPACE_OPENED'),
161
			(error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_NO_WORKSPACE_OPENED));
162 163
	});

S
Sandeep Somavarapu 已提交
164 165 166 167
	test('errors cases - invalid configuration', () => {
		fs.writeFileSync(globalSettingsFile, ',,,,,,,,,,,,,,');
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' })
			.then(() => assert.fail('Should fail with ERROR_INVALID_CONFIGURATION'),
168
			(error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION));
169 170
	});

S
Sandeep Somavarapu 已提交
171 172 173 174
	test('errors cases - dirty', () => {
		instantiationService.stub(ITextFileService, 'isDirty', true);
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' })
			.then(() => assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.'),
175
			(error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_DIRTY));
176 177
	});

S
Sandeep Somavarapu 已提交
178 179 180 181 182 183 184 185 186 187 188 189
	test('dirty error is not thrown if not asked to save', () => {
		instantiationService.stub(ITextFileService, 'isDirty', true);
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotSave: true })
			.then(() => null, error => assert.fail('Should not fail.'));
	});

	test('do not notify error', () => {
		instantiationService.stub(ITextFileService, 'isDirty', true);
		const target = sinon.stub();
		instantiationService.stubPromise(IChoiceService, 'choose', target);
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true })
			.then(() => assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.'),
190
			(error: ConfigurationEditingError) => {
S
Sandeep Somavarapu 已提交
191 192 193 194 195
				assert.equal(false, target.calledOnce);
				assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_DIRTY);
			});
	});

S
Sandeep Somavarapu 已提交
196 197 198 199 200 201 202
	test('write one setting - empty file', () => {
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' })
			.then(() => {
				const contents = fs.readFileSync(globalSettingsFile).toString('utf8');
				const parsed = json.parse(contents);
				assert.equal(parsed['configurationEditing.service.testSetting'], 'value');
			});
203 204
	});

S
Sandeep Somavarapu 已提交
205 206 207 208 209 210 211 212 213
	test('write one setting - existing file', () => {
		fs.writeFileSync(globalSettingsFile, '{ "my.super.setting": "my.super.value" }');
		return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' })
			.then(() => {
				const contents = fs.readFileSync(globalSettingsFile).toString('utf8');
				const parsed = json.parse(contents);
				assert.equal(parsed['configurationEditing.service.testSetting'], 'value');
				assert.equal(parsed['my.super.setting'], 'my.super.value');
			});
214
	});
215

S
Sandeep Somavarapu 已提交
216 217 218 219 220 221 222 223
	test('write workspace standalone setting - empty file', () => {
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks.service.testSetting', value: 'value' })
			.then(() => {
				const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
				const contents = fs.readFileSync(target).toString('utf8');
				const parsed = json.parse(contents);
				assert.equal(parsed['service.testSetting'], 'value');
			});
224 225
	});

S
Sandeep Somavarapu 已提交
226 227 228 229 230 231 232 233 234 235
	test('write workspace standalone setting - existing file', () => {
		const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['launch']);
		fs.writeFileSync(target, '{ "my.super.setting": "my.super.value" }');
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'launch.service.testSetting', value: 'value' })
			.then(() => {
				const contents = fs.readFileSync(target).toString('utf8');
				const parsed = json.parse(contents);
				assert.equal(parsed['service.testSetting'], 'value');
				assert.equal(parsed['my.super.setting'], 'my.super.value');
			});
236
	});
237

S
Sandeep Somavarapu 已提交
238 239 240 241 242 243 244 245 246 247 248
	test('write workspace standalone setting - empty file - full JSON', () => {
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } })
			.then(() => {
				const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
				const contents = fs.readFileSync(target).toString('utf8');
				const parsed = json.parse(contents);

				assert.equal(parsed['version'], '1.0.0');
				assert.equal(parsed['tasks'][0]['taskName'], 'myTask');
			});
	});
249

S
Sandeep Somavarapu 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262
	test('write workspace standalone setting - existing file - full JSON', () => {
		const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['launch']);
		fs.writeFileSync(target, '{ "my.super.setting": "my.super.value" }');
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } })
			.then(() => {
				const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
				const contents = fs.readFileSync(target).toString('utf8');
				const parsed = json.parse(contents);

				assert.equal(parsed['version'], '1.0.0');
				assert.equal(parsed['tasks'][0]['taskName'], 'myTask');
			});
	});
263

S
Sandeep Somavarapu 已提交
264 265 266 267 268 269 270 271 272 273 274 275
	test('write workspace standalone setting - existing file with JSON errors - full JSON', () => {
		const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['launch']);
		fs.writeFileSync(target, '{ "my.super.setting": '); // invalid JSON
		return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } })
			.then(() => {
				const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']);
				const contents = fs.readFileSync(target).toString('utf8');
				const parsed = json.parse(contents);

				assert.equal(parsed['version'], '1.0.0');
				assert.equal(parsed['tasks'][0]['taskName'], 'myTask');
			});
276
	});
277
});