diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.spec.ts b/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.spec.ts new file mode 100644 index 000000000000..c2610c0891f2 --- /dev/null +++ b/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.spec.ts @@ -0,0 +1,219 @@ +import {createTestApp, patchDevkitTreeToExposeTypeScript} from '@angular/cdk/schematics/testing'; +import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing'; +import {createNewTestRunner, migrateComponent, THEME_FILE} from '../test-setup-helper'; + +describe('radio styles', () => { + let runner: SchematicTestRunner; + let cliAppTree: UnitTestTree; + + async function runMigrationTest(oldFileContent: string, newFileContent: string) { + cliAppTree.create(THEME_FILE, oldFileContent); + const tree = await migrateComponent('radio', runner, cliAppTree); + expect(tree.readContent(THEME_FILE)).toBe(newFileContent); + } + + beforeEach(async () => { + runner = createNewTestRunner(); + cliAppTree = patchDevkitTreeToExposeTypeScript(await createTestApp(runner)); + }); + + describe('mixin migrations', () => { + it('should replace the old theme with the new ones', async () => { + await runMigrationTest( + ` + @use '@angular/material' as mat; + $theme: (); + @include mat.radio-theme($theme); + `, + ` + @use '@angular/material' as mat; + $theme: (); + @include mat.mdc-radio-theme($theme); + @include mat.mdc-radio-typography($theme); + `, + ); + }); + + it('should use the correct namespace', async () => { + await runMigrationTest( + ` + @use '@angular/material' as arbitrary; + $theme: (); + @include arbitrary.radio-theme($theme); + `, + ` + @use '@angular/material' as arbitrary; + $theme: (); + @include arbitrary.mdc-radio-theme($theme); + @include arbitrary.mdc-radio-typography($theme); + `, + ); + }); + + it('should handle updating multiple themes', async () => { + await runMigrationTest( + ` + @use '@angular/material' as mat; + $light-theme: (); + $dark-theme: (); + @include mat.radio-theme($light-theme); + @include mat.radio-theme($dark-theme); + `, + ` + @use '@angular/material' as mat; + $light-theme: (); + $dark-theme: (); + @include mat.mdc-radio-theme($light-theme); + @include mat.mdc-radio-typography($light-theme); + @include mat.mdc-radio-theme($dark-theme); + @include mat.mdc-radio-typography($dark-theme); + `, + ); + }); + + it('should preserve whitespace', async () => { + await runMigrationTest( + ` + @use '@angular/material' as mat; + $theme: (); + + + @include mat.radio-theme($theme); + + + `, + ` + @use '@angular/material' as mat; + $theme: (); + + + @include mat.mdc-radio-theme($theme); + @include mat.mdc-radio-typography($theme); + + + `, + ); + }); + }); + + describe('selector migrations', () => { + it('should update the legacy mat-radio-group classname', async () => { + await runMigrationTest( + ` + .mat-radio-group { + display: block; + } + `, + ` + .mat-mdc-radio-group { + display: block; + } + `, + ); + }); + + it('should update multiple legacy classnames', async () => { + await runMigrationTest( + ` + .mat-radio-button { + display: block; + } + .mat-radio-group { + padding: 16px; + } + `, + ` + .mat-mdc-radio-button { + display: block; + } + .mat-mdc-radio-group { + padding: 16px; + } + `, + ); + }); + + it('should update a legacy classname w/ multiple selectors', async () => { + await runMigrationTest( + ` + .some-class.mat-radio-button, .another-class { + display: block; + } + `, + ` + .some-class.mat-mdc-radio-button, .another-class { + display: block; + } + `, + ); + }); + + it('should preserve the whitespace of multiple selectors', async () => { + await runMigrationTest( + ` + .some-class, + .mat-radio-button, + .another-class { padding: 16px; } + `, + ` + .some-class, + .mat-mdc-radio-button, + .another-class { padding: 16px; } + `, + ); + }); + + it('should add comment for potentially deprecated selector', async () => { + await runMigrationTest( + ` + .mat-radio-label-content { + font-size: 24px; + } + `, + ` + /* TODO: The following rule targets internal classes of radio that may no longer apply for the MDC version. */ + + .mat-radio-label-content { + font-size: 24px; + } + `, + ); + }); + + it('should add comment for potentially deprecated multi-line selector', async () => { + await runMigrationTest( + ` + .some-class + .mat-radio-container { + padding: 16px; + } + `, + ` + /* TODO: The following rule targets internal classes of radio that may no longer apply for the MDC version. */ + + .some-class + .mat-radio-container { + padding: 16px; + } + `, + ); + }); + + it('should update the legacy mat-radio-group class and add comment for potentially deprecated selector', async () => { + await runMigrationTest( + ` + .mat-radio-group.some-class, .mat-radio-container { + padding: 16px; + } + `, + ` + /* TODO: The following rule targets internal classes of radio that may no longer apply for the MDC version. */ + + .mat-mdc-radio-group.some-class, .mat-radio-container { + padding: 16px; + } + `, + ); + }); + }); +}); diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.ts b/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.ts new file mode 100644 index 000000000000..9ca02d588fdf --- /dev/null +++ b/src/material/schematics/ng-generate/mdc-migration/rules/components/radio/radio-styles.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {ClassNameChange, StyleMigrator} from '../../style-migrator'; + +export class RadioStylesMigrator extends StyleMigrator { + component = 'radio'; + + deprecatedPrefix = 'mat-radio'; + + mixinChanges = [ + { + old: 'radio-theme', + new: ['mdc-radio-theme', 'mdc-radio-typography'], + }, + ]; + + classChanges: ClassNameChange[] = [ + {old: '.mat-radio-group', new: '.mat-mdc-radio-group'}, + {old: '.mat-radio-button', new: '.mat-mdc-radio-button'}, + ]; +} diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/index.ts b/src/material/schematics/ng-generate/mdc-migration/rules/index.ts index 7bae442af226..ee81005a3b28 100644 --- a/src/material/schematics/ng-generate/mdc-migration/rules/index.ts +++ b/src/material/schematics/ng-generate/mdc-migration/rules/index.ts @@ -9,6 +9,7 @@ import {ButtonStylesMigrator} from './components/button/button-styles'; import {CheckboxStylesMigrator} from './components/checkbox/checkbox-styles'; import {ProgressBarStylesMigrator} from './components/progress-bar/progress-bar-styles'; +import {RadioStylesMigrator} from './components/radio/radio-styles'; import {SlideToggleStylesMigrator} from './components/slide-toggle/slide-toggle-styles'; import {StyleMigrator} from './style-migrator'; @@ -16,5 +17,6 @@ export const MIGRATORS: StyleMigrator[] = [ new ButtonStylesMigrator(), new CheckboxStylesMigrator(), new ProgressBarStylesMigrator(), + new RadioStylesMigrator(), new SlideToggleStylesMigrator(), ];