ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
149 lines (147 loc) • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const compiler_1 = require("./../../../compiler");
const testHelpers_1 = require("./../testHelpers");
describe("MethodDeclaration", () => {
describe("insertOverloads", () => {
function doTest(startCode, index, structures, expectedCode, methodIndex = 0) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(startCode);
const methodDeclaration = firstChild.getAllMembers()[methodIndex];
const result = methodDeclaration.insertOverloads(index, structures);
chai_1.expect(result.length).to.equal(structures.length);
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should insert when no other overloads exist", () => {
doTest("class Identifier {\n identifier() {}\n }", 0, [{ returnType: "number" }, {}], "class Identifier {\n identifier(): number;\n identifier();\n identifier() {}\n }");
});
it("should insert when a JSDoc exists", () => {
doTest("class Identifier {\n otherMethod(): string {}\n\n /** Test */\n identifier() {}\n }", 0, [{ returnType: "number" }], "class Identifier {\n otherMethod(): string {}\n\n identifier(): number;\n /** Test */\n identifier() {}\n }", 1);
});
it("should copy over the static, abstract, and scope keywords", () => {
doTest("class Identifier {\n protected abstract static async *identifier() {}\n }", 0, [{ isStatic: false }, {}], "class Identifier {\n protected abstract identifier();\n protected abstract static identifier();\n protected abstract static async *identifier() {}\n }");
});
it("should be able to insert at start when another overload exists", () => {
doTest("class Identifier {\n identifier();\n identifier() {}\n }", 0, [{ returnType: "string" }], "class Identifier {\n identifier(): string;\n identifier();\n identifier() {}\n }");
});
it("should be able to insert at end when another overload exists", () => {
doTest("class Identifier {\n identifier();\n identifier() {}\n }", 1, [{ returnType: "string" }], "class Identifier {\n identifier();\n identifier(): string;\n identifier() {}\n }");
});
it("should be able to insert in the middle when other overloads exists", () => {
doTest("class Identifier {\n identifier();\n identifier();\n identifier() {}\n }", 1, [{ returnType: "string" }], "class Identifier {\n identifier();\n identifier(): string;\n identifier();\n identifier() {}\n }");
});
});
describe("insertOverload", () => {
function doTest(startCode, index, structure, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(startCode);
const methodDeclaration = firstChild.getAllMembers()[0];
const result = methodDeclaration.insertOverload(index, structure);
chai_1.expect(result).to.be.instanceof(compiler_1.MethodDeclaration);
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should be able to insert in the middle when other overloads exists", () => {
doTest("class Identifier {\n identifier();\n identifier();\n identifier() {}\n }", 1, { returnType: "string" }, "class Identifier {\n identifier();\n identifier(): string;\n identifier();\n identifier() {}\n }");
});
});
describe("addOverloads", () => {
function doTest(startCode, structures, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(startCode);
const methodDeclaration = firstChild.getAllMembers()[0];
const result = methodDeclaration.addOverloads(structures);
chai_1.expect(result.length).to.equal(structures.length);
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should be able to add multiple", () => {
doTest("class Identifier {\n identifier();\n identifier() {}\n }", [{ returnType: "string" }, { returnType: "number" }], "class Identifier {\n identifier();\n identifier(): string;\n identifier(): number;\n identifier() {}\n }");
});
});
describe("addOverload", () => {
function doTest(startCode, structure, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(startCode);
const methodDeclaration = firstChild.getAllMembers()[0];
const result = methodDeclaration.addOverload(structure);
chai_1.expect(result).to.be.instanceof(compiler_1.MethodDeclaration);
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should be able to add an overload", () => {
doTest("class Identifier {\n identifier();\n identifier() {}\n }", { returnType: "string" }, "class Identifier {\n identifier();\n identifier(): string;\n identifier() {}\n }");
});
});
describe("fill", () => {
function doTest(startingCode, structure, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(startingCode);
const method = firstChild.getInstanceMethods()[0];
method.fill(structure);
chai_1.expect(sourceFile.getText()).to.equal(expectedCode);
}
it("should not modify anything if the structure doesn't change anything", () => {
doTest("class identifier {\n method() {}\n}", {}, "class identifier {\n method() {}\n}");
});
it("should modify when changed", () => {
const structure = {
overloads: [{ parameters: [{ name: "param" }] }]
};
doTest("class identifier {\n method() {}\n}", structure, "class identifier {\n method(param);\n method() {}\n}");
});
});
describe("remove", () => {
describe("no overload", () => {
function doTest(code, nameToRemove, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(code);
firstChild.getInstanceMethod(nameToRemove).remove();
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should remove when it's the only method", () => {
doTest("class Identifier {\n method() {}\n}", "method", "class Identifier {\n}");
});
it("should remove when it's the first method", () => {
doTest("class Identifier {\n method() {}\n\n method2() {}\n}", "method", "class Identifier {\n method2() {}\n}");
});
it("should remove when it's the middle method", () => {
doTest("class Identifier {\n method1(){}\n\n method2(){}\n\n method3() {}\n}", "method2", "class Identifier {\n method1(){}\n\n method3() {}\n}");
});
it("should remove when it's the last method", () => {
doTest("class Identifier {\n method() {}\n\n method2() {}\n}", "method2", "class Identifier {\n method() {}\n}");
});
it("should remove when it's beside a property ", () => {
doTest("class Identifier {\n method(){}\n\n prop: string;\n}", "method", "class Identifier {\n prop: string;\n}");
});
it("should remove when it's in an ambient class", () => {
doTest("declare class Identifier {\n method(): void;\n\n prop: string;\n\n method2(): void;\n}", "method", "declare class Identifier {\n prop: string;\n\n method2(): void;\n}");
});
});
describe("overloads", () => {
function doTest(code, nameToRemove, index, expectedCode) {
const { firstChild, sourceFile } = testHelpers_1.getInfoFromText(code);
const method = firstChild.getInstanceMethod(nameToRemove);
[...method.getOverloads(), method][index].remove();
chai_1.expect(sourceFile.getFullText()).to.equal(expectedCode);
}
it("should remove when surrounded by other members", () => {
doTest("class Identifier {\n prop: string;\n\nmethod(str): void;\n method(param) {}\n\nprop2: string;\n}", "method", 1, "class Identifier {\n prop: string;\nprop2: string;\n}");
});
it("should remove the method and all its overloads when calling on the body", () => {
doTest("class Identifier {\n method(str): void;\n method(param) {}\n}", "method", 1, "class Identifier {\n}");
});
it("should remove only the specified overload", () => {
doTest("class Identifier {\n method(str): void;\n method(param) {}\n}", "method", 0, "class Identifier {\n method(param) {}\n}");
});
it("should remove when the first overload", () => {
doTest("class Identifier {\n method(first): void;\n method(second): void;\n method(param) {}\n}", "method", 0, "class Identifier {\n method(second): void;\n method(param) {}\n}");
});
it("should remove when the middle overload", () => {
doTest("class Identifier {\n method(first): void;\n method(second): void;\n method(third): void;\n method(param) {}\n}", "method", 1, "class Identifier {\n method(first): void;\n method(third): void;\n method(param) {}\n}");
});
it("should remove when the last overload", () => {
doTest("class Identifier {\n method(first): void;\n method(last): void;\n method(param) {}\n}", "method", 1, "class Identifier {\n method(first): void;\n method(param) {}\n}");
});
it("should remove only the specified overload and its jsdoc", () => {
doTest("class Identifier {\n /** Test */\n method(str): void;\n method(param) {}\n}", "method", 0, "class Identifier {\n method(param) {}\n}");
});
it("should remove only the specified signature when it's in an ambient class", () => {
doTest("declare class Identifier {\n method(): void;\n method(): void;\n}", "method", 1, "declare class Identifier {\n method(): void;\n}");
});
});
});
});
//# sourceMappingURL=methodDeclarationTests.js.map