UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for AST navigation and code generation.

149 lines (147 loc) 10.6 kB
"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