From de75fe03587dd5cbfc0eb3db44a745cd60293d17 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 11 Mar 2024 16:18:51 +0000 Subject: [PATCH] test(compiler-cli): add tests to verify import generation in TCB files/blocks (#54819) This commit adds some unit tests verifying the import generation in TCB files and inline blocks. We don't seem to have any unit tests for these in general. This commit adds some, verifying some characteristics we would like to guarantee. PR Close #54819 --- .../typecheck/test/type_check_block_spec.ts | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts index cb9af4fee47..79ef478a385 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts @@ -8,10 +8,11 @@ import ts from 'typescript'; +import {absoluteFrom, getSourceFileOrError} from '../../file_system'; import {initMockFileSystem} from '../../file_system/testing'; import {Reference} from '../../imports'; -import {TypeCheckingConfig} from '../api'; -import {ALL_ENABLED_CONFIG, tcb, TestDeclaration, TestDirective} from '../testing'; +import {OptimizeFor, TypeCheckingConfig} from '../api'; +import {ALL_ENABLED_CONFIG, setup, tcb, TestDeclaration, TestDirective} from '../testing'; describe('type check blocks', () => { @@ -1744,4 +1745,55 @@ describe('type check blocks', () => { expect(result).toContain('(this).trackingFn(_t2, _t1, ((this).prop));'); }); }); + + describe('import generation', () => { + const TEMPLATE = `
`; + const DIRECTIVE: TestDeclaration = { + type: 'directive', + name: 'Dir', + selector: '[dir]', + inputs: { + test: { + isSignal: true, + bindingPropertyName: 'test', + classPropertyName: 'test', + required: true, + transform: null, + } + } + }; + + it('should prefer namespace imports in type check files for new imports', () => { + const result = tcb(TEMPLATE, [DIRECTIVE]); + + expect(result).toContain(`import * as i1 from '@angular/core';`); + expect(result).toContain(`[i1.ɵINPUT_SIGNAL_BRAND_WRITE_TYPE]`); + }); + + it('should re-use existing imports from original source files', () => { + // This is especially important for inline type check blocks. + // See: https://github.com/angular/angular/pull/53521#pullrequestreview-1778130879. + const {templateTypeChecker, program, programStrategy} = setup([{ + fileName: absoluteFrom('/test.ts'), + templates: {'AppComponent': TEMPLATE}, + declarations: [DIRECTIVE], + source: ` + import {Component} from '@angular/core'; // should be re-used + + class AppComponent {} + export class Dir {} + `, + }]); + + // Trigger type check block generation. + templateTypeChecker.getDiagnosticsForFile( + getSourceFileOrError(program, absoluteFrom('/test.ts')), OptimizeFor.SingleFile); + + const testSf = getSourceFileOrError(programStrategy.getProgram(), absoluteFrom('/test.ts')); + expect(testSf.text) + .toContain( + `import { Component, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE } from '@angular/core'; // should be re-used`); + expect(testSf.text).toContain(`[ɵINPUT_SIGNAL_BRAND_WRITE_TYPE]`); + }); + }); });