Skip to content

Commit 6140246

Browse files
authored
Feature/test parameter extractor (#157)
1 parent 21664de commit 6140246

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
// You can import and use all API from the 'vscode' module
2+
// as well as import your extension to test it
3+
import * as vscode from 'vscode';
4+
import { integer } from "vscode-languageclient";
5+
import { expect } from 'chai';
6+
7+
import { CSharpParametersExtractor } from './parametersExtractor';
8+
import { Token, TokenType } from '../tokens';
9+
import { ParameterInfo } from '../../documentInfoProvider';
10+
11+
function position(line: number, character: number): vscode.Position {
12+
return new vscode.Position(line, character);
13+
}
14+
15+
function range(startLine: number, startCharacter: number, endLine: number, endCharacter: number): vscode.Range {
16+
return new vscode.Range(
17+
position(startLine, startCharacter),
18+
position(endLine, endCharacter)
19+
);
20+
}
21+
22+
const IRRELEVANT_RANGE = range(1, 1, 1, 1);
23+
const NO_MODIFIERS: string[] = [];
24+
25+
function createToken(text: string, type: TokenType): Token {
26+
return {
27+
text: text,
28+
type: type,
29+
range: IRRELEVANT_RANGE,
30+
modifiers: NO_MODIFIERS,
31+
};
32+
}
33+
34+
function punctuation(text: string): Token {
35+
return createToken(text, TokenType.punctuation);
36+
}
37+
38+
function assertParameterInfo(actual: ParameterInfo[], position: integer, expectedName: string, expectedType: string) {
39+
expect(actual[position].name, "paramter[" + position + "].name").to.equal(expectedName);
40+
expect(actual[position].type, "paramter[" + position + "].type").to.equal(expectedType);
41+
}
42+
43+
44+
suite('CSharpSpanExtractor', () => {
45+
vscode.window.showInformationMessage('Start all tests.');
46+
47+
let extractor: CSharpParametersExtractor;
48+
49+
setup(() => {
50+
extractor = new CSharpParametersExtractor();
51+
});
52+
53+
54+
suite('#extractParameters', () => {
55+
56+
suite('when there are no tokens', () => {
57+
const tokens: Token[] = [];
58+
59+
test('should return zero parameterInfos', async () => {
60+
const paramInfos = await extractor.extractParameters("whatever", tokens);
61+
62+
expect(paramInfos).to.have.lengthOf(0);
63+
});
64+
});
65+
66+
suite('when method has no parameters', () => {
67+
const methodName = "Abcd";
68+
const tokens: Token[] = [
69+
createToken("public", TokenType.plainKeyword),
70+
createToken("void", TokenType.plainKeyword),
71+
createToken(methodName, TokenType.member),
72+
punctuation("("),
73+
punctuation(")"),
74+
];
75+
76+
test('should return zero parameterInfos', async () => {
77+
const paramInfos = await extractor.extractParameters(methodName, tokens);
78+
79+
expect(paramInfos).to.have.lengthOf(0);
80+
});
81+
});
82+
83+
suite('when method has one primitive parameter', () => {
84+
const methodName = "Abcd";
85+
const tokens: Token[] = [
86+
createToken("public", TokenType.plainKeyword),
87+
createToken("void", TokenType.plainKeyword),
88+
createToken(methodName, TokenType.member),
89+
punctuation("("),
90+
createToken("int", TokenType.plainKeyword),
91+
createToken("size", TokenType.parameter),
92+
punctuation(")"),
93+
];
94+
95+
test('should return one parameterInfo', async () => {
96+
const paramInfos = await extractor.extractParameters(methodName, tokens);
97+
98+
expect(paramInfos).to.have.lengthOf(1);
99+
assertParameterInfo(paramInfos, 0, "size", "Int32");
100+
});
101+
});
102+
103+
suite('two parameters (string[] someValues, out bool someBool)', () => {
104+
const methodName = "Abcd";
105+
const tokens: Token[] = [
106+
createToken("public", TokenType.plainKeyword),
107+
createToken("void", TokenType.plainKeyword),
108+
createToken(methodName, TokenType.member),
109+
punctuation("("),
110+
//
111+
createToken("string", TokenType.plainKeyword),
112+
punctuation("["),
113+
punctuation("]"),
114+
createToken("someValues", TokenType.parameter),
115+
//
116+
punctuation(","),
117+
//
118+
createToken("out", TokenType.plainKeyword),
119+
createToken("bool", TokenType.plainKeyword),
120+
createToken("someBool", TokenType.parameter),
121+
//
122+
punctuation(")"),
123+
];
124+
125+
test('should return two parameterInfo', async () => {
126+
const paramInfos = await extractor.extractParameters(methodName, tokens);
127+
128+
expect(paramInfos).to.have.lengthOf(2);
129+
assertParameterInfo(paramInfos, 0, "someValues", "String[]");
130+
assertParameterInfo(paramInfos, 1, "someBool", "Boolean&");
131+
});
132+
});
133+
134+
suite('two parameters (ref long ref2Long, IDictionary<int, string[,]> dictInt2StringMultiDimArray)', () => {
135+
const methodName = "Abcd";
136+
const tokens: Token[] = [
137+
createToken("public", TokenType.plainKeyword),
138+
createToken("void", TokenType.plainKeyword),
139+
createToken(methodName, TokenType.member),
140+
punctuation("("),
141+
//
142+
createToken("ref", TokenType.plainKeyword),
143+
createToken("long", TokenType.plainKeyword),
144+
createToken("ref2Long", TokenType.parameter),
145+
//
146+
punctuation(","),
147+
//
148+
createToken("IDictionary", TokenType.interface),
149+
punctuation("<"),
150+
createToken("int", TokenType.plainKeyword),
151+
punctuation(","),
152+
createToken("string", TokenType.plainKeyword),
153+
punctuation("["), punctuation(","), punctuation("]"),
154+
punctuation(">"),
155+
createToken("dictInt2StringMultiDimArray", TokenType.parameter),
156+
//
157+
punctuation(")"),
158+
];
159+
160+
test('should return two parameterInfo', async () => {
161+
const paramInfos = await extractor.extractParameters(methodName, tokens);
162+
163+
expect(paramInfos).to.have.lengthOf(2);
164+
assertParameterInfo(paramInfos, 0, "ref2Long", "Int64&");
165+
assertParameterInfo(paramInfos, 1, "dictInt2StringMultiDimArray", "IDictionary`2");
166+
});
167+
});
168+
169+
suite('two parameters (IList<SomeClass<string>> listOfClassWithGenerics, int[,,][][,][] multiDimArray)', () => {
170+
const methodName = "Abcd";
171+
const tokens: Token[] = [
172+
createToken("public", TokenType.plainKeyword),
173+
createToken("void", TokenType.plainKeyword),
174+
createToken(methodName, TokenType.member),
175+
punctuation("("),
176+
//
177+
createToken("IList", TokenType.interface),
178+
punctuation("<"),
179+
createToken("SomeClass", TokenType.class),
180+
punctuation("<"),
181+
createToken("string", TokenType.plainKeyword),
182+
punctuation(">"),
183+
punctuation(">"),
184+
createToken("listOfClassWithGenerics", TokenType.parameter),
185+
//
186+
punctuation(","),
187+
//
188+
createToken("int", TokenType.plainKeyword),
189+
punctuation("["), punctuation(","), punctuation(","), punctuation("]"),
190+
punctuation("["), punctuation("]"),
191+
punctuation("["), punctuation(","), punctuation("]"),
192+
punctuation("["), punctuation("]"),
193+
createToken("multiDimArray", TokenType.parameter),
194+
//
195+
punctuation(")"),
196+
];
197+
198+
test('should return two parameterInfo', async () => {
199+
const paramInfos = await extractor.extractParameters(methodName, tokens);
200+
201+
expect(paramInfos).to.have.lengthOf(2);
202+
assertParameterInfo(paramInfos, 0, "listOfClassWithGenerics", "IList`1");
203+
// few comments:
204+
// 1. we encode the commas as semi colons since comma already used as delimiter between the parameters
205+
// 2. dotnet/csharp internals: the actual type order of bracket groups is reversed.
206+
// in this case: [,,][][,][] turns into [][;][][;;]
207+
assertParameterInfo(paramInfos, 1, "multiDimArray", "Int32[][;][][;;]");
208+
});
209+
});
210+
211+
}); // end of #extractParameters
212+
213+
});

0 commit comments

Comments
 (0)