Skip to content

Commit 4792672

Browse files
amysortommalerba
authored andcommitted
feat(material/schematics): add select styles migrator and tests
1 parent 6eac002 commit 4792672

File tree

4 files changed

+345
-0
lines changed

4 files changed

+345
-0
lines changed

integration/mdc-migration/golden/src/styles.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ $sample-project-theme: mat.define-light-theme((
4242
@include mat.mdc-slider-typography($sample-project-theme);
4343
@include mat.mdc-slide-toggle-theme($sample-project-theme);
4444
@include mat.mdc-slide-toggle-typography($sample-project-theme);
45+
@include mat.mdc-select-theme($sample-project-theme);
46+
@include mat.mdc-select-typography($sample-project-theme);
47+
@include mat.mdc-core-theme($sample-project-theme);
48+
@include mat.mdc-core-typography($sample-project-theme);
4549
@include mat.mdc-radio-theme($sample-project-theme);
4650
@include mat.mdc-radio-typography($sample-project-theme);
4751
@include mat.mdc-progress-spinner-theme($sample-project-theme);
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
import {createTestApp, patchDevkitTreeToExposeTypeScript} from '@angular/cdk/schematics/testing';
2+
import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
3+
import {createNewTestRunner, migrateComponents, THEME_FILE} from '../test-setup-helper';
4+
5+
describe('select styles', () => {
6+
let runner: SchematicTestRunner;
7+
let cliAppTree: UnitTestTree;
8+
9+
async function runMigrationTest(oldFileContent: string, newFileContent: string) {
10+
cliAppTree.create(THEME_FILE, oldFileContent);
11+
const tree = await migrateComponents(['select'], runner, cliAppTree);
12+
expect(tree.readContent(THEME_FILE)).toBe(newFileContent);
13+
}
14+
15+
beforeEach(async () => {
16+
runner = createNewTestRunner();
17+
cliAppTree = patchDevkitTreeToExposeTypeScript(await createTestApp(runner));
18+
});
19+
20+
describe('mixin migrations', () => {
21+
it('should replace the old theme with the new ones', async () => {
22+
await runMigrationTest(
23+
`
24+
@use '@angular/material' as mat;
25+
$theme: ();
26+
@include mat.select-theme($theme);
27+
`,
28+
`
29+
@use '@angular/material' as mat;
30+
$theme: ();
31+
@include mat.mdc-select-theme($theme);
32+
@include mat.mdc-select-typography($theme);
33+
@include mat.mdc-core-theme($theme);
34+
@include mat.mdc-core-typography($theme);
35+
`,
36+
);
37+
});
38+
39+
it('should use the correct namespace', async () => {
40+
await runMigrationTest(
41+
`
42+
@use '@angular/material' as arbitrary;
43+
$theme: ();
44+
@include arbitrary.select-theme($theme);
45+
`,
46+
`
47+
@use '@angular/material' as arbitrary;
48+
$theme: ();
49+
@include arbitrary.mdc-select-theme($theme);
50+
@include arbitrary.mdc-select-typography($theme);
51+
@include arbitrary.mdc-core-theme($theme);
52+
@include arbitrary.mdc-core-typography($theme);
53+
`,
54+
);
55+
});
56+
57+
it('should handle updating multiple themes', async () => {
58+
await runMigrationTest(
59+
`
60+
@use '@angular/material' as mat;
61+
$light-theme: ();
62+
$dark-theme: ();
63+
@include mat.select-theme($light-theme);
64+
@include mat.select-theme($dark-theme);
65+
`,
66+
`
67+
@use '@angular/material' as mat;
68+
$light-theme: ();
69+
$dark-theme: ();
70+
@include mat.mdc-select-theme($light-theme);
71+
@include mat.mdc-select-typography($light-theme);
72+
@include mat.mdc-core-theme($light-theme);
73+
@include mat.mdc-core-typography($light-theme);
74+
@include mat.mdc-select-theme($dark-theme);
75+
@include mat.mdc-select-typography($dark-theme);
76+
@include mat.mdc-core-theme($dark-theme);
77+
@include mat.mdc-core-typography($dark-theme);
78+
`,
79+
);
80+
});
81+
82+
it('should add correct theme if all-component-themes mixin included', async () => {
83+
await runMigrationTest(
84+
`
85+
@use '@angular/material' as mat;
86+
$theme: ();
87+
@include mat.all-component-themes($theme);
88+
`,
89+
`
90+
@use '@angular/material' as mat;
91+
$theme: ();
92+
@include mat.all-component-themes($theme);
93+
@include mat.mdc-select-theme($theme);
94+
@include mat.mdc-select-typography($theme);
95+
@include mat.mdc-core-theme($theme);
96+
@include mat.mdc-core-typography($theme);
97+
@include mat.mdc-input-theme($theme);
98+
@include mat.mdc-input-typography($theme);
99+
@include mat.mdc-form-field-theme($theme);
100+
@include mat.mdc-form-field-typography($theme);
101+
@include mat.mdc-autocomplete-theme($theme);
102+
@include mat.mdc-autocomplete-typography($theme);
103+
`,
104+
);
105+
});
106+
107+
it('should add multiple themes for multiple all-component-themes mixins', async () => {
108+
await runMigrationTest(
109+
`
110+
@use '@angular/material' as mat;
111+
$light-theme: ();
112+
$dark-theme: ();
113+
@include mat.all-component-themes($light-theme);
114+
@include mat.all-component-themes($dark-theme);
115+
`,
116+
`
117+
@use '@angular/material' as mat;
118+
$light-theme: ();
119+
$dark-theme: ();
120+
@include mat.all-component-themes($light-theme);
121+
@include mat.mdc-select-theme($light-theme);
122+
@include mat.mdc-select-typography($light-theme);
123+
@include mat.mdc-core-theme($light-theme);
124+
@include mat.mdc-core-typography($light-theme);
125+
@include mat.mdc-input-theme($light-theme);
126+
@include mat.mdc-input-typography($light-theme);
127+
@include mat.mdc-form-field-theme($light-theme);
128+
@include mat.mdc-form-field-typography($light-theme);
129+
@include mat.mdc-autocomplete-theme($light-theme);
130+
@include mat.mdc-autocomplete-typography($light-theme);
131+
@include mat.all-component-themes($dark-theme);
132+
@include mat.mdc-select-theme($dark-theme);
133+
@include mat.mdc-select-typography($dark-theme);
134+
@include mat.mdc-core-theme($dark-theme);
135+
@include mat.mdc-core-typography($dark-theme);
136+
@include mat.mdc-input-theme($dark-theme);
137+
@include mat.mdc-input-typography($dark-theme);
138+
@include mat.mdc-form-field-theme($dark-theme);
139+
@include mat.mdc-form-field-typography($dark-theme);
140+
@include mat.mdc-autocomplete-theme($dark-theme);
141+
@include mat.mdc-autocomplete-typography($dark-theme);
142+
`,
143+
);
144+
});
145+
146+
it('should preserve whitespace', async () => {
147+
await runMigrationTest(
148+
`
149+
@use '@angular/material' as mat;
150+
$theme: ();
151+
152+
153+
@include mat.select-theme($theme);
154+
155+
156+
`,
157+
`
158+
@use '@angular/material' as mat;
159+
$theme: ();
160+
161+
162+
@include mat.mdc-select-theme($theme);
163+
@include mat.mdc-select-typography($theme);
164+
@include mat.mdc-core-theme($theme);
165+
@include mat.mdc-core-typography($theme);
166+
167+
168+
`,
169+
);
170+
});
171+
});
172+
173+
describe('selector migrations', () => {
174+
it('should update the legacy mat-select classname', async () => {
175+
await runMigrationTest(
176+
`
177+
.mat-select {
178+
padding: 16px;
179+
}
180+
`,
181+
`
182+
.mat-mdc-select {
183+
padding: 16px;
184+
}
185+
`,
186+
);
187+
});
188+
189+
it('should update multiple legacy classnames', async () => {
190+
await runMigrationTest(
191+
`
192+
.mat-select {
193+
padding: 16px;
194+
}
195+
.mat-option {
196+
padding: 16px;
197+
}
198+
`,
199+
`
200+
.mat-mdc-select {
201+
padding: 16px;
202+
}
203+
.mat-mdc-option {
204+
padding: 16px;
205+
}
206+
`,
207+
);
208+
});
209+
210+
it('should update a legacy classname w/ multiple selectors', async () => {
211+
await runMigrationTest(
212+
`
213+
.some-class.mat-select, .another-class {
214+
padding: 16px;
215+
}
216+
`,
217+
`
218+
.some-class.mat-mdc-select, .another-class {
219+
padding: 16px;
220+
}
221+
`,
222+
);
223+
});
224+
225+
it('should preserve the whitespace of multiple selectors', async () => {
226+
await runMigrationTest(
227+
`
228+
.some-class,
229+
.mat-select,
230+
.another-class { padding: 16px; }
231+
`,
232+
`
233+
.some-class,
234+
.mat-mdc-select,
235+
.another-class { padding: 16px; }
236+
`,
237+
);
238+
});
239+
240+
it('should add comment for potentially deprecated selector', async () => {
241+
await runMigrationTest(
242+
`
243+
.mat-select-value {
244+
color: red;
245+
}
246+
`,
247+
`
248+
/* TODO: The following rule targets internal classes of select that may no longer apply for the MDC version. */
249+
250+
.mat-select-value {
251+
color: red;
252+
}
253+
`,
254+
);
255+
});
256+
257+
it('should not add comment for legacy selector that also starts with deprecated prefix', async () => {
258+
await runMigrationTest(
259+
`
260+
.mat-select-panel {
261+
padding: 16px;
262+
}
263+
`,
264+
`
265+
.mat-mdc-select-panel {
266+
padding: 16px;
267+
}
268+
`,
269+
);
270+
});
271+
272+
it('should add comment for potentially deprecated multi-line selector', async () => {
273+
await runMigrationTest(
274+
`
275+
.some-class
276+
.mat-select-value {
277+
color: red;
278+
}
279+
`,
280+
`
281+
/* TODO: The following rule targets internal classes of select that may no longer apply for the MDC version. */
282+
283+
.some-class
284+
.mat-select-value {
285+
color: red;
286+
}
287+
`,
288+
);
289+
});
290+
291+
it('should update the legacy mat-select class and add comment for potentially deprecated selector', async () => {
292+
await runMigrationTest(
293+
`
294+
.mat-select.some-class, .mat-select-value {
295+
padding: 16px;
296+
}
297+
`,
298+
`
299+
/* TODO: The following rule targets internal classes of select that may no longer apply for the MDC version. */
300+
301+
.mat-mdc-select.some-class, .mat-select-value {
302+
padding: 16px;
303+
}
304+
`,
305+
);
306+
});
307+
});
308+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {ClassNameChange, StyleMigrator} from '../../style-migrator';
10+
11+
export class SelectStylesMigrator extends StyleMigrator {
12+
component = 'select';
13+
14+
deprecatedPrefixes = ['mat-select', 'mat-option'];
15+
16+
mixinChanges = [
17+
{
18+
old: 'select-theme',
19+
new: ['mdc-select-theme', 'mdc-select-typography', 'mdc-core-theme', 'mdc-core-typography'],
20+
},
21+
];
22+
23+
classChanges: ClassNameChange[] = [
24+
{old: '.mat-select', new: '.mat-mdc-select'},
25+
{old: '.mat-select-panel', new: '.mat-mdc-select-panel'},
26+
{old: '.mat-option', new: '.mat-mdc-option'},
27+
];
28+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {ProgressBarStylesMigrator} from './components/progress-bar/progress-bar-
2626
import {ProgressSpinnerStylesMigrator} from './components/progress-spinner/progress-spinner-styles';
2727
import {RadioStylesMigrator} from './components/radio/radio-styles';
2828
import {RuntimeMigrator} from './runtime-migrator';
29+
import {SelectStylesMigrator} from './components/select/select-styles';
2930
import {SlideToggleStylesMigrator} from './components/slide-toggle/slide-toggle-styles';
3031
import {SliderStylesMigrator} from './components/slider/slider-styles';
3132
import {TableStylesMigrator} from './components/table/table-styles';
@@ -99,6 +100,10 @@ export const MIGRATORS: ComponentMigrator[] = [
99100
component: 'radio',
100101
styles: new RadioStylesMigrator(),
101102
},
103+
{
104+
component: 'select',
105+
styles: new SelectStylesMigrator(),
106+
},
102107
{
103108
component: 'slide-toggle',
104109
styles: new SlideToggleStylesMigrator(),

0 commit comments

Comments
 (0)