diff --git a/src/cdk/schematics/migration.json b/src/cdk/schematics/migration.json index 0bf15e8d6334..b65a92dd0cae 100644 --- a/src/cdk/schematics/migration.json +++ b/src/cdk/schematics/migration.json @@ -1,10 +1,10 @@ { "$schema": "./node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { - "migration-v19": { - "version": "19.0.0-0", - "description": "Updates the Angular CDK to v19", - "factory": "./ng-update/index#updateToV19" + "migration-v20": { + "version": "20.0.0-0", + "description": "Updates the Angular CDK to v20", + "factory": "./ng-update/index#updateToV20" }, "ng-post-update": { "description": "Prints out results after ng-update.", diff --git a/src/cdk/schematics/ng-update/index.ts b/src/cdk/schematics/ng-update/index.ts index 046f272d0060..4ac3019a63ac 100644 --- a/src/cdk/schematics/ng-update/index.ts +++ b/src/cdk/schematics/ng-update/index.ts @@ -13,10 +13,10 @@ import {createMigrationSchematicRule, NullableDevkitMigration} from './devkit-mi const cdkMigrations: NullableDevkitMigration[] = []; -/** Entry point for the migration schematics with target of Angular CDK 18.0.0 */ -export function updateToV19(): Rule { +/** Entry point for the migration schematics with target of Angular CDK 20.0.0 */ +export function updateToV20(): Rule { return createMigrationSchematicRule( - TargetVersion.V19, + TargetVersion.V20, cdkMigrations, cdkUpgradeData, onMigrationComplete, diff --git a/src/cdk/schematics/update-tool/target-version.ts b/src/cdk/schematics/update-tool/target-version.ts index 26908bc23800..295939467932 100644 --- a/src/cdk/schematics/update-tool/target-version.ts +++ b/src/cdk/schematics/update-tool/target-version.ts @@ -10,7 +10,7 @@ // tslint:disable-next-line:prefer-const-enum export enum TargetVersion { - V19 = 'version 19', + V20 = 'version 20', } /** diff --git a/src/google-maps/schematics/migration.json b/src/google-maps/schematics/migration.json index 742d51a5bcb5..45c93051dfc9 100644 --- a/src/google-maps/schematics/migration.json +++ b/src/google-maps/schematics/migration.json @@ -1,9 +1,9 @@ { "schematics": { - "migration-v19": { - "version": "19.0.0-0", - "description": "Updates the Angular Google Maps package to v19", - "factory": "./ng-update/index_bundled#updateToV19" + "migration-v20": { + "version": "20.0.0-0", + "description": "Updates the Angular Google Maps package to v20", + "factory": "./ng-update/index_bundled#updateToV20" } } } diff --git a/src/google-maps/schematics/ng-update/BUILD.bazel b/src/google-maps/schematics/ng-update/BUILD.bazel index 3228023d033b..fa96cad96ab5 100644 --- a/src/google-maps/schematics/ng-update/BUILD.bazel +++ b/src/google-maps/schematics/ng-update/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools:defaults.bzl", "esbuild", "jasmine_node_test", "spec_bundle", "ts_library") +load("//tools:defaults.bzl", "esbuild", "ts_library") ## THIS ONE IS ESM # By default everything is ESM @@ -38,42 +38,3 @@ esbuild( visibility = ["//src/google-maps/schematics:__pkg__"], deps = [":ng_update_lib"], ) - -ts_library( - name = "test_lib", - testonly = True, - srcs = glob(["**/*.spec.ts"]), - deps = [ - ":ng_update_lib", - "@npm//@angular-devkit/core", - "@npm//@angular-devkit/schematics", - "@npm//@bazel/runfiles", - "@npm//@types/jasmine", - "@npm//@types/node", - "@npm//@types/shelljs", - ], -) - -spec_bundle( - name = "spec_bundle", - external = [ - "*/paths.js", - "shelljs", - "@angular-devkit/core/node", - ], - platform = "cjs-legacy", - target = "es2020", - deps = [":test_lib"], -) - -jasmine_node_test( - name = "test", - data = [ - ":ng_update_index", - "//src/google-maps/schematics:schematics_assets", - "@npm//shelljs", - ], - deps = [ - ":spec_bundle", - ], -) diff --git a/src/google-maps/schematics/ng-update/index.ts b/src/google-maps/schematics/ng-update/index.ts index d6834a4382dc..e195902f23b5 100644 --- a/src/google-maps/schematics/ng-update/index.ts +++ b/src/google-maps/schematics/ng-update/index.ts @@ -6,141 +6,5 @@ * found in the LICENSE file at https://angular.dev/license */ -import {Path} from '@angular-devkit/core'; -import {Rule, Tree} from '@angular-devkit/schematics'; -import ts from 'typescript'; - -/** Tag name of the clusterer component. */ -const TAG_NAME = 'map-marker-clusterer'; - -/** Module from which the clusterer is being imported. */ -const MODULE_NAME = '@angular/google-maps'; - -/** Old name of the clusterer class. */ -const CLASS_NAME = 'MapMarkerClusterer'; - -/** New name of the clusterer class. */ -const DEPRECATED_CLASS_NAME = 'DeprecatedMapMarkerClusterer'; - -/** Entry point for the migration schematics with target of Angular Material v19 */ -export function updateToV19(): Rule { - return tree => { - tree.visit(path => { - if (path.includes('node_modules')) { - return; - } - - if (path.endsWith('.html')) { - const content = tree.read(path)?.toString(); - - if (content && content.includes('<' + TAG_NAME)) { - tree.overwrite(path, migrateHtml(content)); - } - } else if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { - migrateTypeScript(path, tree); - } - }); - }; -} - -/** Migrates an HTML template from the old tag name to the new one. */ -function migrateHtml(content: string): string { - return content - .replace(/ { - const symbolName = element.propertyName || element.name; - - if (ts.isIdentifier(symbolName) && symbolName.text === CLASS_NAME) { - results.push(element); - } - }); - } - } else { - node.forEachChild(walk); - } - }); - - // Sort the results in reverse order to make applying the updates easier. - return results.sort((a, b) => b.getStart() - a.getStart()); -} +/** Entry point for the migration schematics with target of Angular Material v20 */ +export function updateToV20(): void {} diff --git a/src/google-maps/schematics/ng-update/v19-ng-update.spec.ts b/src/google-maps/schematics/ng-update/v19-ng-update.spec.ts deleted file mode 100644 index 57ff61787fe9..000000000000 --- a/src/google-maps/schematics/ng-update/v19-ng-update.spec.ts +++ /dev/null @@ -1,213 +0,0 @@ -import {getSystemPath, normalize, virtualFs} from '@angular-devkit/core'; -import {TempScopedNodeJsSyncHost} from '@angular-devkit/core/node/testing'; -import {HostTree} from '@angular-devkit/schematics'; -import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing'; -import {runfiles} from '@bazel/runfiles'; -import shx from 'shelljs'; - -describe('v19 migration', () => { - let runner: SchematicTestRunner; - let host: TempScopedNodeJsSyncHost; - let tree: UnitTestTree; - let tmpDirPath: string; - - function writeFile(filePath: string, contents: string) { - host.sync.write(normalize(filePath), virtualFs.stringToFileBuffer(contents)); - } - - function runMigration() { - return runner.runSchematic('migration-v19', {}, tree); - } - - function stripWhitespace(value: string) { - return value.replace(/\s/g, ''); - } - - beforeEach(() => { - runner = new SchematicTestRunner('test', runfiles.resolvePackageRelative('../migration.json')); - host = new TempScopedNodeJsSyncHost(); - tree = new UnitTestTree(new HostTree(host)); - - writeFile( - '/angular.json', - JSON.stringify({ - version: 1, - projects: {t: {root: '', architect: {build: {options: {tsConfig: './tsconfig.json'}}}}}, - }), - ); - - tmpDirPath = getSystemPath(host.root); - shx.cd(tmpDirPath); - }); - - it('should migrate the clusterer in HTML files', async () => { - writeFile( - '/my-comp.html', - ` -
- - - - - -
- -
-
- - @for (marker of markers; track $index) { - - } - -
-
- `, - ); - - await runMigration(); - - const content = tree.readContent('/my-comp.html'); - - expect(stripWhitespace(content)).toBe( - stripWhitespace(` -
- - - - - -
- -
-
- - @for (marker of markers; track $index) { - - } - -
-
- `), - ); - }); - - it('should migrate the clusterer in a TypeScript file', async () => { - writeFile( - '/my-comp.ts', - ` - import {Component} from '@angular/core'; - import {MapMarkerClusterer, MapMarker} from '@angular/google-maps'; - - @Component({ - template: '', - imports: [MapMarkerClusterer, MapMarker] - }) - export class MyComp {} - `, - ); - - await runMigration(); - - const content = tree.readContent('/my-comp.ts'); - - expect(stripWhitespace(content)).toBe( - stripWhitespace(` - import {Component} from '@angular/core'; - import {DeprecatedMapMarkerClusterer as MapMarkerClusterer, MapMarker} from '@angular/google-maps'; - - @Component({ - template: '', - imports: [MapMarkerClusterer, MapMarker] - }) - export class MyComp {} - `), - ); - }); - - it('should migrate an aliased clusterer in a TypeScript file', async () => { - writeFile( - '/my-comp.ts', - ` - import {Component} from '@angular/core'; - import {MapMarkerClusterer as MyClusterer, MapMarker} from '@angular/google-maps'; - - @Component({ - template: '', - imports: [MyClusterer, MapMarker] - }) - export class MyComp {} - `, - ); - - await runMigration(); - - const content = tree.readContent('/my-comp.ts'); - - expect(stripWhitespace(content)).toBe( - stripWhitespace(` - import {Component} from '@angular/core'; - import {DeprecatedMapMarkerClusterer as MyClusterer, MapMarker} from '@angular/google-maps'; - - @Component({ - template: '', - imports: [MyClusterer, MapMarker] - }) - export class MyComp {} - `), - ); - }); - - it('should migrate a re-exported clusterer', async () => { - writeFile( - '/index.ts', - ` - export {MapMarkerClusterer} from '@angular/google-maps'; - export {MapMarkerClusterer as AliasedMapMarkerClusterer} from '@angular/google-maps'; - `, - ); - - await runMigration(); - - const content = tree.readContent('/index.ts'); - - expect(stripWhitespace(content)).toBe( - stripWhitespace(` - export {DeprecatedMapMarkerClusterer as MapMarkerClusterer} from '@angular/google-maps'; - export {DeprecatedMapMarkerClusterer as AliasedMapMarkerClusterer} from '@angular/google-maps'; - `), - ); - }); - - it('should not migrate an import outside of the Angular module', async () => { - writeFile( - '/my-comp.ts', - ` - import {Component} from '@angular/core'; - import {MapMarkerClusterer} from '@not-angular/google-maps'; - - @Component({ - template: '', - imports: [MapMarkerClusterer] - }) - export class MyComp {} - `, - ); - - await runMigration(); - - const content = tree.readContent('/my-comp.ts'); - - expect(stripWhitespace(content)).toBe( - stripWhitespace(` - import {Component} from '@angular/core'; - import {MapMarkerClusterer} from '@not-angular/google-maps'; - - @Component({ - template: '', - imports: [MapMarkerClusterer] - }) - export class MyComp {} - `), - ); - }); -}); diff --git a/src/material/schematics/migration.json b/src/material/schematics/migration.json index 9a667ca12f4e..7675e20d8658 100644 --- a/src/material/schematics/migration.json +++ b/src/material/schematics/migration.json @@ -1,10 +1,10 @@ { "$schema": "./node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { - "migration-v19": { - "version": "19.0.0-0", - "description": "Updates Angular Material to v19", - "factory": "./ng-update/index_bundled#updateToV19" + "migration-v20": { + "version": "20.0.0-0", + "description": "Updates Angular Material to v20", + "factory": "./ng-update/index_bundled#updateToV20" } } } diff --git a/src/material/schematics/ng-update/index.ts b/src/material/schematics/ng-update/index.ts index e9f51ee593a6..cd99930de5ab 100644 --- a/src/material/schematics/ng-update/index.ts +++ b/src/material/schematics/ng-update/index.ts @@ -23,9 +23,9 @@ const materialMigrations: NullableDevkitMigration[] = [ ]; /** Entry point for the migration schematics with target of Angular Material v19 */ -export function updateToV19(): Rule { +export function updateToV20(): Rule { return createMigrationSchematicRule( - TargetVersion.V19, + TargetVersion.V20, materialMigrations, materialUpgradeData, onMigrationComplete, diff --git a/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts b/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts deleted file mode 100644 index 5a7a86afc73f..000000000000 --- a/src/material/schematics/ng-update/test-cases/v19-explicit-system-variable-prefix.spec.ts +++ /dev/null @@ -1,215 +0,0 @@ -import {UnitTestTree} from '@angular-devkit/schematics/testing'; -import {createTestCaseSetup} from '@angular/cdk/schematics/testing'; -import {MIGRATION_PATH} from '../../paths'; - -const THEME_FILE_PATH = '/projects/cdk-testing/src/theme.scss'; - -describe('v19 explicit system variable prefix migration', () => { - let tree: UnitTestTree; - let writeFile: (filename: string, content: string) => void; - let runMigration: () => Promise; - - function stripWhitespace(content: string): string { - return content.replace(/\s/g, ''); - } - - beforeEach(async () => { - const testSetup = await createTestCaseSetup('migration-v19', MIGRATION_PATH, []); - tree = testSetup.appTree; - writeFile = testSetup.writeFile; - runMigration = testSetup.runFixers; - }); - - it('should add an explicit system variables prefix', async () => { - writeFile( - THEME_FILE_PATH, - ` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true - ), - typography: ( - use-system-variables: true - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `, - ); - - await runMigration(); - - expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe( - stripWhitespace(` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true, - system-variables-prefix: sys, - ), - typography: ( - use-system-variables: true, - system-variables-prefix: sys, - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `), - ); - }); - - it('should add an explicit system variables prefix if the value is using trailing commas', async () => { - writeFile( - THEME_FILE_PATH, - ` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true, - ), - typography: ( - use-system-variables: true, - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `, - ); - - await runMigration(); - - expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe( - stripWhitespace(` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true, - system-variables-prefix: sys, - ), - typography: ( - use-system-variables: true, - system-variables-prefix: sys, - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `), - ); - }); - - it('should not add an explicit system variables prefix if the map has one already', async () => { - writeFile( - THEME_FILE_PATH, - ` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true - ), - typography: ( - use-system-variables: true, - system-variables-prefix: foo - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `, - ); - - await runMigration(); - - expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe( - stripWhitespace(` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: ( - theme-type: 'light', - primary: mat.$azure-palette, - tertiary: mat.$red-palette, - use-system-variables: true, - system-variables-prefix: sys, - ), - typography: ( - use-system-variables: true, - system-variables-prefix: foo - ), - density: ( - scale: -1 - ), - )); - - @include mat.all-component-themes($theme); - `), - ); - }); - - it('should handle a single-line map', async () => { - writeFile( - THEME_FILE_PATH, - ` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: (theme-type: 'light', primary: mat.$azure-palette, use-system-variables: true), - typography: (use-system-variables: true), - density: (scale: -1), - )); - - @include mat.all-component-themes($theme); - `, - ); - - await runMigration(); - - expect(stripWhitespace(tree.readText(THEME_FILE_PATH))).toBe( - stripWhitespace(` - @use '@angular/material' as mat; - - $theme: mat.define-theme(( - color: (theme-type: 'light', primary: mat.$azure-palette, use-system-variables: true, system-variables-prefix: sys,), - typography: (use-system-variables: true, system-variables-prefix: sys,), - density: (scale: -1), - )); - - @include mat.all-component-themes($theme); - `), - ); - }); -}); diff --git a/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts b/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts deleted file mode 100644 index 2a05fac5c73d..000000000000 --- a/src/material/schematics/ng-update/test-cases/v19-mat-core-removal.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import {UnitTestTree} from '@angular-devkit/schematics/testing'; -import {createTestCaseSetup} from '@angular/cdk/schematics/testing'; -import {join} from 'path'; -import {MIGRATION_PATH} from '../../paths'; - -const PROJECT_ROOT_DIR = '/projects/cdk-testing'; -const THEME_FILE_PATH = join(PROJECT_ROOT_DIR, 'src/theme.scss'); - -describe('v19 mat.core migration', () => { - let tree: UnitTestTree; - - /** Writes multiple lines to a file. */ - let writeLines: (path: string, lines: string[]) => void; - - /** Reads multiple lines from a file. */ - let readLines: (path: string) => string[]; - - /** Runs the v15 migration on the test application. */ - let runMigration: () => Promise<{logOutput: string}>; - - beforeEach(async () => { - const testSetup = await createTestCaseSetup('migration-v19', MIGRATION_PATH, []); - tree = testSetup.appTree; - runMigration = testSetup.runFixers; - readLines = (path: string) => tree.readContent(path).split('\n'); - writeLines = (path: string, lines: string[]) => testSetup.writeFile(path, lines.join('\n')); - }); - - describe('style migrations', () => { - async function runSassMigrationTest(ctx: string, opts: {old: string[]; new: string[]}) { - writeLines(THEME_FILE_PATH, opts.old); - await runMigration(); - expect(readLines(THEME_FILE_PATH)).withContext(ctx).toEqual(opts.new); - } - - it('should remove uses of the core mixin', async () => { - await runSassMigrationTest('', { - old: [`@use '@angular/material' as mat;`, `@include mat.core();`], - new: [ - `@use '@angular/material' as mat;`, - `@include mat.elevation-classes();`, - `@include mat.app-background();`, - ], - }); - - await runSassMigrationTest('w/ unique namespace', { - old: [`@use '@angular/material' as material;`, `@include material.core();`], - new: [ - `@use '@angular/material' as material;`, - `@include material.elevation-classes();`, - `@include material.app-background();`, - ], - }); - - await runSassMigrationTest('w/ no namespace', { - old: [`@use '@angular/material';`, `@include material.core();`], - new: [ - `@use '@angular/material';`, - `@include material.elevation-classes();`, - `@include material.app-background();`, - ], - }); - - await runSassMigrationTest('w/ unique whitespace', { - old: [ - ` @use '@angular/material' as material ; `, - ` @include material.core( ) ; `, - ], - new: [ - ` @use '@angular/material' as material ; `, - ` @include material.elevation-classes();`, - ` @include material.app-background(); `, - ], - }); - }); - - it('should not break if there is an invalid syntax', async () => { - await runSassMigrationTest('', { - old: [`@use '@angular/material' as mat;`, `.foo { content: '; }`], - new: [`@use '@angular/material' as mat;`, `.foo { content: '; }`], - }); - }); - }); -});