fix(language-service): reset MockHost after every spec instead of creating new LS (#33200)

This commit speeds up the tests by calling `MockHost.reset()` in
`beforeEach()` instead of destroying the entire language service and
creating a new one. The creation of a new language service instance is
expensive due to the need to initialize many core Symbols when creating
a new program.

This speeds ups the test (on my local machine) from 35 secs to 15 secs.

PR Close #33200
This commit is contained in:
Keen Yee Liau 2019-10-16 12:00:41 -07:00 committed by Matias Niemelä
parent 43241a560a
commit 11bf7679a1
6 changed files with 27 additions and 62 deletions

View File

@ -13,7 +13,6 @@ ts_library(
"//packages/compiler", "//packages/compiler",
"//packages/compiler-cli/test:test_utils", "//packages/compiler-cli/test:test_utils",
"//packages/language-service", "//packages/language-service",
"@npm//reflect-metadata",
"@npm//typescript", "@npm//typescript",
], ],
) )

View File

@ -9,24 +9,17 @@
import * as ts from 'typescript'; import * as ts from 'typescript';
import {createLanguageService} from '../src/language_service'; import {createLanguageService} from '../src/language_service';
import {LanguageService} from '../src/types';
import {TypeScriptServiceHost} from '../src/typescript_host'; import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils'; import {MockTypescriptHost} from './test_utils';
describe('definitions', () => { describe('definitions', () => {
let mockHost: MockTypescriptHost; const mockHost = new MockTypescriptHost(['/app/main.ts']);
let service: ts.LanguageService; const service = ts.createLanguageService(mockHost);
let ngHost: TypeScriptServiceHost; const ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService: LanguageService; const ngService = createLanguageService(ngHost);
beforeEach(() => { beforeEach(() => { mockHost.reset(); });
// Create a new mockHost every time to reset any files that are overridden.
mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
service = ts.createLanguageService(mockHost);
ngHost = new TypeScriptServiceHost(mockHost, service);
ngService = createLanguageService(ngHost);
});
it('should be able to find field in an interpolation', () => { it('should be able to find field in an interpolation', () => {
const fileName = mockHost.addCode(` const fileName = mockHost.addCode(`
@ -201,7 +194,6 @@ describe('definitions', () => {
}); });
it('should be able to find an input provider', () => { it('should be able to find an input provider', () => {
// '/app/parsing-cases.ts', 'tcName',
const fileName = mockHost.addCode(` const fileName = mockHost.addCode(`
@Component({ @Component({
template: '<test-comp ~{start-my}[«tcName»]="name"~{end-my}></div>' template: '<test-comp ~{start-my}[«tcName»]="name"~{end-my}></div>'

View File

@ -8,7 +8,6 @@
import * as ts from 'typescript'; import * as ts from 'typescript';
import {createLanguageService} from '../src/language_service'; import {createLanguageService} from '../src/language_service';
import * as ng from '../src/types';
import {TypeScriptServiceHost} from '../src/typescript_host'; import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils'; import {MockTypescriptHost} from './test_utils';
@ -29,17 +28,12 @@ const NG_FOR_CASES = '/app/ng-for-cases.ts';
const NG_IF_CASES = '/app/ng-if-cases.ts'; const NG_IF_CASES = '/app/ng-if-cases.ts';
describe('diagnostics', () => { describe('diagnostics', () => {
let mockHost: MockTypescriptHost; const mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
let ngHost: TypeScriptServiceHost; const tsLS = ts.createLanguageService(mockHost);
let tsLS: ts.LanguageService; const ngHost = new TypeScriptServiceHost(mockHost, tsLS);
let ngLS: ng.LanguageService; const ngLS = createLanguageService(ngHost);
beforeEach(() => { beforeEach(() => { mockHost.reset(); });
mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
tsLS = ts.createLanguageService(mockHost);
ngHost = new TypeScriptServiceHost(mockHost, tsLS);
ngLS = createLanguageService(ngHost);
});
it('should produce no diagnostics for test.ng', () => { it('should produce no diagnostics for test.ng', () => {
// there should not be any errors on existing external template // there should not be any errors on existing external template

View File

@ -9,28 +9,17 @@
import * as ts from 'typescript'; import * as ts from 'typescript';
import {createLanguageService} from '../src/language_service'; import {createLanguageService} from '../src/language_service';
import {LanguageService} from '../src/types';
import {TypeScriptServiceHost} from '../src/typescript_host'; import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils'; import {MockTypescriptHost} from './test_utils';
fdescribe('hover', () => { describe('hover', () => {
// const mockHost: MockTypescriptHost;
// const tsLS: ts.LanguageService;
// const ngLSHost: TypeScriptServiceHost;
// const ngLS: LanguageService;
const mockHost = new MockTypescriptHost(['/app/main.ts']); const mockHost = new MockTypescriptHost(['/app/main.ts']);
const tsLS = ts.createLanguageService(mockHost); const tsLS = ts.createLanguageService(mockHost);
const ngLSHost = new TypeScriptServiceHost(mockHost, tsLS); const ngLSHost = new TypeScriptServiceHost(mockHost, tsLS);
const ngLS = createLanguageService(ngLSHost); const ngLS = createLanguageService(ngLSHost);
beforeEach(() => { beforeEach(() => { mockHost.reset(); });
// mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
// tsLS = ts.createLanguageService(mockHost);
// ngLSHost = new TypeScriptServiceHost(mockHost, tsLS);
// ngLS = createLanguageService(ngLSHost);
mockHost.reset();
});
it('should be able to find field in an interpolation', () => { it('should be able to find field in an interpolation', () => {
const fileName = mockHost.addCode(` const fileName = mockHost.addCode(`
@ -188,20 +177,18 @@ fdescribe('hover', () => {
}); });
it('should be able to find the NgModule of a directive', () => { it('should be able to find the NgModule of a directive', () => {
const fileName = '/app/app.component.ts'; const fileName = '/app/parsing-cases.ts';
mockHost.override(fileName, ` const content = mockHost.readFile(fileName) !;
import {Directive} from '@angular/core'; const position = content.indexOf('StringModel');
expect(position).toBeGreaterThan(0);
@Directive({ const quickInfo = ngLS.getHoverAt(fileName, position);
selector: '[string-model]',
})
export class «AppComponent» {}`);
const marker = mockHost.getReferenceMarkerFor(fileName, 'AppComponent');
const quickInfo = ngLS.getHoverAt(fileName, marker.start);
expect(quickInfo).toBeTruthy(); expect(quickInfo).toBeTruthy();
const {textSpan, displayParts} = quickInfo !; const {textSpan, displayParts} = quickInfo !;
expect(textSpan).toEqual(marker); expect(textSpan).toEqual({
expect(toText(displayParts)).toBe('(directive) AppModule.AppComponent: class'); start: position,
length: 'StringModel'.length,
});
expect(toText(displayParts)).toBe('(directive) AppModule.StringModel: class');
}); });
}); });

View File

@ -15,18 +15,12 @@ import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils'; import {MockTypescriptHost} from './test_utils';
describe('references', () => { describe('references', () => {
let documentRegistry = ts.createDocumentRegistry(); const mockHost = new MockTypescriptHost(['/app/main.ts']);
let mockHost: MockTypescriptHost; const service = ts.createLanguageService(mockHost);
let service: ts.LanguageService; const ngHost = new TypeScriptServiceHost(mockHost, service);
let ngHost: TypeScriptServiceHost; const ngService = createLanguageService(ngHost);
let ngService: LanguageService = createLanguageService(undefined !);
beforeEach(() => { beforeEach(() => { mockHost.reset(); });
mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
service = ts.createLanguageService(mockHost, documentRegistry);
ngHost = new TypeScriptServiceHost(mockHost, service);
ngService = createLanguageService(ngHost);
});
it('should be able to get template references', it('should be able to get template references',
() => { expect(() => ngService.getTemplateReferences()).not.toThrow(); }); () => { expect(() => ngService.getTemplateReferences()).not.toThrow(); });

View File

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import 'reflect-metadata';
import * as ts from 'typescript'; import * as ts from 'typescript';
import {TypeScriptServiceHost} from '../src/typescript_host'; import {TypeScriptServiceHost} from '../src/typescript_host';