Skip to content

Commit

Permalink
feat(module:schematics): improve migration and component schematics (#…
Browse files Browse the repository at this point in the history
…8577)

* refactor(module:schematics): improve migration schematic

* refactor(module:schematics): improve component schematic
  • Loading branch information
Laffery authored Jun 17, 2024
1 parent 512a577 commit 1f137a3
Show file tree
Hide file tree
Showing 22 changed files with 244 additions and 194 deletions.
1 change: 0 additions & 1 deletion docs/animations.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ Add the `nzNoAnimation` directive to the component.
```HTML
<nz-modal nzNoAnimation></nz-modal>
<ul nz-menu nzNoAnimation></ul>
<nz-form-explain [nzNoAnimation]="true"></nz-form-explain>
```

### Turn Off In Services
Expand Down
1 change: 0 additions & 1 deletion docs/animations.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import { NzNoAnimationModule } from 'ng-zorro-antd/core/no-animation';
```HTML
<nz-modal nzNoAnimation></nz-modal>
<ul nz-menu nzNoAnimation></ul>
<nz-form-explain [nzNoAnimation]="true"></nz-form-explain>
```

### 在服务中关闭
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<% if(displayBlock){ if(style != 'sass') { %>:host {
display: block;
}
<% } else { %>\:host
display: block;
<% }} %>
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
<p>
<%= dasherize(name) %> works!
</p>
<p><%= dasherize(name) %> works!</p>
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';

