refactor(language-service): migrate type_definitions_spec to the new testing package (#40966)
refactor(language-service): migrate type_definitions_spec to the new testing package PR Close #40966
This commit is contained in:
parent
d1b7774753
commit
000ec6be3c
|
@ -6,21 +6,17 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||
import {initMockFileSystem, TestFile} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
||||
import {initMockFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
||||
|
||||
import {LanguageServiceTestEnvironment} from './env';
|
||||
import {humanizeDocumentSpanLike} from './test_utils';
|
||||
import {extractCursorInfo, humanizeDocumentSpanLike, LanguageServiceTestEnv, Project} from '../testing';
|
||||
|
||||
describe('type definitions', () => {
|
||||
let env: LanguageServiceTestEnvironment;
|
||||
let env: LanguageServiceTestEnv;
|
||||
|
||||
it('returns the pipe class as definition when checkTypeOfPipes is false', () => {
|
||||
initMockFileSystem('Native');
|
||||
const testFiles: TestFile[] = [
|
||||
{
|
||||
name: absoluteFrom('/app.ts'),
|
||||
contents: `
|
||||
const files = {
|
||||
'app.ts': `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
|
||||
|
@ -30,17 +26,13 @@ describe('type definitions', () => {
|
|||
@NgModule({declarations: [AppCmp], imports: [CommonModule]})
|
||||
export class AppModule {}
|
||||
`,
|
||||
isRoot: true
|
||||
},
|
||||
{
|
||||
name: absoluteFrom('/app.html'),
|
||||
contents: `Will be overridden`,
|
||||
}
|
||||
];
|
||||
'app.html': `Will be overridden`,
|
||||
};
|
||||
// checkTypeOfPipes is set to false when strict templates is false
|
||||
env = LanguageServiceTestEnvironment.setup(testFiles, {strictTemplates: false});
|
||||
env = LanguageServiceTestEnv.setup();
|
||||
const project = env.addProject('test', files, {strictTemplates: false});
|
||||
const definitions =
|
||||
getTypeDefinitionsAndAssertBoundSpan({templateOverride: '{{"1/1/2020" | dat¦e}}'});
|
||||
getTypeDefinitionsAndAssertBoundSpan(project, {templateOverride: '{{"1/1/2020" | dat¦e}}'});
|
||||
expect(definitions!.length).toEqual(1);
|
||||
|
||||
const [def] = definitions;
|
||||
|
@ -48,14 +40,17 @@ describe('type definitions', () => {
|
|||
expect(def.contextSpan).toContain('DatePipe');
|
||||
});
|
||||
|
||||
function getTypeDefinitionsAndAssertBoundSpan({templateOverride}: {templateOverride: string}) {
|
||||
const {cursor, text} = env.updateFileWithCursor(absoluteFrom('/app.html'), templateOverride);
|
||||
function getTypeDefinitionsAndAssertBoundSpan(
|
||||
project: Project, {templateOverride}: {templateOverride: string}) {
|
||||
const {text} = extractCursorInfo(templateOverride);
|
||||
const template = project.openFile('app.html');
|
||||
template.contents = text;
|
||||
env.expectNoSourceDiagnostics();
|
||||
env.expectNoTemplateDiagnostics(absoluteFrom('/app.ts'), 'AppCmp');
|
||||
const defs = env.ngLS.getTypeDefinitionAtPosition(absoluteFrom('/app.html'), cursor);
|
||||
project.expectNoTemplateDiagnostics('app.ts', 'AppCmp');
|
||||
|
||||
template.moveCursorToText(templateOverride);
|
||||
const defs = template.getTypeDefinitionAtPosition();
|
||||
expect(defs).toBeTruthy();
|
||||
const overrides = new Map<string, string>();
|
||||
overrides.set(absoluteFrom('/app.html'), text);
|
||||
return defs!.map(d => humanizeDocumentSpanLike(d, env, overrides));
|
||||
return defs!.map(d => humanizeDocumentSpanLike(d, env));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -84,4 +84,8 @@ export class OpenBuffer {
|
|||
getQuickInfoAtPosition() {
|
||||
return this.ngLS.getQuickInfoAtPosition(this.scriptInfo.fileName, this._cursor);
|
||||
}
|
||||
|
||||
getTypeDefinitionAtPosition() {
|
||||
return this.ngLS.getTypeDefinitionAtPosition(this.scriptInfo.fileName, this._cursor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
*/
|
||||
|
||||
import {StrictTemplateOptions} from '@angular/compiler-cli/src/ngtsc/core/api';
|
||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||
import {OptimizeFor} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, getSourceFileOrError} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||
import {OptimizeFor, TemplateTypeChecker} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||
import * as ts from 'typescript/lib/tsserverlibrary';
|
||||
import {LanguageService} from '../../language_service';
|
||||
import {OpenBuffer} from './buffer';
|
||||
|
@ -156,4 +156,31 @@ export class Project {
|
|||
|
||||
this.ngLS.compilerFactory.registerLastKnownProgram();
|
||||
}
|
||||
|
||||
expectNoTemplateDiagnostics(projectFileName: string, className: string): void {
|
||||
const program = this.tsLS.getProgram();
|
||||
if (program === undefined) {
|
||||
throw new Error(`Expected to get a ts.Program`);
|
||||
}
|
||||
const fileName = absoluteFrom(`/${this.name}/${projectFileName}`);
|
||||
const sf = getSourceFileOrError(program, fileName);
|
||||
const component = getClassOrError(sf, className);
|
||||
|
||||
const diags = this.getTemplateTypeChecker().getDiagnosticsForComponent(component);
|
||||
this.ngLS.compilerFactory.registerLastKnownProgram();
|
||||
expect(diags.map(diag => diag.messageText)).toEqual([]);
|
||||
}
|
||||
|
||||
getTemplateTypeChecker(): TemplateTypeChecker {
|
||||
return this.ngLS.compilerFactory.getOrCreate().getTemplateTypeChecker();
|
||||
}
|
||||
}
|
||||
|
||||
function getClassOrError(sf: ts.SourceFile, name: string): ts.ClassDeclaration {
|
||||
for (const stmt of sf.statements) {
|
||||
if (ts.isClassDeclaration(stmt) && stmt.name !== undefined && stmt.name.text === name) {
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
throw new Error(`Class ${name} not found in file: ${sf.fileName}: ${sf.text}`);
|
||||
}
|
Loading…
Reference in New Issue