Path: blob/main/extensions/copilot/test/simulation/fixtures/tests/ts-another-test-4636/stickyScroll.test.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import * as assert from 'assert';5import { DisposableStore } from 'vs/base/common/lifecycle';6import { mock } from 'vs/base/test/common/mock';7import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler';8import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';9import { EditorOption } from 'vs/editor/common/config/editorOptions';10import { DocumentSymbol, SymbolKind } from 'vs/editor/common/languages';11import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';12import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';13import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';14import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService';15import { StickyScrollController } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollController';16import { StickyLineCandidate, StickyLineCandidateProvider } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollProvider';17import { withAsyncTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';18import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService';19import { createTextModel } from 'vs/editor/test/common/testTextModel';20import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';21import { IEnvironmentService } from 'vs/platform/environment/common/environment';22import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';23import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';24import { ILogService, NullLogService } from 'vs/platform/log/common/log';2526suite('Sticky Scroll Tests', () => {2728const disposables = new DisposableStore();2930const serviceCollection = new ServiceCollection(31[ILanguageFeaturesService, new LanguageFeaturesService()],32[ILogService, new NullLogService()],33[IContextMenuService, new class extends mock<IContextMenuService>() { }],34[ILanguageConfigurationService, new TestLanguageConfigurationService()],35[IEnvironmentService, new class extends mock<IEnvironmentService>() {36override isBuilt: boolean = true;37override isExtensionDevelopment: boolean = false;38}],39[ILanguageFeatureDebounceService, new SyncDescriptor(LanguageFeatureDebounceService)],40);4142const text = [43'function foo() {',44'',45'}',46'/* comment related to TestClass',47' end of the comment */',48'@classDecorator',49'class TestClass {',50'// comment related to the function functionOfClass',51'functionOfClass(){',52'function function1(){',53'}',54'}}',55'function bar() { function insideBar() {}',56'}'57].join('\n');5859setup(() => {60disposables.clear();61});62teardown(() => {63disposables.clear();64});6566ensureNoDisposablesAreLeakedInTestSuite();6768function documentSymbolProviderForTestModel() {69return {70provideDocumentSymbols() {71return [72{73name: 'foo',74detail: 'foo',75kind: SymbolKind.Function,76tags: [],77range: { startLineNumber: 1, endLineNumber: 3, startColumn: 1, endColumn: 1 },78selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 }79} as DocumentSymbol,80{81name: 'TestClass',82detail: 'TestClass',83kind: SymbolKind.Class,84tags: [],85range: { startLineNumber: 4, endLineNumber: 12, startColumn: 1, endColumn: 1 },86selectionRange: { startLineNumber: 7, endLineNumber: 7, startColumn: 1, endColumn: 1 },87children: [88{89name: 'functionOfClass',90detail: 'functionOfClass',91kind: SymbolKind.Function,92tags: [],93range: { startLineNumber: 8, endLineNumber: 12, startColumn: 1, endColumn: 1 },94selectionRange: { startLineNumber: 9, endLineNumber: 9, startColumn: 1, endColumn: 1 },95children: [96{97name: 'function1',98detail: 'function1',99kind: SymbolKind.Function,100tags: [],101range: { startLineNumber: 10, endLineNumber: 11, startColumn: 1, endColumn: 1 },102selectionRange: { startLineNumber: 10, endLineNumber: 10, startColumn: 1, endColumn: 1 },103}104]105} as DocumentSymbol106]107} as DocumentSymbol,108{109name: 'bar',110detail: 'bar',111kind: SymbolKind.Function,112tags: [],113range: { startLineNumber: 13, endLineNumber: 14, startColumn: 1, endColumn: 1 },114selectionRange: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },115children: [116{117name: 'insideBar',118detail: 'insideBar',119kind: SymbolKind.Function,120tags: [],121range: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },122selectionRange: { startLineNumber: 13, endLineNumber: 13, startColumn: 1, endColumn: 1 },123} as DocumentSymbol124]125} as DocumentSymbol126];127}128};129}130131test('Testing the function getCandidateStickyLinesIntersecting', () => {132return runWithFakedTimers({ useFakeTimers: true }, async () => {133const model = createTextModel(text);134await withAsyncTestCodeEditor(model, {135stickyScroll: {136enabled: true,137maxLineCount: 5,138defaultModel: 'outlineModel'139}, serviceCollection: serviceCollection140}, async (editor, _viewModel, instantiationService) => {141const languageService = instantiationService.get(ILanguageFeaturesService);142const languageConfigurationService = instantiationService.get(ILanguageConfigurationService);143disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));144const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService, languageConfigurationService);145await provider.update();146assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 4 }), [new StickyLineCandidate(1, 2, 1)]);147assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 8, endLineNumber: 10 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);148assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 10, endLineNumber: 13 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);149150provider.dispose();151model.dispose();152});153});154});155156test('issue #157180: Render the correct line corresponding to the scope definition', () => {157return runWithFakedTimers({ useFakeTimers: true }, async () => {158const model = createTextModel(text);159await withAsyncTestCodeEditor(model, {160stickyScroll: {161enabled: true,162maxLineCount: 5,163defaultModel: 'outlineModel'164}, serviceCollection165}, async (editor, _viewModel, instantiationService) => {166167const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);168const lineHeight: number = editor.getOption(EditorOption.lineHeight);169const languageService: ILanguageFeaturesService = instantiationService.get(ILanguageFeaturesService);170disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));171await stickyScrollController.stickyScrollCandidateProvider.update();172let state;173174editor.setScrollTop(1);175state = stickyScrollController.findScrollWidgetState();176assert.deepStrictEqual(state.startLineNumbers, [1]);177178editor.setScrollTop(lineHeight + 1);179state = stickyScrollController.findScrollWidgetState();180assert.deepStrictEqual(state.startLineNumbers, [1]);181182editor.setScrollTop(4 * lineHeight + 1);183state = stickyScrollController.findScrollWidgetState();184assert.deepStrictEqual(state.startLineNumbers, []);185186editor.setScrollTop(8 * lineHeight + 1);187state = stickyScrollController.findScrollWidgetState();188assert.deepStrictEqual(state.startLineNumbers, [7, 9]);189190editor.setScrollTop(9 * lineHeight + 1);191state = stickyScrollController.findScrollWidgetState();192assert.deepStrictEqual(state.startLineNumbers, [7, 9]);193194editor.setScrollTop(10 * lineHeight + 1);195state = stickyScrollController.findScrollWidgetState();196assert.deepStrictEqual(state.startLineNumbers, [7]);197198stickyScrollController.dispose();199stickyScrollController.stickyScrollCandidateProvider.dispose();200model.dispose();201});202});203});204205test('issue #156268 : Do not reveal sticky lines when they are in a folded region ', () => {206return runWithFakedTimers({ useFakeTimers: true }, async () => {207const model = createTextModel(text);208await withAsyncTestCodeEditor(model, {209stickyScroll: {210enabled: true,211maxLineCount: 5,212defaultModel: 'outlineModel'213}, serviceCollection214}, async (editor, viewModel, instantiationService) => {215216const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);217const lineHeight = editor.getOption(EditorOption.lineHeight);218219const languageService = instantiationService.get(ILanguageFeaturesService);220disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel()));221await stickyScrollController.stickyScrollCandidateProvider.update();222editor.setHiddenAreas([{ startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 }, { startLineNumber: 10, endLineNumber: 11, startColumn: 1, endColumn: 1 }]);223let state;224225editor.setScrollTop(1);226state = stickyScrollController.findScrollWidgetState();227assert.deepStrictEqual(state.startLineNumbers, [1]);228229editor.setScrollTop(lineHeight + 1);230state = stickyScrollController.findScrollWidgetState();231assert.deepStrictEqual(state.startLineNumbers, []);232233editor.setScrollTop(6 * lineHeight + 1);234state = stickyScrollController.findScrollWidgetState();235assert.deepStrictEqual(state.startLineNumbers, [7, 9]);236237editor.setScrollTop(7 * lineHeight + 1);238state = stickyScrollController.findScrollWidgetState();239assert.deepStrictEqual(state.startLineNumbers, [7]);240241editor.setScrollTop(10 * lineHeight + 1);242state = stickyScrollController.findScrollWidgetState();243assert.deepStrictEqual(state.startLineNumbers, []);244245stickyScrollController.dispose();246stickyScrollController.stickyScrollCandidateProvider.dispose();247model.dispose();248});249});250});251252253254const textWithScopesWithSameStartingLines = [255'class TestClass { foo() {',256'function bar(){',257'',258'}}',259'}',260''261].join('\n');262263function documentSymbolProviderForSecondTestModel() {264return {265provideDocumentSymbols() {266return [267{268name: 'TestClass',269detail: 'TestClass',270kind: SymbolKind.Class,271tags: [],272range: { startLineNumber: 1, endLineNumber: 5, startColumn: 1, endColumn: 1 },273selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },274children: [275{276name: 'foo',277detail: 'foo',278kind: SymbolKind.Function,279tags: [],280range: { startLineNumber: 1, endLineNumber: 4, startColumn: 1, endColumn: 1 },281selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },282children: [283{284name: 'bar',285detail: 'bar',286kind: SymbolKind.Function,287tags: [],288range: { startLineNumber: 2, endLineNumber: 4, startColumn: 1, endColumn: 1 },289selectionRange: { startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 },290children: []291} as DocumentSymbol292]293} as DocumentSymbol,294]295} as DocumentSymbol296];297}298};299}300301test('issue #159271 : render the correct widget state when the child scope starts on the same line as the parent scope', () => {302return runWithFakedTimers({ useFakeTimers: true }, async () => {303const model = createTextModel(textWithScopesWithSameStartingLines);304await withAsyncTestCodeEditor(model, {305stickyScroll: {306enabled: true,307maxLineCount: 5,308defaultModel: 'outlineModel'309}, serviceCollection310}, async (editor, _viewModel, instantiationService) => {311312const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);313await stickyScrollController.stickyScrollCandidateProvider.update();314const lineHeight = editor.getOption(EditorOption.lineHeight);315316const languageService = instantiationService.get(ILanguageFeaturesService);317disposables.add(languageService.documentSymbolProvider.register('*', documentSymbolProviderForSecondTestModel()));318await stickyScrollController.stickyScrollCandidateProvider.update();319let state;320321editor.setScrollTop(1);322state = stickyScrollController.findScrollWidgetState();323assert.deepStrictEqual(state.startLineNumbers, [1, 2]);324325editor.setScrollTop(lineHeight + 1);326state = stickyScrollController.findScrollWidgetState();327assert.deepStrictEqual(state.startLineNumbers, [1, 2]);328329editor.setScrollTop(2 * lineHeight + 1);330state = stickyScrollController.findScrollWidgetState();331assert.deepStrictEqual(state.startLineNumbers, [1]);332333editor.setScrollTop(3 * lineHeight + 1);334state = stickyScrollController.findScrollWidgetState();335assert.deepStrictEqual(state.startLineNumbers, [1]);336337editor.setScrollTop(4 * lineHeight + 1);338state = stickyScrollController.findScrollWidgetState();339assert.deepStrictEqual(state.startLineNumbers, []);340341stickyScrollController.dispose();342stickyScrollController.stickyScrollCandidateProvider.dispose();343model.dispose();344});345});346});347});348349350