describe('<%= classify(name) %>Component', () => {
let component: <%= classify(name) %>Component;
let fixture: ComponentFixture<<%= classify(name) %>Component>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ <%= classify(name) %>Component ]
beforeEach(async () => {
await TestBed.configureTestingModule({
<%= standalone ? 'imports' : 'declarations' %>: [<%= classify(name) %>Component]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(<%= classify(name) %>Component);
component = fixture.componentInstance;
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { Component, OnInit<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';
import { <% if(changeDetection !== 'Default') { %>ChangeDetectionStrategy, <% }%>Component<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%> } from '@angular/core';

@Component({
selector: '<%= selector %>',<% if(inlineTemplate) { %>
selector: '<%= selector %>',<% if(standalone) {%>
standalone: true,
imports: [],<%}%><% if(inlineTemplate) { %>
template: `
<p>
<%= dasherize(name) %> works!
</p>
`,<% } else { %>
templateUrl: './<%= dasherize(name) %>.component.html',<% } if(inlineStyle) { %>
styles: []<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
`<% } else { %>
templateUrl: './<%= dasherize(name) %>.component.html'<% } if(inlineStyle) { %>,
styles: `<% if(displayBlock){ %>
:host {
display: block;
}
<% } %>`<% } else if (style !== 'none') { %>,
styleUrl: './<%= dasherize(name) %>.component.<%= style %>'<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>,
standalone: true
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
export class <%= classify(name) %>Component implements OnInit {

constructor() { }

ngOnInit() {
}
export class <%= classify(name) %>Component {

}
177 changes: 124 additions & 53 deletions schematics/ng-component/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import { ChangeDetection, Style } from '@schematics/angular/component/schema';

import { describe } from 'node:test'

import { createTestApp } from '../testing/test-app';

const appOptions = {
Expand Down Expand Up @@ -51,70 +53,139 @@ describe('ng-component schematic', () => {
);
});

it('should create a flat component', async () => {
const options = { ...defaultOptions, flat: true };
const tree = await runner.runSchematic('component', options, appTree);
const files = tree.files;

expect(files).toEqual(
jasmine.arrayContaining([
'/projects/ng-zorro/src/app/test.component.less',
'/projects/ng-zorro/src/app/test.component.html',
'/projects/ng-zorro/src/app/test.component.spec.ts',
'/projects/ng-zorro/src/app/test.component.ts'
])
);
describe('style', () => {
it('should create specified style', async() => {
const options = { ...defaultOptions, style: Style.Sass };
const tree = await runner.runSchematic('component', options, appTree);
const files = tree.files.filter(file => file.startsWith('/projects/ng-zorro/src/app/test/'));

expect(files).toEqual(
jasmine.arrayContaining([
'/projects/ng-zorro/src/app/test/test.component.sass',
'/projects/ng-zorro/src/app/test/test.component.html',
'/projects/ng-zorro/src/app/test/test.component.spec.ts',
'/projects/ng-zorro/src/app/test/test.component.ts'
])
);
});

it('should not create style file when inlineStyle is true', async() => {
const options = { ...defaultOptions, inlineStyle: true };
const tree = await runner.runSchematic('component', options, appTree);
const files = tree.files.filter(file => file.startsWith('/projects/ng-zorro/src/app/test/'));

expect(files.length).toEqual(3);
expect(files).toEqual(
jasmine.arrayContaining([
'/projects/ng-zorro/src/app/test/test.component.html',
'/projects/ng-zorro/src/app/test/test.component.spec.ts',
'/projects/ng-zorro/src/app/test/test.component.ts'
])
);
});

it('should not create style file when style is none', async() => {
const options = { ...defaultOptions, style: Style.None };
const tree = await runner.runSchematic('component', options, appTree);
const files = tree.files.filter(file => file.startsWith('/projects/ng-zorro/src/app/test/'));

expect(files.length).toEqual(3);
expect(files).toEqual(
jasmine.arrayContaining([
'/projects/ng-zorro/src/app/test/test.component.html',
'/projects/ng-zorro/src/app/test/test.component.spec.ts',
'/projects/ng-zorro/src/app/test/test.component.ts'
])
);
});
});

it('should find the closest module', async () => {
const options = { ...defaultOptions, standalone: false };
const closestModule = '/projects/ng-zorro/src/app/test/test.module.ts';
describe('displayBlock', () => {
it('should add display block styles to the component', async () => {
const options = { ...defaultOptions, displayBlock: true };
const tree = await runner.runSchematic('component', options, appTree);
const content = tree.readContent('/projects/ng-zorro/src/app/test/test.component.less');

appTree.create(
closestModule,
`
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: []
})
export class ClosestModule { }
`
);
const tree = await runner.runSchematic('component', options, appTree);
const fooModuleContent = tree.readContent(closestModule);
expect(content).toMatch(/display: block/);
});

expect(fooModuleContent).toMatch(/import { TestComponent } from '.\/test.component'/);
it('should add display block styles to the component when inlineStyle is true', async () => {
const options = { ...defaultOptions, displayBlock: true, inlineStyle: true };
const tree = await runner.runSchematic('component', options, appTree);
const content = tree.readContent('/projects/ng-zorro/src/app/test/test.component.ts');

expect(content).toMatch(/display: block/);
});
});

it('should set classname with the closest module', async () => {
const options = { ...defaultOptions, classnameWithModule: true, standalone: false };
const testModule = '/projects/ng-zorro/src/app/test/test.module.ts';
describe('flat', () => {
it('should create a flat component', async () => {
const options = { ...defaultOptions, flat: true };
const tree = await runner.runSchematic('component', options, appTree);
const files = tree.files;

expect(files).toEqual(
jasmine.arrayContaining([
'/projects/ng-zorro/src/app/test.component.less',
'/projects/ng-zorro/src/app/test.component.html',
'/projects/ng-zorro/src/app/test.component.spec.ts',
'/projects/ng-zorro/src/app/test.component.ts'
])
);
});
});

appTree.create(
testModule,
describe('classnameWithModule', () => {
it('should find the closest module', async () => {
const options = { ...defaultOptions, standalone: false };
const closestModule = '/projects/ng-zorro/src/app/test/test.module.ts';

appTree.create(
closestModule,
`
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: []
})
export class ClosestModule { }
`
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: []
})
export class TestModule { }
`
);
);
const tree = await runner.runSchematic('component', options, appTree);
const fooModuleContent = tree.readContent(closestModule);

expect(fooModuleContent).toMatch(/import { TestComponent } from '.\/test.component'/);
});

it('should set classname with the closest module', async () => {
const options = { ...defaultOptions, classnameWithModule: true, standalone: false };
const testModule = '/projects/ng-zorro/src/app/test/test.module.ts';

appTree.create(
testModule,
`
import { NgModule } from '@angular/core';
@NgModule({
imports: [],
declarations: []
})
export class TestModule { }
`
);

const tree = await runner.runSchematic('component', options, appTree);
const fooModuleContent = tree.readContent(testModule);
const tree = await runner.runSchematic('component', options, appTree);
const fooModuleContent = tree.readContent(testModule);

expect(fooModuleContent).toMatch(/import { TestTestComponent } from '.\/test.component'/);
});
expect(fooModuleContent).toMatch(/import { TestTestComponent } from '.\/test.component'/);
});

