Skip to content

Commit

Permalink
feat(material/schematics): add form-field styles migrator and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amysorto authored and mmalerba committed Jul 15, 2022
1 parent 7b5bb76 commit dcc9829
Show file tree
Hide file tree
Showing 4 changed files with 344 additions and 0 deletions.
2 changes: 2 additions & 0 deletions integration/mdc-migration/golden/src/styles.scss
Expand Up @@ -54,6 +54,8 @@ $sample-project-theme: mat.define-light-theme((
@include mat.mdc-menu-typography($sample-project-theme);
@include mat.mdc-list-theme($sample-project-theme);
@include mat.mdc-list-typography($sample-project-theme);
@include mat.mdc-form-field-theme($sample-project-theme);
@include mat.mdc-form-field-typography($sample-project-theme);
@include mat.mdc-dialog-theme($sample-project-theme);
@include mat.mdc-dialog-typography($sample-project-theme);
@include mat.mdc-chips-theme($sample-project-theme);
Expand Down
@@ -0,0 +1,283 @@
import {createTestApp, patchDevkitTreeToExposeTypeScript} from '@angular/cdk/schematics/testing';
import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
import {createNewTestRunner, migrateComponents, THEME_FILE} from '../test-setup-helper';

describe('form-field styles', () => {
let runner: SchematicTestRunner;
let cliAppTree: UnitTestTree;

async function runMigrationTest(oldFileContent: string, newFileContent: string) {
cliAppTree.create(THEME_FILE, oldFileContent);
const tree = await migrateComponents(['form-field'], 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.form-field-theme($theme);
`,
`
@use '@angular/material' as mat;
$theme: ();
@include mat.mdc-form-field-theme($theme);
@include mat.mdc-form-field-typography($theme);
`,
);
});

it('should use the correct namespace', async () => {
await runMigrationTest(
`
@use '@angular/material' as arbitrary;
$theme: ();
@include arbitrary.form-field-theme($theme);
`,
`
@use '@angular/material' as arbitrary;
$theme: ();
@include arbitrary.mdc-form-field-theme($theme);
@include arbitrary.mdc-form-field-typography($theme);
`,
);
});

it('should handle updating multiple themes', async () => {
await runMigrationTest(
`
@use '@angular/material' as mat;
$light-theme: ();
$dark-theme: ();
@include mat.form-field-theme($light-theme);
@include mat.form-field-theme($dark-theme);
`,
`
@use '@angular/material' as mat;
$light-theme: ();
$dark-theme: ();
@include mat.mdc-form-field-theme($light-theme);
@include mat.mdc-form-field-typography($light-theme);
@include mat.mdc-form-field-theme($dark-theme);
@include mat.mdc-form-field-typography($dark-theme);
`,
);
});

it('should add correct theme if all-component-themes mixin included', async () => {
await runMigrationTest(
`
@use '@angular/material' as mat;
$theme: ();
@include mat.all-component-themes($theme);
`,
`
@use '@angular/material' as mat;
$theme: ();
@include mat.all-component-themes($theme);
@include mat.mdc-select-theme($theme);
@include mat.mdc-select-typography($theme);
@include mat.mdc-core-theme($theme);
@include mat.mdc-core-typography($theme);
@include mat.mdc-input-theme($theme);
@include mat.mdc-input-typography($theme);
@include mat.mdc-form-field-theme($theme);
@include mat.mdc-form-field-typography($theme);
@include mat.mdc-autocomplete-theme($theme);
@include mat.mdc-autocomplete-typography($theme);
`,
);
});

it('should add multiple themes for multiple all-component-themes mixins', async () => {
await runMigrationTest(
`
@use '@angular/material' as mat;
$light-theme: ();
$dark-theme: ();
@include mat.all-component-themes($light-theme);
@include mat.all-component-themes($dark-theme);
`,
`
@use '@angular/material' as mat;
$light-theme: ();
$dark-theme: ();
@include mat.all-component-themes($light-theme);
@include mat.mdc-select-theme($light-theme);
@include mat.mdc-select-typography($light-theme);
@include mat.mdc-core-theme($light-theme);
@include mat.mdc-core-typography($light-theme);
@include mat.mdc-input-theme($light-theme);
@include mat.mdc-input-typography($light-theme);
@include mat.mdc-form-field-theme($light-theme);
@include mat.mdc-form-field-typography($light-theme);
@include mat.mdc-autocomplete-theme($light-theme);
@include mat.mdc-autocomplete-typography($light-theme);
@include mat.all-component-themes($dark-theme);
@include mat.mdc-select-theme($dark-theme);
@include mat.mdc-select-typography($dark-theme);
@include mat.mdc-core-theme($dark-theme);
@include mat.mdc-core-typography($dark-theme);
@include mat.mdc-input-theme($dark-theme);
@include mat.mdc-input-typography($dark-theme);
@include mat.mdc-form-field-theme($dark-theme);
@include mat.mdc-form-field-typography($dark-theme);
@include mat.mdc-autocomplete-theme($dark-theme);
@include mat.mdc-autocomplete-typography($dark-theme);
`,
);
});

it('should preserve whitespace', async () => {
await runMigrationTest(
`
@use '@angular/material' as mat;
$theme: ();
@include mat.form-field-theme($theme);
`,
`
@use '@angular/material' as mat;
$theme: ();
@include mat.mdc-form-field-theme($theme);
@include mat.mdc-form-field-typography($theme);
`,
);
});
});

describe('selector migrations', () => {
it('should update the legacy mat-form-field classname', async () => {
await runMigrationTest(
`
.mat-form-field {
padding: 16px;
}
`,
`
.mat-mdc-form-field {
padding: 16px;
}
`,
);
});

it('should update multiple legacy classnames', async () => {
await runMigrationTest(
`
.mat-form-field {
padding: 16px;
}
.mat-hint {
color: red;
}
`,
`
.mat-mdc-form-field {
padding: 16px;
}
.mat-mdc-form-field-hint {
color: red;
}
`,
);
});

it('should update a legacy classname w/ multiple selectors', async () => {
await runMigrationTest(
`
.some-class.mat-form-field, .another-class {
padding: 16px;
}
`,
`
.some-class.mat-mdc-form-field, .another-class {
padding: 16px;
}
`,
);
});

it('should preserve the whitespace of multiple selectors', async () => {
await runMigrationTest(
`
.some-class,
.mat-form-field,
.another-class { padding: 16px; }
`,
`
.some-class,
.mat-mdc-form-field,
.another-class { padding: 16px; }
`,
);
});

it('should add comment for potentially deprecated selector', async () => {
await runMigrationTest(
`
.mat-form-field-wrapper {
padding: 16px;
}
`,
`
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
.mat-form-field-wrapper {
padding: 16px;
}
`,
);
});

it('should add comment for potentially deprecated multi-line selector', async () => {
await runMigrationTest(
`
.some-class
.mat-form-field-wrapper {
padding: 16px;
}
`,
`
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
.some-class
.mat-form-field-wrapper {
padding: 16px;
}
`,
);
});

it('should update the legacy mat-form-field class and add comment for potentially deprecated selector', async () => {
await runMigrationTest(
`
.mat-form-field.some-class, .mat-form-field-wrapper {
padding: 16px;
}
`,
`
/* TODO: The following rule targets internal classes of form-field that may no longer apply for the MDC version. */
.mat-mdc-form-field.some-class, .mat-form-field-wrapper {
padding: 16px;
}
`,
);
});
});
});
@@ -0,0 +1,54 @@
/**
* @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 FormFieldStylesMigrator extends StyleMigrator {
component = 'form-field';

deprecatedPrefixes = [
'.mat-form-field-can-float',
'.mat-form-field-should-float',
'.mat-form-field-has-label',
'.mat-form-field-wrapper',
'.mat-form-field-flex',
'.mat-form-field-outline',
'.mat-form-field-prefix',
'.mat-form-field-infix',
'.mat-form-field-suffix',
'.mat-form-field-label',
'.mat-form-field-required-marker',
'.mat-form-field-underline',
'.mat-form-field-ripple',
'.mat-form-field-subscript-wrapper',
'.mat-form-field-hint-wrapper',
'.mat-form-field-hint-hint-spacer',
];

mixinChanges = [
{
old: 'form-field-theme',
new: ['mdc-form-field-theme', 'mdc-form-field-typography'],
},
];

classChanges: ClassNameChange[] = [
{
old: '.mat-form-field',
new: '.mat-mdc-form-field',
},
{
old: '.mat-hint',
new: '.mat-mdc-form-field-hint',
},
{
old: '.mat-error',
new: '.mat-mdc-form-field-error',
},
];
}
Expand Up @@ -17,6 +17,7 @@ import {CardTemplateMigrator} from './components/card/card-template';
import {CheckboxStylesMigrator} from './components/checkbox/checkbox-styles';
import {ChipsStylesMigrator} from './components/chips/chips-styles';
import {DialogStylesMigrator} from './components/dialog/dialog-styles';
import {FormFieldStylesMigrator} from './components/form-field/form-field-styles';
import {ListStylesMigrator} from './components/list/list-styles';
import {MenuStylesMigrator} from './components/menu/menu-styles';
import {PaginatorStylesMigrator} from './components/paginator/paginator-styles';
Expand Down Expand Up @@ -65,6 +66,10 @@ export const MIGRATORS: ComponentMigrator[] = [
component: 'dialog',
styles: new DialogStylesMigrator(),
},
{
component: 'form-field',
styles: new FormFieldStylesMigrator(),
},
{
component: 'list',
styles: new ListStylesMigrator(),
Expand Down

0 comments on commit dcc9829

Please sign in to comment.