Skip to content

Commit 4a512cf

Browse files
amysortommalerba
authored andcommitted
fix(material/schematics): add custom replacements for imports
1 parent 018a6f7 commit 4a512cf

File tree

3 files changed

+106
-7
lines changed

3 files changed

+106
-7
lines changed

src/material/schematics/ng-generate/mdc-migration/rules/ts-migration/import-replacements.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
export const IMPORT_REPLACEMENTS: {[component: string]: {old: string; new: string}} = {
9+
export interface ImportReplacement {
10+
old: string;
11+
new: string;
12+
additionalMatModuleNamePrefixes?: string[];
13+
customReplacements?: {old: string; new: string}[];
14+
}
15+
16+
// TODO: Add rest of custom replacements for components here
17+
export const REPLACEMENTS: {[component: string]: ImportReplacement} = {
1018
'button': {
1119
old: '@angular/material/legacy-button',
1220
new: '@angular/material/button',
@@ -22,10 +30,12 @@ export const IMPORT_REPLACEMENTS: {[component: string]: {old: string; new: strin
2230
'chips': {
2331
old: '@angular/material/legacy-chips',
2432
new: '@angular/material/chips',
33+
additionalMatModuleNamePrefixes: ['chip'],
2534
},
2635
'dialog': {
2736
old: '@angular/material/legacy-dialog',
2837
new: '@angular/material/dialog',
38+
customReplacements: [{old: 'LegacyDialogRole', new: 'DialogRole'}],
2939
},
3040
'autocomplete': {
3141
old: '@angular/material/legacy-autocomplete',

src/material/schematics/ng-generate/mdc-migration/rules/ts-migration/runtime-migrator.spec.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ describe('button runtime code', () => {
1717

1818
async function runMigrationTest(oldFileContent: string, newFileContent: string) {
1919
cliAppTree.overwrite(APP_MODULE_FILE, oldFileContent);
20-
const tree = await migrateComponents(['button', 'card', 'dialog'], runner, cliAppTree);
20+
const tree = await migrateComponents(
21+
['button', 'card', 'chips', 'dialog', 'progress-bar'],
22+
runner,
23+
cliAppTree,
24+
);
2125
expect(tree.readContent(APP_MODULE_FILE)).toBe(newFileContent);
2226
}
2327

@@ -41,6 +45,25 @@ describe('button runtime code', () => {
4145
);
4246
});
4347

48+
it('should replace the old import with the new one for hyphenated component names', async () => {
49+
await runMigrationTest(
50+
`
51+
import {NgModule} from '@angular/core';
52+
import {MatLegacyProgressBarModule} from '@angular/material/legacy-progress-bar';
53+
54+
@NgModule({imports: [MatLegacyProgressBarModule]})
55+
export class AppModule {}
56+
`,
57+
`
58+
import {NgModule} from '@angular/core';
59+
import {MatProgressBarModule} from '@angular/material/progress-bar';
60+
61+
@NgModule({imports: [MatProgressBarModule]})
62+
export class AppModule {}
63+
`,
64+
);
65+
});
66+
4467
it('should replace the old imports with the new ones', async () => {
4568
await runMigrationTest(
4669
`
@@ -60,6 +83,44 @@ describe('button runtime code', () => {
6083
);
6184
});
6285

86+
it('should replace the old imports with the new ones including different specified module name prefixes', async () => {
87+
await runMigrationTest(
88+
`
89+
import {NgModule} from '@angular/core';
90+
import {MatLegacyChipsModule, MatLegacyChipEvent} from '@angular/material/legacy-chips';
91+
92+
@NgModule({imports: [MatLegacyChipsModule]})
93+
export class AppModule {}
94+
`,
95+
`
96+
import {NgModule} from '@angular/core';
97+
import {MatChipsModule, MatChipEvent} from '@angular/material/chips';
98+
99+
@NgModule({imports: [MatChipsModule]})
100+
export class AppModule {}
101+
`,
102+
);
103+
});
104+
105+
it('should replace the old imports with the new ones including custom replacements', async () => {
106+
await runMigrationTest(
107+
`
108+
import {NgModule} from '@angular/core';
109+
import {MatLegacyDialogModule, LegacyDialogRole} from '@angular/material/legacy-dialog';
110+
111+
@NgModule({imports: [MatLegacyDialogModule]})
112+
export class AppModule {}
113+
`,
114+
`
115+
import {NgModule} from '@angular/core';
116+
import {MatDialogModule, DialogRole} from '@angular/material/dialog';
117+
118+
@NgModule({imports: [MatDialogModule]})
119+
export class AppModule {}
120+
`,
121+
);
122+
});
123+
63124
it('should migrate multi-line imports', async () => {
64125
await runMigrationTest(
65126
`

src/material/schematics/ng-generate/mdc-migration/rules/ts-migration/runtime-migrator.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,47 @@
77
*/
88

99
import * as ts from 'typescript';
10-
import {IMPORT_REPLACEMENTS} from './import-replacements';
10+
import {ImportReplacement, REPLACEMENTS} from './import-replacements';
1111

1212
export class RuntimeMigrator {
1313
oldImportModule: string;
1414
newImportModule: string;
1515
importSpecifierReplacements: {old: string; new: string}[];
1616

1717
constructor(component: string) {
18-
const replacements = IMPORT_REPLACEMENTS[component];
18+
const replacements = REPLACEMENTS[component];
1919
this.oldImportModule = replacements.old;
2020
this.newImportModule = replacements.new;
2121

22-
const firstLetterCapitalizedComponent = component[0].toUpperCase() + component.slice(1);
23-
const capitalizedComponent = component.toUpperCase();
24-
this.importSpecifierReplacements = [
22+
this.importSpecifierReplacements = this.getReplacementsFromComponentName(component);
23+
24+
replacements.additionalMatModuleNamePrefixes?.forEach(prefix => {
25+
this.importSpecifierReplacements = this.importSpecifierReplacements.concat(
26+
this.getReplacementsFromComponentName(prefix),
27+
);
28+
});
29+
30+
replacements.customReplacements?.forEach(replacement => {
31+
this.importSpecifierReplacements = this.importSpecifierReplacements.concat(replacement);
32+
});
33+
34+
console.log(this.importSpecifierReplacements);
35+
}
36+
37+
getReplacementsFromComponentName(componentName: string): ImportReplacement[] {
38+
const words = componentName.split('-');
39+
40+
let firstLetterCapitalizedComponent = '';
41+
let capitalizedComponent = '';
42+
words.forEach(word => {
43+
firstLetterCapitalizedComponent += word[0].toUpperCase() + word.slice(1);
44+
capitalizedComponent += word.toUpperCase() + '_';
45+
});
46+
47+
/// Remove trailing underscore at the end
48+
capitalizedComponent = capitalizedComponent.slice(0, -1);
49+
50+
const specifierReplacements = [
2551
{
2652
old: 'MatLegacy' + firstLetterCapitalizedComponent,
2753
new: 'Mat' + firstLetterCapitalizedComponent,
@@ -31,6 +57,8 @@ export class RuntimeMigrator {
3157
new: 'MAT_' + capitalizedComponent,
3258
},
3359
];
60+
61+
return specifierReplacements;
3462
}
3563

3664
updateImportOrExportSpecifier(specifier: ts.Identifier): ts.Identifier | null {

0 commit comments

Comments
 (0)