From d8f3c0bc421c05e17e998ce1d9e704ceb3306abc Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 5 May 2021 06:38:41 +0200 Subject: [PATCH] fix(material/schematics): run theming API migration during ng update Switches the `themingApi` migration from `ng generate` to `ng update`. Includes refactoring it into a `DevkitMigration` and changing the test setup to match. (cherry picked from commit bd063bf48eab6bc8e2ba5dfe3ff3c2515975786f) --- src/material/schematics/collection.json | 6 - .../ng-generate/theming-api/index.ts | 28 -- .../ng-generate/theming-api/schema.json | 7 - .../ng-generate/theming-api/schema.ts | 9 - src/material/schematics/ng-update/index.ts | 2 + .../migrations/theming-api-v12}/config.ts | 0 .../migrations/theming-api-v12}/migration.ts | 0 .../theming-api-v12/theming-api-migration.ts | 30 +++ .../v12/misc/theming-api-v12.spec.ts} | 245 ++++++++++-------- 9 files changed, 164 insertions(+), 163 deletions(-) delete mode 100644 src/material/schematics/ng-generate/theming-api/index.ts delete mode 100644 src/material/schematics/ng-generate/theming-api/schema.json delete mode 100644 src/material/schematics/ng-generate/theming-api/schema.ts rename src/material/schematics/{ng-generate/theming-api => ng-update/migrations/theming-api-v12}/config.ts (100%) rename src/material/schematics/{ng-generate/theming-api => ng-update/migrations/theming-api-v12}/migration.ts (100%) create mode 100644 src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts rename src/material/schematics/{ng-generate/theming-api/index.spec.ts => ng-update/test-cases/v12/misc/theming-api-v12.spec.ts} (72%) diff --git a/src/material/schematics/collection.json b/src/material/schematics/collection.json index 7e7c546fef6f..0004348db9cf 100644 --- a/src/material/schematics/collection.json +++ b/src/material/schematics/collection.json @@ -42,12 +42,6 @@ "factory": "./ng-generate/address-form/index", "schema": "./ng-generate/address-form/schema.json", "aliases": ["address-form", "material-address-form", "material-addressForm"] - }, - "themingApi": { - "description": "Switch the project to the new @use-based Material theming API", - "factory": "./ng-generate/theming-api/index", - "schema": "./ng-generate/theming-api/schema.json", - "aliases": ["theming-api", "sass-api"] } } } diff --git a/src/material/schematics/ng-generate/theming-api/index.ts b/src/material/schematics/ng-generate/theming-api/index.ts deleted file mode 100644 index 73cb0ba50018..000000000000 --- a/src/material/schematics/ng-generate/theming-api/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @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 {extname} from '@angular-devkit/core'; -import {Rule, Tree} from '@angular-devkit/schematics'; -import {Schema} from './schema'; -import {migrateFileContent} from './migration'; - -export default function(_options: Schema): Rule { - return (tree: Tree) => { - tree.visit((path, entry) => { - if (extname(path) === '.scss' && path.indexOf('node_modules') === -1) { - const content = entry?.content.toString(); - const migratedContent = content ? migrateFileContent(content, - '~@angular/material/', '~@angular/cdk/', '~@angular/material', '~@angular/cdk') : content; - - if (migratedContent && migratedContent !== content) { - tree.overwrite(path, migratedContent); - } - } - }); - }; -} diff --git a/src/material/schematics/ng-generate/theming-api/schema.json b/src/material/schematics/ng-generate/theming-api/schema.json deleted file mode 100644 index e6ef39bd5bea..000000000000 --- a/src/material/schematics/ng-generate/theming-api/schema.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "SchematicsMaterialThemingApi", - "title": "Material Theming API migration", - "type": "object", - "properties": {} -} diff --git a/src/material/schematics/ng-generate/theming-api/schema.ts b/src/material/schematics/ng-generate/theming-api/schema.ts deleted file mode 100644 index 423608e83b67..000000000000 --- a/src/material/schematics/ng-generate/theming-api/schema.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @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 - */ - -export interface Schema {} diff --git a/src/material/schematics/ng-update/index.ts b/src/material/schematics/ng-update/index.ts index 7f0eac808259..41e47f2de066 100644 --- a/src/material/schematics/ng-update/index.ts +++ b/src/material/schematics/ng-update/index.ts @@ -24,6 +24,7 @@ import { import { SecondaryEntryPointsMigration } from './migrations/package-imports-v8/secondary-entry-points-migration'; +import {ThemingApiMigration} from './migrations/theming-api-v12/theming-api-migration'; import {materialUpgradeData} from './upgrade-data'; @@ -36,6 +37,7 @@ const materialMigrations: NullableDevkitMigration[] = [ RippleSpeedFactorMigration, SecondaryEntryPointsMigration, HammerGesturesMigration, + ThemingApiMigration, ]; /** Entry point for the migration schematics with target of Angular Material v6 */ diff --git a/src/material/schematics/ng-generate/theming-api/config.ts b/src/material/schematics/ng-update/migrations/theming-api-v12/config.ts similarity index 100% rename from src/material/schematics/ng-generate/theming-api/config.ts rename to src/material/schematics/ng-update/migrations/theming-api-v12/config.ts diff --git a/src/material/schematics/ng-generate/theming-api/migration.ts b/src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts similarity index 100% rename from src/material/schematics/ng-generate/theming-api/migration.ts rename to src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts diff --git a/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts b/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts new file mode 100644 index 000000000000..eabd6ebc6644 --- /dev/null +++ b/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts @@ -0,0 +1,30 @@ +/** + * @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 {extname} from '@angular-devkit/core'; +import {DevkitMigration, ResolvedResource, TargetVersion} from '@angular/cdk/schematics'; +import {migrateFileContent} from './migration'; + +/** Migration that switches all Sass files using Material theming APIs to `@use`. */ +export class ThemingApiMigration extends DevkitMigration { + enabled = this.targetVersion === TargetVersion.V12; + + visitStylesheet(stylesheet: ResolvedResource): void { + if (extname(stylesheet.filePath) === '.scss') { + const content = stylesheet.content; + const migratedContent = content ? migrateFileContent(content, + '~@angular/material/', '~@angular/cdk/', '~@angular/material', '~@angular/cdk') : content; + + if (migratedContent && migratedContent !== content) { + this.fileSystem.edit(stylesheet.filePath) + .remove(0, stylesheet.content.length) + .insertLeft(0, migratedContent); + } + } + } +} diff --git a/src/material/schematics/ng-generate/theming-api/index.spec.ts b/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts similarity index 72% rename from src/material/schematics/ng-generate/theming-api/index.spec.ts rename to src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts index 8514da7de586..01ad646de414 100644 --- a/src/material/schematics/ng-generate/theming-api/index.spec.ts +++ b/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts @@ -1,19 +1,34 @@ -import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; -import {createTestApp, getFileContent} from '@angular/cdk/schematics/testing'; -import {COLLECTION_PATH} from '../../paths'; -import {Schema} from './schema'; +import {UnitTestTree} from '@angular-devkit/schematics/testing'; +import {createTestCaseSetup} from '@angular/cdk/schematics/testing'; +import {join} from 'path'; +import {MIGRATION_PATH} from '../../../../paths'; + +describe('v12 theming API migration', () => { + const PROJECT_PATH = '/projects/cdk-testing'; + const THEME_PATH = join(PROJECT_PATH, 'src/theme.scss'); + let tree: UnitTestTree; + let _writeFile: (filePath: string, text: string) => void; + let runMigration: () => Promise<{logOutput: string}>; + + beforeEach(async () => { + const testSetup = await createTestCaseSetup('migration-v12', MIGRATION_PATH, []); + tree = testSetup.appTree; + runMigration = testSetup.runFixers; + _writeFile = testSetup.writeFile; + }); -describe('Material theming API schematic', () => { - const options: Schema = {}; - let runner: SchematicTestRunner; + /** Writes an array of lines as a single file. */ + function writeLines(path: string, lines: string[]): void { + _writeFile(path, lines.join('\n')); + } - beforeEach(() => { - runner = new SchematicTestRunner('schematics', COLLECTION_PATH); - }); + /** Reads a file and split it into an array where each item is a new line. */ + function splitFile(path: string): string[] { + return tree.readContent(path).split('\n'); + } it('should migrate a theme based on the theming API', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `@include mat-core();`, @@ -43,10 +58,11 @@ describe('Material theming API schematic', () => { `.unicorn-dark-theme {`, `@include angular-material-color($dark-theme);`, `}` - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.core();`, @@ -80,8 +96,7 @@ describe('Material theming API schematic', () => { }); it('should migrate files using CDK APIs through the theming import', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, ``, `@include cdk-overlay();`, @@ -96,10 +111,11 @@ describe('Material theming API schematic', () => { `outline: solid 1px;`, `}`, `}` - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/cdk' as cdk;`, ``, `@include cdk.overlay();`, @@ -117,8 +133,7 @@ describe('Material theming API schematic', () => { }); it('should migrate files using both Material and CDK APIs', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import './foo'`, `@import '~@angular/material/theming';`, ``, @@ -139,10 +154,11 @@ describe('Material theming API schematic', () => { `.my-dialog {`, `z-index: $cdk-z-index-overlay-container + 1;`, `}`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@use '~@angular/cdk' as cdk;`, `@import './foo'`, @@ -168,43 +184,43 @@ describe('Material theming API schematic', () => { }); it('should detect imports using double quotes', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import "~@angular/material/theming";`, `@include mat-core();`, - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.core();`, ]); }); it('should migrate mixins that are invoked without parentheses', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `@include mat-base-typography;`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.typography-hierarchy;`, ]); }); it('should migrate files that import the Material APIs transitively', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import 're-exports-material-symbols';`, `@include mat-core();`, `@include mat-button-theme();`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@import 're-exports-material-symbols';`, `@include mat.core();`, @@ -213,30 +229,30 @@ describe('Material theming API schematic', () => { }); it('should allow an arbitrary number of spaces after @include and @import', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `@include mat-core;`, - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.core;`, ]); }); it('should insert the new @use statement above other @import statements', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import './foo'`, `@import "~@angular/material/theming";`, `@import './bar'`, `@include mat-core();`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@import './foo'`, `@import './bar'`, @@ -245,16 +261,16 @@ describe('Material theming API schematic', () => { }); it('should account for other @use statements when inserting the new Material @use', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@use './foo'`, `@import './bar'`, `@import "~@angular/material/theming";`, `@include mat-core();`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use './foo'`, `@use '~@angular/material' as mat;`, `@import './bar'`, @@ -263,16 +279,16 @@ describe('Material theming API schematic', () => { }); it('should account for file headers placed aboved the @import statements', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `/** This is a license. */`, `@import './foo'`, `@import '~@angular/material/theming';`, `@include mat-core();`, - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `/** This is a license. */`, `@use '~@angular/material' as mat;`, `@import './foo'`, @@ -281,25 +297,28 @@ describe('Material theming API schematic', () => { }); it('should migrate multiple files within the same project', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + const componentPath = join(PROJECT_PATH, 'components/dialog.scss'); + + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `@include angular-material-theme();`, - ].join('\n')); + ]); - app.create('/components/dialog.scss', [ + writeLines(componentPath, [ `@import '~@angular/material/theming';`, `.my-dialog {`, `z-index: $cdk-z-index-overlay-container + 1;`, `}`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.all-component-themes();`, ]); - expect(getFileContent(tree, '/components/dialog.scss').split('\n')).toEqual([ + + expect(splitFile(componentPath)).toEqual([ `@use '~@angular/cdk' as cdk;`, `.my-dialog {`, `z-index: cdk.$overlay-container-z-index + 1;`, @@ -308,17 +327,17 @@ describe('Material theming API schematic', () => { }); it('should handle variables whose names overlap', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `$one: $mat-blue-grey;`, `$two: $mat-blue;`, '$three: $mat-blue', '$four: $mat-blue-gray', - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `$one: mat.$blue-grey-palette;`, `$two: mat.$blue-palette;`, @@ -328,8 +347,7 @@ describe('Material theming API schematic', () => { }); it('should migrate individual component themes', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, `@include mat-core();`, @@ -348,10 +366,11 @@ describe('Material theming API schematic', () => { `@include mat-expansion-panel-theme($candy-app-theme);`, `@include mat-datepicker-theme($candy-app-theme);`, `@include mat-option-theme($candy-app-theme);`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.core();`, @@ -375,8 +394,7 @@ describe('Material theming API schematic', () => { }); it('should migrate deep imports', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/core/theming/palette';`, `@import '~@angular/material/core/theming/theming';`, `@import '~@angular/material/button/button-theme';`, @@ -400,10 +418,11 @@ describe('Material theming API schematic', () => { `@include mat-table-theme($candy-app-theme);`, `@include mat-datepicker-theme($candy-app-theme);`, `@include mat-option-theme($candy-app-theme);`, - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@use '~@angular/cdk' as cdk;`, @@ -426,8 +445,7 @@ describe('Material theming API schematic', () => { }); it('should migrate usages of @use, with and without namespaces', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@use '~@angular/material/core/theming/palette' as palette;`, `@use '~@angular/material/core/theming/theming';`, `@use '~@angular/material/button/button-theme' as button;`, @@ -452,10 +470,11 @@ describe('Material theming API schematic', () => { `@include table.mat-table-theme($candy-app-theme);`, `@include datepicker.mat-datepicker-theme($candy-app-theme);`, `@include mat-option-theme($candy-app-theme);`, - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@use '~@angular/cdk' as cdk;`, @@ -478,8 +497,7 @@ describe('Material theming API schematic', () => { }); it('should handle edge case inferred Sass import namespaces', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@use '~@angular/material/core/index';`, `@use '~@angular/material/button/_button-theme';`, `@use '~@angular/material/table/table-theme.import';`, @@ -489,10 +507,11 @@ describe('Material theming API schematic', () => { `@include button-theme.mat-button-theme();`, `@include table-theme.mat-table-theme();`, `@include datepicker-theme.mat-datepicker-theme();`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, `@include mat.core();`, @@ -503,17 +522,17 @@ describe('Material theming API schematic', () => { }); it('should drop the old import path even if the file is not using any symbols', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, ``, `.my-dialog {`, `color: red;`, `}`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `.my-dialog {`, `color: red;`, `}`, @@ -521,8 +540,7 @@ describe('Material theming API schematic', () => { }); it('should replace removed variables with their values', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, ``, `@include mat-button-toggle-theme();`, @@ -538,10 +556,11 @@ describe('Material theming API schematic', () => { `height: $mat-button-toggle-standard-minimum-height;`, `}`, `}` - ].join('\n')); + ]); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, ``, `@include mat.button-toggle-theme();`, @@ -561,8 +580,7 @@ describe('Material theming API schematic', () => { }); it('should not replace assignments to removed variables', async () => { - const app = await createTestApp(runner); - app.create('/theme.scss', [ + writeLines(THEME_PATH, [ `@import '~@angular/material/theming';`, ``, `$mat-button-toggle-standard-height: 50px;`, @@ -571,10 +589,11 @@ describe('Material theming API schematic', () => { `$mat-toggle-size: 11px;`, ``, `@include mat-button-toggle-theme();`, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/theme.scss').split('\n')).toEqual([ + expect(splitFile(THEME_PATH)).toEqual([ `@use '~@angular/material' as mat;`, ``, `$mat-button-toggle-standard-height: 50px;`, @@ -587,16 +606,16 @@ describe('Material theming API schematic', () => { }); it('should not migrate files in the node_modules', async () => { - const app = await createTestApp(runner); - app.create('/node_modules/theme.scss', [ + writeLines('/node_modules/theme.scss', [ `@import '~@angular/material/theming';`, ``, `@include mat-button-toggle-theme();`, ``, - ].join('\n')); + ]); + + await runMigration(); - const tree = await runner.runSchematicAsync('theming-api', options, app).toPromise(); - expect(getFileContent(tree, '/node_modules/theme.scss').split('\n')).toEqual([ + expect(splitFile('/node_modules/theme.scss')).toEqual([ `@import '~@angular/material/theming';`, ``, `@include mat-button-toggle-theme();`,