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"}}`, + ); +}