it('should set classname with the specified module', async () => {
const options = { ...defaultOptions, classnameWithModule: true, module: 'app.module.ts', standalone: false };
const app = await createTestApp(runner, { ...appOptions, standalone: false });
const tree = await runner.runSchematic('component', options, app);
it('should set classname with the specified module', async () => {
const options = { ...defaultOptions, classnameWithModule: true, module: 'app.module.ts', standalone: false };
const app = await createTestApp(runner, { ...appOptions, standalone: false });
const tree = await runner.runSchematic('component', options, app);

const appComponentContent = tree.readContent('/projects/ng-zorro/src/app/app.module.ts');
expect(appComponentContent).toMatch(/import { AppTestComponent } from '.\/test\/test.component'/);
const appComponentContent = tree.readContent('/projects/ng-zorro/src/app/app.module.ts');
expect(appComponentContent).toMatch(/import { AppTestComponent } from '.\/test\/test.component'/);
});
});
});
34 changes: 15 additions & 19 deletions schematics/ng-component/schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/schema",
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "PLACEHOLDER_SCHEMATICS_ID",
"title": "PLACEHOLDER_SCHEMATICS_TITLE",
"type": "object",
Expand All @@ -26,6 +26,12 @@
},
"x-prompt": "What should be the name of the component?"
},
"displayBlock": {
"description": "Specifies if the style will contain `:host { display: block; }`.",
"type": "boolean",
"default": false,
"alias": "b"
},
"inlineStyle": {
"description": "When true, includes styles inline in the component.ts file. Only CSS styles can be included inline. By default, an external styles file is created and referenced in the component.ts file.",
"type": "boolean",
Expand All @@ -41,8 +47,7 @@
"standalone": {
"description": "Whether the generated component is standalone.",
"type": "boolean",
"default": true,
"x-user-analytics": "ep.ng_standalone"
"default": true
},
"viewEncapsulation": {
"description": "The view encapsulation strategy to use in the new component.",
Expand Down Expand Up @@ -71,33 +76,23 @@
}
]
},
"styleext": {
"description": "The file extension to use for style files.",
"type": "string",
"default": "css",
"x-deprecated": "Use \"style\" instead."
},
"style": {
"description": "The file extension or preprocessor to use for style files.",
"description": "The file extension or preprocessor to use for style files, or 'none' to skip generating the style file.",
"type": "string",
"default": "css",
"enum": [
"css",
"scss",
"sass",
"less",
"styl"
"styl",
"none"
]
},
"spec": {
"type": "boolean",
"description": "When true (the default), generates a \"spec.ts\" test file for the new component.",
"default": true,
"x-deprecated": "Use \"skipTests\" instead."
},
"skipTests": {
"type": "boolean",
"description": "When true, does not create \"spec.ts\" test files for the new component."
"description": "When true, does not create \"spec.ts\" test files for the new component.",
"default": false
},
"flat": {
"type": "boolean",
Expand All @@ -106,7 +101,8 @@
},
"skipImport": {
"type": "boolean",
"description": "When true, does not import this component into the owning NgModule."
"description": "When true, does not import this component into the owning NgModule.",
"default": false
},
"selector": {
"type": "string",
Expand Down
Loading

0 comments on commit 1f137a3

Please sign in to comment.