Skip to content

Commit

Permalink
fix: ImportSpecifier and ExportSpecifier - Specifying an empty string…
Browse files Browse the repository at this point in the history
… to setAlias should not crash.
  • Loading branch information
dsherret committed Sep 18, 2018
1 parent 576db34 commit a7beb66
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 23 deletions.
5 changes: 5 additions & 0 deletions src/compiler/file/ExportSpecifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export class ExportSpecifier extends Node<ts.ExportSpecifier> {
* @param alias - Alias to set.
*/
setAlias(alias: string) {
if (StringUtils.isNullOrWhitespace(alias)) {
this.removeAliasWithRename();
return this;
}

let aliasIdentifier = this.getAliasNode();
if (aliasIdentifier == null) {
// trick is to insert an alias with the same name, then rename the alias. TS compiler will take care of the rest.
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/file/ImportSpecifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export class ImportSpecifier extends Node<ts.ImportSpecifier> {
* @param alias - Alias to set.
*/
setAlias(alias: string) {
if (StringUtils.isNullOrWhitespace(alias)) {
this.removeAliasWithRename();
return this;
}

let aliasIdentifier = this.getAliasNode();
if (aliasIdentifier == null) {
// trick is to insert an alias with the same name, then rename the alias. TS compiler will take care of the rest.
Expand Down
43 changes: 20 additions & 23 deletions src/tests/compiler/file/exportSpecifierTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,33 +103,30 @@ describe(nameof(ExportSpecifier), () => {
});

describe(nameof<ExportSpecifier>(n => n.setAlias), () => {
function doTest(text: string, newAlias: string, expected: string, expectedImportName: string) {
const { sourceFile, project } = getInfoFromText<ExportDeclaration>(text);
const otherSourceFile = project.createSourceFile("file.ts", "export class name {}");
const importingFile = project.createSourceFile("importingFile.ts", `import { name } from './testFile';`);
const namedImport = sourceFile.getExportDeclarations()[0].getNamedExports()[0];
namedImport.setAlias(newAlias);
expect(sourceFile.getText()).to.equal(expected);
expect(importingFile.getImportDeclarations()[0].getNamedImports()[0].getName()).to.equal(expectedImportName);
expect(otherSourceFile.getText()).to.equal("export class name {}");
}

it("should rename existing alias", () => {
const project = getProject();
const myClassFile = project.createSourceFile("MyClass.ts", {
classes: [{ name: "MyClass", isExported: true }]
});
const exportsFile = project.createSourceFile("Exports.ts", {
exports: [{ namedExports: [{ name: "MyClass", alias: "MyAlias" }], moduleSpecifier: "./MyClass" }]
});
const mainFile = project.createSourceFile("Main.ts", `import { MyAlias } from "./Exports";\n\nconst t = MyAlias;\n`);
exportsFile.getExportDeclarations()[0].getNamedExports()[0].setAlias("MyNewAlias");
expect(exportsFile.getFullText()).to.equal(`export { MyClass as MyNewAlias } from "./MyClass";\n`);
expect(mainFile.getFullText()).to.equal(`import { MyNewAlias } from "./Exports";\n\nconst t = MyNewAlias;\n`);
doTest("import {name as alias} from './file'; export { alias as name };", "newAlias",
"import {name as alias} from './file'; export { alias as newAlias };", "newAlias");
});

it("should add new alias and update all usages to the new alias", () => {
const project = getProject();
const myClassFile = project.createSourceFile("MyClass.ts", {
classes: [{ name: "MyClass", isExported: true }]
});
const exportsFile = project.createSourceFile("Exports.ts", {
exports: [{ namedExports: ["MyClass"], moduleSpecifier: "./MyClass" }]
});
const mainFile = project.createSourceFile("Main.ts", `import { MyClass } from "./Exports";\n\nconst t = MyClass;\n`);
exportsFile.getExportDeclarations()[0].getNamedExports()[0].setAlias("MyNewAlias");
expect(myClassFile.getFullText()).to.equal(`export class MyClass {\n}\n`);
expect(exportsFile.getFullText()).to.equal(`export { MyClass as MyNewAlias } from "./MyClass";\n`);
expect(mainFile.getFullText()).to.equal(`import { MyNewAlias } from "./Exports";\n\nconst t = MyNewAlias;\n`);
doTest("import {name} from './file'; export { name };", "newAlias",
"import {name} from './file'; export { name as newAlias };", "newAlias");
});

it("should remove and rename existing alias when specifying an empty string", () => {
doTest("import {name as alias} from './file'; export { alias as name };", "",
"import {name as alias} from './file'; export { alias };", "alias");
});
});

Expand Down
4 changes: 4 additions & 0 deletions src/tests/compiler/file/importSpecifierTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ describe(nameof(ImportSpecifier), () => {
it("should rename when there is an alias", () => {
doTest("import {name as alias} from './file'; const t = alias;", "newAlias", "import {name as newAlias} from './file'; const t = newAlias;");
});

it("should be remove and update the current file when specifying an empty string", () => {
doTest("import {name as alias} from './file'; const t = alias;", "", "import {name} from './file'; const t = name;");
});
});

describe(nameof<ImportSpecifier>(n => n.removeAlias), () => {
Expand Down

0 comments on commit a7beb66

Please sign in to comment.