Path: blob/main/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts
3296 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*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { MainThreadDocumentsAndEditors } from '../../browser/mainThreadDocumentsAndEditors.js';7import { SingleProxyRPCProtocol } from '../common/testRPCProtocol.js';8import { TestConfigurationService } from '../../../../platform/configuration/test/common/testConfigurationService.js';9import { ModelService } from '../../../../editor/common/services/modelService.js';10import { TestCodeEditorService } from '../../../../editor/test/browser/editorTestServices.js';11import { ITextFileService } from '../../../services/textfile/common/textfiles.js';12import { IDocumentsAndEditorsDelta } from '../../common/extHost.protocol.js';13import { createTestCodeEditor, ITestCodeEditor } from '../../../../editor/test/browser/testCodeEditor.js';14import { mock } from '../../../../base/test/common/mock.js';15import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from '../../../test/browser/workbenchTestServices.js';16import { Event } from '../../../../base/common/event.js';17import { ITextModel } from '../../../../editor/common/model.js';18import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';19import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';20import { IFileService } from '../../../../platform/files/common/files.js';21import { TestThemeService } from '../../../../platform/theme/test/common/testThemeService.js';22import { UndoRedoService } from '../../../../platform/undoRedo/common/undoRedoService.js';23import { TestDialogService } from '../../../../platform/dialogs/test/common/testDialogService.js';24import { TestNotificationService } from '../../../../platform/notification/test/common/testNotificationService.js';25import { TestTextResourcePropertiesService, TestWorkingCopyFileService } from '../../../test/common/workbenchTestServices.js';26import { UriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentityService.js';27import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';28import { IPaneCompositePartService } from '../../../services/panecomposite/browser/panecomposite.js';29import { TextModel } from '../../../../editor/common/model/textModel.js';30import { DisposableStore } from '../../../../base/common/lifecycle.js';31import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';32import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js';33import { ILanguageService } from '../../../../editor/common/languages/language.js';34import { LanguageService } from '../../../../editor/common/services/languageService.js';35import { ILanguageConfigurationService } from '../../../../editor/common/languages/languageConfigurationRegistry.js';36import { TestLanguageConfigurationService } from '../../../../editor/test/common/modes/testLanguageConfigurationService.js';37import { IUndoRedoService } from '../../../../platform/undoRedo/common/undoRedo.js';38import { IQuickDiffModelService } from '../../../contrib/scm/browser/quickDiffModel.js';39import { ITextEditorDiffInformation } from '../../../../platform/editor/common/editor.js';40import { ITreeSitterLibraryService } from '../../../../editor/common/services/treeSitter/treeSitterLibraryService.js';41import { TestTreeSitterLibraryService } from '../../../../editor/test/common/services/testTreeSitterLibraryService.js';4243suite('MainThreadDocumentsAndEditors', () => {4445let disposables: DisposableStore;4647let modelService: ModelService;48let codeEditorService: TestCodeEditorService;49let textFileService: ITextFileService;50const deltas: IDocumentsAndEditorsDelta[] = [];5152function myCreateTestCodeEditor(model: ITextModel | undefined): ITestCodeEditor {53return createTestCodeEditor(model, {54hasTextFocus: false,55serviceCollection: new ServiceCollection(56[ICodeEditorService, codeEditorService]57)58});59}6061setup(() => {62disposables = new DisposableStore();6364deltas.length = 0;65const configService = new TestConfigurationService();66configService.setUserConfiguration('editor', { 'detectIndentation': false });67const dialogService = new TestDialogService();68const notificationService = new TestNotificationService();69const undoRedoService = new UndoRedoService(dialogService, notificationService);70const themeService = new TestThemeService();71const instantiationService = new TestInstantiationService();72instantiationService.set(ILanguageService, disposables.add(new LanguageService()));73instantiationService.set(ILanguageConfigurationService, new TestLanguageConfigurationService());74instantiationService.set(ITreeSitterLibraryService, new TestTreeSitterLibraryService());75instantiationService.set(IUndoRedoService, undoRedoService);76modelService = new ModelService(77configService,78new TestTextResourcePropertiesService(configService),79undoRedoService,80instantiationService81);82codeEditorService = new TestCodeEditorService(themeService);83textFileService = new class extends mock<ITextFileService>() {84override isDirty() { return false; }85override files = <any>{86onDidSave: Event.None,87onDidRevert: Event.None,88onDidChangeDirty: Event.None,89onDidChangeEncoding: Event.None90};91override untitled = <any>{92onDidChangeEncoding: Event.None93};94override getEncoding() { return 'utf8'; }95};96const workbenchEditorService = disposables.add(new TestEditorService());97const editorGroupService = new TestEditorGroupsService();9899const fileService = new class extends mock<IFileService>() {100override onDidRunOperation = Event.None;101override onDidChangeFileSystemProviderCapabilities = Event.None;102override onDidChangeFileSystemProviderRegistrations = Event.None;103};104105new MainThreadDocumentsAndEditors(106SingleProxyRPCProtocol({107$acceptDocumentsAndEditorsDelta: (delta: IDocumentsAndEditorsDelta) => { deltas.push(delta); },108$acceptEditorDiffInformation: (id: string, diffInformation: ITextEditorDiffInformation | undefined) => { }109}),110modelService,111textFileService,112workbenchEditorService,113codeEditorService,114fileService,115null!,116editorGroupService,117new class extends mock<IPaneCompositePartService>() implements IPaneCompositePartService {118override onDidPaneCompositeOpen = Event.None;119override onDidPaneCompositeClose = Event.None;120override getActivePaneComposite() {121return undefined;122}123},124TestEnvironmentService,125new TestWorkingCopyFileService(),126new UriIdentityService(fileService),127new class extends mock<IClipboardService>() {128override readText() {129return Promise.resolve('clipboard_contents');130}131},132new TestPathService(),133new TestConfigurationService(),134new class extends mock<IQuickDiffModelService>() {135override createQuickDiffModelReference() {136return undefined;137}138}139);140});141142teardown(() => {143disposables.dispose();144});145146ensureNoDisposablesAreLeakedInTestSuite();147148test('Model#add', () => {149deltas.length = 0;150151disposables.add(modelService.createModel('farboo', null));152153assert.strictEqual(deltas.length, 1);154const [delta] = deltas;155156assert.strictEqual(delta.addedDocuments!.length, 1);157assert.strictEqual(delta.removedDocuments, undefined);158assert.strictEqual(delta.addedEditors, undefined);159assert.strictEqual(delta.removedEditors, undefined);160assert.strictEqual(delta.newActiveEditor, undefined);161});162163test('ignore huge model', function () {164165const oldLimit = TextModel._MODEL_SYNC_LIMIT;166try {167const largeModelString = 'abc'.repeat(1024);168TextModel._MODEL_SYNC_LIMIT = largeModelString.length / 2;169170const model = modelService.createModel(largeModelString, null);171disposables.add(model);172assert.ok(model.isTooLargeForSyncing());173174assert.strictEqual(deltas.length, 1);175const [delta] = deltas;176assert.strictEqual(delta.newActiveEditor, null);177assert.strictEqual(delta.addedDocuments, undefined);178assert.strictEqual(delta.removedDocuments, undefined);179assert.strictEqual(delta.addedEditors, undefined);180assert.strictEqual(delta.removedEditors, undefined);181182} finally {183TextModel._MODEL_SYNC_LIMIT = oldLimit;184}185});186187test('ignore huge model from editor', function () {188189const oldLimit = TextModel._MODEL_SYNC_LIMIT;190try {191const largeModelString = 'abc'.repeat(1024);192TextModel._MODEL_SYNC_LIMIT = largeModelString.length / 2;193194const model = modelService.createModel(largeModelString, null);195const editor = myCreateTestCodeEditor(model);196197assert.strictEqual(deltas.length, 1);198deltas.length = 0;199assert.strictEqual(deltas.length, 0);200editor.dispose();201model.dispose();202203} finally {204TextModel._MODEL_SYNC_LIMIT = oldLimit;205}206});207208test('ignore simple widget model', function () {209this.timeout(1000 * 60); // increase timeout for this one test210211const model = modelService.createModel('test', null, undefined, true);212disposables.add(model);213assert.ok(model.isForSimpleWidget);214215assert.strictEqual(deltas.length, 1);216const [delta] = deltas;217assert.strictEqual(delta.newActiveEditor, null);218assert.strictEqual(delta.addedDocuments, undefined);219assert.strictEqual(delta.removedDocuments, undefined);220assert.strictEqual(delta.addedEditors, undefined);221assert.strictEqual(delta.removedEditors, undefined);222});223224test('ignore editor w/o model', () => {225const editor = myCreateTestCodeEditor(undefined);226assert.strictEqual(deltas.length, 1);227const [delta] = deltas;228assert.strictEqual(delta.newActiveEditor, null);229assert.strictEqual(delta.addedDocuments, undefined);230assert.strictEqual(delta.removedDocuments, undefined);231assert.strictEqual(delta.addedEditors, undefined);232assert.strictEqual(delta.removedEditors, undefined);233234editor.dispose();235});236237test('editor with model', () => {238deltas.length = 0;239240const model = modelService.createModel('farboo', null);241const editor = myCreateTestCodeEditor(model);242243assert.strictEqual(deltas.length, 2);244const [first, second] = deltas;245assert.strictEqual(first.addedDocuments!.length, 1);246assert.strictEqual(first.newActiveEditor, undefined);247assert.strictEqual(first.removedDocuments, undefined);248assert.strictEqual(first.addedEditors, undefined);249assert.strictEqual(first.removedEditors, undefined);250251assert.strictEqual(second.addedEditors!.length, 1);252assert.strictEqual(second.addedDocuments, undefined);253assert.strictEqual(second.removedDocuments, undefined);254assert.strictEqual(second.removedEditors, undefined);255assert.strictEqual(second.newActiveEditor, undefined);256257editor.dispose();258model.dispose();259});260261test('editor with dispos-ed/-ing model', () => {262const model = modelService.createModel('farboo', null);263const editor = myCreateTestCodeEditor(model);264265// ignore things until now266deltas.length = 0;267268modelService.destroyModel(model.uri);269assert.strictEqual(deltas.length, 1);270const [first] = deltas;271272assert.strictEqual(first.newActiveEditor, undefined);273assert.strictEqual(first.removedEditors!.length, 1);274assert.strictEqual(first.removedDocuments!.length, 1);275assert.strictEqual(first.addedDocuments, undefined);276assert.strictEqual(first.addedEditors, undefined);277278editor.dispose();279model.dispose();280});281});282283284