Path: blob/main/src/vs/platform/configuration/test/common/configurationModels.test.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import assert from 'assert';5import { ResourceMap } from '../../../../base/common/map.js';6import { join } from '../../../../base/common/path.js';7import { URI } from '../../../../base/common/uri.js';8import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';9import { Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser, mergeChanges } from '../../common/configurationModels.js';10import { IConfigurationRegistry, Extensions, ConfigurationScope } from '../../common/configurationRegistry.js';11import { NullLogService } from '../../../log/common/log.js';12import { Registry } from '../../../registry/common/platform.js';13import { WorkspaceFolder } from '../../../workspace/common/workspace.js';14import { Workspace } from '../../../workspace/test/common/testWorkspace.js';1516suite('ConfigurationModelParser', () => {1718ensureNoDisposablesAreLeakedInTestSuite();1920suiteSetup(() => {21Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({22'id': 'ConfigurationModelParserTest',23'type': 'object',24'properties': {25'ConfigurationModelParserTest.windowSetting': {26'type': 'string',27'default': 'isSet',28}29}30});31});3233test('parse configuration model with single override identifier', () => {34const testObject = new ConfigurationModelParser('', new NullLogService());3536testObject.parse(JSON.stringify({ '[x]': { 'a': 1 } }));3738assert.deepStrictEqual(JSON.stringify(testObject.configurationModel.overrides), JSON.stringify([{ identifiers: ['x'], keys: ['a'], contents: { 'a': 1 } }]));39});4041test('parse configuration model with multiple override identifiers', () => {42const testObject = new ConfigurationModelParser('', new NullLogService());4344testObject.parse(JSON.stringify({ '[x][y]': { 'a': 1 } }));4546assert.deepStrictEqual(JSON.stringify(testObject.configurationModel.overrides), JSON.stringify([{ identifiers: ['x', 'y'], keys: ['a'], contents: { 'a': 1 } }]));47});4849test('parse configuration model with multiple duplicate override identifiers', () => {50const testObject = new ConfigurationModelParser('', new NullLogService());5152testObject.parse(JSON.stringify({ '[x][y][x][z]': { 'a': 1 } }));5354assert.deepStrictEqual(JSON.stringify(testObject.configurationModel.overrides), JSON.stringify([{ identifiers: ['x', 'y', 'z'], keys: ['a'], contents: { 'a': 1 } }]));55});5657test('parse configuration model with exclude option', () => {58const testObject = new ConfigurationModelParser('', new NullLogService());5960testObject.parse(JSON.stringify({ 'a': 1, 'b': 2 }), { exclude: ['a'] });6162assert.strictEqual(testObject.configurationModel.getValue('a'), undefined);63assert.strictEqual(testObject.configurationModel.getValue('b'), 2);64});6566test('parse configuration model with exclude option even included', () => {67const testObject = new ConfigurationModelParser('', new NullLogService());6869testObject.parse(JSON.stringify({ 'a': 1, 'b': 2 }), { exclude: ['a'], include: ['a'] });7071assert.strictEqual(testObject.configurationModel.getValue('a'), undefined);72assert.strictEqual(testObject.configurationModel.getValue('b'), 2);73});7475test('parse configuration model with scopes filter', () => {76const testObject = new ConfigurationModelParser('', new NullLogService());7778testObject.parse(JSON.stringify({ 'ConfigurationModelParserTest.windowSetting': '1' }), { scopes: [ConfigurationScope.APPLICATION] });7980assert.strictEqual(testObject.configurationModel.getValue('ConfigurationModelParserTest.windowSetting'), undefined);81});8283test('parse configuration model with include option', () => {84const testObject = new ConfigurationModelParser('', new NullLogService());8586testObject.parse(JSON.stringify({ 'ConfigurationModelParserTest.windowSetting': '1' }), { include: ['ConfigurationModelParserTest.windowSetting'], scopes: [ConfigurationScope.APPLICATION] });8788assert.strictEqual(testObject.configurationModel.getValue('ConfigurationModelParserTest.windowSetting'), '1');89});9091test('parse configuration model with invalid setting key', () => {92const testObject = new ConfigurationModelParser('', new NullLogService());9394testObject.parse(JSON.stringify({ 'a': null, 'a.b.c': { c: 1 } }));9596assert.strictEqual(testObject.configurationModel.getValue('a'), null);97assert.strictEqual(testObject.configurationModel.getValue('a.b'), undefined);98assert.strictEqual(testObject.configurationModel.getValue('a.b.c'), undefined);99});100101});102103suite('ConfigurationModelParser - Excluded Properties', () => {104105ensureNoDisposablesAreLeakedInTestSuite();106107const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);108109let testConfigurationNodes: any[] = [];110111setup(() => reset());112teardown(() => reset());113114function reset() {115if (testConfigurationNodes.length > 0) {116configurationRegistry.deregisterConfigurations(testConfigurationNodes);117testConfigurationNodes = [];118}119}120121function registerTestConfiguration() {122const node = {123'id': 'ExcludedPropertiesTest',124'type': 'object',125'properties': {126'regularProperty': {127'type': 'string' as const,128'default': 'regular',129'restricted': false130},131'restrictedProperty': {132'type': 'string' as const,133'default': 'restricted',134'restricted': true135},136'excludedProperty': {137'type': 'string' as const,138'default': 'excluded',139'restricted': true,140'included': false141},142'excludedNonRestrictedProperty': {143'type': 'string' as const,144'default': 'excludedNonRestricted',145'restricted': false,146'included': false147}148}149};150151configurationRegistry.registerConfiguration(node);152testConfigurationNodes.push(node);153return node;154}155156test('should handle excluded restricted properties correctly', () => {157registerTestConfiguration();158159const testObject = new ConfigurationModelParser('test', new NullLogService());160const testData = {161'regularProperty': 'regularValue',162'restrictedProperty': 'restrictedValue',163'excludedProperty': 'excludedValue',164'excludedNonRestrictedProperty': 'excludedNonRestrictedValue'165};166167testObject.parse(JSON.stringify(testData), { skipRestricted: true });168169assert.strictEqual(testObject.configurationModel.getValue('regularProperty'), 'regularValue');170assert.strictEqual(testObject.configurationModel.getValue('restrictedProperty'), undefined);171assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), 'excludedValue');172assert.strictEqual(testObject.configurationModel.getValue('excludedNonRestrictedProperty'), 'excludedNonRestrictedValue');173assert.ok(testObject.restrictedConfigurations.includes('restrictedProperty'));174assert.ok(!testObject.restrictedConfigurations.includes('excludedProperty'));175});176177test('should find excluded properties when checking for restricted settings', () => {178registerTestConfiguration();179180const testObject = new ConfigurationModelParser('test', new NullLogService());181const testData = {182'excludedProperty': 'excludedValue'183};184185testObject.parse(JSON.stringify(testData));186187assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), 'excludedValue');188assert.ok(!testObject.restrictedConfigurations.includes('excludedProperty'));189});190191test('should handle override properties with excluded configurations', () => {192registerTestConfiguration();193194const testObject = new ConfigurationModelParser('test', new NullLogService());195const testData = {196'[typescript]': {197'regularProperty': 'overrideRegular',198'restrictedProperty': 'overrideRestricted',199'excludedProperty': 'overrideExcluded'200}201};202203testObject.parse(JSON.stringify(testData), { skipRestricted: true });204205const overrideConfig = testObject.configurationModel.override('typescript');206assert.strictEqual(overrideConfig.getValue('regularProperty'), 'overrideRegular');207assert.strictEqual(overrideConfig.getValue('restrictedProperty'), undefined);208assert.strictEqual(overrideConfig.getValue('excludedProperty'), 'overrideExcluded');209});210211test('should handle scope filtering with excluded properties', () => {212const node = {213'id': 'ScopeExcludedTest',214'type': 'object',215'properties': {216'windowProperty': {217'type': 'string' as const,218'default': 'window',219'scope': ConfigurationScope.WINDOW220},221'applicationProperty': {222'type': 'string' as const,223'default': 'application',224'scope': ConfigurationScope.APPLICATION225},226'excludedApplicationProperty': {227'type': 'string' as const,228'default': 'excludedApplication',229'scope': ConfigurationScope.APPLICATION,230'included': false231}232}233};234235configurationRegistry.registerConfiguration(node);236testConfigurationNodes.push(node);237238const testObject = new ConfigurationModelParser('test', new NullLogService());239const testData = {240'windowProperty': 'windowValue',241'applicationProperty': 'applicationValue',242'excludedApplicationProperty': 'excludedApplicationValue'243};244245testObject.parse(JSON.stringify(testData), { scopes: [ConfigurationScope.WINDOW] });246247assert.strictEqual(testObject.configurationModel.getValue('windowProperty'), 'windowValue');248assert.strictEqual(testObject.configurationModel.getValue('applicationProperty'), undefined);249assert.strictEqual(testObject.configurationModel.getValue('excludedApplicationProperty'), undefined);250});251252test('filter should handle include/exclude options with excluded properties', () => {253registerTestConfiguration();254255const testObject = new ConfigurationModelParser('test', new NullLogService());256const testData = {257'regularProperty': 'regularValue',258'excludedProperty': 'excludedValue'259};260261testObject.parse(JSON.stringify(testData), { include: ['excludedProperty'] });262263assert.strictEqual(testObject.configurationModel.getValue('regularProperty'), 'regularValue');264assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), 'excludedValue');265});266267test('should handle exclude options with excluded properties', () => {268registerTestConfiguration();269270const testObject = new ConfigurationModelParser('test', new NullLogService());271const testData = {272'regularProperty': 'regularValue',273'excludedProperty': 'excludedValue'274};275276testObject.parse(JSON.stringify(testData), { exclude: ['regularProperty'] });277278assert.strictEqual(testObject.configurationModel.getValue('regularProperty'), undefined);279assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), 'excludedValue');280});281282test('should report hasExcludedProperties correctly when excluded properties are filtered', () => {283registerTestConfiguration();284285const testObject = new ConfigurationModelParser('test', new NullLogService());286const testData = {287'regularProperty': 'regularValue',288'restrictedProperty': 'restrictedValue',289'excludedProperty': 'excludedValue'290};291292testObject.parse(JSON.stringify(testData), { skipRestricted: true });293294const model = testObject.configurationModel;295296assert.notStrictEqual(model.raw, undefined, 'Raw should be set when properties are excluded');297});298299test('skipUnregistered should exclude unregistered properties', () => {300registerTestConfiguration();301302const testObject = new ConfigurationModelParser('test', new NullLogService());303304testObject.parse(JSON.stringify({305'unregisteredProperty': 'value3'306}), { skipUnregistered: true });307308assert.strictEqual(testObject.configurationModel.getValue('unregisteredProperty'), undefined);309});310311test('shouldInclude method works correctly with excluded properties for skipUnregistered', () => {312registerTestConfiguration();313314const testObject = new ConfigurationModelParser('test', new NullLogService());315316testObject.parse(JSON.stringify({317'regularProperty': 'value1',318'excludedProperty': 'value2',319'unregisteredProperty': 'value3'320}), { skipUnregistered: true });321322assert.strictEqual(testObject.configurationModel.getValue('regularProperty'), 'value1');323assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), undefined);324assert.strictEqual(testObject.configurationModel.getValue('unregisteredProperty'), undefined);325});326327test('excluded properties are found during property schema lookup', () => {328registerTestConfiguration();329330const registry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);331332const excludedProperties = registry.getExcludedConfigurationProperties();333assert.ok(excludedProperties['excludedProperty'], 'Excluded property should be in excluded properties map');334assert.ok(excludedProperties['excludedNonRestrictedProperty'], 'Excluded non-restricted property should be in excluded properties map');335336const regularProperties = registry.getConfigurationProperties();337assert.strictEqual(regularProperties['excludedProperty'], undefined, 'Excluded property should not be in regular properties map');338assert.strictEqual(regularProperties['excludedNonRestrictedProperty'], undefined, 'Excluded non-restricted property should not be in regular properties map');339340assert.ok(regularProperties['regularProperty'], 'Regular property should be in regular properties map');341assert.ok(regularProperties['restrictedProperty'], 'Restricted property should be in regular properties map');342});343344test('should correctly use shouldInclude with excluded properties for scope and unregistered filtering', () => {345registerTestConfiguration();346347const testObject = new ConfigurationModelParser('test', new NullLogService());348const testData = {349'regularProperty': 'regularValue',350'restrictedProperty': 'restrictedValue',351'excludedProperty': 'excludedValue',352'excludedNonRestrictedProperty': 'excludedNonRestrictedValue',353'unknownProperty': 'unknownValue'354};355356testObject.parse(JSON.stringify(testData), { skipRestricted: true });357358assert.strictEqual(testObject.configurationModel.getValue('regularProperty'), 'regularValue');359assert.strictEqual(testObject.configurationModel.getValue('restrictedProperty'), undefined);360assert.ok(testObject.restrictedConfigurations.includes('restrictedProperty'));361assert.strictEqual(testObject.configurationModel.getValue('excludedProperty'), 'excludedValue');362assert.ok(!testObject.restrictedConfigurations.includes('excludedProperty'));363assert.strictEqual(testObject.configurationModel.getValue('excludedNonRestrictedProperty'), 'excludedNonRestrictedValue');364assert.strictEqual(testObject.configurationModel.getValue('unknownProperty'), 'unknownValue');365});366});367368suite('ConfigurationModel', () => {369370ensureNoDisposablesAreLeakedInTestSuite();371372test('setValue for a key that has no sections and not defined', () => {373const testObject = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b'], [], undefined, new NullLogService());374375testObject.setValue('f', 1);376377assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 1 }, 'f': 1 });378assert.deepStrictEqual(testObject.keys, ['a.b', 'f']);379});380381test('setValue for a key that has no sections and defined', () => {382const testObject = new ConfigurationModel({ 'a': { 'b': 1 }, 'f': 1 }, ['a.b', 'f'], [], undefined, new NullLogService());383384testObject.setValue('f', 3);385386assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 1 }, 'f': 3 });387assert.deepStrictEqual(testObject.keys, ['a.b', 'f']);388});389390test('setValue for a key that has sections and not defined', () => {391const testObject = new ConfigurationModel({ 'a': { 'b': 1 }, 'f': 1 }, ['a.b', 'f'], [], undefined, new NullLogService());392393testObject.setValue('b.c', 1);394395const expected: any = {};396expected['a'] = { 'b': 1 };397expected['f'] = 1;398expected['b'] = Object.create(null);399expected['b']['c'] = 1;400assert.deepStrictEqual(testObject.contents, expected);401assert.deepStrictEqual(testObject.keys, ['a.b', 'f', 'b.c']);402});403404test('setValue for a key that has sections and defined', () => {405const testObject = new ConfigurationModel({ 'a': { 'b': 1 }, 'b': { 'c': 1 }, 'f': 1 }, ['a.b', 'b.c', 'f'], [], undefined, new NullLogService());406407testObject.setValue('b.c', 3);408409assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 1 }, 'b': { 'c': 3 }, 'f': 1 });410assert.deepStrictEqual(testObject.keys, ['a.b', 'b.c', 'f']);411});412413test('setValue for a key that has sections and sub section not defined', () => {414const testObject = new ConfigurationModel({ 'a': { 'b': 1 }, 'f': 1 }, ['a.b', 'f'], [], undefined, new NullLogService());415416testObject.setValue('a.c', 1);417418assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 1, 'c': 1 }, 'f': 1 });419assert.deepStrictEqual(testObject.keys, ['a.b', 'f', 'a.c']);420});421422test('setValue for a key that has sections and sub section defined', () => {423const testObject = new ConfigurationModel({ 'a': { 'b': 1, 'c': 1 }, 'f': 1 }, ['a.b', 'a.c', 'f'], [], undefined, new NullLogService());424425testObject.setValue('a.c', 3);426427assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 1, 'c': 3 }, 'f': 1 });428assert.deepStrictEqual(testObject.keys, ['a.b', 'a.c', 'f']);429});430431test('setValue for a key that has sections and last section is added', () => {432const testObject = new ConfigurationModel({ 'a': { 'b': {} }, 'f': 1 }, ['a.b', 'f'], [], undefined, new NullLogService());433434testObject.setValue('a.b.c', 1);435436assert.deepStrictEqual(testObject.contents, { 'a': { 'b': { 'c': 1 } }, 'f': 1 });437assert.deepStrictEqual(testObject.keys, ['a.b', 'f', 'a.b.c']);438});439440test('removeValue: remove a non existing key', () => {441const testObject = new ConfigurationModel({ 'a': { 'b': 2 } }, ['a.b'], [], undefined, new NullLogService());442443testObject.removeValue('a.b.c');444445assert.deepStrictEqual(testObject.contents, { 'a': { 'b': 2 } });446assert.deepStrictEqual(testObject.keys, ['a.b']);447});448449test('removeValue: remove a single segmented key', () => {450const testObject = new ConfigurationModel({ 'a': 1 }, ['a'], [], undefined, new NullLogService());451452testObject.removeValue('a');453454assert.deepStrictEqual(testObject.contents, {});455assert.deepStrictEqual(testObject.keys, []);456});457458test('removeValue: remove a multi segmented key', () => {459const testObject = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b'], [], undefined, new NullLogService());460461testObject.removeValue('a.b');462463assert.deepStrictEqual(testObject.contents, {});464assert.deepStrictEqual(testObject.keys, []);465});466467test('get overriding configuration model for an existing identifier', () => {468const testObject = new ConfigurationModel(469{ 'a': { 'b': 1 }, 'f': 1 }, [],470[{ identifiers: ['c'], contents: { 'a': { 'd': 1 } }, keys: ['a'] }], [], new NullLogService());471472assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1, 'd': 1 }, 'f': 1 });473});474475test('get overriding configuration model for an identifier that does not exist', () => {476const testObject = new ConfigurationModel(477{ 'a': { 'b': 1 }, 'f': 1 }, [],478[{ identifiers: ['c'], contents: { 'a': { 'd': 1 } }, keys: ['a'] }], [], new NullLogService());479480assert.deepStrictEqual(testObject.override('xyz').contents, { 'a': { 'b': 1 }, 'f': 1 });481});482483test('get overriding configuration when one of the keys does not exist in base', () => {484const testObject = new ConfigurationModel(485{ 'a': { 'b': 1 }, 'f': 1 }, [],486[{ identifiers: ['c'], contents: { 'a': { 'd': 1 }, 'g': 1 }, keys: ['a', 'g'] }], [], new NullLogService());487488assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1, 'd': 1 }, 'f': 1, 'g': 1 });489});490491test('get overriding configuration when one of the key in base is not of object type', () => {492const testObject = new ConfigurationModel(493{ 'a': { 'b': 1 }, 'f': 1 }, [],494[{ identifiers: ['c'], contents: { 'a': { 'd': 1 }, 'f': { 'g': 1 } }, keys: ['a', 'f'] }], [], new NullLogService());495496assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1, 'd': 1 }, 'f': { 'g': 1 } });497});498499test('get overriding configuration when one of the key in overriding contents is not of object type', () => {500const testObject = new ConfigurationModel(501{ 'a': { 'b': 1 }, 'f': { 'g': 1 } }, [],502[{ identifiers: ['c'], contents: { 'a': { 'd': 1 }, 'f': 1 }, keys: ['a', 'f'] }], [], new NullLogService());503504assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1, 'd': 1 }, 'f': 1 });505});506507test('get overriding configuration if the value of overriding identifier is not object', () => {508const testObject = new ConfigurationModel(509{ 'a': { 'b': 1 }, 'f': { 'g': 1 } }, [],510[{ identifiers: ['c'], contents: 'abc', keys: [] }], [], new NullLogService());511512assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1 }, 'f': { 'g': 1 } });513});514515test('get overriding configuration if the value of overriding identifier is an empty object', () => {516const testObject = new ConfigurationModel(517{ 'a': { 'b': 1 }, 'f': { 'g': 1 } }, [],518[{ identifiers: ['c'], contents: {}, keys: [] }], [], new NullLogService());519520assert.deepStrictEqual(testObject.override('c').contents, { 'a': { 'b': 1 }, 'f': { 'g': 1 } });521});522523test('simple merge', () => {524const base = new ConfigurationModel({ 'a': 1, 'b': 2 }, ['a', 'b'], [], undefined, new NullLogService());525const add = new ConfigurationModel({ 'a': 3, 'c': 4 }, ['a', 'c'], [], undefined, new NullLogService());526const result = base.merge(add);527528assert.deepStrictEqual(result.contents, { 'a': 3, 'b': 2, 'c': 4 });529assert.deepStrictEqual(result.keys, ['a', 'b', 'c']);530});531532test('recursive merge', () => {533const base = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b'], [], undefined, new NullLogService());534const add = new ConfigurationModel({ 'a': { 'b': 2 } }, ['a.b'], [], undefined, new NullLogService());535const result = base.merge(add);536537assert.deepStrictEqual(result.contents, { 'a': { 'b': 2 } });538assert.deepStrictEqual(result.getValue('a'), { 'b': 2 });539assert.deepStrictEqual(result.keys, ['a.b']);540});541542test('simple merge overrides', () => {543const base = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b'], [{ identifiers: ['c'], contents: { 'a': 2 }, keys: ['a'] }], undefined, new NullLogService());544const add = new ConfigurationModel({ 'a': { 'b': 2 } }, ['a.b'], [{ identifiers: ['c'], contents: { 'b': 2 }, keys: ['b'] }], undefined, new NullLogService());545const result = base.merge(add);546547assert.deepStrictEqual(result.contents, { 'a': { 'b': 2 } });548assert.deepStrictEqual(result.overrides, [{ identifiers: ['c'], contents: { 'a': 2, 'b': 2 }, keys: ['a', 'b'] }]);549assert.deepStrictEqual(result.override('c').contents, { 'a': 2, 'b': 2 });550assert.deepStrictEqual(result.keys, ['a.b']);551});552553test('recursive merge overrides', () => {554const base = new ConfigurationModel({ 'a': { 'b': 1 }, 'f': 1 }, ['a.b', 'f'], [{ identifiers: ['c'], contents: { 'a': { 'd': 1 } }, keys: ['a'] }], undefined, new NullLogService());555const add = new ConfigurationModel({ 'a': { 'b': 2 } }, ['a.b'], [{ identifiers: ['c'], contents: { 'a': { 'e': 2 } }, keys: ['a'] }], undefined, new NullLogService());556const result = base.merge(add);557558assert.deepStrictEqual(result.contents, { 'a': { 'b': 2 }, 'f': 1 });559assert.deepStrictEqual(result.overrides, [{ identifiers: ['c'], contents: { 'a': { 'd': 1, 'e': 2 } }, keys: ['a'] }]);560assert.deepStrictEqual(result.override('c').contents, { 'a': { 'b': 2, 'd': 1, 'e': 2 }, 'f': 1 });561assert.deepStrictEqual(result.keys, ['a.b', 'f']);562});563564test('Test contents while getting an existing property', () => {565let testObject = new ConfigurationModel({ 'a': 1 }, [], [], undefined, new NullLogService());566assert.deepStrictEqual(testObject.getValue('a'), 1);567568testObject = new ConfigurationModel({ 'a': { 'b': 1 } }, [], [], undefined, new NullLogService());569assert.deepStrictEqual(testObject.getValue('a'), { 'b': 1 });570});571572test('Test contents are undefined for non existing properties', () => {573const testObject = new ConfigurationModel({ awesome: true }, [], [], undefined, new NullLogService());574575assert.deepStrictEqual(testObject.getValue('unknownproperty'), undefined);576});577578test('Test override gives all content merged with overrides', () => {579const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, [], [{ identifiers: ['b'], contents: { 'a': 2 }, keys: ['a'] }], undefined, new NullLogService());580581assert.deepStrictEqual(testObject.override('b').contents, { 'a': 2, 'c': 1 });582});583584test('Test override when an override has multiple identifiers', () => {585const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x', 'y'], contents: { 'a': 2 }, keys: ['a'] }], undefined, new NullLogService());586587let actual = testObject.override('x');588assert.deepStrictEqual(actual.contents, { 'a': 2, 'c': 1 });589assert.deepStrictEqual(actual.keys, ['a', 'c']);590assert.deepStrictEqual(testObject.getKeysForOverrideIdentifier('x'), ['a']);591592actual = testObject.override('y');593assert.deepStrictEqual(actual.contents, { 'a': 2, 'c': 1 });594assert.deepStrictEqual(actual.keys, ['a', 'c']);595assert.deepStrictEqual(testObject.getKeysForOverrideIdentifier('y'), ['a']);596});597598test('Test override when an identifier is defined in multiple overrides', () => {599const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x'], contents: { 'a': 3, 'b': 1 }, keys: ['a', 'b'] }, { identifiers: ['x', 'y'], contents: { 'a': 2 }, keys: ['a'] }], undefined, new NullLogService());600601const actual = testObject.override('x');602assert.deepStrictEqual(actual.contents, { 'a': 3, 'c': 1, 'b': 1 });603assert.deepStrictEqual(actual.keys, ['a', 'c']);604605assert.deepStrictEqual(testObject.getKeysForOverrideIdentifier('x'), ['a', 'b']);606});607608test('Test merge when configuration models have multiple identifiers', () => {609const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['y'], contents: { 'c': 1 }, keys: ['c'] }, { identifiers: ['x', 'y'], contents: { 'a': 2 }, keys: ['a'] }], undefined, new NullLogService());610const target = new ConfigurationModel({ 'a': 2, 'b': 1 }, ['a', 'b'], [{ identifiers: ['x'], contents: { 'a': 3, 'b': 2 }, keys: ['a', 'b'] }, { identifiers: ['x', 'y'], contents: { 'b': 3 }, keys: ['b'] }], undefined, new NullLogService());611612const actual = testObject.merge(target);613614assert.deepStrictEqual(actual.contents, { 'a': 2, 'c': 1, 'b': 1 });615assert.deepStrictEqual(actual.keys, ['a', 'c', 'b']);616assert.deepStrictEqual(actual.overrides, [617{ identifiers: ['y'], contents: { 'c': 1 }, keys: ['c'] },618{ identifiers: ['x', 'y'], contents: { 'a': 2, 'b': 3 }, keys: ['a', 'b'] },619{ identifiers: ['x'], contents: { 'a': 3, 'b': 2 }, keys: ['a', 'b'] },620]);621});622623test('inspect when raw is same', () => {624const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, 'b': 1 }, keys: ['a'] }], undefined, new NullLogService());625626assert.deepStrictEqual(testObject.inspect('a'), { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });627assert.deepStrictEqual(testObject.inspect('a', 'x'), { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });628assert.deepStrictEqual(testObject.inspect('b', 'x'), { value: undefined, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });629assert.deepStrictEqual(testObject.inspect('d'), { value: undefined, override: undefined, merged: undefined, overrides: undefined });630});631632test('inspect when raw is not same', () => {633const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {634'a': 1,635'b': 2,636'c': 1,637'd': 3,638'[x][y]': {639'a': 2,640'b': 1641}642}, new NullLogService());643644assert.deepStrictEqual(testObject.inspect('a'), { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });645assert.deepStrictEqual(testObject.inspect('a', 'x'), { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });646assert.deepStrictEqual(testObject.inspect('b', 'x'), { value: 2, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });647assert.deepStrictEqual(testObject.inspect('d'), { value: 3, override: undefined, merged: 3, overrides: undefined });648assert.deepStrictEqual(testObject.inspect('e'), { value: undefined, override: undefined, merged: undefined, overrides: undefined });649});650651test('inspect in merged configuration when raw is same', () => {652const target1 = new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], undefined, new NullLogService());653const target2 = new ConfigurationModel({ 'b': 3 }, ['b'], [], undefined, new NullLogService());654const testObject = target1.merge(target2);655656assert.deepStrictEqual(testObject.inspect('a'), { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });657assert.deepStrictEqual(testObject.inspect('a', 'x'), { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });658assert.deepStrictEqual(testObject.inspect('b'), { value: 3, override: undefined, merged: 3, overrides: undefined });659assert.deepStrictEqual(testObject.inspect('b', 'y'), { value: 3, override: undefined, merged: 3, overrides: undefined });660assert.deepStrictEqual(testObject.inspect('c'), { value: undefined, override: undefined, merged: undefined, overrides: undefined });661});662663test('inspect in merged configuration when raw is not same for one model', () => {664const target1 = new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {665'a': 1,666'b': 2,667'c': 3,668'[x][y]': {669'a': 2,670'b': 4,671}672}, new NullLogService());673const target2 = new ConfigurationModel({ 'b': 3 }, ['b'], [], undefined, new NullLogService());674const testObject = target1.merge(target2);675676assert.deepStrictEqual(testObject.inspect('a'), { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });677assert.deepStrictEqual(testObject.inspect('a', 'x'), { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });678assert.deepStrictEqual(testObject.inspect('b'), { value: 3, override: undefined, merged: 3, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });679assert.deepStrictEqual(testObject.inspect('b', 'y'), { value: 3, override: 4, merged: 4, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });680assert.deepStrictEqual(testObject.inspect('c'), { value: 3, override: undefined, merged: 3, overrides: undefined });681});682683test('inspect: return all overrides', () => {684const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [685{ identifiers: ['x', 'y'], contents: { 'a': 2, 'b': 1 }, keys: ['a', 'b'] },686{ identifiers: ['x'], contents: { 'a': 3 }, keys: ['a'] },687{ identifiers: ['y'], contents: { 'b': 3 }, keys: ['b'] }688], undefined, new NullLogService());689690assert.deepStrictEqual(testObject.inspect('a').overrides, [691{ identifiers: ['x', 'y'], value: 2 },692{ identifiers: ['x'], value: 3 }693]);694});695696test('inspect when no overrides', () => {697const testObject = new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [], undefined, new NullLogService());698699assert.strictEqual(testObject.inspect('a').overrides, undefined);700});701702});703704suite('CustomConfigurationModel', () => {705706ensureNoDisposablesAreLeakedInTestSuite();707708test('simple merge using models', () => {709const base = new ConfigurationModelParser('base', new NullLogService());710base.parse(JSON.stringify({ 'a': 1, 'b': 2 }));711712const add = new ConfigurationModelParser('add', new NullLogService());713add.parse(JSON.stringify({ 'a': 3, 'c': 4 }));714715const result = base.configurationModel.merge(add.configurationModel);716assert.deepStrictEqual(result.contents, { 'a': 3, 'b': 2, 'c': 4 });717});718719test('simple merge with an undefined contents', () => {720let base = new ConfigurationModelParser('base', new NullLogService());721base.parse(JSON.stringify({ 'a': 1, 'b': 2 }));722let add = new ConfigurationModelParser('add', new NullLogService());723let result = base.configurationModel.merge(add.configurationModel);724assert.deepStrictEqual(result.contents, { 'a': 1, 'b': 2 });725726base = new ConfigurationModelParser('base', new NullLogService());727add = new ConfigurationModelParser('add', new NullLogService());728add.parse(JSON.stringify({ 'a': 1, 'b': 2 }));729result = base.configurationModel.merge(add.configurationModel);730assert.deepStrictEqual(result.contents, { 'a': 1, 'b': 2 });731732base = new ConfigurationModelParser('base', new NullLogService());733add = new ConfigurationModelParser('add', new NullLogService());734result = base.configurationModel.merge(add.configurationModel);735assert.deepStrictEqual(result.contents, {});736});737738test('Recursive merge using config models', () => {739const base = new ConfigurationModelParser('base', new NullLogService());740base.parse(JSON.stringify({ 'a': { 'b': 1 } }));741const add = new ConfigurationModelParser('add', new NullLogService());742add.parse(JSON.stringify({ 'a': { 'b': 2 } }));743const result = base.configurationModel.merge(add.configurationModel);744assert.deepStrictEqual(result.contents, { 'a': { 'b': 2 } });745});746747test('Test contents while getting an existing property', () => {748const testObject = new ConfigurationModelParser('test', new NullLogService());749testObject.parse(JSON.stringify({ 'a': 1 }));750assert.deepStrictEqual(testObject.configurationModel.getValue('a'), 1);751752testObject.parse(JSON.stringify({ 'a': { 'b': 1 } }));753assert.deepStrictEqual(testObject.configurationModel.getValue('a'), { 'b': 1 });754});755756test('Test contents are undefined for non existing properties', () => {757const testObject = new ConfigurationModelParser('test', new NullLogService());758testObject.parse(JSON.stringify({759awesome: true760}));761762assert.deepStrictEqual(testObject.configurationModel.getValue('unknownproperty'), undefined);763});764765test('Test contents are undefined for undefined config', () => {766const testObject = new ConfigurationModelParser('test', new NullLogService());767768assert.deepStrictEqual(testObject.configurationModel.getValue('unknownproperty'), undefined);769});770771test('Test configWithOverrides gives all content merged with overrides', () => {772const testObject = new ConfigurationModelParser('test', new NullLogService());773testObject.parse(JSON.stringify({ 'a': 1, 'c': 1, '[b]': { 'a': 2 } }));774775assert.deepStrictEqual(testObject.configurationModel.override('b').contents, { 'a': 2, 'c': 1, '[b]': { 'a': 2 } });776});777778test('Test configWithOverrides gives empty contents', () => {779const testObject = new ConfigurationModelParser('test', new NullLogService());780781assert.deepStrictEqual(testObject.configurationModel.override('b').contents, {});782});783784test('Test update with empty data', () => {785const testObject = new ConfigurationModelParser('test', new NullLogService());786testObject.parse('');787788assert.deepStrictEqual(testObject.configurationModel.contents, Object.create(null));789assert.deepStrictEqual(testObject.configurationModel.keys, []);790791testObject.parse(null);792793assert.deepStrictEqual(testObject.configurationModel.contents, Object.create(null));794assert.deepStrictEqual(testObject.configurationModel.keys, []);795796testObject.parse(undefined);797798assert.deepStrictEqual(testObject.configurationModel.contents, Object.create(null));799assert.deepStrictEqual(testObject.configurationModel.keys, []);800});801802test('Test empty property is not ignored', () => {803const testObject = new ConfigurationModelParser('test', new NullLogService());804testObject.parse(JSON.stringify({ '': 1 }));805806// deepStrictEqual seems to ignore empty properties, fall back807// to comparing the output of JSON.stringify808assert.strictEqual(JSON.stringify(testObject.configurationModel.contents), JSON.stringify({ '': 1 }));809assert.deepStrictEqual(testObject.configurationModel.keys, ['']);810});811812});813814export class TestConfiguration extends Configuration {815816constructor(817defaultConfiguration: ConfigurationModel,818policyConfiguration: ConfigurationModel,819applicationConfiguration: ConfigurationModel,820localUserConfiguration: ConfigurationModel,821remoteUserConfiguration?: ConfigurationModel,822) {823super(824defaultConfiguration,825policyConfiguration,826applicationConfiguration,827localUserConfiguration,828remoteUserConfiguration ?? ConfigurationModel.createEmptyModel(new NullLogService()),829ConfigurationModel.createEmptyModel(new NullLogService()),830new ResourceMap<ConfigurationModel>(),831ConfigurationModel.createEmptyModel(new NullLogService()),832new ResourceMap<ConfigurationModel>(),833new NullLogService()834);835}836837}838839suite('Configuration', () => {840841ensureNoDisposablesAreLeakedInTestSuite();842843test('Test inspect for overrideIdentifiers', () => {844const defaultConfigurationModel = parseConfigurationModel({ '[l1]': { 'a': 1 }, '[l2]': { 'b': 1 } });845const userConfigurationModel = parseConfigurationModel({ '[l3]': { 'a': 2 } });846const workspaceConfigurationModel = parseConfigurationModel({ '[l1]': { 'a': 3 }, '[l4]': { 'a': 3 } });847const testObject: Configuration = new TestConfiguration(defaultConfigurationModel, ConfigurationModel.createEmptyModel(new NullLogService()), userConfigurationModel, workspaceConfigurationModel);848849const { overrideIdentifiers } = testObject.inspect('a', {}, undefined);850851assert.deepStrictEqual(overrideIdentifiers, ['l1', 'l3', 'l4']);852});853854test('Test update value', () => {855const parser = new ConfigurationModelParser('test', new NullLogService());856parser.parse(JSON.stringify({ 'a': 1 }));857const testObject: Configuration = new TestConfiguration(parser.configurationModel, ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));858859testObject.updateValue('a', 2);860861assert.strictEqual(testObject.getValue('a', {}, undefined), 2);862});863864test('Test update value after inspect', () => {865const parser = new ConfigurationModelParser('test', new NullLogService());866parser.parse(JSON.stringify({ 'a': 1 }));867const testObject: Configuration = new TestConfiguration(parser.configurationModel, ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));868869testObject.inspect('a', {}, undefined);870testObject.updateValue('a', 2);871872assert.strictEqual(testObject.getValue('a', {}, undefined), 2);873});874875test('Test compare and update default configuration', () => {876const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));877testObject.updateDefaultConfiguration(toConfigurationModel({878'editor.lineNumbers': 'on',879}));880881const actual = testObject.compareAndUpdateDefaultConfiguration(toConfigurationModel({882'editor.lineNumbers': 'off',883'[markdown]': {884'editor.wordWrap': 'off'885}886}), ['editor.lineNumbers', '[markdown]']);887888assert.deepStrictEqual(actual, { keys: ['editor.lineNumbers', '[markdown]'], overrides: [['markdown', ['editor.wordWrap']]] });889890});891892test('Test compare and update application configuration', () => {893const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));894testObject.updateApplicationConfiguration(toConfigurationModel({895'update.mode': 'on',896}));897898const actual = testObject.compareAndUpdateApplicationConfiguration(toConfigurationModel({899'update.mode': 'none',900'[typescript]': {901'editor.wordWrap': 'off'902}903}));904905assert.deepStrictEqual(actual, { keys: ['[typescript]', 'update.mode',], overrides: [['typescript', ['editor.wordWrap']]] });906907});908909test('Test compare and update user configuration', () => {910const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));911testObject.updateLocalUserConfiguration(toConfigurationModel({912'editor.lineNumbers': 'off',913'editor.fontSize': 12,914'[typescript]': {915'editor.wordWrap': 'off'916}917}));918919const actual = testObject.compareAndUpdateLocalUserConfiguration(toConfigurationModel({920'editor.lineNumbers': 'on',921'window.zoomLevel': 1,922'[typescript]': {923'editor.wordWrap': 'on',924'editor.insertSpaces': false925}926}));927928assert.deepStrictEqual(actual, { keys: ['window.zoomLevel', 'editor.lineNumbers', '[typescript]', 'editor.fontSize'], overrides: [['typescript', ['editor.insertSpaces', 'editor.wordWrap']]] });929930});931932test('Test compare and update workspace configuration', () => {933const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));934testObject.updateWorkspaceConfiguration(toConfigurationModel({935'editor.lineNumbers': 'off',936'editor.fontSize': 12,937'[typescript]': {938'editor.wordWrap': 'off'939}940}));941942const actual = testObject.compareAndUpdateWorkspaceConfiguration(toConfigurationModel({943'editor.lineNumbers': 'on',944'window.zoomLevel': 1,945'[typescript]': {946'editor.wordWrap': 'on',947'editor.insertSpaces': false948}949}));950951assert.deepStrictEqual(actual, { keys: ['window.zoomLevel', 'editor.lineNumbers', '[typescript]', 'editor.fontSize'], overrides: [['typescript', ['editor.insertSpaces', 'editor.wordWrap']]] });952953});954955test('Test compare and update workspace folder configuration', () => {956const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));957testObject.updateFolderConfiguration(URI.file('file1'), toConfigurationModel({958'editor.lineNumbers': 'off',959'editor.fontSize': 12,960'[typescript]': {961'editor.wordWrap': 'off'962}963}));964965const actual = testObject.compareAndUpdateFolderConfiguration(URI.file('file1'), toConfigurationModel({966'editor.lineNumbers': 'on',967'window.zoomLevel': 1,968'[typescript]': {969'editor.wordWrap': 'on',970'editor.insertSpaces': false971}972}));973974assert.deepStrictEqual(actual, { keys: ['window.zoomLevel', 'editor.lineNumbers', '[typescript]', 'editor.fontSize'], overrides: [['typescript', ['editor.insertSpaces', 'editor.wordWrap']]] });975976});977978test('Test compare and delete workspace folder configuration', () => {979const testObject = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));980testObject.updateFolderConfiguration(URI.file('file1'), toConfigurationModel({981'editor.lineNumbers': 'off',982'editor.fontSize': 12,983'[typescript]': {984'editor.wordWrap': 'off'985}986}));987988const actual = testObject.compareAndDeleteFolderConfiguration(URI.file('file1'));989990assert.deepStrictEqual(actual, { keys: ['editor.lineNumbers', 'editor.fontSize', '[typescript]'], overrides: [['typescript', ['editor.wordWrap']]] });991992});993994function parseConfigurationModel(content: any): ConfigurationModel {995const parser = new ConfigurationModelParser('test', new NullLogService());996parser.parse(JSON.stringify(content));997return parser.configurationModel;998}9991000});10011002suite('ConfigurationChangeEvent', () => {10031004ensureNoDisposablesAreLeakedInTestSuite();10051006test('changeEvent affecting keys with new configuration', () => {1007const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1008const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1009'window.zoomLevel': 1,1010'workbench.editor.enablePreview': false,1011'files.autoSave': 'off',1012}));1013const testObject = new ConfigurationChangeEvent(change, undefined, configuration, undefined, new NullLogService());10141015assert.deepStrictEqual([...testObject.affectedKeys], ['window.zoomLevel', 'workbench.editor.enablePreview', 'files.autoSave']);10161017assert.ok(testObject.affectsConfiguration('window.zoomLevel'));1018assert.ok(testObject.affectsConfiguration('window'));10191020assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));1021assert.ok(testObject.affectsConfiguration('workbench.editor'));1022assert.ok(testObject.affectsConfiguration('workbench'));10231024assert.ok(testObject.affectsConfiguration('files'));1025assert.ok(testObject.affectsConfiguration('files.autoSave'));1026assert.ok(!testObject.affectsConfiguration('files.exclude'));10271028assert.ok(!testObject.affectsConfiguration('[markdown]'));1029assert.ok(!testObject.affectsConfiguration('editor'));1030});10311032test('changeEvent affecting keys when configuration changed', () => {1033const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1034configuration.updateLocalUserConfiguration(toConfigurationModel({1035'window.zoomLevel': 2,1036'workbench.editor.enablePreview': true,1037'files.autoSave': 'off',1038}));1039const data = configuration.toData();1040const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1041'window.zoomLevel': 1,1042'workbench.editor.enablePreview': false,1043'files.autoSave': 'off',1044}));1045const testObject = new ConfigurationChangeEvent(change, { data }, configuration, undefined, new NullLogService());10461047assert.deepStrictEqual([...testObject.affectedKeys], ['window.zoomLevel', 'workbench.editor.enablePreview']);10481049assert.ok(testObject.affectsConfiguration('window.zoomLevel'));1050assert.ok(testObject.affectsConfiguration('window'));10511052assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));1053assert.ok(testObject.affectsConfiguration('workbench.editor'));1054assert.ok(testObject.affectsConfiguration('workbench'));10551056assert.ok(!testObject.affectsConfiguration('files'));1057assert.ok(!testObject.affectsConfiguration('[markdown]'));1058assert.ok(!testObject.affectsConfiguration('editor'));1059});10601061test('changeEvent affecting overrides with new configuration', () => {1062const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1063const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1064'files.autoSave': 'off',1065'[markdown]': {1066'editor.wordWrap': 'off'1067},1068'[typescript][jsonc]': {1069'editor.lineNumbers': 'off'1070}1071}));1072const testObject = new ConfigurationChangeEvent(change, undefined, configuration, undefined, new NullLogService());10731074assert.deepStrictEqual([...testObject.affectedKeys], ['files.autoSave', '[markdown]', '[typescript][jsonc]', 'editor.wordWrap', 'editor.lineNumbers']);10751076assert.ok(testObject.affectsConfiguration('files'));1077assert.ok(testObject.affectsConfiguration('files.autoSave'));1078assert.ok(!testObject.affectsConfiguration('files.exclude'));10791080assert.ok(testObject.affectsConfiguration('[markdown]'));1081assert.ok(!testObject.affectsConfiguration('[markdown].editor'));1082assert.ok(!testObject.affectsConfiguration('[markdown].workbench'));10831084assert.ok(testObject.affectsConfiguration('editor'));1085assert.ok(testObject.affectsConfiguration('editor.wordWrap'));1086assert.ok(testObject.affectsConfiguration('editor.lineNumbers'));1087assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'markdown' }));1088assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'jsonc' }));1089assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'typescript' }));1090assert.ok(testObject.affectsConfiguration('editor.wordWrap', { overrideIdentifier: 'markdown' }));1091assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { overrideIdentifier: 'jsonc' }));1092assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { overrideIdentifier: 'typescript' }));1093assert.ok(!testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'markdown' }));1094assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'typescript' }));1095assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'jsonc' }));1096assert.ok(!testObject.affectsConfiguration('editor', { overrideIdentifier: 'json' }));1097assert.ok(!testObject.affectsConfiguration('editor.fontSize', { overrideIdentifier: 'markdown' }));10981099assert.ok(!testObject.affectsConfiguration('editor.fontSize'));1100assert.ok(!testObject.affectsConfiguration('window'));1101});11021103test('changeEvent affecting overrides when configuration changed', () => {1104const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1105configuration.updateLocalUserConfiguration(toConfigurationModel({1106'workbench.editor.enablePreview': true,1107'[markdown]': {1108'editor.fontSize': 12,1109'editor.wordWrap': 'off'1110},1111'[css][scss]': {1112'editor.lineNumbers': 'off',1113'css.lint.emptyRules': 'error'1114},1115'files.autoSave': 'off',1116}));1117const data = configuration.toData();1118const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1119'files.autoSave': 'off',1120'[markdown]': {1121'editor.fontSize': 13,1122'editor.wordWrap': 'off'1123},1124'[css][scss]': {1125'editor.lineNumbers': 'relative',1126'css.lint.emptyRules': 'error'1127},1128'window.zoomLevel': 1,1129}));1130const testObject = new ConfigurationChangeEvent(change, { data }, configuration, undefined, new NullLogService());11311132assert.deepStrictEqual([...testObject.affectedKeys], ['window.zoomLevel', '[markdown]', '[css][scss]', 'workbench.editor.enablePreview', 'editor.fontSize', 'editor.lineNumbers']);11331134assert.ok(!testObject.affectsConfiguration('files'));11351136assert.ok(testObject.affectsConfiguration('[markdown]'));1137assert.ok(!testObject.affectsConfiguration('[markdown].editor'));1138assert.ok(!testObject.affectsConfiguration('[markdown].editor.fontSize'));1139assert.ok(!testObject.affectsConfiguration('[markdown].editor.wordWrap'));1140assert.ok(!testObject.affectsConfiguration('[markdown].workbench'));1141assert.ok(testObject.affectsConfiguration('[css][scss]'));11421143assert.ok(testObject.affectsConfiguration('editor'));1144assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'markdown' }));1145assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'css' }));1146assert.ok(testObject.affectsConfiguration('editor', { overrideIdentifier: 'scss' }));1147assert.ok(testObject.affectsConfiguration('editor.fontSize', { overrideIdentifier: 'markdown' }));1148assert.ok(!testObject.affectsConfiguration('editor.fontSize', { overrideIdentifier: 'css' }));1149assert.ok(!testObject.affectsConfiguration('editor.fontSize', { overrideIdentifier: 'scss' }));1150assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'scss' }));1151assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'css' }));1152assert.ok(!testObject.affectsConfiguration('editor.lineNumbers', { overrideIdentifier: 'markdown' }));1153assert.ok(!testObject.affectsConfiguration('editor.wordWrap'));1154assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { overrideIdentifier: 'markdown' }));1155assert.ok(!testObject.affectsConfiguration('editor', { overrideIdentifier: 'json' }));1156assert.ok(!testObject.affectsConfiguration('editor.fontSize', { overrideIdentifier: 'json' }));11571158assert.ok(testObject.affectsConfiguration('window'));1159assert.ok(testObject.affectsConfiguration('window.zoomLevel'));1160assert.ok(testObject.affectsConfiguration('window', { overrideIdentifier: 'markdown' }));1161assert.ok(testObject.affectsConfiguration('window.zoomLevel', { overrideIdentifier: 'markdown' }));11621163assert.ok(testObject.affectsConfiguration('workbench'));1164assert.ok(testObject.affectsConfiguration('workbench.editor'));1165assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));1166assert.ok(testObject.affectsConfiguration('workbench', { overrideIdentifier: 'markdown' }));1167assert.ok(testObject.affectsConfiguration('workbench.editor', { overrideIdentifier: 'markdown' }));1168});11691170test('changeEvent affecting workspace folders', () => {1171const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1172configuration.updateWorkspaceConfiguration(toConfigurationModel({ 'window.title': 'custom' }));1173configuration.updateFolderConfiguration(URI.file('folder1'), toConfigurationModel({ 'window.zoomLevel': 2, 'window.restoreFullscreen': true }));1174configuration.updateFolderConfiguration(URI.file('folder2'), toConfigurationModel({ 'workbench.editor.enablePreview': true, 'window.restoreWindows': true }));1175const data = configuration.toData();1176const workspace = new Workspace('a', [new WorkspaceFolder({ index: 0, name: 'a', uri: URI.file('folder1') }), new WorkspaceFolder({ index: 1, name: 'b', uri: URI.file('folder2') }), new WorkspaceFolder({ index: 2, name: 'c', uri: URI.file('folder3') })]);1177const change = mergeChanges(1178configuration.compareAndUpdateWorkspaceConfiguration(toConfigurationModel({ 'window.title': 'native' })),1179configuration.compareAndUpdateFolderConfiguration(URI.file('folder1'), toConfigurationModel({ 'window.zoomLevel': 1, 'window.restoreFullscreen': false })),1180configuration.compareAndUpdateFolderConfiguration(URI.file('folder2'), toConfigurationModel({ 'workbench.editor.enablePreview': false, 'window.restoreWindows': false }))1181);1182const testObject = new ConfigurationChangeEvent(change, { data, workspace }, configuration, workspace, new NullLogService());11831184assert.deepStrictEqual([...testObject.affectedKeys], ['window.title', 'window.zoomLevel', 'window.restoreFullscreen', 'workbench.editor.enablePreview', 'window.restoreWindows']);11851186assert.ok(testObject.affectsConfiguration('window.zoomLevel'));1187assert.ok(testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('folder1') }));1188assert.ok(testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file(join('folder1', 'file1')) }));1189assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file1') }));1190assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file2') }));1191assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file(join('folder2', 'file2')) }));1192assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file(join('folder3', 'file3')) }));11931194assert.ok(testObject.affectsConfiguration('window.restoreFullscreen'));1195assert.ok(testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file(join('folder1', 'file1')) }));1196assert.ok(testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('folder1') }));1197assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file1') }));1198assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file2') }));1199assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file(join('folder2', 'file2')) }));1200assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file(join('folder3', 'file3')) }));12011202assert.ok(testObject.affectsConfiguration('window.restoreWindows'));1203assert.ok(testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('folder2') }));1204assert.ok(testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file(join('folder2', 'file2')) }));1205assert.ok(!testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('file2') }));1206assert.ok(!testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file(join('folder1', 'file1')) }));1207assert.ok(!testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file(join('folder3', 'file3')) }));12081209assert.ok(testObject.affectsConfiguration('window.title'));1210assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('folder1') }));1211assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file(join('folder1', 'file1')) }));1212assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('folder2') }));1213assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file(join('folder2', 'file2')) }));1214assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('folder3') }));1215assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file(join('folder3', 'file3')) }));1216assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file1') }));1217assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file2') }));1218assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file3') }));12191220assert.ok(testObject.affectsConfiguration('window'));1221assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('folder1') }));1222assert.ok(testObject.affectsConfiguration('window', { resource: URI.file(join('folder1', 'file1')) }));1223assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('folder2') }));1224assert.ok(testObject.affectsConfiguration('window', { resource: URI.file(join('folder2', 'file2')) }));1225assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('folder3') }));1226assert.ok(testObject.affectsConfiguration('window', { resource: URI.file(join('folder3', 'file3')) }));1227assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file1') }));1228assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file2') }));1229assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file3') }));12301231assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));1232assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('folder2') }));1233assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file(join('folder2', 'file2')) }));1234assert.ok(!testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('folder1') }));1235assert.ok(!testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file(join('folder1', 'file1')) }));1236assert.ok(!testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('folder3') }));12371238assert.ok(testObject.affectsConfiguration('workbench.editor'));1239assert.ok(testObject.affectsConfiguration('workbench.editor', { resource: URI.file('folder2') }));1240assert.ok(testObject.affectsConfiguration('workbench.editor', { resource: URI.file(join('folder2', 'file2')) }));1241assert.ok(!testObject.affectsConfiguration('workbench.editor', { resource: URI.file('folder1') }));1242assert.ok(!testObject.affectsConfiguration('workbench.editor', { resource: URI.file(join('folder1', 'file1')) }));1243assert.ok(!testObject.affectsConfiguration('workbench.editor', { resource: URI.file('folder3') }));12441245assert.ok(testObject.affectsConfiguration('workbench'));1246assert.ok(testObject.affectsConfiguration('workbench', { resource: URI.file('folder2') }));1247assert.ok(testObject.affectsConfiguration('workbench', { resource: URI.file(join('folder2', 'file2')) }));1248assert.ok(!testObject.affectsConfiguration('workbench', { resource: URI.file('folder1') }));1249assert.ok(!testObject.affectsConfiguration('workbench', { resource: URI.file('folder3') }));12501251assert.ok(!testObject.affectsConfiguration('files'));1252assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('folder1') }));1253assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file(join('folder1', 'file1')) }));1254assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('folder2') }));1255assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file(join('folder2', 'file2')) }));1256assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('folder3') }));1257assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file(join('folder3', 'file3')) }));1258});12591260test('changeEvent - all', () => {1261const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1262configuration.updateFolderConfiguration(URI.file('file1'), toConfigurationModel({ 'window.zoomLevel': 2, 'window.restoreFullscreen': true }));1263const data = configuration.toData();1264const change = mergeChanges(1265configuration.compareAndUpdateDefaultConfiguration(toConfigurationModel({1266'editor.lineNumbers': 'off',1267'[markdown]': {1268'editor.wordWrap': 'off'1269}1270}), ['editor.lineNumbers', '[markdown]']),1271configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1272'[json]': {1273'editor.lineNumbers': 'relative'1274}1275})),1276configuration.compareAndUpdateWorkspaceConfiguration(toConfigurationModel({ 'window.title': 'custom' })),1277configuration.compareAndDeleteFolderConfiguration(URI.file('file1')),1278configuration.compareAndUpdateFolderConfiguration(URI.file('file2'), toConfigurationModel({ 'workbench.editor.enablePreview': true, 'window.restoreWindows': true })));1279const workspace = new Workspace('a', [new WorkspaceFolder({ index: 0, name: 'a', uri: URI.file('file1') }), new WorkspaceFolder({ index: 1, name: 'b', uri: URI.file('file2') }), new WorkspaceFolder({ index: 2, name: 'c', uri: URI.file('folder3') })]);1280const testObject = new ConfigurationChangeEvent(change, { data, workspace }, configuration, workspace, new NullLogService());12811282assert.deepStrictEqual([...testObject.affectedKeys], ['editor.lineNumbers', '[markdown]', '[json]', 'window.title', 'window.zoomLevel', 'window.restoreFullscreen', 'workbench.editor.enablePreview', 'window.restoreWindows', 'editor.wordWrap']);12831284assert.ok(testObject.affectsConfiguration('window.title'));1285assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file1') }));1286assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file2') }));12871288assert.ok(testObject.affectsConfiguration('window'));1289assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file1') }));1290assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file2') }));12911292assert.ok(testObject.affectsConfiguration('window.zoomLevel'));1293assert.ok(testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file1') }));1294assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file2') }));12951296assert.ok(testObject.affectsConfiguration('window.restoreFullscreen'));1297assert.ok(testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file1') }));1298assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file2') }));12991300assert.ok(testObject.affectsConfiguration('window.restoreWindows'));1301assert.ok(testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('file2') }));1302assert.ok(!testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('file1') }));13031304assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));1305assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('file2') }));1306assert.ok(!testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('file1') }));13071308assert.ok(testObject.affectsConfiguration('workbench.editor'));1309assert.ok(testObject.affectsConfiguration('workbench.editor', { resource: URI.file('file2') }));1310assert.ok(!testObject.affectsConfiguration('workbench.editor', { resource: URI.file('file1') }));13111312assert.ok(testObject.affectsConfiguration('workbench'));1313assert.ok(testObject.affectsConfiguration('workbench', { resource: URI.file('file2') }));1314assert.ok(!testObject.affectsConfiguration('workbench', { resource: URI.file('file1') }));13151316assert.ok(!testObject.affectsConfiguration('files'));1317assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('file1') }));1318assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('file2') }));13191320assert.ok(testObject.affectsConfiguration('editor'));1321assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1') }));1322assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2') }));1323assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'json' }));1324assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));1325assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));1326assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'json' }));1327assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));1328assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));13291330assert.ok(testObject.affectsConfiguration('editor.lineNumbers'));1331assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1') }));1332assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2') }));1333assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'json' }));1334assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));1335assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));1336assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'json' }));1337assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));1338assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));13391340assert.ok(testObject.affectsConfiguration('editor.wordWrap'));1341assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1') }));1342assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2') }));1343assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'json' }));1344assert.ok(testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));1345assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));1346assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'json' }));1347assert.ok(testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));1348assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));13491350assert.ok(!testObject.affectsConfiguration('editor.fontSize'));1351assert.ok(!testObject.affectsConfiguration('editor.fontSize', { resource: URI.file('file1') }));1352assert.ok(!testObject.affectsConfiguration('editor.fontSize', { resource: URI.file('file2') }));1353});13541355test('changeEvent affecting tasks and launches', () => {1356const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1357const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({1358'launch': {1359'configuraiton': {}1360},1361'launch.version': 1,1362'tasks': {1363'version': 21364}1365}));1366const testObject = new ConfigurationChangeEvent(change, undefined, configuration, undefined, new NullLogService());13671368assert.deepStrictEqual([...testObject.affectedKeys], ['launch', 'launch.version', 'tasks']);1369assert.ok(testObject.affectsConfiguration('launch'));1370assert.ok(testObject.affectsConfiguration('launch.version'));1371assert.ok(testObject.affectsConfiguration('tasks'));1372});13731374test('affectsConfiguration returns false for empty string', () => {1375const configuration = new TestConfiguration(ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()), ConfigurationModel.createEmptyModel(new NullLogService()));1376const change = configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({ 'window.zoomLevel': 1 }));1377const testObject = new ConfigurationChangeEvent(change, undefined, configuration, undefined, new NullLogService());13781379assert.strictEqual(false, testObject.affectsConfiguration(''));1380});13811382});13831384suite('Configuration.Parse', () => {13851386const logService = new NullLogService();1387ensureNoDisposablesAreLeakedInTestSuite();13881389test('parsing configuration only with local user configuration and raw is same', () => {1390const configuration = new TestConfiguration(1391ConfigurationModel.createEmptyModel(logService),1392ConfigurationModel.createEmptyModel(logService),1393ConfigurationModel.createEmptyModel(logService),1394new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, 'b': 1 }, keys: ['a'] }], undefined, logService)1395);13961397const actual = Configuration.parse(configuration.toData(), logService);13981399assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1400assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1401assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).userLocal, { value: undefined, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });1402assert.deepStrictEqual(actual.inspect('d', {}, undefined).userLocal, undefined);14031404assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, undefined);1405assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1406assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1407assert.deepStrictEqual(actual.inspect('d', {}, undefined).userRemote, undefined);14081409assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1410assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1411assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).user, { value: undefined, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });1412assert.deepStrictEqual(actual.inspect('d', {}, undefined).user, undefined);1413});14141415test('parsing configuration only with local user configuration and raw is not same', () => {1416const configuration = new TestConfiguration(1417ConfigurationModel.createEmptyModel(logService),1418ConfigurationModel.createEmptyModel(logService),1419ConfigurationModel.createEmptyModel(logService),1420new ConfigurationModel({ 'a': 1, 'c': 1 }, ['a', 'c'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {1421'a': 1,1422'b': 2,1423'c': 1,1424'd': 3,1425'[x][y]': {1426'a': 2,1427'b': 11428}1429}, logService)1430);14311432const actual = Configuration.parse(configuration.toData(), logService);14331434assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1435assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1436assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 2, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });1437assert.deepStrictEqual(actual.inspect('d', {}, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });1438assert.deepStrictEqual(actual.inspect('e', {}, undefined).userLocal, undefined);14391440assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, undefined);1441assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1442assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1443assert.deepStrictEqual(actual.inspect('d', {}, undefined).userRemote, undefined);1444assert.deepStrictEqual(actual.inspect('e', {}, undefined).userRemote, undefined);14451446assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1447assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1448assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'x' }, undefined).user, { value: 2, override: 1, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 1 }] });1449assert.deepStrictEqual(actual.inspect('d', {}, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1450assert.deepStrictEqual(actual.inspect('e', {}, undefined).user, undefined);1451});14521453test('parsing configuration with local and remote user configuration and raw is same for both', () => {1454const configuration = new TestConfiguration(1455ConfigurationModel.createEmptyModel(logService),1456ConfigurationModel.createEmptyModel(logService),1457ConfigurationModel.createEmptyModel(logService),1458new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], undefined, logService),1459new ConfigurationModel({ 'b': 3 }, ['b'], [], undefined, logService)1460);14611462const actual = Configuration.parse(configuration.toData(), logService);14631464assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1465assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1466assert.deepStrictEqual(actual.inspect('b', {}, undefined).userLocal, undefined);1467assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userLocal, undefined);1468assert.deepStrictEqual(actual.inspect('c', {}, undefined).userLocal, undefined);14691470assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, undefined);1471assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1472assert.deepStrictEqual(actual.inspect('b', {}, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });1473assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });1474assert.deepStrictEqual(actual.inspect('c', {}, undefined).userRemote, undefined);14751476assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1477assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1478assert.deepStrictEqual(actual.inspect('b', {}, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1479assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1480assert.deepStrictEqual(actual.inspect('c', {}, undefined).user, undefined);1481});14821483test('parsing configuration with local and remote user configuration and raw is not same for local user', () => {1484const configuration = new TestConfiguration(1485ConfigurationModel.createEmptyModel(logService),1486ConfigurationModel.createEmptyModel(logService),1487ConfigurationModel.createEmptyModel(logService),1488new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {1489'a': 1,1490'b': 2,1491'c': 3,1492'[x][y]': {1493'a': 2,1494'b': 4,1495}1496}, logService),1497new ConfigurationModel({ 'b': 3 }, ['b'], [], undefined, logService)1498);14991500const actual = Configuration.parse(configuration.toData(), logService);15011502assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1503assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1504assert.deepStrictEqual(actual.inspect('b', {}, undefined).userLocal, { value: 2, override: undefined, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1505assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userLocal, { value: 2, override: 4, merged: 4, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1506assert.deepStrictEqual(actual.inspect('c', {}, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });15071508assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, undefined);1509assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, undefined);1510assert.deepStrictEqual(actual.inspect('b', {}, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });1511assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });1512assert.deepStrictEqual(actual.inspect('c', {}, undefined).userRemote, undefined);15131514assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1515assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1516assert.deepStrictEqual(actual.inspect('b', {}, undefined).user, { value: 3, merged: 3, override: undefined, overrides: undefined });1517assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1518assert.deepStrictEqual(actual.inspect('c', {}, undefined).user, undefined);1519});15201521test('parsing configuration with local and remote user configuration and raw is not same for remote user', () => {1522const configuration = new TestConfiguration(1523ConfigurationModel.createEmptyModel(logService),1524ConfigurationModel.createEmptyModel(logService),1525ConfigurationModel.createEmptyModel(logService),1526new ConfigurationModel({ 'b': 3 }, ['b'], [], undefined, logService),1527new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {1528'a': 1,1529'b': 2,1530'c': 3,1531'[x][y]': {1532'a': 2,1533'b': 4,1534}1535}, logService),1536);15371538const actual = Configuration.parse(configuration.toData(), logService);15391540assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, undefined);1541assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, undefined);1542assert.deepStrictEqual(actual.inspect('b', {}, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });1543assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });1544assert.deepStrictEqual(actual.inspect('c', {}, undefined).userLocal, undefined);15451546assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1547assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1548assert.deepStrictEqual(actual.inspect('b', {}, undefined).userRemote, { value: 2, override: undefined, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1549assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userRemote, { value: 2, override: 4, merged: 4, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1550assert.deepStrictEqual(actual.inspect('c', {}, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });15511552assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1553assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1554assert.deepStrictEqual(actual.inspect('b', {}, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1555assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1556assert.deepStrictEqual(actual.inspect('c', {}, undefined).user, undefined);1557});15581559test('parsing configuration with local and remote user configuration and raw is not same for both', () => {1560const configuration = new TestConfiguration(1561ConfigurationModel.createEmptyModel(logService),1562ConfigurationModel.createEmptyModel(logService),1563ConfigurationModel.createEmptyModel(logService),1564new ConfigurationModel({ 'b': 3 }, ['b'], [], {1565'a': 4,1566'b': 31567}, logService),1568new ConfigurationModel({ 'a': 1 }, ['a'], [{ identifiers: ['x', 'y'], contents: { 'a': 2, }, keys: ['a'] }], {1569'a': 1,1570'b': 2,1571'c': 3,1572'[x][y]': {1573'a': 2,1574'b': 4,1575}1576}, logService),1577);15781579const actual = Configuration.parse(configuration.toData(), logService);15801581assert.deepStrictEqual(actual.inspect('a', {}, undefined).userLocal, { value: 4, override: undefined, merged: 4, overrides: undefined });1582assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userLocal, { value: 4, override: undefined, merged: 4, overrides: undefined });1583assert.deepStrictEqual(actual.inspect('b', {}, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });1584assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userLocal, { value: 3, override: undefined, merged: 3, overrides: undefined });1585assert.deepStrictEqual(actual.inspect('c', {}, undefined).userLocal, undefined);15861587assert.deepStrictEqual(actual.inspect('a', {}, undefined).userRemote, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1588assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).userRemote, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1589assert.deepStrictEqual(actual.inspect('b', {}, undefined).userRemote, { value: 2, override: undefined, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1590assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).userRemote, { value: 2, override: 4, merged: 4, overrides: [{ identifiers: ['x', 'y'], value: 4 }] });1591assert.deepStrictEqual(actual.inspect('c', {}, undefined).userRemote, { value: 3, override: undefined, merged: 3, overrides: undefined });15921593assert.deepStrictEqual(actual.inspect('a', {}, undefined).user, { value: 1, override: undefined, merged: 1, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1594assert.deepStrictEqual(actual.inspect('a', { overrideIdentifier: 'x' }, undefined).user, { value: 1, override: 2, merged: 2, overrides: [{ identifiers: ['x', 'y'], value: 2 }] });1595assert.deepStrictEqual(actual.inspect('b', {}, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1596assert.deepStrictEqual(actual.inspect('b', { overrideIdentifier: 'y' }, undefined).user, { value: 3, override: undefined, merged: 3, overrides: undefined });1597assert.deepStrictEqual(actual.inspect('c', {}, undefined).user, undefined);1598});159916001601});16021603function toConfigurationModel(obj: any): ConfigurationModel {1604const parser = new ConfigurationModelParser('test', new NullLogService());1605parser.parse(JSON.stringify(obj));1606return parser.configurationModel;1607}160816091610