diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 93b2d217d8e..0b4830a4c8a 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -107,12 +107,16 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { return isObject(target) ? new Proxy(target, { get: (target: any, property: string) => { + if (typeof property === 'string' && property.toLowerCase() === 'tojson') { + cloneTarget(); + return () => clonedTarget; + } if (clonedConfig) { clonedTarget = clonedTarget ? clonedTarget : lookUp(clonedConfig, accessor); return clonedTarget[property]; } const result = target[property]; - if (typeof property === 'string' && property.toLowerCase() !== 'tojson') { + if (typeof property === 'string') { return cloneOnWriteProxy(result, `${accessor}.${property}`); } return result; diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 382cbc08b75..4aae41a952d 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -17,6 +17,7 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { NullLogService } from 'vs/platform/log/common/log'; +import { assign } from 'vs/base/common/objects'; suite('ExtHostConfiguration', function () { @@ -146,6 +147,88 @@ suite('ExtHostConfiguration', function () { assert.equal(actual['statusBar.foreground'], 'somevalue'); }); + test('Stringify returned configuration', function () { + + const all = createExtHostConfiguration({ + 'farboo': { + 'config0': true, + 'nested': { + 'config1': 42, + 'config2': 'Das Pferd frisst kein Reis.' + }, + 'config4': '' + }, + 'workbench': { + 'colorCustomizations': { + 'statusBar.foreground': 'somevalue' + }, + 'emptyobjectkey': { + } + } + }); + + let testObject = all.getConfiguration(); + let actual = testObject.get('farboo'); + assert.deepEqual(JSON.stringify({ + 'config0': true, + 'nested': { + 'config1': 42, + 'config2': 'Das Pferd frisst kein Reis.' + }, + 'config4': '' + }), JSON.stringify(actual)); + + assert.deepEqual(undefined, JSON.stringify(testObject.get('unknownkey'))); + + actual = testObject.get('farboo'); + actual['config0'] = false; + assert.deepEqual(JSON.stringify({ + 'config0': false, + 'nested': { + 'config1': 42, + 'config2': 'Das Pferd frisst kein Reis.' + }, + 'config4': '' + }), JSON.stringify(actual)); + + actual = testObject.get('workbench')['colorCustomizations']; + actual['statusBar.background'] = 'anothervalue'; + assert.deepEqual(JSON.stringify({ + 'statusBar.foreground': 'somevalue', + 'statusBar.background': 'anothervalue' + }), JSON.stringify(actual)); + + actual = testObject.get('workbench'); + actual['unknownkey'] = 'somevalue'; + assert.deepEqual(JSON.stringify({ + 'colorCustomizations': { + 'statusBar.foreground': 'somevalue' + }, + 'emptyobjectkey': {}, + 'unknownkey': 'somevalue' + }), JSON.stringify(actual)); + + actual = all.getConfiguration('workbench').get('emptyobjectkey'); + actual = assign(actual || {}, { + 'statusBar.background': `#0ff`, + 'statusBar.foreground': `#ff0`, + }); + assert.deepEqual(JSON.stringify({ + 'statusBar.background': `#0ff`, + 'statusBar.foreground': `#ff0`, + }), JSON.stringify(actual)); + + actual = all.getConfiguration('workbench').get('unknownkey'); + actual = assign(actual || {}, { + 'statusBar.background': `#0ff`, + 'statusBar.foreground': `#ff0`, + }); + assert.deepEqual(JSON.stringify({ + 'statusBar.background': `#0ff`, + 'statusBar.foreground': `#ff0`, + }), JSON.stringify(actual)); + }); + test('cannot modify returned configuration', function () { const all = createExtHostConfiguration({