-
Notifications
You must be signed in to change notification settings - Fork 189
/
overloadableNodeTests.ts
143 lines (121 loc) · 6.2 KB
/
overloadableNodeTests.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import { nameof } from "@ts-morph/common";
import { expect } from "chai";
import { ClassDeclaration, ConstructorDeclaration, FunctionDeclaration, OverloadableNode } from "../../../../compiler";
import { getInfoFromText } from "../../testHelpers";
describe("OverloadableNode", () => {
const functionCode = `function myFunction();function myFunction() {}`;
const { sourceFile: functionSourceFile } = getInfoFromText<FunctionDeclaration>(functionCode);
const functions = functionSourceFile.getChildSyntaxListOrThrow().getChildren() as FunctionDeclaration[];
const constructorCode =
`class MyClass { constructor();constructor();constructor() {} myMethod(): void;myMethod() {} static myMethod(): void;static myMethod(): void;static myMethod() {} abstract test(); }`;
const { firstChild: classChild } = getInfoFromText<ClassDeclaration>(constructorCode);
const constructors = classChild.getChildSyntaxListOrThrow().getChildren().filter(c => c instanceof ConstructorDeclaration) as ConstructorDeclaration[];
const ambientCode = `declare function func();declare function func();`;
const { sourceFile: ambientSourceFile } = getInfoFromText<FunctionDeclaration>(ambientCode);
const ambientFunctions = ambientSourceFile.getChildSyntaxListOrThrow().getChildren() as FunctionDeclaration[];
describe(nameof<OverloadableNode>("isImplementation"), () => {
it("should not be an implementation when not one", () => {
expect(functions[0].isImplementation()).to.be.false;
});
it("should be an implementation when is one", () => {
expect(functions[1].isImplementation()).to.be.true;
});
});
describe(nameof<OverloadableNode>("isOverload"), () => {
it("should be an overload when is one", () => {
expect(functions[0].isOverload()).to.be.true;
});
it("should not be an overload when not one", () => {
expect(functions[1].isOverload()).to.be.false;
});
it("should not be for abstract methods", () => {
expect(classChild.getMethodOrThrow(m => m.isAbstract()).isOverload()).to.be.true;
});
it("should be in ambient contexts", () => {
expect(ambientFunctions.map(f => f.isOverload())).to.deep.equal([true, true]);
});
});
describe(nameof<OverloadableNode>("getOverloads"), () => {
describe("functions", () => {
it("should have the right number of overloads when asking an overload", () => {
const overloads = functions[0].getOverloads();
expect(functions[0].isOverload()).to.be.true;
expect(overloads.length).to.equal(1);
expect(overloads[0]).to.equal(functions[0]);
});
it("should have the right number of overloads when asking an implementation", () => {
const overloads = functions[1].getOverloads();
expect(functions[1].isImplementation()).to.be.true;
expect(overloads.length).to.equal(1);
expect(overloads[0]).to.equal(functions[0]);
});
});
describe("constructors", () => {
it("should have the right number of overloads when asking an overload", () => {
const overloads = constructors[0].getOverloads();
expect(constructors[0].isOverload()).to.be.true;
expect(overloads.length).to.equal(2);
expect(overloads.map(o => o.isOverload())).to.deep.equal([true, true]);
});
it("should have the right number of overloads when asking an implementation", () => {
const overloads = constructors[2].getOverloads();
expect(constructors[2].isImplementation()).to.be.true;
expect(overloads.length).to.equal(2);
expect(overloads.map(o => o.isOverload())).to.deep.equal([true, true]);
});
});
describe("ambient context", () => {
it("should return all the overloads in an ambient context", () => {
const code = `declare function myFunction(): void;declare function myFunction(): void;`;
const { firstChild } = getInfoFromText<FunctionDeclaration>(code);
expect(firstChild.getOverloads().length).to.equal(2);
});
});
describe("methods", () => {
it("should get the correct number of overloads for method", () => {
expect(classChild.getInstanceMethodOrThrow("myMethod").getOverloads().length).to.equal(1);
expect(classChild.getStaticMethodOrThrow("myMethod").getOverloads().length).to.equal(2);
});
});
});
describe(nameof<OverloadableNode>("getImplementation"), () => {
describe("functions", () => {
it("should get the implementation when asking an overload", () => {
const implementation = functions[0].getImplementation();
expect(implementation).to.equal(functions[1]);
});
it("should have the right number of overloads when asking an implementation", () => {
const implementation = functions[1].getImplementation();
expect(implementation).to.equal(functions[1]);
});
});
describe("constructors", () => {
it("should get the implementation when asking an overload", () => {
const implementation = constructors[0].getImplementation();
expect(implementation).to.equal(constructors[2]);
});
it("should have the right number of overloads when asking an implementation", () => {
const implementation = constructors[2].getImplementation();
expect(implementation).to.equal(constructors[2]);
});
});
describe("ambient context", () => {
it("should return undefined in an ambient context", () => {
const code = `declare function myFunction(): void;declare function myFunction(): void;`;
const { firstChild } = getInfoFromText<FunctionDeclaration>(code);
expect(firstChild.getImplementation()).to.be.undefined;
});
});
});
describe(nameof<OverloadableNode>("getImplementationOrThrow"), () => {
it("should get the implementation when asking an overload", () => {
const implementation = functions[0].getImplementationOrThrow();
expect(implementation).to.equal(functions[1]);
});
it("should throw in an ambient context", () => {
const code = `declare function myFunction(): void;declare function myFunction(): void;`;
const { firstChild } = getInfoFromText<FunctionDeclaration>(code);
expect(() => firstChild.getImplementationOrThrow()).to.throw();
});
});
});