Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts
5243 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 assert from 'assert';
7
import { MainThreadDocumentsAndEditors } from '../../browser/mainThreadDocumentsAndEditors.js';
8
import { SingleProxyRPCProtocol } from '../common/testRPCProtocol.js';
9
import { TestConfigurationService } from '../../../../platform/configuration/test/common/testConfigurationService.js';
10
import { ModelService } from '../../../../editor/common/services/modelService.js';
11
import { TestCodeEditorService } from '../../../../editor/test/browser/editorTestServices.js';
12
import { ITextFileService } from '../../../services/textfile/common/textfiles.js';
13
import { IDocumentsAndEditorsDelta } from '../../common/extHost.protocol.js';
14
import { createTestCodeEditor, ITestCodeEditor } from '../../../../editor/test/browser/testCodeEditor.js';
15
import { mock } from '../../../../base/test/common/mock.js';
16
import { TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestPathService } from '../../../test/browser/workbenchTestServices.js';
17
import { Event } from '../../../../base/common/event.js';
18
import { ITextModel } from '../../../../editor/common/model.js';
19
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
20
import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';
21
import { IFileService } from '../../../../platform/files/common/files.js';
22
import { TestThemeService } from '../../../../platform/theme/test/common/testThemeService.js';
23
import { UndoRedoService } from '../../../../platform/undoRedo/common/undoRedoService.js';
24
import { TestDialogService } from '../../../../platform/dialogs/test/common/testDialogService.js';
25
import { TestNotificationService } from '../../../../platform/notification/test/common/testNotificationService.js';
26
import { TestTextResourcePropertiesService, TestWorkingCopyFileService } from '../../../test/common/workbenchTestServices.js';
27
import { UriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentityService.js';
28
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
29
import { IPaneCompositePartService } from '../../../services/panecomposite/browser/panecomposite.js';
30
import { TextModel } from '../../../../editor/common/model/textModel.js';
31
import { DisposableStore } from '../../../../base/common/lifecycle.js';
32
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
33
import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js';
34
import { ILanguageService } from '../../../../editor/common/languages/language.js';
35
import { LanguageService } from '../../../../editor/common/services/languageService.js';
36
import { ILanguageConfigurationService } from '../../../../editor/common/languages/languageConfigurationRegistry.js';
37
import { TestLanguageConfigurationService } from '../../../../editor/test/common/modes/testLanguageConfigurationService.js';
38
import { IUndoRedoService } from '../../../../platform/undoRedo/common/undoRedo.js';
39
import { IQuickDiffModelService } from '../../../contrib/scm/browser/quickDiffModel.js';
40
import { ITextEditorDiffInformation } from '../../../../platform/editor/common/editor.js';
41
import { ITreeSitterLibraryService } from '../../../../editor/common/services/treeSitter/treeSitterLibraryService.js';
42
import { TestTreeSitterLibraryService } from '../../../../editor/test/common/services/testTreeSitterLibraryService.js';
43
44
suite('MainThreadDocumentsAndEditors', () => {
45
46
let disposables: DisposableStore;
47
48
let modelService: ModelService;
49
let codeEditorService: TestCodeEditorService;
50
let textFileService: ITextFileService;
51
const deltas: IDocumentsAndEditorsDelta[] = [];
52
53
function myCreateTestCodeEditor(model: ITextModel | undefined): ITestCodeEditor {
54
return createTestCodeEditor(model, {
55
hasTextFocus: false,
56
serviceCollection: new ServiceCollection(
57
[ICodeEditorService, codeEditorService]
58
)
59
});
60
}
61
62
setup(() => {
63
disposables = new DisposableStore();
64
65
deltas.length = 0;
66
const configService = new TestConfigurationService();
67
configService.setUserConfiguration('editor', { 'detectIndentation': false });
68
const dialogService = new TestDialogService();
69
const notificationService = new TestNotificationService();
70
const undoRedoService = new UndoRedoService(dialogService, notificationService);
71
const themeService = new TestThemeService();
72
const instantiationService = new TestInstantiationService();
73
instantiationService.set(ILanguageService, disposables.add(new LanguageService()));
74
instantiationService.set(ILanguageConfigurationService, new TestLanguageConfigurationService());
75
instantiationService.set(ITreeSitterLibraryService, new TestTreeSitterLibraryService());
76
instantiationService.set(IUndoRedoService, undoRedoService);
77
modelService = new ModelService(
78
configService,
79
new TestTextResourcePropertiesService(configService),
80
undoRedoService,
81
instantiationService
82
);
83
codeEditorService = new TestCodeEditorService(themeService);
84
textFileService = new class extends mock<ITextFileService>() {
85
override isDirty() { return false; }
86
// eslint-disable-next-line local/code-no-any-casts
87
override files = <any>{
88
onDidSave: Event.None,
89
onDidRevert: Event.None,
90
onDidChangeDirty: Event.None,
91
onDidChangeEncoding: Event.None
92
};
93
// eslint-disable-next-line local/code-no-any-casts
94
override untitled = <any>{
95
onDidChangeEncoding: Event.None
96
};
97
override getEncoding() { return 'utf8'; }
98
};
99
const workbenchEditorService = disposables.add(new TestEditorService());
100
const editorGroupService = new TestEditorGroupsService();
101
102
const fileService = new class extends mock<IFileService>() {
103
override onDidRunOperation = Event.None;
104
override onDidChangeFileSystemProviderCapabilities = Event.None;
105
override onDidChangeFileSystemProviderRegistrations = Event.None;
106
};
107
108
new MainThreadDocumentsAndEditors(
109
SingleProxyRPCProtocol({
110
$acceptDocumentsAndEditorsDelta: (delta: IDocumentsAndEditorsDelta) => { deltas.push(delta); },
111
$acceptEditorDiffInformation: (id: string, diffInformation: ITextEditorDiffInformation | undefined) => { }
112
}),
113
modelService,
114
textFileService,
115
workbenchEditorService,
116
codeEditorService,
117
fileService,
118
null!,
119
editorGroupService,
120
new class extends mock<IPaneCompositePartService>() implements IPaneCompositePartService {
121
override onDidPaneCompositeOpen = Event.None;
122
override onDidPaneCompositeClose = Event.None;
123
override getActivePaneComposite() {
124
return undefined;
125
}
126
},
127
TestEnvironmentService,
128
new TestWorkingCopyFileService(),
129
new UriIdentityService(fileService),
130
new class extends mock<IClipboardService>() {
131
override readText() {
132
return Promise.resolve('clipboard_contents');
133
}
134
},
135
new TestPathService(),
136
new TestConfigurationService(),
137
new class extends mock<IQuickDiffModelService>() {
138
override createQuickDiffModelReference() {
139
return undefined;
140
}
141
}
142
);
143
});
144
145
teardown(() => {
146
disposables.dispose();
147
});
148
149
ensureNoDisposablesAreLeakedInTestSuite();
150
151
test('Model#add', () => {
152
deltas.length = 0;
153
154
disposables.add(modelService.createModel('farboo', null));
155
156
assert.strictEqual(deltas.length, 1);
157
const [delta] = deltas;
158
159
assert.strictEqual(delta.addedDocuments!.length, 1);
160
assert.strictEqual(delta.removedDocuments, undefined);
161
assert.strictEqual(delta.addedEditors, undefined);
162
assert.strictEqual(delta.removedEditors, undefined);
163
assert.strictEqual(delta.newActiveEditor, undefined);
164
});
165
166
test('ignore huge model', function () {
167
168
const oldLimit = TextModel._MODEL_SYNC_LIMIT;
169
try {
170
const largeModelString = 'abc'.repeat(1024);
171
TextModel._MODEL_SYNC_LIMIT = largeModelString.length / 2;
172
173
const model = modelService.createModel(largeModelString, null);
174
disposables.add(model);
175
assert.ok(model.isTooLargeForSyncing());
176
177
assert.strictEqual(deltas.length, 1);
178
const [delta] = deltas;
179
assert.strictEqual(delta.newActiveEditor, null);
180
assert.strictEqual(delta.addedDocuments, undefined);
181
assert.strictEqual(delta.removedDocuments, undefined);
182
assert.strictEqual(delta.addedEditors, undefined);
183
assert.strictEqual(delta.removedEditors, undefined);
184
185
} finally {
186
TextModel._MODEL_SYNC_LIMIT = oldLimit;
187
}
188
});
189
190
test('ignore huge model from editor', function () {
191
192
const oldLimit = TextModel._MODEL_SYNC_LIMIT;
193
try {
194
const largeModelString = 'abc'.repeat(1024);
195
TextModel._MODEL_SYNC_LIMIT = largeModelString.length / 2;
196
197
const model = modelService.createModel(largeModelString, null);
198
const editor = myCreateTestCodeEditor(model);
199
200
assert.strictEqual(deltas.length, 1);
201
deltas.length = 0;
202
assert.strictEqual(deltas.length, 0);
203
editor.dispose();
204
model.dispose();
205
206
} finally {
207
TextModel._MODEL_SYNC_LIMIT = oldLimit;
208
}
209
});
210
211
test('ignore simple widget model', function () {
212
this.timeout(1000 * 60); // increase timeout for this one test
213
214
const model = modelService.createModel('test', null, undefined, true);
215
disposables.add(model);
216
assert.ok(model.isForSimpleWidget);
217
218
assert.strictEqual(deltas.length, 1);
219
const [delta] = deltas;
220
assert.strictEqual(delta.newActiveEditor, null);
221
assert.strictEqual(delta.addedDocuments, undefined);
222
assert.strictEqual(delta.removedDocuments, undefined);
223
assert.strictEqual(delta.addedEditors, undefined);
224
assert.strictEqual(delta.removedEditors, undefined);
225
});
226
227
test('ignore editor w/o model', () => {
228
const editor = myCreateTestCodeEditor(undefined);
229
assert.strictEqual(deltas.length, 1);
230
const [delta] = deltas;
231
assert.strictEqual(delta.newActiveEditor, null);
232
assert.strictEqual(delta.addedDocuments, undefined);
233
assert.strictEqual(delta.removedDocuments, undefined);
234
assert.strictEqual(delta.addedEditors, undefined);
235
assert.strictEqual(delta.removedEditors, undefined);
236
237
editor.dispose();
238
});
239
240
test('editor with model', () => {
241
deltas.length = 0;
242
243
const model = modelService.createModel('farboo', null);
244
const editor = myCreateTestCodeEditor(model);
245
246
assert.strictEqual(deltas.length, 2);
247
const [first, second] = deltas;
248
assert.strictEqual(first.addedDocuments!.length, 1);
249
assert.strictEqual(first.newActiveEditor, undefined);
250
assert.strictEqual(first.removedDocuments, undefined);
251
assert.strictEqual(first.addedEditors, undefined);
252
assert.strictEqual(first.removedEditors, undefined);
253
254
assert.strictEqual(second.addedEditors!.length, 1);
255
assert.strictEqual(second.addedDocuments, undefined);
256
assert.strictEqual(second.removedDocuments, undefined);
257
assert.strictEqual(second.removedEditors, undefined);
258
assert.strictEqual(second.newActiveEditor, undefined);
259
260
editor.dispose();
261
model.dispose();
262
});
263
264
test('editor with dispos-ed/-ing model', () => {
265
const model = modelService.createModel('farboo', null);
266
const editor = myCreateTestCodeEditor(model);
267
268
// ignore things until now
269
deltas.length = 0;
270
271
modelService.destroyModel(model.uri);
272
assert.strictEqual(deltas.length, 1);
273
const [first] = deltas;
274
275
assert.strictEqual(first.newActiveEditor, undefined);
276
assert.strictEqual(first.removedEditors!.length, 1);
277
assert.strictEqual(first.removedDocuments!.length, 1);
278
assert.strictEqual(first.addedDocuments, undefined);
279
assert.strictEqual(first.addedEditors, undefined);
280
281
editor.dispose();
282
model.dispose();
283
});
284
});
285
286