Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/simulation/fixtures/tests/ts-another-test-4636/stickyScroll.test.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
import * as assert from 'assert';
6
import { DisposableStore } from 'vs/base/common/lifecycle';
7
import { mock } from 'vs/base/test/common/mock';
8
import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler';
9
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
10
import { EditorOption } from 'vs/editor/common/config/editorOptions';
11
import { DocumentSymbol, SymbolKind } from 'vs/editor/common/languages';
12
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
13
import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';
14
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
15
import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService';
16
import { StickyScrollController } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollController';
17
import { StickyLineCandidate, StickyLineCandidateProvider } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollProvider';
18
import { withAsyncTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
19
import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService';
20
import { createTextModel } from 'vs/editor/test/common/testTextModel';
21
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
22
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
23
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
24
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
25
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
26
27
suite('Sticky Scroll Tests', () => {
28
29
const disposables = new DisposableStore();
30
31
const serviceCollection = new ServiceCollection(
32
[ILanguageFeaturesService, new LanguageFeaturesService()],
33
[ILogService, new NullLogService()],
34
[IContextMenuService, new class extends mock<IContextMenuService>() { }],
35
[ILanguageConfigurationService, new TestLanguageConfigurationService()],
36
[IEnvironmentService, new class extends mock<IEnvironmentService>() {
37
override isBuilt: boolean = true;
38
override isExtensionDevelopment: boolean = false;
39
}],
40
[ILanguageFeatureDebounceService, new SyncDescriptor(LanguageFeatureDebounceService)],
41
);
42
43
const text = [
44
'function foo() {',
45
'',
46
'}',
47
'/* comment related to TestClass',
48
' end of the comment */',
49
'@classDecorator',
50
'class TestClass {',
51
'// comment related to the function functionOfClass',
52
'functionOfClass(){',
53
'function function1(){',
54
'}',
55
'}}',
56
'function bar() { function insideBar() {}',
57
'}'
58
].join('\n');
59
60
setup(() => {
61
disposables.clear();
62
});
63
teardown(() => {
64
disposables.clear();
65
});
66
67
ensureNoDisposablesAreLeakedInTestSuite();
68
69
function documentSymbolProviderForTestModel() {
70
return {
71
provideDocumentSymbols() {
72
return [
73
{
74
name: 'foo',
75
detail: 'foo',
76
kind: SymbolKind.Function,
77
tags: [],
78
range: { startLineNumber: 1, endLineNumber: 3, startColumn: 1, endColumn: 1 },
79
selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 }
80
} as DocumentSymbol,
81
{
82
name: 'TestClass',
83
detail: 'TestClass',
84
kind: SymbolKind.Class,
85
tags: [],
86
range: { startLineNumber: 4, endLineNumber: 12, startColumn: 1, endColumn: 1 },
87
selectionRange: { startLineNumber: 7, endLineNumber: 7, startColumn: 1, endColumn: 1 },
88
children: [
89
{
90
name: 'functionOfClass',
91
detail: 'functionOfClass',
92
kind: SymbolKind.Function,
93
tags: [],
94
range: { startLineNumber: 8, endLineNumber: 12, startColumn: 1, endColumn: 1 },
95
selectionRange: { startLineNumber: 9, endLineNumber: 9, startColumn: 1, endColumn: 1 },
96
children: [
97
{
98
name: 'function1',
99
detail: 'function1',
100
kind: SymbolKind.Function,
101
tags: [],
102
range: { startLineNumber: 10, endLineNumber: 11, startColumn: 1, endColumn: 1 },
103
selectionRange: { startLineNumber: 10, endLineNumber: 10, startColumn: 1, endColumn: 1 },
104
}
105
]
106
} as DocumentSymbol
107
]
108
} as DocumentSymbol,
109
{
110
name: 'bar',
111
detail: 'bar',
112
kind: SymbolKind.Function,
113
tags: [],
114
range: { startLineNumber: 13, endLineNumber: 14, startColumn: 1, endColumn: 1 },
115
selectionRange: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },
116
children: [
117
{
118
name: 'insideBar',
119
detail: 'insideBar',
120
kind: SymbolKind.Function,
121
tags: [],
122
range: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },
123
selectionRange: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },
124
} as DocumentSymbol
125
]
126
} as DocumentSymbol
127
];
128
}
129
};
130
}
131
132
test('Testing the function getCandidateStickyLinesIntersecting', () => {
133
return runWithFakedTimers({ useFakeTimers: true }, async () => {
134
const model = createTextModel(text);
135
await withAsyncTestCodeEditor(model, {
136
stickyScroll: {
137
enabled: true,
138
maxLineCount: 5,
139
defaultModel: 'outlineModel'
140
}, serviceCollection: serviceCollection
141
}, async (editor, _viewModel, instantiationService) => {
142
const languageService = instantiationService.get(ILanguageFeaturesService);
143
const languageConfigurationService = instantiationService.get(ILanguageConfigurationService);
144
disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));
145
const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService, languageConfigurationService);
146
await provider.update();
147
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 4 }), [new StickyLineCandidate(1, 2, 1)]);
148
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 8, endLineNumber: 10 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
149
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 10, endLineNumber: 13 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
150
151
provider.dispose();
152
model.dispose();
153
});
154
});
155
});
156
157
test('issue #157180: Render the correct line corresponding to the scope definition', () => {
158
return runWithFakedTimers({ useFakeTimers: true }, async () => {
159
const model = createTextModel(text);
160
await withAsyncTestCodeEditor(model, {
161
stickyScroll: {
162
enabled: true,
163
maxLineCount: 5,
164
defaultModel: 'outlineModel'
165
}, serviceCollection
166
}, async (editor, _viewModel, instantiationService) => {
167
168
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
169
const lineHeight: number = editor.getOption(EditorOption.lineHeight);
170
const languageService: ILanguageFeaturesService = instantiationService.get(ILanguageFeaturesService);
171
disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));
172
await stickyScrollController.stickyScrollCandidateProvider.update();
173
let state;
174
175
editor.setScrollTop(1);
176
state = stickyScrollController.findScrollWidgetState();
177
assert.deepStrictEqual(state.startLineNumbers, [1]);
178
179
editor.setScrollTop(lineHeight + 1);
180
state = stickyScrollController.findScrollWidgetState();
181
assert.deepStrictEqual(state.startLineNumbers, [1]);
182
183
editor.setScrollTop(4 * lineHeight + 1);
184
state = stickyScrollController.findScrollWidgetState();
185
assert.deepStrictEqual(state.startLineNumbers, []);
186
187
editor.setScrollTop(8 * lineHeight + 1);
188
state = stickyScrollController.findScrollWidgetState();
189
assert.deepStrictEqual(state.startLineNumbers, [7, 9]);
190
191
editor.setScrollTop(9 * lineHeight + 1);
192
state = stickyScrollController.findScrollWidgetState();
193
assert.deepStrictEqual(state.startLineNumbers, [7, 9]);
194
195
editor.setScrollTop(10 * lineHeight + 1);
196
state = stickyScrollController.findScrollWidgetState();
197
assert.deepStrictEqual(state.startLineNumbers, [7]);
198
199
stickyScrollController.dispose();
200
stickyScrollController.stickyScrollCandidateProvider.dispose();
201
model.dispose();
202
});
203
});
204
});
205
206
test('issue #156268 : Do not reveal sticky lines when they are in a folded region ', () => {
207
return runWithFakedTimers({ useFakeTimers: true }, async () => {
208
const model = createTextModel(text);
209
await withAsyncTestCodeEditor(model, {
210
stickyScroll: {
211
enabled: true,
212
maxLineCount: 5,
213
defaultModel: 'outlineModel'
214
}, serviceCollection
215
}, async (editor, viewModel, instantiationService) => {
216
217
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
218
const lineHeight = editor.getOption(EditorOption.lineHeight);
219
220
const languageService = instantiationService.get(ILanguageFeaturesService);
221
disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));
222
await stickyScrollController.stickyScrollCandidateProvider.update();
223
editor.setHiddenAreas([{ startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 }, { startLineNumber: 10, endLineNumber: 11, startColumn: 1, endColumn: 1 }]);
224
let state;
225
226
editor.setScrollTop(1);
227
state = stickyScrollController.findScrollWidgetState();
228
assert.deepStrictEqual(state.startLineNumbers, [1]);
229
230
editor.setScrollTop(lineHeight + 1);
231
state = stickyScrollController.findScrollWidgetState();
232
assert.deepStrictEqual(state.startLineNumbers, []);
233
234
editor.setScrollTop(6 * lineHeight + 1);
235
state = stickyScrollController.findScrollWidgetState();
236
assert.deepStrictEqual(state.startLineNumbers, [7, 9]);
237
238
editor.setScrollTop(7 * lineHeight + 1);
239
state = stickyScrollController.findScrollWidgetState();
240
assert.deepStrictEqual(state.startLineNumbers, [7]);
241
242
editor.setScrollTop(10 * lineHeight + 1);
243
state = stickyScrollController.findScrollWidgetState();
244
assert.deepStrictEqual(state.startLineNumbers, []);
245
246
stickyScrollController.dispose();
247
stickyScrollController.stickyScrollCandidateProvider.dispose();
248
model.dispose();
249
});
250
});
251
});
252
253
254
255
const textWithScopesWithSameStartingLines = [
256
'class TestClass { foo() {',
257
'function bar(){',
258
'',
259
'}}',
260
'}',
261
''
262
].join('\n');
263
264
function documentSymbolProviderForSecondTestModel() {
265
return {
266
provideDocumentSymbols() {
267
return [
268
{
269
name: 'TestClass',
270
detail: 'TestClass',
271
kind: SymbolKind.Class,
272
tags: [],
273
range: { startLineNumber: 1, endLineNumber: 5, startColumn: 1, endColumn: 1 },
274
selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },
275
children: [
276
{
277
name: 'foo',
278
detail: 'foo',
279
kind: SymbolKind.Function,
280
tags: [],
281
range: { startLineNumber: 1, endLineNumber: 4, startColumn: 1, endColumn: 1 },
282
selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },
283
children: [
284
{
285
name: 'bar',
286
detail: 'bar',
287
kind: SymbolKind.Function,
288
tags: [],
289
range: { startLineNumber: 2, endLineNumber: 4, startColumn: 1, endColumn: 1 },
290
selectionRange: { startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 },
291
children: []
292
} as DocumentSymbol
293
]
294
} as DocumentSymbol,
295
]
296
} as DocumentSymbol
297
];
298
}
299
};
300
}
301
302
test('issue #159271 : render the correct widget state when the child scope starts on the same line as the parent scope', () => {
303
return runWithFakedTimers({ useFakeTimers: true }, async () => {
304
const model = createTextModel(textWithScopesWithSameStartingLines);
305
await withAsyncTestCodeEditor(model, {
306
stickyScroll: {
307
enabled: true,
308
maxLineCount: 5,
309
defaultModel: 'outlineModel'
310
}, serviceCollection
311
}, async (editor, _viewModel, instantiationService) => {
312
313
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
314
await stickyScrollController.stickyScrollCandidateProvider.update();
315
const lineHeight = editor.getOption(EditorOption.lineHeight);
316
317
const languageService = instantiationService.get(ILanguageFeaturesService);
318
disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForSecondTestModel()));
319
await stickyScrollController.stickyScrollCandidateProvider.update();
320
let state;
321
322
editor.setScrollTop(1);
323
state = stickyScrollController.findScrollWidgetState();
324
assert.deepStrictEqual(state.startLineNumbers, [1, 2]);
325
326
editor.setScrollTop(lineHeight + 1);
327
state = stickyScrollController.findScrollWidgetState();
328
assert.deepStrictEqual(state.startLineNumbers, [1, 2]);
329
330
editor.setScrollTop(2 * lineHeight + 1);
331
state = stickyScrollController.findScrollWidgetState();
332
assert.deepStrictEqual(state.startLineNumbers, [1]);
333
334
editor.setScrollTop(3 * lineHeight + 1);
335
state = stickyScrollController.findScrollWidgetState();
336
assert.deepStrictEqual(state.startLineNumbers, [1]);
337
338
editor.setScrollTop(4 * lineHeight + 1);
339
state = stickyScrollController.findScrollWidgetState();
340
assert.deepStrictEqual(state.startLineNumbers, []);
341
342
stickyScrollController.dispose();
343
stickyScrollController.stickyScrollCandidateProvider.dispose();
344
model.dispose();
345
});
346
});
347
});
348
});
349
350