Skip to content

Commit fe6629a

Browse files
devversionandrewseguin
authored andcommitted
fix(schematics): ensure project "style" and "skipTests" options are respected (#15513)
With angular/angular-cli@a12a4e0, the CLI made the option naming consistent. Since the default schematic are therefore named differently, we need to update our logic to work with the old option name and the new option name. Fixes #15502
1 parent 345cd8c commit fe6629a

35 files changed

+161
-98
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
"zone.js": "^0.8.29"
4848
},
4949
"devDependencies": {
50-
"@angular-devkit/core": "7.1.2",
51-
"@angular-devkit/schematics": "7.1.2",
50+
"@angular-devkit/core": "7.3.6",
51+
"@angular-devkit/schematics": "7.3.6",
5252
"@angular/bazel": "8.0.0-beta.6",
5353
"@angular/compiler-cli": "8.0.0-beta.6",
5454
"@angular/http": "8.0.0-beta.6",
@@ -62,7 +62,7 @@
6262
"@bazel/typescript": "0.26.0",
6363
"@firebase/app-types": "^0.3.2",
6464
"@octokit/rest": "^15.9.4",
65-
"@schematics/angular": "7.1.2",
65+
"@schematics/angular": "7.3.6",
6666
"@types/browser-sync": "^0.0.42",
6767
"@types/chalk": "^0.4.31",
6868
"@types/fs-extra": "^4.0.3",

src/cdk/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/dr
1010
styles: [`
1111
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
1212
`],<% } else { %>
13-
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>'],<% } %><% if(!!viewEncapsulation) { %>
13+
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'],<% } %><% if(!!viewEncapsulation) { %>
1414
encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } if (changeDetection !== 'Default') { %>
1515
changeDetection: ChangeDetectionStrategy.<%= changeDetection %>,<% } %>
1616
})

src/cdk/schematics/ng-generate/drag-drop/index.spec.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
2+
import {getProjectFromWorkspace} from '@angular/cdk/schematics';
3+
import {getWorkspace} from '@schematics/angular/utility/config';
4+
import {getProject} from '@schematics/angular/utility/project';
25
import {createTestApp, getFileContent} from '../../testing';
36
import {Schema} from './schema';
47

@@ -38,17 +41,34 @@ describe('CDK drag-drop schematic', () => {
3841
expect(moduleContent).toContain('DragDropModule');
3942
});
4043

