fix(migrations): account for variables in imports initializer (#55081)

Fixes that the control flow migration was throwing an error if the `imports` of a component are initialized to an identifier.

Fixes #55080.

PR Close #55081
This commit is contained in:
Kristiyan Kostadinov 2024-03-28 09:01:11 +01:00 committed by Dylan Hunn
parent ee76001431
commit 2f9d94bc4a
2 changed files with 74 additions and 2 deletions

View file

@ -84,9 +84,16 @@ function updateImportClause(clause: ts.ImportClause, removeCommonModule: boolean
function updateClassImports(
propAssignment: ts.PropertyAssignment, removeCommonModule: boolean): string|null {
const printer = ts.createPrinter();
const importList = propAssignment.initializer as ts.ArrayLiteralExpression;
const importList = propAssignment.initializer;
// Can't change non-array literals.
if (!ts.isArrayLiteralExpression(importList)) {
return null;
}
const removals = removeCommonModule ? importWithCommonRemovals : importRemovals;
const elements = importList.elements.filter(el => !removals.includes(el.getText()));
const elements =
importList.elements.filter(el => !ts.isIdentifier(el) || !removals.includes(el.text));
if (elements.length === importList.elements.length) {
// nothing changed
return null;

View file

@ -5442,6 +5442,71 @@ describe('control flow migration', () => {
expect(actual).toBe(expected);
});
it('should not modify `imports` initialized to a variable reference', async () => {
writeFile('/comp.ts', [
`import {Component} from '@angular/core';`,
`import {CommonModule} from '@angular/common';\n`,
`const IMPORTS = [CommonModule];\n`,
`@Component({`,
` imports: IMPORTS,`,
` template: '<span *ngIf="show">Content here</span>',`,
`})`,
`class Comp {`,
` show = false;`,
`}`,
].join('\n'));
await runMigration();
const actual = tree.readContent('/comp.ts');
const expected = [
`import {Component} from '@angular/core';`,
`import {CommonModule} from '@angular/common';\n`,
`const IMPORTS = [CommonModule];\n`,
`@Component({`,
` imports: IMPORTS,`,
` template: '@if (show) {<span>Content here</span>}',`,
`})`,
`class Comp {`,
` show = false;`,
`}`,
].join('\n');
expect(actual).toBe(expected);
});
it('should handle spread elements in the `imports` array', async () => {
writeFile('/comp.ts', [
`import {Component} from '@angular/core';`,
`import {CommonModule} from '@angular/common';\n`,
`const BEFORE = [];\n`,
`const AFTER = [];\n`,
`@Component({`,
` imports: [...BEFORE, CommonModule, ...AFTER],`,
` template: '<span *ngIf="show">Content here</span>',`,
`})`,
`class Comp {`,
` show = false;`,
`}`,
].join('\n'));
await runMigration();
const actual = tree.readContent('/comp.ts');
const expected = [
`import {Component} from '@angular/core';\n\n`,
`const BEFORE = [];\n`,
`const AFTER = [];\n`,
`@Component({`,
` imports: [...BEFORE, ...AFTER],`,
` template: '@if (show) {<span>Content here</span>}',`,
`})`,
`class Comp {`,
` show = false;`,
`}`,
].join('\n');
expect(actual).toBe(expected);
});
});
describe('no migration needed', () => {