Skip to content

Commit

Permalink
refactor: Moved spec files to test folder
Browse files Browse the repository at this point in the history
  • Loading branch information
unlight committed Apr 16, 2021
1 parent 82d944c commit aba712c
Show file tree
Hide file tree
Showing 11 changed files with 368 additions and 333 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ module.exports = {
},
overrides: [
{
files: ['*.spec.ts', '**/testing/**/*.ts'],
files: ['*.spec.ts', '**/test/**/*.ts'],
rules: {
'sonarjs/no-identical-functions': 0,
'consistent-return': 0,
Expand Down
2 changes: 1 addition & 1 deletion Taskfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ build() {
cp -fv README.md LICENSE package.json dist
cd dist
/usr/bin/find . -name '*.spec.ts' | xargs rm -rf
rm -rf fixtures testing example @generated
rm -rf fixtures test example @generated
tsc -p .
rm -rf tsconfig.json
/usr/bin/find . -name '*.ts' | xargs rm -rf
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"test": "npm run eslint && npm run tscheck && npm run test:cov",
"mocha": "node node_modules/mocha/bin/_mocha",
"test:r": "mocha -r ts-node/register/transpile-only src/**/*.spec.ts",
"test:cov": "c8 --reporter text --exclude \"**/*.spec.ts\" --exclude \"**/testing/**\" npm run test:r -- --no-timeouts",
"test:cov": "c8 --reporter text --exclude \"**/*.spec.ts\" --exclude \"**/test/**\" npm run test:r -- --no-timeouts",
"test:w": "mocha -r ts-node/register/transpile-only --watch-files src/**/*.ts --no-timeouts --watch src/**/*.spec.ts",
"test:d": "ndb -r ts-node/register/transpile-only node_modules/mocha/bin/_mocha --no-timeouts --watch-files src/**/*.ts --watch src/**/*.spec.ts",
"tscheck": "tsc --noEmit",
Expand Down
2 changes: 1 addition & 1 deletion src/example/user/user.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { GraphQLResolveInfo } from 'graphql';
import { AggregateUserArgs } from '../../@generated/user/aggregate-user.args';
import { AggregateUser } from '../../@generated/user/aggregate-user.output';
import { User } from '../../@generated/user/user.model';
import { UserCreateInput } from '../../@generated/user/user-create.input';
import { UserUpdateInput } from '../../@generated/user/user-update.input';
import { UserWhereInput } from '../../@generated/user/user-where.input';
import { UserDateInput } from './user-date.input';
import { UserCreateInput } from '../../@generated/user/user-create.input';

const prisma = new PrismaClient({
errorFormat: 'colorless',
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function createGeneratorOptions(
previewFeatures = ["orderByRelation", "selectRelationCount"]
}
generator proxy {
provider = "node -r ts-node/register/transpile-only src/testing/proxy-generator.ts"
provider = "node -r ts-node/register/transpile-only src/test/proxy-generator.ts"
output = "."
hash = "${hash}"
${options?.join('\n') || ''}
Expand Down
239 changes: 239 additions & 0 deletions src/test/custom-decorators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import expect from 'expect';
import {
ClassDeclaration,
Project,
PropertyDeclarationStructure,
SourceFile,
} from 'ts-morph';

import { getImportDeclarations, getPropertyStructure } from './helpers';
import { testGenerate } from './test-generate';

let sourceFile: SourceFile;
let sourceText: string;
let project: Project;
let propertyStructure: PropertyDeclarationStructure;
let imports: ReturnType<typeof getImportDeclarations>;
let classFile: ClassDeclaration;
let sourceFiles: SourceFile[];

const p = (name: string) => getPropertyStructure(sourceFile, name);
const d = (name: string) => getPropertyStructure(sourceFile, name)?.decorators?.[0];
const setSourceFile = (name: string) => {
sourceFile = project.getSourceFile(s => s.getFilePath().endsWith(name))!;
classFile = sourceFile.getClass(() => true)!;
sourceText = sourceFile.getText();
imports = getImportDeclarations(sourceFile);
};

describe('custom decorators namespace both input and output', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
model User {
id Int @id
/// @Validator.MaxLength(30)
name String
/// @Validator.Max(999)
/// @Validator.Min(18)
age Int
/// @Validator.IsEmail()
email String?
}`,
options: [
`outputFilePattern = "{name}.{type}.ts"`,
// custom decorators (validate)
// import * as Validator from 'class-validator'
// @Validator.IsEmail()
// email: string
`fields_Validator_from = "class-validator"`,
`fields_Validator_input = true`,
],
}));
});

describe('custom decorators in user create input', () => {
before(() => {
setSourceFile('user-create.input.ts');
importDeclarations = sourceFile
.getImportDeclarations()
.map(d => d.getStructure());
});

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

it('decorator validator maxlength should exists', () => {
const d = classFile
.getProperty('name')
?.getDecorator(d => d.getFullName() === 'Validator.MaxLength');
expect(d).toBeTruthy();
expect(d?.getText()).toBe('@Validator.MaxLength(30)');
});

it('imports should contains custom import', () => {
expect(importDeclarations).toContainEqual(
expect.objectContaining({
namespaceImport: 'Validator',
moduleSpecifier: 'class-validator',
}),
);
});

it('several decorators', () => {
const decorators = p('age')?.decorators;
expect(decorators).toHaveLength(3);
});
});

describe('user model output should not have validator decorator', () => {
before(() => setSourceFile('user.model.ts'));

describe('should not have metadata in description', () => {
it('age', () => {
expect(d('age')?.arguments?.[1]).not.toContain('description');
});

it('name', () => {
expect(d('name')?.arguments?.[1]).not.toContain('description');
});

it('email', () => {
expect(d('email')?.arguments?.[1]).not.toContain('description');
});
});

it('output model has no maxlength decorator', () => {
const decorator = p('name')?.decorators?.find(d => d.name === 'MaxLength');
expect(decorator).toBeFalsy();
});

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

describe('custom decorators default import', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
model User {
id Int @id
/// @IsValidName()
name String
}`,
options: [
`outputFilePattern = "{name}.{type}.ts"`,
`fields_IsValidName_from = "is-valid-name"`,
`fields_IsValidName_input = true`,
`fields_IsValidName_defaultImport = IsValidName`,
],
}));
});

describe('in user create input', () => {
before(() => {
setSourceFile('user-create.input.ts');
});

it('importDeclarations should import default', () => {
importDeclarations = sourceFile
.getImportDeclarations()
.map(d => d.getStructure())
.filter(d => d.moduleSpecifier === 'is-valid-name');

expect(importDeclarations).toHaveLength(1);
expect(importDeclarations[0]).toEqual(
expect.objectContaining({
defaultImport: 'IsValidName',
namedImports: [],
namespaceImport: undefined,
}),
);
});

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

describe('custom decorators field custom type namespace', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
model User {
id Int @id
/// @FieldType({ name: 'Scalars.EmailAddress', output: true, input: true })
email String
/// @FieldType('Scalars.EmailAddress')
secondEmail String
}`,
options: [
`outputFilePattern = "{name}.{type}.ts"`,
// import { EmailAddress } from 'graphql-scalars'
// @Field(() => EmailAddress)
`fields_Scalars_from = "graphql-scalars"`,
`fields_Scalars_input = true`,
],
}));
});

describe('user create input', () => {
before(() => {
setSourceFile('user-create.input.ts');
});

it('field type', () => {
const decorator = p('email')?.decorators?.find(d => d.name === 'Field');
const typeArgument = decorator?.arguments?.[0];
expect(typeArgument).toEqual('() => Scalars.EmailAddress');
});

it('should not apply to field as decorator', () => {
const decorators = p('email')?.decorators;
expect(decorators).toHaveLength(1);
});

it('field type secondemail', () => {
const decorator = p('secondEmail')?.decorators?.find(
d => d.name === 'Field',
);
const typeArgument = decorator?.arguments?.[0];
expect(typeArgument).toEqual('() => Scalars.EmailAddress');
});

it('importdeclarations should import namespace', () => {
importDeclarations = sourceFile
.getImportDeclarations()
.map(d => d.getStructure())
.filter(d => d.moduleSpecifier === 'graphql-scalars');

expect(importDeclarations).toHaveLength(1);
expect(importDeclarations[0]).toEqual(
expect.objectContaining({
defaultImport: undefined,
namedImports: [],
namespaceImport: 'Scalars',
}),
);
});

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

describe('custom type user model', () => {
before(() => {
setSourceFile('user.model.ts');
});

it('custom type user model email field type', () => {
const decorator = p('email')?.decorators?.find(d => d.name === 'Field');
const typeArgument = decorator?.arguments?.[0];
expect(typeArgument).toEqual('() => Scalars.EmailAddress');
});

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

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

0 comments on commit aba712c

Please sign in to comment.