Skip to content

Commit

Permalink
feat(react): adds and updates React schematics with more options
Browse files Browse the repository at this point in the history
- Added component schematic that adds to existing project.
    * Supports CSS-in-JS styles, functional components, etc.
- Lib and app schematics now support new style, funtional components options (same as component)
  • Loading branch information
jaysoo authored and vsavkin committed May 22, 2019
1 parent d72db4d commit 0923dab
Show file tree
Hide file tree
Showing 33 changed files with 926 additions and 195 deletions.
16 changes: 16 additions & 0 deletions docs/api-react/schematics/application.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ ng generate application ...

## Options

### classComponent

Default: `false`

Type: `boolean`

Use class components instead of functional component

### directory

Type: `string`
Expand All @@ -31,6 +39,14 @@ Type: `string`

The name of the application.

### pascalCaseFiles

Default: `false`

Type: `boolean`

Use pascal case component file name (e.g. App.tsx)®

### skipFormat

Default: `false`
Expand Down
64 changes: 64 additions & 0 deletions docs/api-react/schematics/component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# component

Create a component

## Usage

```bash
ng generate component ...

```

## Options

### classComponent

Default: `false`

Type: `boolean`

Use class components instead of functional component

### export

Default: `false`

Type: `boolean`

When true, the component is exported from the project index.ts (if it exists).

### name

Type: `string`

The name of the component.

### pascalCaseFiles

Default: `false`

Type: `boolean`

Use pascal case component file name (e.g. App.tsx)

### project

Type: `string`

The name of the project (as specified in angular.json).

### skipTests

Default: `false`

Type: `boolean`

When true, does not create "spec.ts" test files for the new component.

### style

Default: `css`

Type: `string`

The file extension to be used for style files.
8 changes: 8 additions & 0 deletions docs/api-react/schematics/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ Type: `string`

Library name

### pascalCaseFiles

Default: `false`

Type: `boolean`

Use pascal case component file name (e.g. App.tsx)®

### skipFormat

Default: `false`
Expand Down
6 changes: 6 additions & 0 deletions packages/react/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
"schema": "./src/schematics/library/schema.json",
"aliases": ["lib"],
"description": "Create a library"
},

"component": {
"factory": "./src/schematics/component/component",
"schema": "./src/schematics/component/schema.json",
"description": "Create a component"
}
}
}
135 changes: 116 additions & 19 deletions packages/react/src/schematics/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ describe('app', () => {
const tree = await runSchematic(
'app',
{
name: 'my-App'
name: 'my-app'
},
appTree
);
Expand All @@ -206,7 +206,7 @@ describe('app', () => {
const tree = await runSchematic(
'app',
{
name: 'my-App'
name: 'my-app'
},
appTree
);
Expand All @@ -220,7 +220,7 @@ describe('app', () => {
const tree = await runSchematic(
'app',
{
name: 'my-App'
name: 'my-app'
},
appTree
);
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('app', () => {
const tree = await runSchematic(
'app',
{
name: 'my-App'
name: 'my-app'
},
appTree
);
Expand All @@ -284,7 +284,7 @@ describe('app', () => {
const tree = await runSchematic(
'app',
{
name: 'my-App'
name: 'my-app'
},
appTree
);
Expand All @@ -301,20 +301,6 @@ describe('app', () => {
});
});

describe('--prefix', () => {
it('should use the prefix in the index.html', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', prefix: 'prefix' },
appTree
);

expect(tree.readContent('apps/my-app/src/index.html')).toContain(
'<prefix-root></prefix-root>'
);
});
});

describe('--unit-test-runner none', () => {
it('should not generate test configuration', async () => {
const tree = await runSchematic(
Expand Down Expand Up @@ -345,4 +331,115 @@ describe('app', () => {
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
});
});

describe('--pascalCaseFiles', () => {
it('should use upper case app file', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', pascalCaseFiles: true },
appTree
);

expect(tree.exists('apps/my-app/src/app/App.tsx')).toBeTruthy();
expect(tree.exists('apps/my-app/src/app/App.spec.tsx')).toBeTruthy();
expect(tree.exists('apps/my-app/src/app/App.css')).toBeTruthy();
});
});

it('should generate functional components by default', async () => {
const tree = await runSchematic('app', { name: 'myApp' }, appTree);

const appContent = tree.read('apps/my-app/src/app/app.tsx').toString();

expect(appContent).not.toMatch(/extends Component/);
});

describe('--class-component', () => {
it('should generate class components', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', classComponent: true },
appTree
);

const appContent = tree.read('apps/my-app/src/app/app.tsx').toString();

expect(appContent).toMatch(/extends Component/);
});
});

describe('--style styled-components', () => {
it('should use styled-components as the styled API library', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', style: 'styled-components' },
appTree
);

expect(
tree.exists('apps/my-app/src/app/app.styled-components')
).toBeFalsy();
expect(tree.exists('apps/my-app/src/app/app.tsx')).toBeTruthy();

const content = tree.read('apps/my-app/src/app/app.tsx').toString();
expect(content).toContain('styled-component');
expect(content).toContain('<StyledApp>');
});

it('should add dependencies to package.json', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', style: 'styled-components' },
appTree
);

const packageJSON = readJsonInTree(tree, 'package.json');
expect(packageJSON.dependencies['styled-components']).toBeDefined();
});
});

describe('--style @emotion/styled', () => {
it('should use @emotion/styled as the styled API library', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', style: '@emotion/styled' },
appTree
);

expect(
tree.exists('apps/my-app/src/app/app.@emotion/styled')
).toBeFalsy();
expect(tree.exists('apps/my-app/src/app/app.tsx')).toBeTruthy();

const content = tree.read('apps/my-app/src/app/app.tsx').toString();
expect(content).toContain('@emotion/styled');
expect(content).toContain('<StyledApp>');
});

it('should exclude styles from angular.json', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', style: '@emotion/styled' },
appTree
);

const angularJSON = readJsonInTree(tree, 'angular.json');

expect(
angularJSON.projects['my-app'].architect.build.options.styles
).toEqual([]);
});

it('should add dependencies to package.json', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', style: '@emotion/styled' },
appTree
);

const packageJSON = readJsonInTree(tree, 'package.json');
expect(packageJSON.dependencies['@emotion/core']).toBeDefined();
expect(packageJSON.dependencies['@emotion/styled']).toBeDefined();
});
});
});
Loading

0 comments on commit 0923dab

Please sign in to comment.