Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/test/common/model/model.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
6
import assert from 'assert';
7
import { Disposable, DisposableStore, dispose } from '../../../../base/common/lifecycle.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
9
import { EditOperation } from '../../../common/core/editOperation.js';
10
import { Position } from '../../../common/core/position.js';
11
import { Range } from '../../../common/core/range.js';
12
import { MetadataConsts } from '../../../common/encodedTokenAttributes.js';
13
import { EncodedTokenizationResult, IState, TokenizationRegistry } from '../../../common/languages.js';
14
import { ILanguageService } from '../../../common/languages/language.js';
15
import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.js';
16
import { NullState } from '../../../common/languages/nullTokenize.js';
17
import { TextModel } from '../../../common/model/textModel.js';
18
import { InternalModelContentChangeEvent, ModelRawContentChangedEvent, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from '../../../common/textModelEvents.js';
19
import { createModelServices, createTextModel, instantiateTextModel } from '../testTextModel.js';
20
21
// --------- utils
22
23
const LINE1 = 'My First Line';
24
const LINE2 = '\t\tMy Second Line';
25
const LINE3 = ' Third Line';
26
const LINE4 = '';
27
const LINE5 = '1';
28
29
suite('Editor Model - Model', () => {
30
31
let thisModel: TextModel;
32
33
setup(() => {
34
const text =
35
LINE1 + '\r\n' +
36
LINE2 + '\n' +
37
LINE3 + '\n' +
38
LINE4 + '\r\n' +
39
LINE5;
40
thisModel = createTextModel(text);
41
});
42
43
teardown(() => {
44
thisModel.dispose();
45
});
46
47
ensureNoDisposablesAreLeakedInTestSuite();
48
49
// --------- insert text
50
51
test('model getValue', () => {
52
assert.strictEqual(thisModel.getValue(), 'My First Line\n\t\tMy Second Line\n Third Line\n\n1');
53
});
54
55
test('model insert empty text', () => {
56
thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '')]);
57
assert.strictEqual(thisModel.getLineCount(), 5);
58
assert.strictEqual(thisModel.getLineContent(1), 'My First Line');
59
});
60
61
test('model insert text without newline 1', () => {
62
thisModel.applyEdits([EditOperation.insert(new Position(1, 1), 'foo ')]);
63
assert.strictEqual(thisModel.getLineCount(), 5);
64
assert.strictEqual(thisModel.getLineContent(1), 'foo My First Line');
65
});
66
67
test('model insert text without newline 2', () => {
68
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' foo')]);
69
assert.strictEqual(thisModel.getLineCount(), 5);
70
assert.strictEqual(thisModel.getLineContent(1), 'My foo First Line');
71
});
72
73
test('model insert text with one newline', () => {
74
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' new line\nNo longer')]);
75
assert.strictEqual(thisModel.getLineCount(), 6);
76
assert.strictEqual(thisModel.getLineContent(1), 'My new line');
77
assert.strictEqual(thisModel.getLineContent(2), 'No longer First Line');
78
});
79
80
test('model insert text with two newlines', () => {
81
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' new line\nOne more line in the middle\nNo longer')]);
82
assert.strictEqual(thisModel.getLineCount(), 7);
83
assert.strictEqual(thisModel.getLineContent(1), 'My new line');
84
assert.strictEqual(thisModel.getLineContent(2), 'One more line in the middle');
85
assert.strictEqual(thisModel.getLineContent(3), 'No longer First Line');
86
});
87
88
test('model insert text with many newlines', () => {
89
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), '\n\n\n\n')]);
90
assert.strictEqual(thisModel.getLineCount(), 9);
91
assert.strictEqual(thisModel.getLineContent(1), 'My');
92
assert.strictEqual(thisModel.getLineContent(2), '');
93
assert.strictEqual(thisModel.getLineContent(3), '');
94
assert.strictEqual(thisModel.getLineContent(4), '');
95
assert.strictEqual(thisModel.getLineContent(5), ' First Line');
96
});
97
98
99
// --------- insert text eventing
100
101
test('model insert empty text does not trigger eventing', () => {
102
const disposable = thisModel.onDidChangeContentOrInjectedText((e) => {
103
assert.ok(false, 'was not expecting event');
104
});
105
thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '')]);
106
disposable.dispose();
107
});
108
109
test('model insert text without newline eventing', () => {
110
let e: ModelRawContentChangedEvent | null = null;
111
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
112
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
113
assert.fail('Unexpected assertion error');
114
}
115
e = _e.rawContentChangedEvent;
116
});
117
thisModel.applyEdits([EditOperation.insert(new Position(1, 1), 'foo ')]);
118
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
119
[
120
new ModelRawLineChanged(1, 'foo My First Line', null)
121
],
122
2,
123
false,
124
false
125
));
126
disposable.dispose();
127
});
128
129
test('model insert text with one newline eventing', () => {
130
let e: ModelRawContentChangedEvent | null = null;
131
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
132
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
133
assert.fail('Unexpected assertion error');
134
}
135
e = _e.rawContentChangedEvent;
136
});
137
thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' new line\nNo longer')]);
138
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
139
[
140
new ModelRawLineChanged(1, 'My new line', null),
141
new ModelRawLinesInserted(2, 2, ['No longer First Line'], [null]),
142
],
143
2,
144
false,
145
false
146
));
147
disposable.dispose();
148
});
149
150
151
// --------- delete text
152
153
test('model delete empty text', () => {
154
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 1))]);
155
assert.strictEqual(thisModel.getLineCount(), 5);
156
assert.strictEqual(thisModel.getLineContent(1), 'My First Line');
157
});
158
159
test('model delete text from one line', () => {
160
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 2))]);
161
assert.strictEqual(thisModel.getLineCount(), 5);
162
assert.strictEqual(thisModel.getLineContent(1), 'y First Line');
163
});
164
165
test('model delete text from one line 2', () => {
166
thisModel.applyEdits([EditOperation.insert(new Position(1, 1), 'a')]);
167
assert.strictEqual(thisModel.getLineContent(1), 'aMy First Line');
168
169
thisModel.applyEdits([EditOperation.delete(new Range(1, 2, 1, 4))]);
170
assert.strictEqual(thisModel.getLineCount(), 5);
171
assert.strictEqual(thisModel.getLineContent(1), 'a First Line');
172
});
173
174
test('model delete all text from a line', () => {
175
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 14))]);
176
assert.strictEqual(thisModel.getLineCount(), 5);
177
assert.strictEqual(thisModel.getLineContent(1), '');
178
});
179
180
test('model delete text from two lines', () => {
181
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 2, 6))]);
182
assert.strictEqual(thisModel.getLineCount(), 4);
183
assert.strictEqual(thisModel.getLineContent(1), 'My Second Line');
184
});
185
186
test('model delete text from many lines', () => {
187
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 3, 5))]);
188
assert.strictEqual(thisModel.getLineCount(), 3);
189
assert.strictEqual(thisModel.getLineContent(1), 'My Third Line');
190
});
191
192
test('model delete everything', () => {
193
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 5, 2))]);
194
assert.strictEqual(thisModel.getLineCount(), 1);
195
assert.strictEqual(thisModel.getLineContent(1), '');
196
});
197
198
// --------- delete text eventing
199
200
test('model delete empty text does not trigger eventing', () => {
201
const disposable = thisModel.onDidChangeContentOrInjectedText((e) => {
202
assert.ok(false, 'was not expecting event');
203
});
204
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 1))]);
205
disposable.dispose();
206
});
207
208
test('model delete text from one line eventing', () => {
209
let e: ModelRawContentChangedEvent | null = null;
210
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
211
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
212
assert.fail('Unexpected assertion error');
213
}
214
e = _e.rawContentChangedEvent;
215
});
216
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 2))]);
217
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
218
[
219
new ModelRawLineChanged(1, 'y First Line', null),
220
],
221
2,
222
false,
223
false
224
));
225
disposable.dispose();
226
});
227
228
test('model delete all text from a line eventing', () => {
229
let e: ModelRawContentChangedEvent | null = null;
230
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
231
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
232
assert.fail('Unexpected assertion error');
233
}
234
e = _e.rawContentChangedEvent;
235
});
236
thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 14))]);
237
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
238
[
239
new ModelRawLineChanged(1, '', null),
240
],
241
2,
242
false,
243
false
244
));
245
disposable.dispose();
246
});
247
248
test('model delete text from two lines eventing', () => {
249
let e: ModelRawContentChangedEvent | null = null;
250
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
251
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
252
assert.fail('Unexpected assertion error');
253
}
254
e = _e.rawContentChangedEvent;
255
});
256
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 2, 6))]);
257
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
258
[
259
new ModelRawLineChanged(1, 'My Second Line', null),
260
new ModelRawLinesDeleted(2, 2),
261
],
262
2,
263
false,
264
false
265
));
266
disposable.dispose();
267
});
268
269
test('model delete text from many lines eventing', () => {
270
let e: ModelRawContentChangedEvent | null = null;
271
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
272
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
273
assert.fail('Unexpected assertion error');
274
}
275
e = _e.rawContentChangedEvent;
276
});
277
thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 3, 5))]);
278
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
279
[
280
new ModelRawLineChanged(1, 'My Third Line', null),
281
new ModelRawLinesDeleted(2, 3),
282
],
283
2,
284
false,
285
false
286
));
287
disposable.dispose();
288
});
289
290
// --------- getValueInRange
291
292
test('getValueInRange', () => {
293
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 1, 1)), '');
294
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 1, 2)), 'M');
295
assert.strictEqual(thisModel.getValueInRange(new Range(1, 2, 1, 3)), 'y');
296
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 1, 14)), 'My First Line');
297
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 2, 1)), 'My First Line\n');
298
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 2, 2)), 'My First Line\n\t');
299
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 2, 3)), 'My First Line\n\t\t');
300
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 2, 17)), 'My First Line\n\t\tMy Second Line');
301
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 3, 1)), 'My First Line\n\t\tMy Second Line\n');
302
assert.strictEqual(thisModel.getValueInRange(new Range(1, 1, 4, 1)), 'My First Line\n\t\tMy Second Line\n Third Line\n');
303
});
304
305
// --------- getValueLengthInRange
306
307
test('getValueLengthInRange', () => {
308
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 1, 1)), ''.length);
309
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 1, 2)), 'M'.length);
310
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 2, 1, 3)), 'y'.length);
311
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 1, 14)), 'My First Line'.length);
312
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 2, 1)), 'My First Line\n'.length);
313
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 2, 2)), 'My First Line\n\t'.length);
314
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 2, 3)), 'My First Line\n\t\t'.length);
315
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 2, 17)), 'My First Line\n\t\tMy Second Line'.length);
316
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 3, 1)), 'My First Line\n\t\tMy Second Line\n'.length);
317
assert.strictEqual(thisModel.getValueLengthInRange(new Range(1, 1, 4, 1)), 'My First Line\n\t\tMy Second Line\n Third Line\n'.length);
318
});
319
320
// --------- setValue
321
test('setValue eventing', () => {
322
let e: ModelRawContentChangedEvent | null = null;
323
const disposable = thisModel.onDidChangeContentOrInjectedText((_e) => {
324
if (e !== null || !(_e instanceof InternalModelContentChangeEvent)) {
325
assert.fail('Unexpected assertion error');
326
}
327
e = _e.rawContentChangedEvent;
328
});
329
thisModel.setValue('new value');
330
assert.deepStrictEqual(e, new ModelRawContentChangedEvent(
331
[
332
new ModelRawFlush()
333
],
334
2,
335
false,
336
false
337
));
338
disposable.dispose();
339
});
340
341
test('issue #46342: Maintain edit operation order in applyEdits', () => {
342
const res = thisModel.applyEdits([
343
{ range: new Range(2, 1, 2, 1), text: 'a' },
344
{ range: new Range(1, 1, 1, 1), text: 'b' },
345
], true);
346
347
assert.deepStrictEqual(res[0].range, new Range(2, 1, 2, 2));
348
assert.deepStrictEqual(res[1].range, new Range(1, 1, 1, 2));
349
});
350
});
351
352
353
// --------- Special Unicode LINE SEPARATOR character
354
suite('Editor Model - Model Line Separators', () => {
355
356
let thisModel: TextModel;
357
358
setup(() => {
359
const text =
360
LINE1 + '\u2028' +
361
LINE2 + '\n' +
362
LINE3 + '\u2028' +
363
LINE4 + '\r\n' +
364
LINE5;
365
thisModel = createTextModel(text);
366
});
367
368
teardown(() => {
369
thisModel.dispose();
370
});
371
372
ensureNoDisposablesAreLeakedInTestSuite();
373
374
test('model getValue', () => {
375
assert.strictEqual(thisModel.getValue(), 'My First Line\u2028\t\tMy Second Line\n Third Line\u2028\n1');
376
});
377
378
test('model lines', () => {
379
assert.strictEqual(thisModel.getLineCount(), 3);
380
});
381
382
test('Bug 13333:Model should line break on lonely CR too', () => {
383
const model = createTextModel('Hello\rWorld!\r\nAnother line');
384
assert.strictEqual(model.getLineCount(), 3);
385
assert.strictEqual(model.getValue(), 'Hello\r\nWorld!\r\nAnother line');
386
model.dispose();
387
});
388
});
389
390
391
// --------- Words
392
393
suite('Editor Model - Words', () => {
394
395
const OUTER_LANGUAGE_ID = 'outerMode';
396
const INNER_LANGUAGE_ID = 'innerMode';
397
398
class OuterMode extends Disposable {
399
400
public readonly languageId = OUTER_LANGUAGE_ID;
401
402
constructor(
403
@ILanguageService languageService: ILanguageService,
404
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService
405
) {
406
super();
407
this._register(languageService.registerLanguage({ id: this.languageId }));
408
this._register(languageConfigurationService.register(this.languageId, {}));
409
410
const languageIdCodec = languageService.languageIdCodec;
411
this._register(TokenizationRegistry.register(this.languageId, {
412
getInitialState: (): IState => NullState,
413
tokenize: undefined!,
414
tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => {
415
const tokensArr: number[] = [];
416
let prevLanguageId: string | undefined = undefined;
417
for (let i = 0; i < line.length; i++) {
418
const languageId = (line.charAt(i) === 'x' ? INNER_LANGUAGE_ID : OUTER_LANGUAGE_ID);
419
const encodedLanguageId = languageIdCodec.encodeLanguageId(languageId);
420
if (prevLanguageId !== languageId) {
421
tokensArr.push(i);
422
tokensArr.push((encodedLanguageId << MetadataConsts.LANGUAGEID_OFFSET));
423
}
424
prevLanguageId = languageId;
425
}
426
427
const tokens = new Uint32Array(tokensArr.length);
428
for (let i = 0; i < tokens.length; i++) {
429
tokens[i] = tokensArr[i];
430
}
431
return new EncodedTokenizationResult(tokens, state);
432
}
433
}));
434
}
435
}
436
437
class InnerMode extends Disposable {
438
439
public readonly languageId = INNER_LANGUAGE_ID;
440
441
constructor(
442
@ILanguageService languageService: ILanguageService,
443
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService
444
) {
445
super();
446
this._register(languageService.registerLanguage({ id: this.languageId }));
447
this._register(languageConfigurationService.register(this.languageId, {}));
448
}
449
}
450
451
let disposables: Disposable[] = [];
452
453
setup(() => {
454
disposables = [];
455
});
456
457
teardown(() => {
458
dispose(disposables);
459
disposables = [];
460
});
461
462
ensureNoDisposablesAreLeakedInTestSuite();
463
464
test('Get word at position', () => {
465
const text = ['This text has some words. '];
466
const thisModel = createTextModel(text.join('\n'));
467
disposables.push(thisModel);
468
469
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 1)), { word: 'This', startColumn: 1, endColumn: 5 });
470
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 2)), { word: 'This', startColumn: 1, endColumn: 5 });
471
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 4)), { word: 'This', startColumn: 1, endColumn: 5 });
472
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 5)), { word: 'This', startColumn: 1, endColumn: 5 });
473
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 6)), { word: 'text', startColumn: 6, endColumn: 10 });
474
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 19)), { word: 'some', startColumn: 15, endColumn: 19 });
475
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 20)), null);
476
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 21)), { word: 'words', startColumn: 21, endColumn: 26 });
477
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 26)), { word: 'words', startColumn: 21, endColumn: 26 });
478
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 27)), null);
479
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 28)), null);
480
});
481
482
test('getWordAtPosition at embedded language boundaries', () => {
483
const disposables = new DisposableStore();
484
const instantiationService = createModelServices(disposables);
485
const outerMode = disposables.add(instantiationService.createInstance(OuterMode));
486
disposables.add(instantiationService.createInstance(InnerMode));
487
488
const model = disposables.add(instantiateTextModel(instantiationService, 'ab<xx>ab<x>', outerMode.languageId));
489
490
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 1)), { word: 'ab', startColumn: 1, endColumn: 3 });
491
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 2)), { word: 'ab', startColumn: 1, endColumn: 3 });
492
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 3)), { word: 'ab', startColumn: 1, endColumn: 3 });
493
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 4)), { word: 'xx', startColumn: 4, endColumn: 6 });
494
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 5)), { word: 'xx', startColumn: 4, endColumn: 6 });
495
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 6)), { word: 'xx', startColumn: 4, endColumn: 6 });
496
assert.deepStrictEqual(model.getWordAtPosition(new Position(1, 7)), { word: 'ab', startColumn: 7, endColumn: 9 });
497
498
disposables.dispose();
499
});
500
501
test('issue #61296: VS code freezes when editing CSS file with emoji', () => {
502
const MODE_ID = 'testMode';
503
const disposables = new DisposableStore();
504
const instantiationService = createModelServices(disposables);
505
const languageConfigurationService = instantiationService.get(ILanguageConfigurationService);
506
const languageService = instantiationService.get(ILanguageService);
507
508
disposables.add(languageService.registerLanguage({ id: MODE_ID }));
509
disposables.add(languageConfigurationService.register(MODE_ID, {
510
wordPattern: /(#?-?\d*\.\d\w*%?)|(::?[\w-]*(?=[^,{;]*[,{]))|(([@#.!])?[\w-?]+%?|[@#!.])/g
511
}));
512
513
const thisModel = disposables.add(instantiateTextModel(instantiationService, '.🐷-a-b', MODE_ID));
514
515
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 1)), { word: '.', startColumn: 1, endColumn: 2 });
516
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 2)), { word: '.', startColumn: 1, endColumn: 2 });
517
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 3)), null);
518
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 4)), { word: '-a-b', startColumn: 4, endColumn: 8 });
519
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 5)), { word: '-a-b', startColumn: 4, endColumn: 8 });
520
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 6)), { word: '-a-b', startColumn: 4, endColumn: 8 });
521
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 7)), { word: '-a-b', startColumn: 4, endColumn: 8 });
522
assert.deepStrictEqual(thisModel.getWordAtPosition(new Position(1, 8)), { word: '-a-b', startColumn: 4, endColumn: 8 });
523
524
disposables.dispose();
525
});
526
});
527
528