Skip to content

Commit 9abd3eb

Browse files
committed
refactor(schematics): add test cases for cdk ng-update
1 parent 2e4a511 commit 9abd3eb

28 files changed

+507
-190
lines changed

src/cdk/schematics/BUILD.bazel

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1 @@
1-
package(default_visibility = ["//visibility:public"])
2-
3-
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
4-
load("@build_bazel_rules_nodejs//:defs.bzl", "npm_package", "jasmine_node_test")
5-
load("//:packages.bzl", "VERSION_PLACEHOLDER_REPLACEMENTS")
6-
7-
# TODO(devversion): remove when https://github.com/bazelbuild/rules_nodejs/issues/352 is fixed
8-
exports_files(["#bazel_workaround.txt"])
9-
10-
filegroup(
11-
name = "schematics_assets",
12-
srcs = glob(["**/files/**/*", "**/*.json"]) + ["README.md"],
13-
)
14-
15-
ts_library(
16-
name = "schematics",
17-
module_name = "@angular/cdk/schematics",
18-
srcs = glob(["**/*.ts"], exclude=["**/files/**/*.ts", "**/*.spec.ts"]),
19-
tsconfig = ":tsconfig.json",
20-
deps = [
21-
"@npm//:@schematics/angular",
22-
"@npm//:@angular-devkit/schematics",
23-
# TODO(devversion): Only include jasmine for test sources.
24-
"@npm//:@types/jasmine",
25-
"@npm//:@types/node",
26-
"@npm//:glob",
27-
"@npm//:jasmine",
28-
"@npm//:parse5",
29-
"@npm//:rxjs",
30-
"@npm//:tslint",
31-
"@npm//:typescript"
32-
],
33-
)
34-
35-
# This package is intended to be combined into the main @angular/cdk package as a dep.
36-
npm_package(
37-
name = "npm_package",
38-
srcs = [":schematics_assets"],
39-
deps = [":schematics"],
40-
replacements = VERSION_PLACEHOLDER_REPLACEMENTS,
41-
)
42-
43-
### Testing rules
44-
45-
jasmine_node_test(
46-
name = "unit_tests",
47-
srcs = [":schematics_test_sources"],
48-
data = [":schematics_assets"],
49-
deps = ["@npm//:jasmine"],
50-
)
51-
52-
ts_library(
53-
name = "schematics_test_sources",
54-
srcs = glob(["**/*.spec.ts"], exclude = ["**/files/**/*.spec.ts"]),
55-
deps = [
56-
":schematics",
57-
"@npm//:@schematics/angular",
58-
"@npm//:@angular-devkit/schematics",
59-
"@npm//:@types/jasmine",
60-
"@npm//:@types/node",
61-
"@npm//:mock-fs",
62-
"@npm//:tslint",
63-
"@npm//:typescript",
64-
],
65-
tsconfig = ":tsconfig.json",
66-
testonly = True,
67-
)
1+
package(default_visibility = ["//visibility:public"])load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")load("@build_bazel_rules_nodejs//:defs.bzl", "npm_package", "jasmine_node_test")load("//:packages.bzl", "VERSION_PLACEHOLDER_REPLACEMENTS")# TODO(devversion): remove when https://github.com/bazelbuild/rules_nodejs/issues/352 is fixedexports_files(["#bazel_workaround.txt"])filegroup( name = "schematics_assets", srcs = glob(["**/files/**/*", "**/*.json"]) + ["README.md"],)ts_library( name = "schematics", module_name = "@angular/cdk/schematics", srcs = glob(["**/*.ts"], exclude=[ "**/files/**/*.ts", "**/*.spec.ts", "ng-update/test-cases/**/*", ]), tsconfig = ":tsconfig.json", deps = [ "@npm//:@schematics/angular", "@npm//:@angular-devkit/schematics", # TODO(devversion): Only include jasmine for test sources. "@npm//:@types/jasmine", "@npm//:@types/node", # TODO(devversion): Similarly to "jasmine", we need to extract these into testing only. "@npm//:fs-extra", "@npm//:glob", "@npm//:jasmine", "@npm//:parse5", "@npm//:rxjs", "@npm//:tslint", "@npm//:typescript" ],)# This package is intended to be combined into the main @angular/cdk package as a dep.npm_package( name = "npm_package", srcs = [":schematics_assets"], deps = [":schematics"], replacements = VERSION_PLACEHOLDER_REPLACEMENTS,)### Testing rulesjasmine_node_test( name = "unit_tests", srcs = [":schematics_test_sources"], data = [":schematics_assets", ":schematics_test_cases"], deps = ["@npm//:jasmine"],)ts_library( name = "schematics_test_sources", srcs = glob(["**/*.spec.ts"], exclude = ["**/files/**/*.spec.ts"]), deps = [ ":schematics", "@npm//:@schematics/angular", "@npm//:@angular-devkit/schematics", "@npm//:@types/jasmine", "@npm//:@types/node", "@npm//:mock-fs", "@npm//:tslint", "@npm//:typescript", ], tsconfig = ":tsconfig.json", testonly = True,)filegroup( name = "schematics_test_cases", srcs = glob([ "ng-update/test-cases/**/*_input.ts", "ng-update/test-cases/**/*_expected_output.ts" ]), testonly = True,)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/** Path to the schematic collection that includes the migrations. */
2+
export const migrationCollection = require.resolve('../../migration.json');
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {migrationCollection} from '../index.spec';
2+
import {runTestCases} from '../../../testing';
3+
4+
describe('v6 method call checks', () => {
5+
6+
it('should properly report invalid method calls', async () => {
7+
const {logOutput} = await runTestCases('migration-v6', migrationCollection, {
8+
'method-call-checks': require.resolve('./method-call-checks_input.ts')
9+
});
10+
11+
expect(logOutput)
12+
.toMatch(/\[15,.*Found call to "FocusMonitor\.monitor".*renderer.*has been removed/);
13+
expect(logOutput)
14+
.toMatch(/\[16,.*Found call to "FocusMonitor\.monitor".*renderer.*has been removed/);
15+
});
16+
});

src/lib/schematics/ng-update/test-cases/misc/method-call-checks_input.ts renamed to src/cdk/schematics/ng-update/test-cases/misc/method-call-checks_input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class A implements AfterViewInit {
1515
this.focusMonitor.monitor(this.elementRef.nativeElement, this.renderer, true);
1616
this.self.a.monitor(this.elementRef.nativeElement, this.renderer, true);
1717
}
18-
}
18+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {join} from 'path';
2+
import {readFileContent, runTestCases} from '../../testing';
3+
import {migrationCollection} from './index.spec';
4+
5+
describe('v6 upgrade test cases', () => {
6+
7+
/**
8+
* Name of test cases that will be used to verify that update schematics properly update
9+
* a developers application.
10+
*/
11+
const testCases = [
12+
'v6/attribute-selectors',
13+
'v6/class-names',
14+
'v6/input-names',
15+
'v6/property-names',
16+
];
17+
18+
let testCasesOutputPath: string;
19+
20+
beforeAll(async () => {
21+
const testCaseInputs = testCases.reduce((inputs, testCaseName) => {
22+
inputs[testCaseName] = require.resolve(`./${testCaseName}_input.ts`);
23+
return inputs;
24+
}, {} as {[name: string]: string});
25+
26+
const {tempPath} = await runTestCases('migration-v6', migrationCollection, testCaseInputs);
27+
28+
testCasesOutputPath = join(tempPath, 'projects/cdk-testing/src/test-cases/');
29+
});
30+
31+
// Iterates through every test case directory and generates a jasmine test block that will
32+
// verify that the update schematics properly updated the test input to the expected output.
33+
testCases.forEach(testCaseName => {
34+
const expectedOutputPath = require.resolve(`./${testCaseName}_expected_output.ts`);
35+
36+
it(`should apply update schematics to test case: ${testCaseName}`, () => {
37+
expect(readFileContent(join(testCasesOutputPath, `${testCaseName}.ts`)))
38+
.toBe(readFileContent(expectedOutputPath));
39+
});
40+
});
41+
});
42+
43+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {Component} from '@angular/core';
2+
import {By} from '@angular/platform-browser';
3+
4+
const a = By.css('[cdkPortalOutlet]');
5+
const b = By.css('[cdkPortalOutlet]');
6+
7+
// These should not change because we only update string literals that are
8+
// inside of a call expression.
9+
const c = 'cdkPortalHost';
10+
const d = 'portalHost';
11+
12+
@Component({
13+
template: `
14+
<div cdkPortalOutlet="E"></div>
15+
<div [cdkPortalOutlet]="myPortal"></div>
16+
`,
17+
styles: [
18+
'[cdkPortalOutlet] {background: red}',
19+
'div[cdkPortalOutlet] {color: blue}'
20+
]
21+
})
22+
class E {}
23+
24+
@Component({
25+
template: `
26+
<div cdkPortalOutlet="F"></div>
27+
<div [cdkPortalOutlet]="myPortal"></div>
28+
`,
29+
styles: [
30+
'[cdkPortalOutlet] {background: red}',
31+
'div[cdkPortalOutlet] {color: blue}'
32+
]
33+
})
34+
class F {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {Component} from '@angular/core';
2+
import {By} from '@angular/platform-browser';
3+
4+
const a = By.css('[cdkPortalHost]');
5+
const b = By.css('[portalHost]');
6+
7+
// These should not change because we only update string literals that are
8+
// inside of a call expression.
9+
const c = 'cdkPortalHost';
10+
const d = 'portalHost';
11+
12+
@Component({
13+
template: `
14+
<div cdkPortalHost="E"></div>
15+
<div [cdkPortalHost]="myPortal"></div>
16+
`,
17+
styles: [
18+
'[cdkPortalHost] {background: red}',
19+
'div[cdkPortalHost] {color: blue}'
20+
]
21+
})
22+
class E {}
23+
24+
@Component({
25+
template: `
26+
<div portalHost="F"></div>
27+
<div [portalHost]="myPortal"></div>
28+
`,
29+
styles: [
30+
'[portalHost] {background: red}',
31+
'div[portalHost] {color: blue}'
32+
]
33+
})
34+
class F {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {CdkConnectedOverlay, CdkOverlayOrigin} from '@angular/cdk/overlay';
2+
import {CdkObserveContent} from '@angular/cdk/observers';
3+
import {CdkTrapFocus} from '@angular/cdk/a11y';
4+
5+
const a = new CdkConnectedOverlay();
6+
const b = new CdkOverlayOrigin();
7+
const c = new CdkObserveContent();
8+
const d = new CdkTrapFocus();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {ConnectedOverlayDirective, OverlayOrigin} from '@angular/cdk/overlay';
2+
import {ObserveContent} from '@angular/cdk/observers';
3+
import {FocusTrapDirective} from '@angular/cdk/a11y';
4+
5+
const a = new ConnectedOverlayDirective();
6+
const b = new OverlayOrigin();
7+
const c = new ObserveContent();
8+
const d = new FocusTrapDirective();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
template: `
5+
<ng-template cdkConnectedOverlay
6+
[cdkConnectedOverlayOrigin]="myOrigin"
7+
[cdkConnectedOverlayPositions]="myPositions"
8+
[cdkConnectedOverlayOffsetX]="myOffsetX"
9+
[cdkConnectedOverlayOffsetY]="myOffsetY"
10+
[cdkConnectedOverlayWidth]="myWidth"
11+
[cdkConnectedOverlayHeight]="myHeight"
12+
[cdkConnectedOverlayMinWidth]="myMinWidth"
13+
[cdkConnectedOverlayMinHeight]="myMinHeight"
14+
[cdkConnectedOverlayBackdropClass]="myBackdropClass"
15+
[cdkConnectedOverlayScrollStrategy]="myScrollStrategy"
16+
[cdkConnectedOverlayOpen]="isOpen"
17+
[cdkConnectedOverlayHasBackdrop]="hasBackdrop">
18+
</ng-template>
19+
`
20+
})
21+
class A {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
template: `
5+
<ng-template cdkConnectedOverlay
6+
[origin]="myOrigin"
7+
[positions]="myPositions"
8+
[offsetX]="myOffsetX"
9+
[offsetY]="myOffsetY"
10+
[width]="myWidth"
11+
[height]="myHeight"
12+
[minWidth]="myMinWidth"
13+
[minHeight]="myMinHeight"
14+
[backdropClass]="myBackdropClass"
15+
[scrollStrategy]="myScrollStrategy"
16+
[open]="isOpen"
17+
[hasBackdrop]="hasBackdrop">
18+
</ng-template>
19+
`
20+
})
21+
class A {}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
class CdkConnectedOverlay {
2+
_deprecatedOrigin: any;
3+
_deprecatedPositions: any;
4+
_deprecatedOffsetX: any;
5+
_deprecatedOffsetY: any;
6+
_deprecatedWidth: any;
7+
_deprecatedHeight: any;
8+
_deprecatedMinWidth: any;
9+
_deprecatedMinHeight: any;
10+
_deprecatedBackdropClass: any;
11+
_deprecatedScrollStrategy: any;
12+
_deprecatedOpen: any;
13+
_deprecatedHasBackdrop: any;
14+
}
15+
16+
class CdkPortalOutlet {
17+
_deprecatedPortal: any;
18+
_deprecatedPortalHost: any;
19+
}
20+
21+
class A {
22+
self = {me: this};
23+
24+
constructor(private a: CdkConnectedOverlay) {}
25+
26+
onAngularClick() {
27+
this.a.origin = '1';
28+
this.a.positions = '2';
29+
this.a.offsetX = '3';
30+
this.a.offsetY = '4';
31+
this.a.height = '5';
32+
33+
console.log(this.a.width || 10);
34+
console.log(this.a.minWidth || this.a.minHeight);
35+
36+
this.self.me.a.backdropClass = ['a', 'b', 'c'];
37+
38+
const x = ({test: true} || this.a);
39+
40+
if (this.isConnectedOverlay(x)) {
41+
x.scrollStrategy = 'myScrollStrategy';
42+
x.open = false;
43+
x.hasBackdrop = true;
44+
}
45+
}
46+
47+
isConnectedOverlay(val: any): val is CdkConnectedOverlay {
48+
return val instanceof CdkConnectedOverlay;
49+
}
50+
}
51+
52+
class B {
53+
self = {me: this};
54+
55+
constructor(protected a: CdkPortalOutlet) {}
56+
57+
onClick() {
58+
this.a.portal = this.a.portal = 'myNewPortal';
59+
60+
if (this.self.me.a) {
61+
console.log(this.a.portal || this.self.me.a.portal);
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)