Skip to content

Commit

Permalink
fix: Multiple namespace imports
Browse files Browse the repository at this point in the history
closes: #27
  • Loading branch information
unlight committed May 9, 2021
1 parent c369a78 commit e096af0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
6 changes: 5 additions & 1 deletion src/helpers/import-declaration-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export class ImportDeclarationMap extends Map<
namespaceImport?: string;
namedImport?: boolean;
}) {
const { name, from, defaultImport, namespaceImport, namedImport } = args;
const { from, defaultImport, namespaceImport, namedImport } = args;
let name = args.name;
const value = {
moduleSpecifier: from,
namedImports: [] as OptionalKind<ImportSpecifierStructure>[],
Expand All @@ -38,10 +39,13 @@ export class ImportDeclarationMap extends Map<
};
if (namedImport === true && namespaceImport) {
value.namedImports = [{ name: namespaceImport }];
name = namespaceImport;
} else if (defaultImport) {
value.defaultImport = defaultImport === true ? name : defaultImport;
name = value.defaultImport;
} else if (namespaceImport) {
value.namespaceImport = namespaceImport;
name = namespaceImport;
} else {
value.namedImports = [{ name }];
}
Expand Down
16 changes: 9 additions & 7 deletions src/test/custom-decorators.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import expect from 'expect';
import {
ClassDeclaration,
ImportDeclarationStructure,
Project,
PropertyDeclarationStructure,
SourceFile,
Expand All @@ -16,6 +17,7 @@ let propertyStructure: PropertyDeclarationStructure;
let imports: ReturnType<typeof getImportDeclarations>;
let classFile: ClassDeclaration;
let sourceFiles: SourceFile[];
let importDeclarations: ImportDeclarationStructure[] = [];

const p = (name: string) => getPropertyStructure(sourceFile, name);
const d = (name: string) => getPropertyStructure(sourceFile, name)?.decorators?.[0];
Expand Down Expand Up @@ -184,7 +186,6 @@ describe('custom types', () => {
});

describe('custom type json in user model', () => {
let importDeclarations: any[] = [];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
Expand Down Expand Up @@ -222,7 +223,6 @@ describe('custom types', () => {
});

describe('custom decorators namespace both input and output', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
Expand Down Expand Up @@ -275,10 +275,16 @@ describe('custom decorators namespace both input and output', () => {
);
});

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

it('validator should be imported once', () => {
expect(
importDeclarations.filter(x => x.moduleSpecifier === 'class-validator'),
).toHaveLength(1);
});
});

describe('user model output should not have validator decorator', () => {
Expand Down Expand Up @@ -308,7 +314,6 @@ describe('custom decorators namespace both input and output', () => {
});

describe('custom decorators and description', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
Expand Down Expand Up @@ -348,8 +353,6 @@ describe('custom decorators and description', () => {
});

describe('custom decorators default import', () => {
let importDeclarations: any[];

before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
Expand Down Expand Up @@ -428,7 +431,6 @@ describe('custom decorators default import', () => {
});

describe('custom decorators field custom type namespace', () => {
let importDeclarations: any[];
before(async () => {
({ project, sourceFiles } = await testGenerate({
schema: `
Expand Down
26 changes: 19 additions & 7 deletions src/test/test-generate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ok } from 'assert';
import AwaitEventEmitter from 'await-event-emitter/types';
import expect from 'expect';
import { uniq } from 'lodash';
import { Project } from 'ts-morph';

import { generate } from '../generate';
Expand Down Expand Up @@ -53,13 +54,24 @@ export async function testGenerate(args: {

ok(project, 'Project is not defined');
const sourceFiles = project.getSourceFiles();
let emptyFiles: string[] = [];
try {
emptyFiles = sourceFiles.filter(s => !s.getText()).map(s => s.getFilePath());
expect(emptyFiles).toHaveLength(0);
} catch {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw `Project should not contain empty files: ${emptyFiles}`;

for (const sourceFile of sourceFiles) {
const filePath = sourceFile.getFilePath();
const text = sourceFile.getText();
if (!text) {
throw `Project should not contain empty files: ${filePath}`;
}
const imports = sourceFile
.getImportDeclarations()
.map(d => d.getStructure())
.flatMap(s => {
return [...s.namedImports?.map(x => x.name), s.namespaceImport].filter(
Boolean,
);
});
if (uniq(imports).length !== imports.length) {
throw `Duplicated import in ${filePath}: ${imports.toString()}`;
}
}

return { project, sourceFiles };
Expand Down

0 comments on commit e096af0

Please sign in to comment.