refactor(language-service): migrate gettcb_spec to new testing package (#40966)

refactor(language-service): migrate gettcb_spec to new testing package

PR Close #40966
This commit is contained in:
Andrew Scott 2021-02-08 10:11:39 -08:00 committed by atscott
parent af3f95bd75
commit 8808002e54
3 changed files with 72 additions and 27 deletions

View File

@ -6,11 +6,9 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
import {initMockFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing'; import {initMockFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
import {extractCursorInfo} from './env'; import {createModuleAndProjectWithDeclarations, LanguageServiceTestEnv} from '../testing';
import {createModuleWithDeclarations} from './test_utils';
describe('get typecheck block', () => { describe('get typecheck block', () => {
beforeEach(() => { beforeEach(() => {
@ -18,20 +16,24 @@ describe('get typecheck block', () => {
}); });
it('should find the typecheck block for an inline template', () => { it('should find the typecheck block for an inline template', () => {
const {text, cursor} = extractCursorInfo(` const files = {
'app.ts': `
import {Component} from '@angular/core'; import {Component} from '@angular/core';
@Component({ @Component({
template: '<div>{{ my¦Prop }}</div>', template: '<div>{{ myProp }}</div>',
}) })
export class AppCmp { export class AppCmp {
myProp!: string; myProp!: string;
}`); }`
const appFi = absoluteFrom('/app.ts'); };
const env = createModuleWithDeclarations([{name: appFi, contents: text}]); const env = LanguageServiceTestEnv.setup();
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
project.expectNoSourceDiagnostics();
env.expectNoSourceDiagnostics(); const appFile = project.openFile('app.ts');
const result = env.ngLS.getTcb(appFi, cursor); appFile.moveCursorToText('{{ my¦Prop }}');
const result = appFile.getTcb();
if (result === undefined) { if (result === undefined) {
fail('Expected a valid TCB response'); fail('Expected a valid TCB response');
return; return;
@ -43,12 +45,8 @@ describe('get typecheck block', () => {
}); });
it('should find the typecheck block for an external template', () => { it('should find the typecheck block for an external template', () => {
const {text, cursor} = extractCursorInfo(`<div>{{ my¦Prop }}</div>`); const files = {
const templateFi = absoluteFrom('/app.html'); 'app.ts': `
const env = createModuleWithDeclarations(
[{
name: absoluteFrom('/app.ts'),
contents: `
import {Component} from '@angular/core'; import {Component} from '@angular/core';
@Component({ @Component({
@ -57,11 +55,15 @@ describe('get typecheck block', () => {
export class AppCmp { export class AppCmp {
myProp!: string; myProp!: string;
}`, }`,
}], 'app.html': '<div>{{ myProp }}</div>'
[{name: templateFi, contents: text}]); };
const env = LanguageServiceTestEnv.setup();
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
project.expectNoSourceDiagnostics();
env.expectNoSourceDiagnostics(); const htmlFile = project.openFile('app.html');
const result = env.ngLS.getTcb(templateFi, cursor); htmlFile.moveCursorToText('{{ my¦Prop }}');
const result = htmlFile.getTcb();
if (result === undefined) { if (result === undefined) {
fail('Expected a valid TCB response'); fail('Expected a valid TCB response');
return; return;
@ -73,20 +75,24 @@ describe('get typecheck block', () => {
}); });
it('should not find typecheck blocks outside a template', () => { it('should not find typecheck blocks outside a template', () => {
const {text, cursor} = extractCursorInfo(` const files = {
'app.ts': `
import {Component} from '@angular/core'; import {Component} from '@angular/core';
@Component({ @Component({
template: '<div>{{ myProp }}</div>', template: '<div>{{ myProp }}</div>',
}) })
export class AppCmp { export class AppCmp {
my¦Prop!: string; myProp!: string;
}`); }`
const appFi = absoluteFrom('/app.ts'); };
const env = createModuleWithDeclarations([{name: appFi, contents: text}]); const env = LanguageServiceTestEnv.setup();
const project = createModuleAndProjectWithDeclarations(env, 'test', files);
project.expectNoSourceDiagnostics();
env.expectNoSourceDiagnostics(); const appFile = project.openFile('app.ts');
const result = env.ngLS.getTcb(appFi, cursor); appFile.moveCursorToText('my¦Prop!: string;');
const result = appFile.getTcb();
expect(result).toBeUndefined(); expect(result).toBeUndefined();
}); });
}); });

View File

@ -76,4 +76,8 @@ export class OpenBuffer {
return this.ngLS.getCompletionEntryDetails( return this.ngLS.getCompletionEntryDetails(
this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences); this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences);
} }
getTcb() {
return this.ngLS.getTcb(this.scriptInfo.fileName, this._cursor);
}
} }

View File

@ -8,6 +8,7 @@
import {StrictTemplateOptions} from '@angular/compiler-cli/src/ngtsc/core/api'; import {StrictTemplateOptions} from '@angular/compiler-cli/src/ngtsc/core/api';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system'; import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
import { OptimizeFor } from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import * as ts from 'typescript/lib/tsserverlibrary'; import * as ts from 'typescript/lib/tsserverlibrary';
import {LanguageService} from '../../language_service'; import {LanguageService} from '../../language_service';
import {OpenBuffer} from './buffer'; import {OpenBuffer} from './buffer';
@ -119,4 +120,38 @@ export class Project {
diagnostics.push(...this.ngLS.getSemanticDiagnostics(fileName)); diagnostics.push(...this.ngLS.getSemanticDiagnostics(fileName));
return diagnostics; return diagnostics;
} }
expectNoSourceDiagnostics(): void {
const program = this.tsLS.getProgram();
if (program === undefined) {
throw new Error(`Expected to get a ts.Program`);
}
const ngCompiler = this.ngLS.compilerFactory.getOrCreate();
for (const sf of program.getSourceFiles()) {
if (sf.isDeclarationFile || sf.fileName.endsWith('.ngtypecheck.ts')) {
continue;
}
const syntactic = program.getSyntacticDiagnostics(sf);
expect(syntactic.map(diag => diag.messageText)).toEqual([]);
if (syntactic.length > 0) {
continue;
}
const semantic = program.getSemanticDiagnostics(sf);
expect(semantic.map(diag => diag.messageText)).toEqual([]);
if (semantic.length > 0) {
continue;
}
// It's more efficient to optimize for WholeProgram since we call this with every file in the
// program.
const ngDiagnostics = ngCompiler.getDiagnosticsForFile(sf, OptimizeFor.WholeProgram);
expect(ngDiagnostics.map(diag => diag.messageText)).toEqual([]);
}
this.ngLS.compilerFactory.registerLastKnownProgram();
}
} }