Skip to content

Commit

Permalink
Merge pull request #967 from stanimirovv/fix/allow-underscores-in-names
Browse files Browse the repository at this point in the history
Allow underscores in names
  • Loading branch information
kamilmysliwiec committed Mar 7, 2022
2 parents d9ad002 + 69998cf commit 784404d
Show file tree
Hide file tree
Showing 37 changed files with 967 additions and 310 deletions.
102 changes: 83 additions & 19 deletions src/lib/application/application.factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ describe('Application Factory', () => {
const options: ApplicationOptions = {
name: 'project',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/project/.eslintrc.js',
Expand All @@ -35,15 +37,19 @@ describe('Application Factory', () => {
'/project/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/project/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/project/package.json')),
).toMatchObject({
name: 'project',
});
});
it('should manage name with dots in it', async () => {
const options: ApplicationOptions = {
name: 'project.foo.bar',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
`/project.foo.bar/.eslintrc.js`,
Expand All @@ -63,15 +69,19 @@ describe('Application Factory', () => {
`/project.foo.bar/test/jest-e2e.json`,
]);

expect(JSON.parse(tree.readContent('/project.foo.bar/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/project.foo.bar/package.json')),
).toMatchObject({
name: 'project.foo.bar',
});
});
it('should manage name to dasherize from camel case name', async () => {
it('should manage name to normalize from camel case name', async () => {
const options: ApplicationOptions = {
name: 'awesomeProject',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/awesome-project/.eslintrc.js',
Expand All @@ -91,15 +101,51 @@ describe('Application Factory', () => {
'/awesome-project/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/awesome-project/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/awesome-project/package.json')),
).toMatchObject({
name: 'awesome-project',
});
});
it('should keep underscores', async () => {
const options: ApplicationOptions = {
name: '_awesomeProject',
};
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/_awesome-project/.eslintrc.js',
'/_awesome-project/.gitignore',
'/_awesome-project/.prettierrc',
'/_awesome-project/README.md',
'/_awesome-project/nest-cli.json',
'/_awesome-project/package.json',
'/_awesome-project/tsconfig.build.json',
'/_awesome-project/tsconfig.json',
'/_awesome-project/src/app.controller.spec.ts',
'/_awesome-project/src/app.controller.ts',
'/_awesome-project/src/app.module.ts',
'/_awesome-project/src/app.service.ts',
'/_awesome-project/src/main.ts',
'/_awesome-project/test/app.e2e-spec.ts',
'/_awesome-project/test/jest-e2e.json',
]);

expect(
JSON.parse(tree.readContent('/_awesome-project/package.json')),
).toMatchObject({
name: '_awesome-project',
});
});
it('should manage basic name that has no scope name in it but starts with "@"', async () => {
const options: ApplicationOptions = {
name: '@/package',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/@/package/.eslintrc.js',
Expand All @@ -119,15 +165,19 @@ describe('Application Factory', () => {
'/@/package/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/@/package/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/@/package/package.json')),
).toMatchObject({
name: 'package',
});
});
it('should manage the name "." (ie., current working directory)', async () => {
const options: ApplicationOptions = {
name: '.',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/.eslintrc.js',
Expand Down Expand Up @@ -157,7 +207,9 @@ describe('Application Factory', () => {
const options: ApplicationOptions = {
name: '@scope/package',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/@scope/package/.eslintrc.js',
Expand All @@ -177,15 +229,19 @@ describe('Application Factory', () => {
'/@scope/package/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/@scope/package/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/@scope/package/package.json')),
).toMatchObject({
name: '@scope/package',
});
});
it('should manage name with blank space right after the "@" symbol', async () => {
const options: ApplicationOptions = {
name: '@ /package',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/@-/package/.eslintrc.js',
Expand All @@ -205,7 +261,9 @@ describe('Application Factory', () => {
'/@-/package/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/@-/package/package.json'))).toMatchObject({
expect(
JSON.parse(tree.readContent('/@-/package/package.json')),
).toMatchObject({
name: '@-/package',
});
});
Expand All @@ -217,7 +275,9 @@ describe('Application Factory', () => {
name: 'project',
language: 'js',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/project/.babelrc',
Expand All @@ -238,16 +298,20 @@ describe('Application Factory', () => {
'/project/test/jest-e2e.json',
]);

expect(JSON.parse(tree.readContent('/project/package.json'))).toMatchObject({
name: 'project',
});
expect(JSON.parse(tree.readContent('/project/package.json'))).toMatchObject(
{
name: 'project',
},
);
});
it('should manage destination directory', async () => {
const options: ApplicationOptions = {
name: 'project',
directory: 'app',
};
const tree: UnitTestTree = await runner.runSchematicAsync('application', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('application', options)
.toPromise();
const files: string[] = tree.files;
expect(files).toEqual([
'/app/.eslintrc.js',
Expand Down
3 changes: 2 additions & 1 deletion src/lib/application/application.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
url,
} from '@angular-devkit/schematics';
import { basename, parse } from 'path';
import { normalizeToKebabOrSnakeCase } from '../../utils/formatting';
import {
DEFAULT_AUTHOR,
DEFAULT_DESCRIPTION,
Expand All @@ -18,7 +19,7 @@ import {
import { ApplicationOptions } from './application.schema';

export function main(options: ApplicationOptions): Rule {
options.name = strings.dasherize(options.name);
options.name = normalizeToKebabOrSnakeCase(options.name);

const path =
!options.directory || options.directory === 'undefined'
Expand Down
56 changes: 36 additions & 20 deletions src/lib/class/class.factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ describe('Class Factory', () => {
spec: true,
flat: true,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;

expect(files.find(filename => filename === '/foo.ts')).not.toBeUndefined();
expect(
files.find((filename) => filename === '/foo.ts'),
).not.toBeUndefined();
expect(tree.readContent('/foo.ts')).toEqual('export class Foo {}\n');
});
it('should manage name as a path', async () => {
Expand All @@ -28,11 +32,13 @@ describe('Class Factory', () => {
flat: false,
spec: false,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;

expect(
files.find(filename => filename === '/bar/foo/foo.ts'),
files.find((filename) => filename === '/bar/foo/foo.ts'),
).not.toBeUndefined();
expect(tree.readContent('/bar/foo/foo.ts')).toEqual(
'export class Foo {}\n',
Expand All @@ -45,42 +51,48 @@ describe('Class Factory', () => {
flat: false,
spec: false,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;
expect(
files.find(filename => filename === '/baz/foo/foo.ts'),
files.find((filename) => filename === '/baz/foo/foo.ts'),
).not.toBeUndefined();
expect(tree.readContent('/baz/foo/foo.ts')).toEqual(
'export class Foo {}\n',
);
});
it('should manage name to dasherize', async () => {
it('should manage name to normalize', async () => {
const options: ClassOptions = {
name: 'fooBar',
name: '_fooBar',
flat: false,
spec: false,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;
expect(
files.find(filename => filename === '/foo-bar/foo-bar.ts'),
files.find((filename) => filename === '/_foo-bar/_foo-bar.ts'),
).not.toBeUndefined();
expect(tree.readContent('/foo-bar/foo-bar.ts')).toEqual(
expect(tree.readContent('/_foo-bar/_foo-bar.ts')).toEqual(
'export class FooBar {}\n',
);
});
it('should manage path to dasherize', async () => {
it('should manage path to normalize', async () => {
const options: ClassOptions = {
name: 'barBaz/foo',
name: 'barBaz/_foo',
spec: false,
flat: false,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;
expect(
files.find(filename => filename === '/bar-baz/foo/foo.ts'),
files.find((filename) => filename === '/bar-baz/_foo/_foo.ts'),
).not.toBeUndefined();
expect(tree.readContent('/bar-baz/foo/foo.ts')).toEqual(
expect(tree.readContent('/bar-baz/_foo/_foo.ts')).toEqual(
'export class Foo {}\n',
);
});
Expand All @@ -91,10 +103,12 @@ describe('Class Factory', () => {
flat: false,
spec: false,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;
expect(
files.find(filename => filename === '/foo/foo.js'),
files.find((filename) => filename === '/foo/foo.js'),
).not.toBeUndefined();
expect(tree.readContent('/foo/foo.js')).toEqual('export class Foo {}\n');
});
Expand All @@ -104,11 +118,13 @@ describe('Class Factory', () => {
spec: true,
flat: true,
};
const tree: UnitTestTree = await runner.runSchematicAsync('class', options).toPromise();
const tree: UnitTestTree = await runner
.runSchematicAsync('class', options)
.toPromise();
const files: string[] = tree.files;

expect(
files.find(filename => filename === '/foo.entity.ts'),
files.find((filename) => filename === '/foo.entity.ts'),
).not.toBeUndefined();
expect(tree.readContent('/foo.entity.ts')).toEqual(
'export class FooEntity {}\n',
Expand Down
7 changes: 4 additions & 3 deletions src/lib/class/class.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
template,
url,
} from '@angular-devkit/schematics';
import { normalizeToKebabOrSnakeCase } from '../../utils/formatting';
import { Location, NameParser } from '../../utils/name.parser';
import { mergeSourceRoot } from '../../utils/source-root.helpers';
import { DEFAULT_LANGUAGE } from '../defaults';
Expand All @@ -30,7 +31,7 @@ function transform(options: ClassOptions): ClassOptions {
}
const location: Location = new NameParser().parse(target);

target.name = strings.dasherize(location.name);
target.name = normalizeToKebabOrSnakeCase(location.name);
if (target.name.includes('.')) {
target.className = strings.classify(target.name).replace('.', '');
} else {
Expand All @@ -40,7 +41,7 @@ function transform(options: ClassOptions): ClassOptions {
target.language =
target.language !== undefined ? target.language : DEFAULT_LANGUAGE;

target.path = strings.dasherize(location.path);
target.path = normalizeToKebabOrSnakeCase(location.path);
target.path = target.flat
? target.path
: join(target.path as Path, target.name);
Expand All @@ -51,7 +52,7 @@ function transform(options: ClassOptions): ClassOptions {
function generate(options: ClassOptions): Source {
return (context: SchematicContext) =>
apply(url(join('./files' as Path, options.language)), [
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
options.spec ? noop() : filter((path) => !path.endsWith('.spec.ts')),
template({
...strings,
...options,
Expand Down
Loading

0 comments on commit 784404d

Please sign in to comment.