Fixes all TypeScript failures caused by enabling the `--strict` flag for test source files. We also want to enable the strict options for tests as the strictness enforcement improves the overall codehealth, unveiled common issues and additionally it allows us to enable `strict` in the `tsconfig.json` that is picked up by IDE's. PR Close #30993
186 lines
6.0 KiB
TypeScript
186 lines
6.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import {AbsoluteFsPath, resolve} from '@angular/compiler-cli/src/ngtsc/file_system';
|
|
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
import {AbsoluteSourceSpan, IdentifierKind, IndexedComponent, TopLevelIdentifier} from '@angular/compiler-cli/src/ngtsc/indexer';
|
|
import {ParseSourceFile} from '@angular/compiler/src/compiler';
|
|
|
|
import {NgtscTestEnvironment} from './env';
|
|
|
|
runInEachFileSystem(() => {
|
|
describe('ngtsc component indexing', () => {
|
|
let env !: NgtscTestEnvironment;
|
|
let testSourceFile: AbsoluteFsPath;
|
|
let testTemplateFile: AbsoluteFsPath;
|
|
|
|
beforeEach(() => {
|
|
env = NgtscTestEnvironment.setup();
|
|
env.tsconfig();
|
|
testSourceFile = resolve(env.basePath, 'test.ts');
|
|
testTemplateFile = resolve(env.basePath, 'test.html');
|
|
});
|
|
|
|
describe('indexing metadata', () => {
|
|
it('should generate component metadata', () => {
|
|
const componentContent = `
|
|
import {Component} from '@angular/core';
|
|
|
|
@Component({
|
|
selector: 'test-cmp',
|
|
template: '<div></div>',
|
|
})
|
|
export class TestCmp {}
|
|
`;
|
|
env.write(testSourceFile, componentContent);
|
|
const indexed = env.driveIndexer();
|
|
expect(indexed.size).toBe(1);
|
|
|
|
const [[decl, indexedComp]] = Array.from(indexed.entries());
|
|
|
|
expect(decl.getText()).toContain('export class TestCmp {}');
|
|
expect(indexedComp).toEqual(jasmine.objectContaining<IndexedComponent>({
|
|
name: 'TestCmp',
|
|
selector: 'test-cmp',
|
|
file: new ParseSourceFile(componentContent, testSourceFile),
|
|
}));
|
|
});
|
|
|
|
it('should index inline templates', () => {
|
|
const componentContent = `
|
|
import {Component} from '@angular/core';
|
|
|
|
@Component({
|
|
selector: 'test-cmp',
|
|
template: '{{foo}}',
|
|
})
|
|
export class TestCmp { foo = 0; }
|
|
`;
|
|
env.write(testSourceFile, componentContent);
|
|
const indexed = env.driveIndexer();
|
|
const [[_, indexedComp]] = Array.from(indexed.entries());
|
|
const template = indexedComp.template;
|
|
|
|
expect(template).toEqual({
|
|
identifiers: new Set<TopLevelIdentifier>([{
|
|
name: 'foo',
|
|
kind: IdentifierKind.Property,
|
|
span: new AbsoluteSourceSpan(127, 130),
|
|
}]),
|
|
usedComponents: new Set(),
|
|
isInline: true,
|
|
file: new ParseSourceFile(componentContent, testSourceFile),
|
|
});
|
|
});
|
|
|
|
it('should index external templates', () => {
|
|
env.write(testSourceFile, `
|
|
import {Component} from '@angular/core';
|
|
|
|
@Component({
|
|
selector: 'test-cmp',
|
|
templateUrl: './test.html',
|
|
})
|
|
export class TestCmp { foo = 0; }
|
|
`);
|
|
env.write(testTemplateFile, '{{foo}}');
|
|
const indexed = env.driveIndexer();
|
|
const [[_, indexedComp]] = Array.from(indexed.entries());
|
|
const template = indexedComp.template;
|
|
|
|
expect(template).toEqual({
|
|
identifiers: new Set<TopLevelIdentifier>([{
|
|
name: 'foo',
|
|
kind: IdentifierKind.Property,
|
|
span: new AbsoluteSourceSpan(2, 5),
|
|
}]),
|
|
usedComponents: new Set(),
|
|
isInline: false,
|
|
file: new ParseSourceFile('{{foo}}', testTemplateFile),
|
|
});
|
|
});
|
|
|
|
it('should index templates compiled without preserving whitespace', () => {
|
|
env.tsconfig({
|
|
preserveWhitespaces: false,
|
|
});
|
|
|
|
env.write(testSourceFile, `
|
|
import {Component} from '@angular/core';
|
|
|
|
@Component({
|
|
selector: 'test-cmp',
|
|
templateUrl: './test.html',
|
|
})
|
|
export class TestCmp { foo = 0; }
|
|
`);
|
|
env.write(testTemplateFile, ' \n {{foo}}');
|
|
const indexed = env.driveIndexer();
|
|
const [[_, indexedComp]] = Array.from(indexed.entries());
|
|
const template = indexedComp.template;
|
|
|
|
expect(template).toEqual({
|
|
identifiers: new Set<TopLevelIdentifier>([{
|
|
name: 'foo',
|
|
kind: IdentifierKind.Property,
|
|
span: new AbsoluteSourceSpan(7, 10),
|
|
}]),
|
|
usedComponents: new Set(),
|
|
isInline: false,
|
|
file: new ParseSourceFile(' \n {{foo}}', testTemplateFile),
|
|
});
|
|
});
|
|
|
|
it('should generate information about used components', () => {
|
|
env.write(testSourceFile, `
|
|
import {Component} from '@angular/core';
|
|
|
|
@Component({
|
|
selector: 'test-cmp',
|
|
templateUrl: './test.html',
|
|
})
|
|
export class TestCmp {}
|
|
`);
|
|
env.write(testTemplateFile, '<div></div>');
|
|
env.write('test_import.ts', `
|
|
import {Component, NgModule} from '@angular/core';
|
|
import {TestCmp} from './test';
|
|
|
|
@Component({
|
|
templateUrl: './test_import.html',
|
|
})
|
|
export class TestImportCmp {}
|
|
|
|
@NgModule({
|
|
declarations: [
|
|
TestCmp,
|
|
TestImportCmp,
|
|
],
|
|
bootstrap: [TestImportCmp]
|
|
})
|
|
export class TestModule {}
|
|
`);
|
|
env.write('test_import.html', '<test-cmp></test-cmp>');
|
|
const indexed = env.driveIndexer();
|
|
expect(indexed.size).toBe(2);
|
|
|
|
const indexedComps = Array.from(indexed.values());
|
|
const testComp = indexedComps.find(comp => comp.name === 'TestCmp');
|
|
const testImportComp = indexedComps.find(cmp => cmp.name === 'TestImportCmp');
|
|
expect(testComp).toBeDefined();
|
|
expect(testImportComp).toBeDefined();
|
|
|
|
expect(testComp !.template.usedComponents.size).toBe(0);
|
|
expect(testImportComp !.template.usedComponents.size).toBe(1);
|
|
|
|
const [usedComp] = Array.from(testImportComp !.template.usedComponents);
|
|
expect(indexed.get(usedComp)).toEqual(testComp);
|
|
});
|
|
});
|
|
});
|
|
});
|