Update the license headers throughout the repository to reference Google LLC rather than Google Inc, for the required license headers. PR Close #37205
		
			
				
	
	
		
			189 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google LLC 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),
 | |
|             target: null,
 | |
|           }]),
 | |
|           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),
 | |
|             target: null,
 | |
|           }]),
 | |
|           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),
 | |
|             target: null,
 | |
|           }]),
 | |
|           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);
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| });
 |