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
5241 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
// eslint-disable-next-line local/code-no-any-casts
266
opts.value.indentSize = <any>'2';
267
assertState(opts, {
268
tabSize: 4,
269
indentSize: 2,
270
insertSpaces: false,
271
cursorStyle: TextEditorCursorStyle.Line,
272
lineNumbers: RenderLineNumbersType.On
273
});
274
assert.deepStrictEqual(calls, [{ indentSize: 2 }]);
275
});
276
277
test('indentSize can request to use tabSize', () => {
278
opts.value.indentSize = 'tabSize';
279
assertState(opts, {
280
tabSize: 4,
281
indentSize: 4,
282
insertSpaces: false,
283
cursorStyle: TextEditorCursorStyle.Line,
284
lineNumbers: RenderLineNumbersType.On
285
});
286
assert.deepStrictEqual(calls, [{ indentSize: 'tabSize' }]);
287
});
288
289
test('indentSize cannot request indentation detection', () => {
290
// eslint-disable-next-line local/code-no-any-casts
291
opts.value.indentSize = <any>'auto';
292
assertState(opts, {
293
tabSize: 4,
294
indentSize: 4,
295
insertSpaces: false,
296
cursorStyle: TextEditorCursorStyle.Line,
297
lineNumbers: RenderLineNumbersType.On
298
});
299
assert.deepStrictEqual(calls, []);
300
});
301
302
test('ignores invalid indentSize 1', () => {
303
opts.value.indentSize = null!;
304
assertState(opts, {
305
tabSize: 4,
306
indentSize: 4,
307
insertSpaces: false,
308
cursorStyle: TextEditorCursorStyle.Line,
309
lineNumbers: RenderLineNumbersType.On
310
});
311
assert.deepStrictEqual(calls, []);
312
});
313
314
test('ignores invalid indentSize 2', () => {
315
opts.value.indentSize = -5;
316
assertState(opts, {
317
tabSize: 4,
318
indentSize: 4,
319
insertSpaces: false,
320
cursorStyle: TextEditorCursorStyle.Line,
321
lineNumbers: RenderLineNumbersType.On
322
});
323
assert.deepStrictEqual(calls, []);
324
});
325
326
test('ignores invalid indentSize 3', () => {
327
// eslint-disable-next-line local/code-no-any-casts
328
opts.value.indentSize = <any>'hello';
329
assertState(opts, {
330
tabSize: 4,
331
indentSize: 4,
332
insertSpaces: false,
333
cursorStyle: TextEditorCursorStyle.Line,
334
lineNumbers: RenderLineNumbersType.On
335
});
336
assert.deepStrictEqual(calls, []);
337
});
338
339
test('ignores invalid indentSize 4', () => {
340
// eslint-disable-next-line local/code-no-any-casts
341
opts.value.indentSize = <any>'-17';
342
assertState(opts, {
343
tabSize: 4,
344
indentSize: 4,
345
insertSpaces: false,
346
cursorStyle: TextEditorCursorStyle.Line,
347
lineNumbers: RenderLineNumbersType.On
348
});
349
assert.deepStrictEqual(calls, []);
350
});
351
352
test('can set insertSpaces to the same value', () => {
353
opts.value.insertSpaces = false;
354
assertState(opts, {
355
tabSize: 4,
356
indentSize: 4,
357
insertSpaces: false,
358
cursorStyle: TextEditorCursorStyle.Line,
359
lineNumbers: RenderLineNumbersType.On
360
});
361
assert.deepStrictEqual(calls, []);
362
});
363
364
test('can set insertSpaces to boolean', () => {
365
opts.value.insertSpaces = true;
366
assertState(opts, {
367
tabSize: 4,
368
indentSize: 4,
369
insertSpaces: true,
370
cursorStyle: TextEditorCursorStyle.Line,
371
lineNumbers: RenderLineNumbersType.On
372
});
373
assert.deepStrictEqual(calls, [{ insertSpaces: true }]);
374
});
375
376
test('can set insertSpaces to false string', () => {
377
opts.value.insertSpaces = 'false';
378
assertState(opts, {
379
tabSize: 4,
380
indentSize: 4,
381
insertSpaces: false,
382
cursorStyle: TextEditorCursorStyle.Line,
383
lineNumbers: RenderLineNumbersType.On
384
});
385
assert.deepStrictEqual(calls, []);
386
});
387
388
test('can set insertSpaces to truey', () => {
389
opts.value.insertSpaces = 'hello';
390
assertState(opts, {
391
tabSize: 4,
392
indentSize: 4,
393
insertSpaces: true,
394
cursorStyle: TextEditorCursorStyle.Line,
395
lineNumbers: RenderLineNumbersType.On
396
});
397
assert.deepStrictEqual(calls, [{ insertSpaces: true }]);
398
});
399
400
test('insertSpaces can request indentation detection', () => {
401
opts.value.insertSpaces = 'auto';
402
assertState(opts, {
403
tabSize: 4,
404
indentSize: 4,
405
insertSpaces: false,
406
cursorStyle: TextEditorCursorStyle.Line,
407
lineNumbers: RenderLineNumbersType.On
408
});
409
assert.deepStrictEqual(calls, [{ insertSpaces: 'auto' }]);
410
});
411
412
test('can set cursorStyle to same value', () => {
413
opts.value.cursorStyle = TextEditorCursorStyle.Line;
414
assertState(opts, {
415
tabSize: 4,
416
indentSize: 4,
417
insertSpaces: false,
418
cursorStyle: TextEditorCursorStyle.Line,
419
lineNumbers: RenderLineNumbersType.On
420
});
421
assert.deepStrictEqual(calls, []);
422
});
423
424
test('can change cursorStyle', () => {
425
opts.value.cursorStyle = TextEditorCursorStyle.Block;
426
assertState(opts, {
427
tabSize: 4,
428
indentSize: 4,
429
insertSpaces: false,
430
cursorStyle: TextEditorCursorStyle.Block,
431
lineNumbers: RenderLineNumbersType.On
432
});
433
assert.deepStrictEqual(calls, [{ cursorStyle: TextEditorCursorStyle.Block }]);
434
});
435
436
test('can set lineNumbers to same value', () => {
437
opts.value.lineNumbers = TextEditorLineNumbersStyle.On;
438
assertState(opts, {
439
tabSize: 4,
440
indentSize: 4,
441
insertSpaces: false,
442
cursorStyle: TextEditorCursorStyle.Line,
443
lineNumbers: RenderLineNumbersType.On
444
});
445
assert.deepStrictEqual(calls, []);
446
});
447
448
test('can change lineNumbers', () => {
449
opts.value.lineNumbers = TextEditorLineNumbersStyle.Off;
450
assertState(opts, {
451
tabSize: 4,
452
indentSize: 4,
453
insertSpaces: false,
454
cursorStyle: TextEditorCursorStyle.Line,
455
lineNumbers: RenderLineNumbersType.Off
456
});
457
assert.deepStrictEqual(calls, [{ lineNumbers: RenderLineNumbersType.Off }]);
458
});
459
460
test('can do bulk updates 0', () => {
461
opts.assign({
462
tabSize: 4,
463
indentSize: 4,
464
insertSpaces: false,
465
cursorStyle: TextEditorCursorStyle.Line,
466
lineNumbers: TextEditorLineNumbersStyle.On
467
});
468
assertState(opts, {
469
tabSize: 4,
470
indentSize: 4,
471
insertSpaces: false,
472
cursorStyle: TextEditorCursorStyle.Line,
473
lineNumbers: RenderLineNumbersType.On
474
});
475
assert.deepStrictEqual(calls, [{ indentSize: 4 }]);
476
});
477
478
test('can do bulk updates 1', () => {
479
opts.assign({
480
tabSize: 'auto',
481
insertSpaces: true
482
});
483
assertState(opts, {
484
tabSize: 4,
485
indentSize: 4,
486
insertSpaces: true,
487
cursorStyle: TextEditorCursorStyle.Line,
488
lineNumbers: RenderLineNumbersType.On
489
});
490
assert.deepStrictEqual(calls, [{ tabSize: 'auto', insertSpaces: true }]);
491
});
492
493
test('can do bulk updates 2', () => {
494
opts.assign({
495
tabSize: 3,
496
insertSpaces: 'auto'
497
});
498
assertState(opts, {
499
tabSize: 3,
500
indentSize: 4,
501
insertSpaces: false,
502
cursorStyle: TextEditorCursorStyle.Line,
503
lineNumbers: RenderLineNumbersType.On
504
});
505
assert.deepStrictEqual(calls, [{ tabSize: 3, insertSpaces: 'auto' }]);
506
});
507
508
test('can do bulk updates 3', () => {
509
opts.assign({
510
cursorStyle: TextEditorCursorStyle.Block,
511
lineNumbers: TextEditorLineNumbersStyle.Relative
512
});
513
assertState(opts, {
514
tabSize: 4,
515
indentSize: 4,
516
insertSpaces: false,
517
cursorStyle: TextEditorCursorStyle.Block,
518
lineNumbers: RenderLineNumbersType.Relative
519
});
520
assert.deepStrictEqual(calls, [{ cursorStyle: TextEditorCursorStyle.Block, lineNumbers: RenderLineNumbersType.Relative }]);
521
});
522
523
ensureNoDisposablesAreLeakedInTestSuite();
524
});
525
526