Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance improvements for initialization #6172

Merged
merged 1 commit into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions packages/core/src/browser/preferences/preference-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export interface PreferenceResolveResult<T> {
@injectable()
export abstract class PreferenceProvider implements Disposable {

protected readonly onDidPreferencesChangedEmitter = new Emitter<PreferenceProviderDataChanges | undefined>();
readonly onDidPreferencesChanged: Event<PreferenceProviderDataChanges | undefined> = this.onDidPreferencesChangedEmitter.event;
protected readonly onDidPreferencesChangedEmitter = new Emitter<PreferenceProviderDataChanges>();
readonly onDidPreferencesChanged: Event<PreferenceProviderDataChanges> = this.onDidPreferencesChangedEmitter.event;

protected readonly toDispose = new DisposableCollection();

Expand Down Expand Up @@ -74,14 +74,6 @@ export abstract class PreferenceProvider implements Disposable {
}
}

/**
* Informs the listeners that one or more preferences of this provider are changed.
* @deprecated Use emitPreferencesChangedEvent instead.
*/
protected fireOnDidPreferencesChanged(): void {
this.onDidPreferencesChangedEmitter.fire(undefined);
}

get<T>(preferenceName: string, resourceUri?: string): T | undefined {
return this.resolve<T>(preferenceName, resourceUri).value;
}
Expand Down
168 changes: 158 additions & 10 deletions packages/core/src/browser/preferences/preference-proxy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,166 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { createPreferenceProxy } from './preference-proxy';
import { MockPreferenceService } from './test/mock-preference-service';
import { expect } from 'chai';
// tslint:disable:no-any
// tslint:disable:no-unused-expression

describe('preference proxy', function (): void {
/** Verify the return type of the ready property. */
it('.ready should return a promise', function (): void {
import { enableJSDOM } from '../test/jsdom';

const proxy = createPreferenceProxy(new MockPreferenceService(), {
properties: {}
let disableJSDOM = enableJSDOM();

import * as assert from 'assert';
import { Container } from 'inversify';
import { bindPreferenceService } from '../frontend-application-bindings';
import { bindMockPreferenceProviders, MockPreferenceProvider } from './test';
import { PreferenceService, PreferenceServiceImpl } from './preference-service';
import { PreferenceSchemaProvider, PreferenceSchema } from './preference-contribution';
import { PreferenceScope } from './preference-scope';
import { PreferenceProvider } from './preference-provider';
import { FrontendApplicationConfigProvider } from '../frontend-application-config-provider';
import { createPreferenceProxy, PreferenceProxyOptions, PreferenceProxy, PreferenceChangeEvent } from './preference-proxy';

disableJSDOM();

process.on('unhandledRejection', (reason, promise) => {
console.error(reason);
throw reason;
});

const { expect } = require('chai');
let testContainer: Container;

function createTestContainer(): Container {
const result = new Container();
bindPreferenceService(result.bind.bind(result));
bindMockPreferenceProviders(result.bind.bind(result), result.unbind.bind(result));
return result;
}

describe('Preference Proxy', () => {
let prefService: PreferenceServiceImpl;
let prefSchema: PreferenceSchemaProvider;

before(() => {
disableJSDOM = enableJSDOM();
FrontendApplicationConfigProvider.set({
'applicationName': 'test',
});
});

after(() => {
disableJSDOM();
});

beforeEach(async () => {
testContainer = createTestContainer();
prefSchema = testContainer.get(PreferenceSchemaProvider);
prefService = testContainer.get<PreferenceService>(PreferenceService) as PreferenceServiceImpl;
getProvider(PreferenceScope.User).markReady();
getProvider(PreferenceScope.Workspace).markReady();
getProvider(PreferenceScope.Folder).markReady();
console.log('before ready');
try {
await prefService.ready;
} catch (e) {
console.error(e);
}
console.log('done');
});

afterEach(() => {
});

function getProvider(scope: PreferenceScope): MockPreferenceProvider {
return testContainer.getNamed(PreferenceProvider, scope) as MockPreferenceProvider;
}

function getProxy(schema?: PreferenceSchema, options?: PreferenceProxyOptions): PreferenceProxy<{ [key: string]: any }> {
const s: PreferenceSchema = schema || {
properties: {
'my.pref': {
type: 'string',
defaultValue: 'foo'
}
}
};
prefSchema.setSchema(s);
return createPreferenceProxy(prefService, s, options);
}

it('by default, it should get provide access in flat style but not deep', () => {
const proxy = getProxy();
expect(proxy['my.pref']).to.equal('foo');
expect(proxy.my).to.equal(undefined);
expect(Object.keys(proxy).join()).to.equal(['my.pref'].join());
});

it('it should get provide access in deep style but not flat', () => {
const proxy = getProxy(undefined, { style: 'deep' });
expect(proxy['my.pref']).to.equal(undefined);
expect(proxy.my.pref).to.equal('foo');
expect(Object.keys(proxy).join()).to.equal(['my'].join());
});

it('it should get provide access in to both styles', () => {
const proxy = getProxy(undefined, { style: 'both' });
expect(proxy['my.pref']).to.equal('foo');
expect(proxy.my.pref).to.equal('foo');
expect(Object.keys(proxy).join()).to.equal(['my', 'my.pref'].join());
});

it('it should forward change events', () => {
const proxy = getProxy(undefined, { style: 'both' });
let theChange: PreferenceChangeEvent<{ [key: string]: any }>;
proxy.onPreferenceChanged(change => {
expect(theChange).to.equal(undefined);
theChange = change;
});
const proto = Object.getPrototypeOf(proxy.ready);
expect(proto).to.equal(Promise.prototype);
let theSecondChange: PreferenceChangeEvent<{ [key: string]: any }>;
(proxy.my as PreferenceProxy<{ [key: string]: any }>).onPreferenceChanged(change => {
expect(theSecondChange).to.equal(undefined);
theSecondChange = change;
});

getProvider(PreferenceScope.User).setPreference('my.pref', 'bar');

expect(theChange!.newValue).to.equal('bar');
expect(theChange!.oldValue).to.equal(undefined);
expect(theChange!.preferenceName).to.equal('my.pref');
expect(theSecondChange!.newValue).to.equal('bar');
expect(theSecondChange!.oldValue).to.equal(undefined);
expect(theSecondChange!.preferenceName).to.equal('my.pref');
});

it('toJSON with deep', () => {
const proxy = getProxy({
properties: {
'foo.baz': {
type: 'number',
default: 4
},
'foo.bar.x': {
type: 'boolean',
default: true
},
'foo.bar.y': {
type: 'boolean',
default: false
},
'a': {
type: 'string',
default: 'a'
}
}
}, { style: 'deep' });
assert.deepStrictEqual(JSON.stringify(proxy, undefined, 2), JSON.stringify({
foo: {
baz: 4,
bar: {
x: true,
y: false
}
},
a: 'a'
}, undefined, 2), 'there should not be foo.bar.x to avoid sending excessive data to remote clients');
});
});
Loading