mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)
* Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d * Fix vs unit tests and hygiene issue * Fix strict null check issue
This commit is contained in:
@@ -131,11 +131,13 @@ export interface IDefaultConfigurationExtension {
|
||||
defaults: { [key: string]: {} };
|
||||
}
|
||||
|
||||
export const allSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
|
||||
export const applicationSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
|
||||
export const machineSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
|
||||
export const windowSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
|
||||
export const resourceSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
|
||||
type SettingProperties = { [key: string]: any };
|
||||
|
||||
export const allSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
|
||||
export const applicationSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
|
||||
export const machineSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
|
||||
export const windowSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
|
||||
export const resourceSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
|
||||
|
||||
export const editorConfigurationSchemaId = 'vscode://schemas/settings/editor';
|
||||
const contributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ConfigurationModelParser, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { ConfigWatcher } from 'vs/base/node/config';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
export class NodeBasedUserConfiguration extends Disposable {
|
||||
|
||||
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser>;
|
||||
private initializePromise: Promise<void>;
|
||||
|
||||
private readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
|
||||
readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
|
||||
|
||||
constructor(private settingsPath: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize(): Promise<ConfigurationModel> {
|
||||
if (!this.initializePromise) {
|
||||
this.initializePromise = new Promise<void>((c, e) => {
|
||||
this.userConfigModelWatcher = new ConfigWatcher(this.settingsPath, {
|
||||
changeBufferDelay: 300, onError: error => onUnexpectedError(error), defaultConfig: new ConfigurationModelParser(this.settingsPath), parse: (content: string, parseErrors: any[]) => {
|
||||
const userConfigModelParser = new ConfigurationModelParser(this.settingsPath);
|
||||
userConfigModelParser.parseContent(content);
|
||||
parseErrors = [...userConfigModelParser.errors];
|
||||
return userConfigModelParser;
|
||||
}, initCallback: () => c(undefined)
|
||||
});
|
||||
this._register(this.userConfigModelWatcher);
|
||||
|
||||
// Listeners
|
||||
this._register(this.userConfigModelWatcher.onDidUpdateConfiguration(() => this._onDidChangeConfiguration.fire(this.userConfigModelWatcher.getConfig().configurationModel)));
|
||||
});
|
||||
}
|
||||
return this.initializePromise.then(() => this.userConfigModelWatcher.getConfig().configurationModel);
|
||||
}
|
||||
|
||||
initializeSync(): ConfigurationModel {
|
||||
this.initialize();
|
||||
return this.userConfigModelWatcher.getConfig().configurationModel;
|
||||
}
|
||||
|
||||
reload(): Promise<ConfigurationModel> {
|
||||
return this.initialize().then(() => new Promise<ConfigurationModel>(c => this.userConfigModelWatcher.reload(userConfigModelParser => c(userConfigModelParser.configurationModel))));
|
||||
}
|
||||
|
||||
getConfigurationModel(): ConfigurationModel {
|
||||
return this.userConfigModelWatcher.getConfig().configurationModel;
|
||||
}
|
||||
}
|
||||
@@ -7,40 +7,49 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationService, IConfigurationChangeEvent, IConfigurationOverrides, ConfigurationTarget, compare, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
|
||||
import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
|
||||
import { ConfigWatcher } from 'vs/base/node/config';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
|
||||
export class ConfigurationService extends Disposable implements IConfigurationService, IDisposable {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private _configuration: Configuration;
|
||||
private userConfiguration: NodeBasedUserConfiguration;
|
||||
private configuration: Configuration;
|
||||
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser> | undefined;
|
||||
|
||||
private readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
|
||||
readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
|
||||
|
||||
constructor(
|
||||
configurationPath: string
|
||||
private readonly configurationPath: string
|
||||
) {
|
||||
super();
|
||||
|
||||
this.userConfiguration = this._register(new NodeBasedUserConfiguration(configurationPath));
|
||||
|
||||
// Initialize
|
||||
const defaults = new DefaultConfigurationModel();
|
||||
const user = this.userConfiguration.initializeSync();
|
||||
this._configuration = new Configuration(defaults, user);
|
||||
|
||||
// Listeners
|
||||
this._register(this.userConfiguration.onDidChangeConfiguration(userConfigurationModel => this.onDidChangeUserConfiguration(userConfigurationModel)));
|
||||
this.configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());
|
||||
this._register(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidUpdateConfiguration(configurationProperties => this.onDidDefaultConfigurationChange(configurationProperties)));
|
||||
}
|
||||
|
||||
get configuration(): Configuration {
|
||||
return this._configuration;
|
||||
initialize(): Promise<void> {
|
||||
if (this.userConfigModelWatcher) {
|
||||
this.userConfigModelWatcher.dispose();
|
||||
}
|
||||
|
||||
return new Promise<void>((c, e) => {
|
||||
this.userConfigModelWatcher = this._register(new ConfigWatcher(this.configurationPath, {
|
||||
changeBufferDelay: 300, onError: error => onUnexpectedError(error), defaultConfig: new ConfigurationModelParser(this.configurationPath), parse: (content: string, parseErrors: any[]) => {
|
||||
const userConfigModelParser = new ConfigurationModelParser(this.configurationPath);
|
||||
userConfigModelParser.parseContent(content);
|
||||
parseErrors = [...userConfigModelParser.errors];
|
||||
return userConfigModelParser;
|
||||
}, initCallback: () => {
|
||||
this.configuration = new Configuration(new DefaultConfigurationModel(), this.userConfigModelWatcher!.getConfig().configurationModel);
|
||||
this._register(this.userConfigModelWatcher!.onDidUpdateConfiguration(() => this.onDidChangeUserConfiguration(this.userConfigModelWatcher!.getConfig().configurationModel)));
|
||||
c();
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
getConfigurationData(): IConfigurationData {
|
||||
@@ -85,21 +94,26 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
}
|
||||
|
||||
reloadConfiguration(folder?: IWorkspaceFolder): Promise<void> {
|
||||
return folder ? Promise.resolve(undefined) :
|
||||
this.userConfiguration.reload().then(userConfigurationModel => this.onDidChangeUserConfiguration(userConfigurationModel));
|
||||
if (this.userConfigModelWatcher) {
|
||||
return new Promise<void>(c => this.userConfigModelWatcher!.reload(userConfigModelParser => {
|
||||
this.onDidChangeUserConfiguration(userConfigModelParser.configurationModel);
|
||||
c();
|
||||
}));
|
||||
}
|
||||
return this.initialize();
|
||||
}
|
||||
|
||||
private onDidChangeUserConfiguration(userConfigurationModel: ConfigurationModel): void {
|
||||
const { added, updated, removed } = compare(this._configuration.localUserConfiguration, userConfigurationModel);
|
||||
const { added, updated, removed } = compare(this.configuration.localUserConfiguration, userConfigurationModel);
|
||||
const changedKeys = [...added, ...updated, ...removed];
|
||||
if (changedKeys.length) {
|
||||
this._configuration.updateLocalUserConfiguration(userConfigurationModel);
|
||||
this.configuration.updateLocalUserConfiguration(userConfigurationModel);
|
||||
this.trigger(changedKeys, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidDefaultConfigurationChange(keys: string[]): void {
|
||||
this._configuration.updateDefaultConfiguration(new DefaultConfigurationModel());
|
||||
this.configuration.updateDefaultConfiguration(new DefaultConfigurationModel());
|
||||
this.trigger(keys, ConfigurationTarget.DEFAULT);
|
||||
}
|
||||
|
||||
@@ -110,9 +124,9 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
private getTargetConfiguration(target: ConfigurationTarget): any {
|
||||
switch (target) {
|
||||
case ConfigurationTarget.DEFAULT:
|
||||
return this._configuration.defaults.contents;
|
||||
return this.configuration.defaults.contents;
|
||||
case ConfigurationTarget.USER:
|
||||
return this._configuration.localUserConfiguration.contents;
|
||||
return this.configuration.localUserConfiguration.contents;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, { 'a': { 'b': 2 } });
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a single segemented key', () => {
|
||||
test('removeFromValueTree: remove a single segmented key', () => {
|
||||
let target = { 'a': 1 };
|
||||
|
||||
removeFromValueTree(target, 'a');
|
||||
@@ -40,7 +40,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, {});
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a single segemented key when its value is undefined', () => {
|
||||
test('removeFromValueTree: remove a single segmented key when its value is undefined', () => {
|
||||
let target = { 'a': undefined };
|
||||
|
||||
removeFromValueTree(target, 'a');
|
||||
@@ -48,7 +48,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, {});
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key when its value is undefined', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key when its value is undefined', () => {
|
||||
let target = { 'a': { 'b': 1 } };
|
||||
|
||||
removeFromValueTree(target, 'a.b');
|
||||
@@ -56,7 +56,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, {});
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key when its value is array', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key when its value is array', () => {
|
||||
let target = { 'a': { 'b': [1] } };
|
||||
|
||||
removeFromValueTree(target, 'a.b');
|
||||
@@ -64,7 +64,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, {});
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key first segment value is array', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key first segment value is array', () => {
|
||||
let target = { 'a': [1] };
|
||||
|
||||
removeFromValueTree(target, 'a.0');
|
||||
@@ -80,7 +80,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, {});
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key when the first node has more values', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key when the first node has more values', () => {
|
||||
let target = { 'a': { 'b': { 'c': 1 }, 'd': 1 } };
|
||||
|
||||
removeFromValueTree(target, 'a.b.c');
|
||||
@@ -88,7 +88,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, { 'a': { 'd': 1 } });
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key when in between node has more values', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key when in between node has more values', () => {
|
||||
let target = { 'a': { 'b': { 'c': { 'd': 1 }, 'd': 1 } } };
|
||||
|
||||
removeFromValueTree(target, 'a.b.c.d');
|
||||
@@ -96,7 +96,7 @@ suite('Configuration', () => {
|
||||
assert.deepEqual(target, { 'a': { 'b': { 'd': 1 } } });
|
||||
});
|
||||
|
||||
test('removeFromValueTree: remove a multi segemented key when the last but one node has more values', () => {
|
||||
test('removeFromValueTree: remove a multi segmented key when the last but one node has more values', () => {
|
||||
let target = { 'a': { 'b': { 'c': 1, 'd': 1 } } };
|
||||
|
||||
removeFromValueTree(target, 'a.b.c');
|
||||
|
||||
@@ -82,7 +82,7 @@ suite('ConfigurationModel', () => {
|
||||
assert.deepEqual(testObject.keys, ['a.b']);
|
||||
});
|
||||
|
||||
test('removeValue: remove a single segemented key', () => {
|
||||
test('removeValue: remove a single segmented key', () => {
|
||||
let testObject = new ConfigurationModel({ 'a': 1 }, ['a']);
|
||||
|
||||
testObject.removeValue('a');
|
||||
@@ -91,7 +91,7 @@ suite('ConfigurationModel', () => {
|
||||
assert.deepEqual(testObject.keys, []);
|
||||
});
|
||||
|
||||
test('removeValue: remove a multi segemented key', () => {
|
||||
test('removeValue: remove a multi segmented key', () => {
|
||||
let testObject = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b']);
|
||||
|
||||
testObject.removeValue('a.b');
|
||||
|
||||
@@ -21,6 +21,7 @@ suite('ConfigurationService - Node', () => {
|
||||
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
|
||||
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
await service.initialize();
|
||||
const config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -38,6 +39,7 @@ suite('ConfigurationService - Node', () => {
|
||||
fs.writeFileSync(res.testFile, '{ "testworkbench.editor.tabs": true }');
|
||||
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
await service.initialize();
|
||||
const config = service.getValue<{
|
||||
testworkbench: {
|
||||
editor: {
|
||||
@@ -60,6 +62,7 @@ suite('ConfigurationService - Node', () => {
|
||||
fs.writeFileSync(res.testFile, ',,,,');
|
||||
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
await service.initialize();
|
||||
const config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -69,13 +72,14 @@ suite('ConfigurationService - Node', () => {
|
||||
return res.cleanUp();
|
||||
});
|
||||
|
||||
test('missing file does not explode', () => {
|
||||
test('missing file does not explode', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'config', id);
|
||||
const testFile = path.join(newDir, 'config.json');
|
||||
|
||||
const service = new ConfigurationService(testFile);
|
||||
await service.initialize();
|
||||
|
||||
const config = service.getValue<{ foo: string }>();
|
||||
assert.ok(config);
|
||||
@@ -87,6 +91,7 @@ suite('ConfigurationService - Node', () => {
|
||||
const res = await testFile('config', 'config.json');
|
||||
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
await service.initialize();
|
||||
return new Promise((c, e) => {
|
||||
service.onDidChangeConfiguration(() => {
|
||||
assert.equal(service.getValue('foo'), 'bar');
|
||||
@@ -104,6 +109,7 @@ suite('ConfigurationService - Node', () => {
|
||||
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
|
||||
|
||||
const service = new ConfigurationService(res.testFile);
|
||||
await service.initialize();
|
||||
let config = service.getValue<{
|
||||
foo: string;
|
||||
}>();
|
||||
@@ -130,7 +136,7 @@ suite('ConfigurationService - Node', () => {
|
||||
return res.cleanUp();
|
||||
});
|
||||
|
||||
test('model defaults', () => {
|
||||
test('model defaults', async () => {
|
||||
interface ITestSetting {
|
||||
configuration: {
|
||||
service: {
|
||||
@@ -152,6 +158,7 @@ suite('ConfigurationService - Node', () => {
|
||||
});
|
||||
|
||||
let serviceWithoutFile = new ConfigurationService('__testFile');
|
||||
await serviceWithoutFile.initialize();
|
||||
let setting = serviceWithoutFile.getValue<ITestSetting>();
|
||||
|
||||
assert.ok(setting);
|
||||
@@ -194,6 +201,8 @@ suite('ConfigurationService - Node', () => {
|
||||
|
||||
const r = await testFile('config', 'config.json');
|
||||
const service = new ConfigurationService(r.testFile);
|
||||
service.initialize();
|
||||
|
||||
let res = service.inspect('something.missing');
|
||||
assert.strictEqual(res.value, undefined);
|
||||
assert.strictEqual(res.default, undefined);
|
||||
@@ -230,6 +239,8 @@ suite('ConfigurationService - Node', () => {
|
||||
|
||||
const r = await testFile('config', 'config.json');
|
||||
const service = new ConfigurationService(r.testFile);
|
||||
service.initialize();
|
||||
|
||||
let res = service.inspect('lookup.service.testNullSetting');
|
||||
assert.strictEqual(res.default, null);
|
||||
assert.strictEqual(res.value, null);
|
||||
|
||||
Reference in New Issue
Block a user