Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/test/browser/extHostTextEditor.test.ts
3296 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 assert from 'assert';
6
import { Lazy } from '../../../../base/common/lazy.js';
7
import { URI } from '../../../../base/common/uri.js';
8
import { mock } from '../../../../base/test/common/mock.js';
9
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
10
import { RenderLineNumbersType, TextEditorCursorStyle } from '../../../../editor/common/config/editorOptions.js';
11
import { NullLogService } from '../../../../platform/log/common/log.js';
12
import { IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate, MainThreadTextEditorsShape } from '../../common/extHost.protocol.js';
13
import { ExtHostDocumentData } from '../../common/extHostDocumentData.js';
14
import { ExtHostTextEditor, ExtHostTextEditorOptions } from '../../common/extHostTextEditor.js';
15
import { Range, TextEditorLineNumbersStyle } from '../../common/extHostTypes.js';
16
17
suite('ExtHostTextEditor', () => {
18
19
let editor: ExtHostTextEditor;
20
const doc = new ExtHostDocumentData(undefined!, URI.file(''), [
21
'aaaa bbbb+cccc abc'
22
], '\n', 1, 'text', false, 'utf8');
23
24
setup(() => {
25
editor = new ExtHostTextEditor('fake', null!, new NullLogService(), new Lazy(() => doc.document), [], { cursorStyle: TextEditorCursorStyle.Line, insertSpaces: true, lineNumbers: 1, tabSize: 4, indentSize: 4, originalIndentSize: 'tabSize' }, [], 1);
26
});
27
28
test('disposed editor', () => {
29
30
assert.ok(editor.value.document);
31
editor._acceptViewColumn(3);
32
assert.strictEqual(3, editor.value.viewColumn);
33
34
editor.dispose();
35
36
assert.throws(() => editor._acceptViewColumn(2));
37
assert.strictEqual(3, editor.value.viewColumn);
38
39
assert.ok(editor.value.document);
40
assert.throws(() => editor._acceptOptions(null!));
41
assert.throws(() => editor._acceptSelections([]));
42
});
43
44
test('API [bug]: registerTextEditorCommand clears redo stack even if no edits are made #55163', async function () {
45
let applyCount = 0;
46
const editor = new ExtHostTextEditor('edt1',
47
new class extends mock<MainThreadTextEditorsShape>() {
48
override $tryApplyEdits(): Promise<boolean> {
49
applyCount += 1;
50
return Promise.resolve(true);
51
}
52
}, new NullLogService(), new Lazy(() => doc.document), [], { cursorStyle: TextEditorCursorStyle.Line, insertSpaces: true, lineNumbers: 1, tabSize: 4, indentSize: 4, originalIndentSize: 'tabSize' }, [], 1);
53
54
await editor.value.edit(edit => { });
55
assert.strictEqual(applyCount, 0);
56
57
await editor.value.edit(edit => { edit.setEndOfLine(1); });
58
assert.strictEqual(applyCount, 1);
59
60
await editor.value.edit(edit => { edit.delete(new Range(0, 0, 1, 1)); });
61
assert.strictEqual(applyCount, 2);
62
});
63
64
ensureNoDisposablesAreLeakedInTestSuite();
65
});
66
67
suite('ExtHostTextEditorOptions', () => {
68
69
let opts: ExtHostTextEditorOptions;
70
let calls: ITextEditorConfigurationUpdate[] = [];
71
72
setup(() => {
73
calls = [];
74
const mockProxy: MainThreadTextEditorsShape = {
75
dispose: undefined!,
76
$trySetOptions: (id: string, options: ITextEditorConfigurationUpdate) => {
77
assert.strictEqual(id, '1');
78
calls.push(options);
79
return Promise.resolve(undefined);
80
},
81
$tryShowTextDocument: undefined!,
82
$registerTextEditorDecorationType: undefined!,
83
$removeTextEditorDecorationType: undefined!,
84
$tryShowEditor: undefined!,
85
$tryHideEditor: undefined!,
86
$trySetDecorations: undefined!,
87
$trySetDecorationsFast: undefined!,
88
$tryRevealRange: undefined!,
89
$trySetSelections: undefined!,
90
$tryApplyEdits: undefined!,
91
$tryInsertSnippet: undefined!,
92
$getDiffInformation: undefined!
93
};
94
opts = new ExtHostTextEditorOptions(mockProxy, '1', {
95
tabSize: 4,
96
indentSize: 4,
97
originalIndentSize: 'tabSize',
98
insertSpaces: false,
99
cursorStyle: TextEditorCursorStyle.Line,
100
lineNumbers: RenderLineNumbersType.On
101
}, new NullLogService());
102
});
103
104
teardown(() => {
105
opts = null!;
106
calls = null!;
107
});
108
109
function assertState(opts: ExtHostTextEditorOptions, expected: Omit<IResolvedTextEditorConfiguration, 'originalIndentSize'>): void {
110
const actual = {
111
tabSize: opts.value.tabSize,
112
indentSize: opts.value.indentSize,
113
insertSpaces: opts.value.insertSpaces,
114
cursorStyle: opts.value.cursorStyle,
115
lineNumbers: opts.value.lineNumbers
116
};
117
assert.deepStrictEqual(actual, expected);
118
}
119
120
test('can set tabSize to the same value', () => {
121
opts.value.tabSize = 4;
122
assertState(opts, {
123
tabSize: 4,
124
indentSize: 4,
125
insertSpaces: false,
126
cursorStyle: TextEditorCursorStyle.Line,
127
lineNumbers: RenderLineNumbersType.On
128
});
129
assert.deepStrictEqual(calls, []);
130
});
131
132
test('can change tabSize to positive integer', () => {
133
opts.value.tabSize = 1;
134
assertState(opts, {
135
tabSize: 1,
136
indentSize: 4,
137
insertSpaces: false,
138
cursorStyle: TextEditorCursorStyle.Line,
139
lineNumbers: RenderLineNumbersType.On
140
});
141
assert.deepStrictEqual(calls, [{ tabSize: 1 }]);
142
});
143
144
test('can change tabSize to positive float', () => {
145
opts.value.tabSize = 2.3;
146
assertState(opts, {
147
tabSize: 2,
148
indentSize: 4,
149
insertSpaces: false,
150
cursorStyle: TextEditorCursorStyle.Line,
151
lineNumbers: RenderLineNumbersType.On
152
});
153
assert.deepStrictEqual(calls, [{ tabSize: 2 }]);
154
});
155
156
test('can change tabSize to a string number', () => {
157
opts.value.tabSize = '2';
158
assertState(opts, {
159
tabSize: 2,
160
indentSize: 4,
161
insertSpaces: false,
162
cursorStyle: TextEditorCursorStyle.Line,
163
lineNumbers: RenderLineNumbersType.On
164
});
165
assert.deepStrictEqual(calls, [{ tabSize: 2 }]);
166
});
167
168
test('tabSize can request indentation detection', () => {
169
opts.value.tabSize = 'auto';
170
assertState(opts, {
171
tabSize: 4,
172
indentSize: 4,
173
insertSpaces: false,
174
cursorStyle: TextEditorCursorStyle.Line,
175
lineNumbers: RenderLineNumbersType.On
176
});
177
assert.deepStrictEqual(calls, [{ tabSize: 'auto' }]);
178
});
179
180
test('ignores invalid tabSize 1', () => {
181
opts.value.tabSize = null!;
182
assertState(opts, {
183
tabSize: 4,
184
indentSize: 4,
185
insertSpaces: false,
186
cursorStyle: TextEditorCursorStyle.Line,
187
lineNumbers: RenderLineNumbersType.On
188
});
189
assert.deepStrictEqual(calls, []);
190
});
191
192
test('ignores invalid tabSize 2', () => {
193
opts.value.tabSize = -5;
194
assertState(opts, {
195
tabSize: 4,
196
indentSize: 4,
197
insertSpaces: false,
198
cursorStyle: TextEditorCursorStyle.Line,
199
lineNumbers: RenderLineNumbersType.On
200
});
201
assert.deepStrictEqual(calls, []);
202
});
203
204
test('ignores invalid tabSize 3', () => {
205
opts.value.tabSize = 'hello';
206
assertState(opts, {
207
tabSize: 4,
208
indentSize: 4,
209
insertSpaces: false,
210
cursorStyle: TextEditorCursorStyle.Line,
211
lineNumbers: RenderLineNumbersType.On
212
});
213
assert.deepStrictEqual(calls, []);
214
});
215
216
test('ignores invalid tabSize 4', () => {
217
opts.value.tabSize = '-17';
218
assertState(opts, {
219
tabSize: 4,
220
indentSize: 4,
221
insertSpaces: false,
222
cursorStyle: TextEditorCursorStyle.Line,
223
lineNumbers: RenderLineNumbersType.On
224
});
225
assert.deepStrictEqual(calls, []);
226
});
227
228
test('can set indentSize to the same value', () => {
229
opts.value.indentSize = 4;
230
assertState(opts, {
231
tabSize: 4,
232
indentSize: 4,
233
insertSpaces: false,
234
cursorStyle: TextEditorCursorStyle.Line,
235
lineNumbers: RenderLineNumbersType.On
236
});
237
assert.deepStrictEqual(calls, [{ indentSize: 4 }]);
238
});
239
240
test('can change indentSize to positive integer', () => {
241
opts.value.indentSize = 1;
242
assertState(opts, {
243
tabSize: 4,
244
indentSize: 1,
245
insertSpaces: false,
246
cursorStyle: TextEditorCursorStyle.Line,
247
lineNumbers: RenderLineNumbersType.On
248
});
249
assert.deepStrictEqual(calls, [{ indentSize: 1 }]);
250
});
251
252
test('can change indentSize to positive float', () => {
253
opts.value.indentSize = 2.3;
254
assertState(opts, {
255
tabSize: 4,
256
indentSize: 2,
257
insertSpaces: false,
258
cursorStyle: TextEditorCursorStyle.Line,
259
lineNumbers: RenderLineNumbersType.On
260
});
261
assert.deepStrictEqual(calls, [{ indentSize: 2 }]);
262
});
263
264
test('can change indentSize to a string number', () => {
265
opts.value.indentSize = <any>'2';
266
assertState(opts, {
267
tabSize: 4,
268
indentSize: 2,
269
insertSpaces: false,
270
cursorStyle: TextEditorCursorStyle.Line,
271
lineNumbers: RenderLineNumbersType.On
272
});
273
assert.deepStrictEqual(calls, [{ indentSize: 2 }]);
274
});
275
276
test('indentSize can request to use tabSize', () => {
277
opts.value.indentSize = 'tabSize';
278
assertState(opts, {
279
tabSize: 4,
280
indentSize: 4,
281
insertSpaces: false,
282
cursorStyle: TextEditorCursorStyle.Line,
283
lineNumbers: RenderLineNumbersType.On
284
});
285
assert.deepStrictEqual(calls, [{ indentSize: 'tabSize' }]);
286
});
287
288
test('indentSize cannot request indentation detection', () => {
289
opts.value.indentSize = <any>'auto';
290
assertState(opts, {
291
tabSize: 4,
292
indentSize: 4,
293
insertSpaces: false,
294
cursorStyle: TextEditorCursorStyle.Line,
295
lineNumbers: RenderLineNumbersType.On
296
});
297
assert.deepStrictEqual(calls, []);
298
});
299
300
test('ignores invalid indentSize 1', () => {
301
opts.value.indentSize = null!;
302
assertState(opts, {
303
tabSize: 4,
304
indentSize: 4,
305
insertSpaces: false,
306
cursorStyle: TextEditorCursorStyle.Line,
307
lineNumbers: RenderLineNumbersType.On
308
});
309
assert.deepStrictEqual(calls, []);
310
});
311
312
test('ignores invalid indentSize 2', () => {
313
opts.value.indentSize = -5;
314
assertState(opts, {
315
tabSize: 4,
316
indentSize: 4,
317
insertSpaces: false,
318
cursorStyle: TextEditorCursorStyle.Line,
319
lineNumbers: RenderLineNumbersType.On
320
});
321
assert.deepStrictEqual(calls, []);
322
});
323
324
test('ignores invalid indentSize 3', () => {
325
opts.value.indentSize = <any>'hello';
326
assertState(opts, {
327
tabSize: 4,
328
indentSize: 4,
329
insertSpaces: false,
330
cursorStyle: TextEditorCursorStyle.Line,
331
lineNumbers: RenderLineNumbersType.On
332
});
333
assert.deepStrictEqual(calls, []);
334
});
335
336
test('ignores invalid indentSize 4', () => {
337
opts.value.indentSize = <any>'-17';
338
assertState(opts, {
339
tabSize: 4,
340
indentSize: 4,
341
insertSpaces: false,
342
cursorStyle: TextEditorCursorStyle.Line,
343
lineNumbers: RenderLineNumbersType.On
344
});
345
assert.deepStrictEqual(calls, []);
346
});
347
348
test('can set insertSpaces to the same value', () => {
349
opts.value.insertSpaces = false;
350
assertState(opts, {
351
tabSize: 4,
352
indentSize: 4,
353
insertSpaces: false,
354
cursorStyle: TextEditorCursorStyle.Line,
355
lineNumbers: RenderLineNumbersType.On
356
});
357
assert.deepStrictEqual(calls, []);
358
});
359
360
test('can set insertSpaces to boolean', () => {
361
opts.value.insertSpaces = true;
362
assertState(opts, {
363
tabSize: 4,
364
indentSize: 4,
365
insertSpaces: true,
366
cursorStyle: TextEditorCursorStyle.Line,
367
lineNumbers: RenderLineNumbersType.On
368
});
369
assert.deepStrictEqual(calls, [{ insertSpaces: true }]);
370
});
371
372
test('can set insertSpaces to false string', () => {
373
opts.value.insertSpaces = 'false';
374
assertState(opts, {
375
tabSize: 4,
376
indentSize: 4,
377
insertSpaces: false,
378
cursorStyle: TextEditorCursorStyle.Line,
379
lineNumbers: RenderLineNumbersType.On
380
});
381
assert.deepStrictEqual(calls, []);
382
});
383
384
test('can set insertSpaces to truey', () => {
385
opts.value.insertSpaces = 'hello';
386
assertState(opts, {
387
tabSize: 4,
388
indentSize: 4,
389
insertSpaces: true,
390
cursorStyle: TextEditorCursorStyle.Line,
391
lineNumbers: RenderLineNumbersType.On
392
});
393
assert.deepStrictEqual(calls, [{ insertSpaces: true }]);
394
});
395
396
test('insertSpaces can request indentation detection', () => {
397
opts.value.insertSpaces = 'auto';
398
assertState(opts, {
399
tabSize: 4,
400
indentSize: 4,
401
insertSpaces: false,
402
cursorStyle: TextEditorCursorStyle.Line,
403
lineNumbers: RenderLineNumbersType.On
404
});
405
assert.deepStrictEqual(calls, [{ insertSpaces: 'auto' }]);
406
});
407
408
test('can set cursorStyle to same value', () => {
409
opts.value.cursorStyle = TextEditorCursorStyle.Line;
410
assertState(opts, {
411
tabSize: 4,
412
indentSize: 4,
413
insertSpaces: false,
414
cursorStyle: TextEditorCursorStyle.Line,
415
lineNumbers: RenderLineNumbersType.On
416
});
417
assert.deepStrictEqual(calls, []);
418
});
419
420
test('can change cursorStyle', () => {
421
opts.value.cursorStyle = TextEditorCursorStyle.Block;
422
assertState(opts, {
423
tabSize: 4,
424
indentSize: 4,
425
insertSpaces: false,
426
cursorStyle: TextEditorCursorStyle.Block,
427
lineNumbers: RenderLineNumbersType.On
428
});
429
assert.deepStrictEqual(calls, [{ cursorStyle: TextEditorCursorStyle.Block }]);
430
});
431
432
test('can set lineNumbers to same value', () => {
433
opts.value.lineNumbers = TextEditorLineNumbersStyle.On;
434
assertState(opts, {
435
tabSize: 4,
436
indentSize: 4,
437
insertSpaces: false,
438
cursorStyle: TextEditorCursorStyle.Line,
439
lineNumbers: RenderLineNumbersType.On
440
});
441
assert.deepStrictEqual(calls, []);
442
});
443
444
test('can change lineNumbers', () => {
445
opts.value.lineNumbers = TextEditorLineNumbersStyle.Off;
446
assertState(opts, {
447
tabSize: 4,
448
indentSize: 4,
449
insertSpaces: false,
450
cursorStyle: TextEditorCursorStyle.Line,
451
lineNumbers: RenderLineNumbersType.Off
452
});
453
assert.deepStrictEqual(calls, [{ lineNumbers: RenderLineNumbersType.Off }]);
454
});
455
456
test('can do bulk updates 0', () => {
457
opts.assign({
458
tabSize: 4,
459
indentSize: 4,
460
insertSpaces: false,
461
cursorStyle: TextEditorCursorStyle.Line,
462
lineNumbers: TextEditorLineNumbersStyle.On
463
});
464
assertState(opts, {
465
tabSize: 4,
466
indentSize: 4,
467
insertSpaces: false,
468
cursorStyle: TextEditorCursorStyle.Line,
469
lineNumbers: RenderLineNumbersType.On
470
});
471
assert.deepStrictEqual(calls, [{ indentSize: 4 }]);
472
});
473
474
test('can do bulk updates 1', () => {
475
opts.assign({
476
tabSize: 'auto',
477
insertSpaces: true
478
});
479
assertState(opts, {
480
tabSize: 4,
481
indentSize: 4,
482
insertSpaces: true,
483
cursorStyle: TextEditorCursorStyle.Line,
484
lineNumbers: RenderLineNumbersType.On
485
});
486
assert.deepStrictEqual(calls, [{ tabSize: 'auto', insertSpaces: true }]);
487
});
488
489
test('can do bulk updates 2', () => {
490
opts.assign({
491
tabSize: 3,
492
insertSpaces: 'auto'
493
});
494
assertState(opts, {
495
tabSize: 3,
496
indentSize: 4,
497
insertSpaces: false,
498
cursorStyle: TextEditorCursorStyle.Line,
499
lineNumbers: RenderLineNumbersType.On
500
});
501
assert.deepStrictEqual(calls, [{ tabSize: 3, insertSpaces: 'auto' }]);
502
});
503
504
test('can do bulk updates 3', () => {
505
opts.assign({
506
cursorStyle: TextEditorCursorStyle.Block,
507
lineNumbers: TextEditorLineNumbersStyle.Relative
508
});
509
assertState(opts, {
510
tabSize: 4,
511
indentSize: 4,
512
insertSpaces: false,
513
cursorStyle: TextEditorCursorStyle.Block,
514
lineNumbers: RenderLineNumbersType.Relative
515
});
516
assert.deepStrictEqual(calls, [{ cursorStyle: TextEditorCursorStyle.Block, lineNumbers: RenderLineNumbersType.Relative }]);
517
});
518
519
ensureNoDisposablesAreLeakedInTestSuite();
520
});
521
522