From 399f03f668fc2be474ed8d4f155a8360cea49f1c Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 21 Sep 2016 12:41:10 +0200 Subject: [PATCH] configurationResolverService tests --- .../parts/debug/node/debugAdapter.ts | 4 +- .../node/configurationResolverService.ts | 7 +- .../node/configurationResolverService.test.ts | 210 +++++++++++++++++- 3 files changed, 214 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index dbe51351aa2..3d7b58cfcb5 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -58,11 +58,11 @@ export class Adapter { this.args = this.args || rawAdapter.args; if (this.program) { - this.program = configurationResolverService.resolve(this.program); + this.program = configurationResolverService ? configurationResolverService.resolve(this.program) : this.program; this.program = paths.join(extensionDescription.extensionFolderPath, this.program); } if (this.runtime && this.runtime.indexOf('./') === 0) { - this.runtime = configurationResolverService.resolve(this.runtime); + this.runtime = configurationResolverService ? configurationResolverService.resolve(this.runtime) : this.runtime; this.runtime = paths.join(extensionDescription.extensionFolderPath, this.runtime); } diff --git a/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts index 7197d9e3533..09f21a84492 100644 --- a/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/node/configurationResolverService.ts @@ -109,6 +109,7 @@ export class ConfigurationResolverService implements IConfigurationResolverServi private resolveString(value: string): string { let regexp = /\$\{(.*?)\}/g; + const originalValue = value; const resolvedString = value.replace(regexp, (match: string, name: string) => { let newValue = (this)[name]; if (types.isString(newValue)) { @@ -118,17 +119,17 @@ export class ConfigurationResolverService implements IConfigurationResolverServi } }); - return this.resolveConfigVariable(resolvedString); + return this.resolveConfigVariable(resolvedString, originalValue); } - private resolveConfigVariable(value: string): string { + private resolveConfigVariable(value: string, originalValue: string): string { let regexp = /\$\{config\.(.*?)\}/g; return value.replace(regexp, (match: string, name: string) => { let config = this.configurationService.getConfiguration(); let newValue = new Function('_', 'try {return _.' + name + ';} catch (ex) { return "";}')(config); if (types.isString(newValue)) { // Prevent infinite recursion and also support nested references (or tokens) - return newValue === value ? '' : this.resolveString(newValue); + return newValue === originalValue ? '' : this.resolveString(newValue); } else { return this.resolve(newValue) + ''; } diff --git a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts index cdd8f723993..cf17d8f11a9 100644 --- a/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts @@ -4,9 +4,215 @@ *--------------------------------------------------------------------------------------------*/ import assert = require('assert'); +import uri from 'vs/base/common/uri'; +import platform = require('vs/base/common/platform'); +import {IConfigurationService, getConfigurationValue} from 'vs/platform/configuration/common/configuration'; +import {IConfigurationResolverService} from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import {ConfigurationResolverService} from 'vs/workbench/services/configurationResolver/node/configurationResolverService'; +import {TestEnvironmentService, TestConfigurationService, TestEditorService} from 'vs/test/utils/servicesTestUtils'; +import {TPromise} from 'vs/base/common/winjs.base'; suite('Configuration Resolver Service', () => { - test('fake', () => { - assert.equal(true, true); + let configurationResolverService: IConfigurationResolverService; + let envVariables: { [key: string]: string } = { key1: 'Value for Key1', key2: 'Value for Key2' }; + + setup(() => { + configurationResolverService = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, new TestConfigurationService()); + }); + + teardown(() => { + configurationResolverService = null; + }); + + + test('substitute one', () => { + if (platform.isWindows) { + assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} xyz'), 'abc \\VSCode\\workspaceLocation xyz'); + } else { + assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} xyz'), 'abc /VSCode/workspaceLocation xyz'); + } + }); + + test('substitute many', () => { + if (platform.isWindows) { + assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot}'), '\\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation'); + } else { + assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot}'), '/VSCode/workspaceLocation - /VSCode/workspaceLocation'); + } + }); + + test('substitute one env variable', () => { + if (platform.isWindows) { + assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env.key1} xyz'), 'abc \\VSCode\\workspaceLocation Value for Key1 xyz'); + } else { + assert.strictEqual(configurationResolverService.resolve('abc ${workspaceRoot} ${env.key1} xyz'), 'abc /VSCode/workspaceLocation Value for Key1 xyz'); + } + }); + + test('substitute many env variable', () => { + if (platform.isWindows) { + assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), '\\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2'); + } else { + assert.strictEqual(configurationResolverService.resolve('${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), '/VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2'); + } + }); + + test('substitute one configuration variable', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} xyz'), 'abc foo xyz'); + }); + + test('substitute many configuration variables', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz'); + }); + + test('substitute nested configuration variables', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo ${workspaceRoot} ${config.terminal.integrated.fontFamily}' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + if (platform.isWindows) { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz'); + } else { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz'); + } + }); + + test('substitute accidental self referenced configuration variables', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo ${workspaceRoot} ${config.terminal.integrated.fontFamily} ${config.editor.fontFamily}' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + if (platform.isWindows) { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo \\VSCode\\workspaceLocation bar bar xyz'); + } else { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} xyz'), 'abc foo /VSCode/workspaceLocation bar bar xyz'); + } + }); + + test('substitute one env variable and a configuration variable', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + if (platform.isWindows) { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${workspaceRoot} ${env.key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for Key1 xyz'); + } else { + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${workspaceRoot} ${env.key1} xyz'), 'abc foo /VSCode/workspaceLocation Value for Key1 xyz'); + } + }); + + test('substitute many env variable and a configuration variable', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo' + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + if (platform.isWindows) { + assert.strictEqual(service.resolve('${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for Key1 - Value for Key2'); + } else { + assert.strictEqual(service.resolve('${config.editor.fontFamily} ${config.terminal.integrated.fontFamily} ${workspaceRoot} - ${workspaceRoot} ${env.key1} - ${env.key2}'), 'foo bar /VSCode/workspaceLocation - /VSCode/workspaceLocation Value for Key1 - Value for Key2'); + } + }); + + test('mixed types of configuration variables', () => { + let configurationService: IConfigurationService; + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo', + lineNumbers: 123, + insertSpaces: false + }, + terminal: { + integrated: { + fontFamily: 'bar' + } + }, + json: { + schemas: [ + { + fileMatch: [ + '{{/myfile}}', + '{{/myOtherfile}}' + ], + url: '{{schemaURL}}' + } + ] + } + }); + + let service = new ConfigurationResolverService(uri.parse('file:///VSCode/workspaceLocation'), envVariables, new TestEditorService(), TestEnvironmentService, configurationService); + assert.strictEqual(service.resolve('abc ${config.editor.fontFamily} ${config.editor.lineNumbers} ${config.editor.insertSpaces} ${config.json.schemas[0].fileMatch[1]} xyz'), 'abc foo 123 false {{/myOtherfile}} xyz'); }); }); + + +class MockConfigurationService implements IConfigurationService { + public _serviceBrand: any; + public serviceId = IConfigurationService; + public constructor(private configuration: any = {}) { } + public reloadConfiguration(section?: string): TPromise { return TPromise.as(this.getConfiguration()); } + public lookup(key: string) { return { value: getConfigurationValue(this.getConfiguration(), key), default: getConfigurationValue(this.getConfiguration(), key), user: getConfigurationValue(this.getConfiguration(), key) }; } + public getConfiguration(): any { return this.configuration; } + public onDidUpdateConfiguration() { return { dispose() { } }; } +} \ No newline at end of file -- GitLab