41-
describe('styleext option', () => {
44+
describe('style option', () => {
4245
it('should respect the option value', () => {
4346
const tree = runner.runSchematic(
44-
'drag-drop', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
47+
'drag-drop', {style: 'scss', ...baseOptions}, createTestApp(runner));
48+
49+
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
50+
});
51+
52+
it('should respect the deprecated "styleext" option value', () => {
53+
let tree = createTestApp(runner);
54+
const workspace = getWorkspace(tree);
55+
const project = getProjectFromWorkspace(workspace);
56+
57+
// We need to specify the default component options by overwriting
58+
// the existing workspace configuration because passing the "styleext"
59+
// option is no longer supported. Though we want to verify that we
60+
// properly handle old CLI projects which still use the "styleext" option.
61+
project.schematics!['@schematics/angular:component'] = {styleext: 'scss'};
62+
63+
tree.overwrite('angular.json', JSON.stringify(workspace));
64+
tree = runner.runSchematic('drag-drop', baseOptions, tree);
4565

4666
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
4767
});
4868

4969
it('should not generate invalid stylesheets', () => {
5070
const tree = runner.runSchematic(
51-
'drag-drop', {styleext: 'styl', ...baseOptions}, createTestApp(runner));
71+
'drag-drop', {style: 'styl', ...baseOptions}, createTestApp(runner));
5272

5373
// In this case we expect the schematic to generate a plain "css" file because
5474
// the component schematics are using CSS style templates which are not compatible
@@ -99,10 +119,27 @@ describe('CDK drag-drop schematic', () => {
99119
});
100120
});
101121

102-
describe('spec option', () => {
122+
describe('skipTests option', () => {
103123
it('should respect the option value', () => {
104124
const tree = runner.runSchematic(
105-
'drag-drop', {spec: false, ...baseOptions}, createTestApp(runner));
125+
'drag-drop', {skipTests: true, ...baseOptions}, createTestApp(runner));
126+
127+
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
128+
});
129+
130+
it('should respect the deprecated global "spec" option value', () => {
131+
let tree = createTestApp(runner);
132+
const workspace = getWorkspace(tree);
133+
const project = getProjectFromWorkspace(workspace);
134+
135+
// We need to specify the default component options by overwriting
136+
// the existing workspace configuration because passing the "spec"
137+
// option is no longer supported. Though we want to verify that we
138+
// properly handle old CLI projects which still use the "spec" option.
139+
project.schematics!['@schematics/angular:component'] = {spec: false};
140+
141+
tree.overwrite('angular.json', JSON.stringify(workspace));
142+
tree = runner.runSchematic('drag-drop', baseOptions, tree);
106143

107144
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
108145
});

src/cdk/schematics/ng-generate/drag-drop/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default function(options: Schema): Rule {
1515
return chain([
1616
buildComponent({...options}, {
1717
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
18-
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
18+
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
1919
}),
2020
options.skipImport ? noop() : addDragDropModulesToModule(options)
2121
]);

src/cdk/schematics/ng-generate/drag-drop/schema.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@
5555
"description": "The prefix to apply to generated selectors.",
5656
"alias": "p"
5757
},
58-
"styleext": {
58+
"style": {
5959
"description": "The file extension to be used for style files.",
6060
"type": "string"
6161
},
62-
"spec": {
62+
"skipTests": {
6363
"type": "boolean",
64-
"description": "Specifies if a spec file is generated."
64+
"description": "When true, does not generate a test file."
6565
},
6666
"flat": {
6767
"type": "boolean",

src/cdk/schematics/utils/ast.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ export function addModuleImportToModule(host: Tree, modulePath: string, moduleNa
5151
throw new SchematicsException(`Module not found: ${modulePath}`);
5252
}
5353

54-
const changes = addImportToModule(moduleSource, modulePath, moduleName, src);
54+
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
55+
// than Material. Cast to any to avoid the type assignment failure.
56+
const changes = addImportToModule(moduleSource as any, modulePath, moduleName, src);
5557
const recorder = host.beginUpdate(modulePath);
5658

5759
changes.forEach((change) => {

src/cdk/schematics/utils/build-component.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
url,
2323
} from '@angular-devkit/schematics';
2424
import {FileSystemSchematicContext} from '@angular-devkit/schematics/tools';
25-
import {Schema as ComponentOptions} from '@schematics/angular/component/schema';
25+
import {Schema as ComponentOptions, Style} from '@schematics/angular/component/schema';
2626
import {
2727
addDeclarationToModule,
2828
addEntryComponentToModule,
@@ -72,7 +72,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
7272
const classifiedName = strings.classify(`${options.name}Component`);
7373

7474
const declarationChanges = addDeclarationToModule(
75-
source,
75+
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
76+
// than Material. Cast to any to avoid the type assignment failure.
77+
source as any,
7678
modulePath,
7779
classifiedName,
7880
relativePath);
@@ -91,7 +93,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
9193

9294
const exportRecorder = host.beginUpdate(modulePath);
9395
const exportChanges = addExportToModule(
94-
source,
96+
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
97+
// than Material. Cast to any to avoid the type assignment failure.
98+
source as any,
9599
modulePath,
96100
strings.classify(`${options.name}Component`),
97101
relativePath);
@@ -110,7 +114,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
110114

111115
const entryComponentRecorder = host.beginUpdate(modulePath);
112116
const entryComponentChanges = addEntryComponentToModule(
113-
source,
117+
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
118+
// than Material. Cast to any to avoid the type assignment failure.
119+
source as any,
114120
modulePath,
115121
strings.classify(`${options.name}Component`),
116122
relativePath);
@@ -205,8 +211,10 @@ export function buildComponent(options: ComponentOptions,
205211
// we generate the stylesheets with the "css" extension. This ensures that we don't
206212
// accidentally generate invalid stylesheets (e.g. drag-drop-comp.styl) which will
207213
// break the Angular CLI project. See: https://github.com/angular/material2/issues/15164
208-
if (!supportedCssExtensions.includes(options.styleext!)) {
209-
options.styleext = 'css';
214+
if (!supportedCssExtensions.includes(options.style!)) {
215+
// TODO: Cast is necessary as we can't use the Style enum which has been introduced
216+
// within CLI v7.3.0-rc.0. This would break the schematic for older CLI versions.
217+
options.style = 'css' as Style;
210218
}
211219

212220
// Object that will be used as context for the EJS templates.
@@ -230,8 +238,8 @@ export function buildComponent(options: ComponentOptions,
230238
}
231239

232240
const templateSource = apply(url(schematicFilesUrl), [
233-
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
234-
options.inlineStyle ? filter(path => !path.endsWith('.__styleext__')) : noop(),
241+
options.skipTests ? filter(path => !path.endsWith('.spec.ts')) : noop(),
242+
options.inlineStyle ? filter(path => !path.endsWith('.__style__')) : noop(),
235243
options.inlineTemplate ? filter(path => !path.endsWith('.html')) : noop(),
236244
// Treat the template options as any, because the type definition for the template options
237245
// is made unnecessarily explicit. Every type of object can be used in the EJS template.

src/cdk/schematics/utils/schematic-options.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,20 @@ export function getDefaultComponentOptions(project: WorkspaceProject) {
2020
// Note: Not all options which are available when running "ng new" will be stored in the
2121
// workspace config. List of options which will be available in the configuration:
2222
// angular/angular-cli/blob/master/packages/schematics/angular/application/index.ts#L109-L131
23+
let skipTests = getDefaultComponentOption<boolean|null>(project, ['skipTests'], null);
24+
25+
// In case "skipTests" is not set explicitly, also look for the "spec" option. The "spec"
26+
// option has been deprecated but can be still used in older Angular CLI projects.
27+
// See: https://github.com/angular/angular-cli/commit/a12a4e02a4689b5bdbc6e740c0d9865afb55671a
28+
if (skipTests === null) {
29+
skipTests = !getDefaultComponentOption(project, ['spec'], true);
30+
}
31+
2332
return {
24-
styleext: getDefaultComponentOption(project, 'styleext', 'css'),
25-
inlineStyle: getDefaultComponentOption(project, 'inlineStyle', false),
26-
inlineTemplate: getDefaultComponentOption(project, 'inlineTemplate', false),
27-
spec: getDefaultComponentOption(project, 'spec', true),
33+
style: getDefaultComponentOption(project, ['style', 'styleext'], 'css'),
34+
inlineStyle: getDefaultComponentOption(project, ['inlineStyle'], false),
35+
inlineTemplate: getDefaultComponentOption(project, ['inlineTemplate'], false),
36+
skipTests: skipTests,
2837
};
2938
}
3039

@@ -33,13 +42,15 @@ export function getDefaultComponentOptions(project: WorkspaceProject) {
3342
* by looking at the stored schematic options for `@schematics/angular:component` in the
3443
* CLI workspace configuration.
3544
*/
36-
function getDefaultComponentOption<T>(project: WorkspaceProject, optionName: string,
37-
fallbackValue: T): T | null {
38-
if (project.schematics &&
39-
project.schematics['@schematics/angular:component'] &&
40-
project.schematics['@schematics/angular:component'][optionName] != null) {
45+
function getDefaultComponentOption<T>(project: WorkspaceProject, optionNames: string[],
46+
fallbackValue: T): T {
47+
for (let optionName of optionNames) {
48+
if (project.schematics &&
49+
project.schematics['@schematics/angular:component'] &&
50+
project.schematics['@schematics/angular:component'][optionName] != null) {
4151

42-
return project.schematics['@schematics/angular:component'][optionName];
52+
return project.schematics['@schematics/angular:component'][optionName];
53+
}
4354
}
4455

4556
return fallbackValue;

0 commit comments

Comments
 (0)