Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/parser/test/node/getNodeMatchingSelection.spec.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { outdent } from 'outdent';
7
import { afterAll, expect, suite, test } from 'vitest';
8
import {
9
_dispose,
10
} from '../../node/parserImpl';
11
import { _parse } from '../../node/parserWithCaching';
12
import { _getNodeMatchingSelection } from '../../node/selectionParsing';
13
import { WASMLanguage } from '../../node/treeSitterLanguages';
14
15
suite('getNodeMatchingSelection', () => {
16
function deannotateSrc(annotatedSrc: string) {
17
const startIndex = annotatedSrc.indexOf('<<');
18
const endIndex = annotatedSrc.indexOf('>>') - 2;
19
return {
20
deannotatedSrc: annotatedSrc.replace('<<', '').replace('>>', ''),
21
annotatedRange: {
22
startIndex,
23
endIndex,
24
},
25
};
26
}
27
28
async function getNode(
29
annotatedSrc: string,
30
languageId = WASMLanguage.TypeScript
31
) {
32
const { deannotatedSrc, annotatedRange } = deannotateSrc(annotatedSrc);
33
34
const parseTreeRef = await _parse(languageId, deannotatedSrc);
35
36
try {
37
const r = _getNodeMatchingSelection(
38
parseTreeRef.tree,
39
annotatedRange,
40
languageId
41
);
42
return r ? r.text : 'undefined';
43
} finally {
44
parseTreeRef.dispose();
45
}
46
}
47
48
afterAll(() => _dispose());
49
50
suite('with function', () => {
51
test('within identifier', async () => {
52
const source = outdent`
53
class Foo {
54
55
ba<<>>r() {
56
57
}
58
}
59
`;
60
expect(await getNode(source)).toMatchInlineSnapshot(`"undefined"`);
61
});
62
63
test('whitespace before', async () => {
64
const source = outdent`
65
class Foo {
66
67
<< bar() {
68
69
}>>
70
}
71
`;
72
expect(await getNode(source)).toMatchInlineSnapshot(`
73
"bar() {
74
75
}"
76
`);
77
});
78
79
test('whitespace before & after', async () => {
80
const source = outdent`
81
class Foo {
82
83
<< bar() {
84
85
}
86
>>
87
}
88
`;
89
expect(await getNode(source)).toMatchInlineSnapshot(`
90
"bar() {
91
92
}"
93
`);
94
});
95
96
test('range misses closes }', async () => {
97
const source = outdent`
98
class Foo {
99
100
<<bar() {
101
102
>>}
103
}
104
`;
105
expect(await getNode(source)).toMatchInlineSnapshot(`
106
"bar() {
107
108
}"
109
`);
110
});
111
112
test('imprecise selection', async () => {
113
const source = outdent`
114
class Foo {
115
116
b<<ar() {
117
118
>>}
119
}
120
`;
121
expect(await getNode(source)).toMatchInlineSnapshot(`
122
"bar() {
123
124
}"
125
`);
126
});
127
});
128
129
suite('with class', () => {
130
test('precise selection', async () => {
131
const source = outdent`
132
<<class Foo {
133
134
bar() {
135
136
}
137
}>>
138
`;
139
expect(await getNode(source)).toMatchInlineSnapshot(`
140
"class Foo {
141
142
bar() {
143
144
}
145
}"
146
`);
147
});
148
149
test('range misses closing }', async () => {
150
const source = outdent`
151
<<class Foo {
152
153
bar() {
154
155
}
156
>>}
157
`;
158
expect(await getNode(source)).toMatchInlineSnapshot(`
159
"class Foo {
160
161
bar() {
162
163
}
164
}"
165
`);
166
});
167
168
test('imprecise selection', async () => {
169
const source = outdent`
170
class Foo << {
171
172
bar() {
173
174
}>>
175
}
176
`;
177
expect(await getNode(source)).toMatchInlineSnapshot(`
178
"class Foo {
179
180
bar() {
181
182
}
183
}"
184
`);
185
});
186
});
187
188
suite('with interface', () => {
189
test('precise selection', async () => {
190
const source = outdent`
191
<<interface Foo {
192
193
bar(): void;
194
195
}>>`;
196
expect(await getNode(source)).toMatchInlineSnapshot(`
197
"interface Foo {
198
199
bar(): void;
200
201
}"
202
`);
203
});
204
205
test('whitespace before & after', async () => {
206
const source = outdent`
207
<<
208
interface Foo {
209
210
bar(): void;
211
212
}
213
>>`;
214
expect(await getNode(source)).toMatchInlineSnapshot(`
215
"interface Foo {
216
217
bar(): void;
218
219
}"
220
`);
221
});
222
223
test('within a function', async () => {
224
const source = outdent`
225
<<
226
function bar() {
227
interface Foo {
228
229
bar(): void;
230
231
}
232
233
return 42;
234
}
235
>>`;
236
expect(await getNode(source)).toMatchInlineSnapshot(`
237
"function bar() {
238
interface Foo {
239
240
bar(): void;
241
242
}
243
244
return 42;
245
}"
246
`);
247
});
248
249
test('most of function is selected', async () => {
250
const source = outdent`
251
<<
252
function bar() {
253
interface Foo {
254
255
bar(): void;
256
257
}
258
259
return 42;>>
260
}
261
`;
262
expect(await getNode(source)).toMatchInlineSnapshot(`
263
"function bar() {
264
interface Foo {
265
266
bar(): void;
267
268
}
269
270
return 42;
271
}"
272
`);
273
});
274
});
275
});
276
277
278