Skip to content

Commit

Permalink
fix(custom decorators): Reget decorator full name
Browse files Browse the repository at this point in the history
close: unlight#29
  • Loading branch information
unlight committed May 11, 2021
1 parent 2b5c679 commit 9e279bf
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 13 deletions.
30 changes: 30 additions & 0 deletions src/handlers/generate-files.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ok } from 'assert';
import {
ClassDeclarationStructure,
ImportSpecifierStructure,
Expand All @@ -21,7 +22,36 @@ export function beforeGenerateFiles(args: EventArguments) {
if (s === sourceFile) {
return [];
}
const classDeclaration = s.getClass(() => true);
const statements = s.getStructure().statements;
// Reget decorator full name
// TODO: Check possible bug of ts-morph
if (Array.isArray(statements)) {
for (const statement of statements) {
if (
!(
typeof statement === 'object' &&
statement.kind === StructureKind.Class
)
) {
continue;
}
for (const property of statement.properties || []) {
for (const decorator of property.decorators || []) {
const fullName = classDeclaration
?.getProperty(property.name)
?.getDecorator(decorator.name)
?.getFullName();
ok(
fullName,
`Cannot get full name of decorator of class ${statement.name!}`,
);
decorator.name = fullName;
}
}
}
}

project.removeSourceFile(s);
return statements;
});
Expand Down
71 changes: 58 additions & 13 deletions src/test/generate.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import expect from 'expect';
import { trim } from 'lodash';
import {
ClassDeclaration,
EnumDeclarationStructure,
ImportDeclarationStructure,
ImportSpecifierStructure,
Project,
PropertyDeclaration,
PropertyDeclarationStructure,
SourceFile,
} from 'ts-morph';
Expand Down Expand Up @@ -1414,13 +1416,67 @@ describe('reexport option', () => {
});
});

describe('emit single and decorators', () => {
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
model User {
id Int @id
/// @Validator.MinLength(3)
name String
/// @PropertyType({ name: 'G.Email', from: 'graphql-type-email' })
email String?
}
`,
options: [
`emitSingle = true`,
`outputFilePattern = "{name}.{type}.ts"`,
`fields_Validator_from = "class-validator"`,
`fields_Validator_input = true`,
],
}));
setSourceFile('index.ts');
});

it('should contain custom decorator import', () => {
const importDeclaration = importDeclarations.find(
x => x.moduleSpecifier === 'graphql-type-email',
);
expect(importDeclaration).toEqual(
expect.objectContaining({
namespaceImport: 'G',
}),
);
});

it('validator namespace for name should be imported', () => {
expect(importDeclarations).toContainEqual(
expect.objectContaining({
namespaceImport: 'Validator',
}),
);
});

describe('user create input name', () => {
let property: PropertyDeclaration;
before(() => {
property = sourceFile.getClass('UserCreateInput')?.getProperty('name')!;
});

it('decorator validator', () => {
const d = property.getDecorator(d => d.getFullText().includes('MinLength'));
expect(trim(d?.getFullText())).toEqual('@Validator.MinLength(3)');
});
});

// it('^', () => console.log(sourceFile.getText()));
});

describe('emit single', () => {
const schema = `
model User {
id Int @id
posts Post[]
/// @PropertyType({ name: 'G.Email', from: 'graphql-type-email' })
email String?
}
model Post {
id Int @id
Expand Down Expand Up @@ -1449,17 +1505,6 @@ describe('emit single', () => {
expect(badImport).toBeUndefined();
});

it('should contain custom decorator import', () => {
const importDeclaration = importDeclarations.find(
x => x.moduleSpecifier === 'graphql-type-email',
);
expect(importDeclaration).toEqual(
expect.objectContaining({
namespaceImport: 'G',
}),
);
});

it('should contains class user', () => {
expect(sourceText).toMatch(/export class User {/);
});
Expand Down

0 comments on commit 9e279bf

Please sign in to comment.