From da739b5e61af195cd3bd92136b39ec45aa464c45 Mon Sep 17 00:00:00 2001
From: Vladimir Potekhin <46284632+vladimirpotekhin@users.noreply.github.com>
Date: Thu, 2 Nov 2023 17:31:33 +0300
Subject: [PATCH] chore: add toggle migration (#5835)
---
.../ng-update/interfaces/html-comment.ts | 5 +
.../schematics/ng-update/interfaces/index.ts | 1 +
.../ng-update/utils/templates/index.ts | 6 +
.../utils/templates/template-comments.ts | 44 +++++++
.../v4/steps/constants/html-comments.ts | 9 ++
.../steps/constants/identifiers-to-replace.ts | 4 +
.../ng-update/v4/steps/constants/index.ts | 5 +
.../v4/steps/constants/inputs-to-remove.ts | 2 +
.../ng-update/v4/steps/migrate-templates.ts | 27 +++-
.../v4/steps/templates/toggles/index.ts | 1 +
.../steps/templates/toggles/migrate-toggle.ts | 40 ++++++
.../v4/tests/schematic-migrate-toggle.spec.ts | 120 ++++++++++++++++++
12 files changed, 257 insertions(+), 7 deletions(-)
create mode 100644 projects/cdk/schematics/ng-update/interfaces/html-comment.ts
create mode 100644 projects/cdk/schematics/ng-update/utils/templates/index.ts
create mode 100644 projects/cdk/schematics/ng-update/utils/templates/template-comments.ts
create mode 100644 projects/cdk/schematics/ng-update/v4/steps/constants/html-comments.ts
create mode 100644 projects/cdk/schematics/ng-update/v4/steps/constants/index.ts
create mode 100644 projects/cdk/schematics/ng-update/v4/steps/templates/toggles/migrate-toggle.ts
create mode 100644 projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-toggle.spec.ts
diff --git a/projects/cdk/schematics/ng-update/interfaces/html-comment.ts b/projects/cdk/schematics/ng-update/interfaces/html-comment.ts
new file mode 100644
index 000000000000..6959a1c85b60
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/interfaces/html-comment.ts
@@ -0,0 +1,5 @@
+export interface HtmlComment {
+ readonly tag: string;
+ readonly withAttrs: string[];
+ readonly comment: string;
+}
diff --git a/projects/cdk/schematics/ng-update/interfaces/index.ts b/projects/cdk/schematics/ng-update/interfaces/index.ts
index be8301b1760a..905962357780 100644
--- a/projects/cdk/schematics/ng-update/interfaces/index.ts
+++ b/projects/cdk/schematics/ng-update/interfaces/index.ts
@@ -1,4 +1,5 @@
export * from './asset';
+export * from './html-comment';
export * from './migration-warning';
export * from './removable-input';
export * from './removed-module';
diff --git a/projects/cdk/schematics/ng-update/utils/templates/index.ts b/projects/cdk/schematics/ng-update/utils/templates/index.ts
new file mode 100644
index 000000000000..8f18ddf5bcde
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/utils/templates/index.ts
@@ -0,0 +1,6 @@
+export * from './remove-inputs';
+export * from './replace-attr-values';
+export * from './replace-attrs';
+export * from './replace-tag';
+export * from './replace-tags';
+export * from './template-comments';
diff --git a/projects/cdk/schematics/ng-update/utils/templates/template-comments.ts b/projects/cdk/schematics/ng-update/utils/templates/template-comments.ts
new file mode 100644
index 000000000000..92a5fb986e35
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/utils/templates/template-comments.ts
@@ -0,0 +1,44 @@
+import {UpdateRecorder} from '@angular-devkit/schematics';
+import {DevkitFileSystem} from 'ng-morph';
+
+import {TODO_MARK} from '../../../utils/insert-todo';
+import {findElementsWithAttributeOnTag} from '../../../utils/templates/elements';
+import {
+ getTemplateFromTemplateResource,
+ getTemplateOffset,
+} from '../../../utils/templates/template-resource';
+import {TemplateResource} from '../../interfaces';
+import {HtmlComment} from '../../interfaces';
+
+export function addHTMLCommentTags({
+ resource,
+ recorder,
+ fileSystem,
+ data,
+}: {
+ fileSystem: DevkitFileSystem;
+ recorder: UpdateRecorder;
+ data: readonly HtmlComment[];
+ resource: TemplateResource;
+}): void {
+ const template = getTemplateFromTemplateResource(resource, fileSystem);
+ const templateOffset = getTemplateOffset(resource);
+
+ data.forEach(({comment, tag, withAttrs}) => {
+ const elementStartOffsets = [
+ ...findElementsWithAttributeOnTag(template, withAttrs, [tag]),
+ ...findElementsWithAttributeOnTag(
+ template,
+ withAttrs.map(attr => `[${attr}]`),
+ [tag],
+ ),
+ ].map(
+ ({sourceCodeLocation}) =>
+ (sourceCodeLocation?.startOffset || 0) + templateOffset,
+ );
+
+ elementStartOffsets.forEach(offset => {
+ recorder.insertRight(offset, `\n`);
+ });
+ });
+}
diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/html-comments.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/html-comments.ts
new file mode 100644
index 000000000000..db3ca689883c
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/steps/constants/html-comments.ts
@@ -0,0 +1,9 @@
+import {HtmlComment} from '../../../interfaces';
+
+export const HTML_COMMENTS: HtmlComment[] = [
+ {
+ tag: `tui-toggle`,
+ withAttrs: [`singleColor`, `showLoader`],
+ comment: `toggle [singleColor] and [showLoader] inputs have been removed due to design changes`,
+ },
+];
diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
index 878f0b301e21..a7c8278cff28 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts
@@ -24,6 +24,10 @@ export const IDENTIFIERS_TO_REPLACE: ReplacementIdentifier[] = [
from: {name: `TuiRadioModule`, moduleSpecifier: `@taiga-ui/experimental`},
to: {name: `TuiRadioModule`, moduleSpecifier: `@taiga-ui/kit`},
},
+ {
+ from: {name: `TuiToggleModule`, moduleSpecifier: `@taiga-ui/experimental`},
+ to: {name: `TuiToggleModule`, moduleSpecifier: `@taiga-ui/kit`},
+ },
{
from: {name: `TuiTextAreaModule`, moduleSpecifier: `@taiga-ui/kit`},
to: {name: `TuiTextareaModule`, moduleSpecifier: `@taiga-ui/kit`},
diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/index.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/index.ts
new file mode 100644
index 000000000000..60b6f766557f
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/steps/constants/index.ts
@@ -0,0 +1,5 @@
+export * from './attrs-to-replace';
+export * from './html-comments';
+export * from './identifiers-to-replace';
+export * from './inputs-to-remove';
+export * from './tags-to-replace';
diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/inputs-to-remove.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/inputs-to-remove.ts
index 086e6dd9b6fb..411de39978e1 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/constants/inputs-to-remove.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/constants/inputs-to-remove.ts
@@ -2,4 +2,6 @@ import {RemovableInput} from '../../../interfaces';
export const INPUTS_TO_REMOVE: RemovableInput[] = [
{inputName: `active`, tags: [`tui-card`, `tui-thumbnail-card`]},
+ {inputName: `showLoader`, tags: [`tui-toggle`]},
+ {inputName: `singleColor`, tags: [`tui-toggle`]},
];
diff --git a/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts b/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts
index 53459328e8bf..cdcdd126bb78 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts
@@ -13,13 +13,24 @@ import {setupProgressLogger} from '../../../utils/progress';
import {getComponentTemplates} from '../../../utils/templates/get-component-templates';
import {getPathFromTemplateResource} from '../../../utils/templates/template-resource';
import {TemplateResource} from '../../interfaces/template-resource';
-import {removeInputs} from '../../utils/templates/remove-inputs';
-import {replaceAttrs} from '../../utils/templates/replace-attrs';
-import {replaceTags} from '../../utils/templates/replace-tags';
-import {ATTRS_TO_REPLACE} from './constants/attrs-to-replace';
-import {INPUTS_TO_REMOVE} from './constants/inputs-to-remove';
-import {TAGS_TO_REPLACE} from './constants/tags-to-replace';
-import {migrateBadgeValue, migrateCheckbox, migrateRadio} from './templates';
+import {
+ addHTMLCommentTags,
+ removeInputs,
+ replaceAttrs,
+ replaceTags,
+} from '../../utils/templates';
+import {
+ ATTRS_TO_REPLACE,
+ HTML_COMMENTS,
+ INPUTS_TO_REMOVE,
+ TAGS_TO_REPLACE,
+} from './constants';
+import {
+ migrateBadgeValue,
+ migrateCheckbox,
+ migrateRadio,
+ migrateToggle,
+} from './templates';
export function migrateTemplates(fileSystem: DevkitFileSystem, options: TuiSchema): void {
!options[`skip-logs`] &&
@@ -28,12 +39,14 @@ export function migrateTemplates(fileSystem: DevkitFileSystem, options: TuiSchem
const componentWithTemplatesPaths = getComponentTemplates(ALL_TS_FILES);
const actions = [
+ getAction({action: addHTMLCommentTags, requiredData: HTML_COMMENTS}),
getAction({action: replaceTags, requiredData: TAGS_TO_REPLACE}),
getAction({action: replaceAttrs, requiredData: ATTRS_TO_REPLACE}),
getAction({action: removeInputs, requiredData: INPUTS_TO_REMOVE}),
migrateBadgeValue,
migrateCheckbox,
migrateRadio,
+ migrateToggle,
] as const;
const progressLog = setupProgressLogger({
diff --git a/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/index.ts b/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/index.ts
index 167960c7e954..b1c7862cdcce 100644
--- a/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/index.ts
+++ b/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/index.ts
@@ -1,2 +1,3 @@
export * from './migrate-checkbox';
export * from './migrate-radio';
+export * from './migrate-toggle';
diff --git a/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/migrate-toggle.ts b/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/migrate-toggle.ts
new file mode 100644
index 000000000000..cc6feba1b850
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/steps/templates/toggles/migrate-toggle.ts
@@ -0,0 +1,40 @@
+import {UpdateRecorder} from '@angular-devkit/schematics';
+import {DevkitFileSystem} from 'ng-morph';
+
+import {findElementsByTagName} from '../../../../../utils/templates/elements';
+import {
+ getTemplateFromTemplateResource,
+ getTemplateOffset,
+} from '../../../../../utils/templates/template-resource';
+import {TemplateResource} from '../../../../interfaces';
+import {closeStartTag, removeClosingTag, replaceOpenTag, replaceSizeAttr} from './common';
+
+export function migrateToggle({
+ resource,
+ recorder,
+ fileSystem,
+}: {
+ fileSystem: DevkitFileSystem;
+ recorder: UpdateRecorder;
+ resource: TemplateResource;
+}): void {
+ const template = getTemplateFromTemplateResource(resource, fileSystem);
+ const templateOffset = getTemplateOffset(resource);
+
+ const elements = findElementsByTagName(template, `tui-toggle`);
+
+ elements.forEach(({attrs, sourceCodeLocation}) => {
+ if (!sourceCodeLocation) {
+ return;
+ }
+
+ replaceSizeAttr(attrs, sourceCodeLocation, recorder, templateOffset);
+ replaceOpenTag(sourceCodeLocation, recorder, templateOffset, {
+ tag: `tui-toggle`,
+ directive: `tuiToggle`,
+ type: `checkbox`,
+ });
+ closeStartTag(sourceCodeLocation, recorder, templateOffset);
+ removeClosingTag(sourceCodeLocation, recorder, templateOffset);
+ });
+}
diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-toggle.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-toggle.spec.ts
new file mode 100644
index 000000000000..a109bb8bff6c
--- /dev/null
+++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-toggle.spec.ts
@@ -0,0 +1,120 @@
+/* eslint-disable rxjs/no-topromise */
+import {HostTree} from '@angular-devkit/schematics';
+import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
+import {TuiSchema} from '@taiga-ui/cdk/schematics/ng-add/schema';
+import {
+ createProject,
+ createSourceFile,
+ resetActiveProject,
+ saveActiveProject,
+ setActiveProject,
+} from 'ng-morph';
+import {join} from 'path';
+
+import {createAngularJson} from '../../../utils/create-angular-json';
+
+const collectionPath = join(__dirname, `../../../migration.json`);
+
+const COMPONENT_BEFORE = `
+import { TuiToggleModule } from "@taiga-ui/experimental";
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiToggleModule]
+})
+export class TestComponent {
+}`;
+
+const COMPONENT_AFTER = `import { TuiToggleModule } from "@taiga-ui/kit";
+
+@Component({
+ standalone: true,
+ templateUrl: './test.template.html',
+ imports: [TuiToggleModule]
+})
+export class TestComponent {
+}`;
+
+const TEMPLATE_BEFORE = `
+
+
+`;
+
+const TEMPLATE_AFTER = `
+
+
+
+`;
+
+describe(`ng-update`, () => {
+ let host: UnitTestTree;
+ let runner: SchematicTestRunner;
+
+ beforeEach(() => {
+ host = new UnitTestTree(new HostTree());
+ runner = new SchematicTestRunner(`schematics`, collectionPath);
+
+ setActiveProject(createProject(host));
+
+ createMainFiles();
+
+ saveActiveProject();
+ });
+
+ it(`should migrate toggle in template`, async () => {
+ const tree = await runner
+ .runSchematicAsync(
+ `updateToV4`,
+ {'skip-logs': process.env[`TUI_CI`] === `true`} as Partial,
+ host,
+ )
+ .toPromise();
+
+ expect(tree.readContent(`test/app/test.template.html`)).toEqual(TEMPLATE_AFTER);
+ });
+
+ it(`should migrate toggle references in ts files`, async () => {
+ const tree = await runner
+ .runSchematicAsync(
+ `updateToV4`,
+ {'skip-logs': process.env[`TUI_CI`] === `true`} as Partial,
+ host,
+ )
+ .toPromise();
+
+ expect(tree.readContent(`test/app/test.component.ts`)).toEqual(COMPONENT_AFTER);
+ });
+
+ afterEach(() => resetActiveProject());
+});
+
+function createMainFiles(): void {
+ createSourceFile(`test/app/test.component.ts`, COMPONENT_BEFORE);
+
+ createSourceFile(`test/app/test.template.html`, TEMPLATE_BEFORE);
+
+ createAngularJson();
+ createSourceFile(
+ `package.json`,
+ `{"dependencies": {"@angular/core": "~13.0.0", "@taiga-ui/addon-commerce": "~3.42.0"}}`,
+ );
+}