Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/test/common/viewLayout/lineHeights.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 { LineHeightsManager } from '../../../common/viewLayout/lineHeights.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
9
10
suite('Editor ViewLayout - LineHeightsManager', () => {
11
12
ensureNoDisposablesAreLeakedInTestSuite();
13
14
test('default line height is used when no custom heights exist', () => {
15
const manager = new LineHeightsManager(10, []);
16
17
// Check individual line heights
18
assert.strictEqual(manager.heightForLineNumber(1), 10);
19
assert.strictEqual(manager.heightForLineNumber(5), 10);
20
assert.strictEqual(manager.heightForLineNumber(100), 10);
21
22
// Check accumulated heights
23
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 10);
24
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(5), 50);
25
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(10), 100);
26
});
27
28
test('can change default line height', () => {
29
const manager = new LineHeightsManager(10, []);
30
manager.defaultLineHeight = 20;
31
32
// Check individual line heights
33
assert.strictEqual(manager.heightForLineNumber(1), 20);
34
assert.strictEqual(manager.heightForLineNumber(5), 20);
35
36
// Check accumulated heights
37
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 20);
38
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(5), 100);
39
});
40
41
test('can add single custom line height', () => {
42
const manager = new LineHeightsManager(10, []);
43
manager.insertOrChangeCustomLineHeight('dec1', 3, 3, 20);
44
manager.commit();
45
46
// Check individual line heights
47
assert.strictEqual(manager.heightForLineNumber(1), 10);
48
assert.strictEqual(manager.heightForLineNumber(2), 10);
49
assert.strictEqual(manager.heightForLineNumber(3), 20);
50
assert.strictEqual(manager.heightForLineNumber(4), 10);
51
52
// Check accumulated heights
53
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 10);
54
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(2), 20);
55
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 40);
56
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 50);
57
});
58
59
test('can add multiple custom line heights', () => {
60
const manager = new LineHeightsManager(10, []);
61
manager.insertOrChangeCustomLineHeight('dec1', 2, 2, 15);
62
manager.insertOrChangeCustomLineHeight('dec2', 4, 4, 25);
63
manager.commit();
64
65
// Check individual line heights
66
assert.strictEqual(manager.heightForLineNumber(1), 10);
67
assert.strictEqual(manager.heightForLineNumber(2), 15);
68
assert.strictEqual(manager.heightForLineNumber(3), 10);
69
assert.strictEqual(manager.heightForLineNumber(4), 25);
70
assert.strictEqual(manager.heightForLineNumber(5), 10);
71
72
// Check accumulated heights
73
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 10);
74
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(2), 25);
75
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 35);
76
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 60);
77
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(5), 70);
78
});
79
80
test('can add range of custom line heights', () => {
81
const manager = new LineHeightsManager(10, []);
82
manager.insertOrChangeCustomLineHeight('dec1', 2, 4, 15);
83
manager.commit();
84
85
// Check individual line heights
86
assert.strictEqual(manager.heightForLineNumber(1), 10);
87
assert.strictEqual(manager.heightForLineNumber(2), 15);
88
assert.strictEqual(manager.heightForLineNumber(3), 15);
89
assert.strictEqual(manager.heightForLineNumber(4), 15);
90
assert.strictEqual(manager.heightForLineNumber(5), 10);
91
92
// Check accumulated heights
93
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 10);
94
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(2), 25);
95
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 40);
96
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 55);
97
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(5), 65);
98
});
99
100
test('can change existing custom line height', () => {
101
const manager = new LineHeightsManager(10, []);
102
manager.insertOrChangeCustomLineHeight('dec1', 3, 3, 20);
103
manager.commit();
104
assert.strictEqual(manager.heightForLineNumber(3), 20);
105
106
manager.insertOrChangeCustomLineHeight('dec1', 3, 3, 30);
107
manager.commit();
108
assert.strictEqual(manager.heightForLineNumber(3), 30);
109
110
// Check accumulated heights after change
111
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 50);
112
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 60);
113
});
114
115
test('can remove custom line height', () => {
116
const manager = new LineHeightsManager(10, []);
117
manager.insertOrChangeCustomLineHeight('dec1', 3, 3, 20);
118
manager.commit();
119
assert.strictEqual(manager.heightForLineNumber(3), 20);
120
121
manager.removeCustomLineHeight('dec1');
122
manager.commit();
123
assert.strictEqual(manager.heightForLineNumber(3), 10);
124
125
// Check accumulated heights after removal
126
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 30);
127
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 40);
128
});
129
130
test('handles overlapping custom line heights (last one wins)', () => {
131
const manager = new LineHeightsManager(10, []);
132
manager.insertOrChangeCustomLineHeight('dec1', 3, 5, 20);
133
manager.insertOrChangeCustomLineHeight('dec2', 4, 6, 30);
134
manager.commit();
135
136
assert.strictEqual(manager.heightForLineNumber(2), 10);
137
assert.strictEqual(manager.heightForLineNumber(3), 20);
138
assert.strictEqual(manager.heightForLineNumber(4), 30);
139
assert.strictEqual(manager.heightForLineNumber(5), 30);
140
assert.strictEqual(manager.heightForLineNumber(6), 30);
141
assert.strictEqual(manager.heightForLineNumber(7), 10);
142
});
143
144
test('handles deleting lines before custom line heights', () => {
145
const manager = new LineHeightsManager(10, []);
146
manager.insertOrChangeCustomLineHeight('dec1', 10, 12, 20);
147
manager.commit();
148
149
manager.onLinesDeleted(5, 7); // Delete lines 5-7
150
151
assert.strictEqual(manager.heightForLineNumber(7), 20); // Was line 10
152
assert.strictEqual(manager.heightForLineNumber(8), 20); // Was line 11
153
assert.strictEqual(manager.heightForLineNumber(9), 20); // Was line 12
154
assert.strictEqual(manager.heightForLineNumber(10), 10);
155
});
156
157
test('handles deleting lines overlapping with custom line heights', () => {
158
const manager = new LineHeightsManager(10, []);
159
manager.insertOrChangeCustomLineHeight('dec1', 5, 10, 20);
160
manager.commit();
161
162
manager.onLinesDeleted(7, 12); // Delete lines 7-12, including part of decoration
163
164
assert.strictEqual(manager.heightForLineNumber(5), 20);
165
assert.strictEqual(manager.heightForLineNumber(6), 20);
166
assert.strictEqual(manager.heightForLineNumber(7), 10);
167
});
168
169
test('handles deleting lines containing custom line heights completely', () => {
170
const manager = new LineHeightsManager(10, []);
171
manager.insertOrChangeCustomLineHeight('dec1', 5, 7, 20);
172
manager.commit();
173
174
manager.onLinesDeleted(4, 8); // Delete lines 4-8, completely contains decoration
175
176
// The decoration collapses to a single line which matches the behavior in the text buffer
177
assert.strictEqual(manager.heightForLineNumber(3), 10);
178
assert.strictEqual(manager.heightForLineNumber(4), 20);
179
assert.strictEqual(manager.heightForLineNumber(5), 10);
180
});
181
182
test('handles deleting lines at the very beginning', () => {
183
const manager = new LineHeightsManager(10, []);
184
manager.insertOrChangeCustomLineHeight('decA', 1, 1, 40);
185
manager.commit();
186
187
manager.onLinesDeleted(2, 4); // Delete lines 2-4 after the variable line height
188
189
// Check individual line heights
190
assert.strictEqual(manager.heightForLineNumber(1), 40);
191
});
192
193
test('handles inserting lines before custom line heights', () => {
194
const manager = new LineHeightsManager(10, []);
195
manager.insertOrChangeCustomLineHeight('dec1', 5, 7, 20);
196
manager.commit();
197
198
manager.onLinesInserted(3, 4); // Insert 2 lines at line 3
199
200
assert.strictEqual(manager.heightForLineNumber(5), 10);
201
assert.strictEqual(manager.heightForLineNumber(6), 10);
202
assert.strictEqual(manager.heightForLineNumber(7), 20); // Was line 5
203
assert.strictEqual(manager.heightForLineNumber(8), 20); // Was line 6
204
assert.strictEqual(manager.heightForLineNumber(9), 20); // Was line 7
205
});
206
207
test('handles inserting lines inside custom line heights range', () => {
208
const manager = new LineHeightsManager(10, []);
209
manager.insertOrChangeCustomLineHeight('dec1', 5, 7, 20);
210
manager.commit();
211
212
manager.onLinesInserted(6, 7); // Insert 2 lines at line 6
213
214
assert.strictEqual(manager.heightForLineNumber(5), 20);
215
assert.strictEqual(manager.heightForLineNumber(6), 20);
216
assert.strictEqual(manager.heightForLineNumber(7), 20);
217
assert.strictEqual(manager.heightForLineNumber(8), 20);
218
assert.strictEqual(manager.heightForLineNumber(9), 20);
219
});
220
221
test('changing decoration id maintains custom line height', () => {
222
const manager = new LineHeightsManager(10, []);
223
manager.insertOrChangeCustomLineHeight('dec1', 5, 7, 20);
224
manager.commit();
225
226
manager.removeCustomLineHeight('dec1');
227
manager.insertOrChangeCustomLineHeight('dec2', 5, 7, 20);
228
manager.commit();
229
230
assert.strictEqual(manager.heightForLineNumber(5), 20);
231
assert.strictEqual(manager.heightForLineNumber(6), 20);
232
assert.strictEqual(manager.heightForLineNumber(7), 20);
233
});
234
235
test('accumulates heights correctly with complex setup', () => {
236
const manager = new LineHeightsManager(10, []);
237
manager.insertOrChangeCustomLineHeight('dec1', 3, 3, 15);
238
manager.insertOrChangeCustomLineHeight('dec2', 5, 7, 20);
239
manager.insertOrChangeCustomLineHeight('dec3', 10, 10, 30);
240
manager.commit();
241
242
// Check accumulated heights
243
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(1), 10);
244
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(2), 20);
245
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(3), 35);
246
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(4), 45);
247
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(5), 65);
248
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(7), 105);
249
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(9), 125);
250
assert.strictEqual(manager.getAccumulatedLineHeightsIncludingLineNumber(10), 155);
251
});
252
253
test('partial deletion with multiple lines for the same decoration ID', () => {
254
const manager = new LineHeightsManager(10, []);
255
manager.insertOrChangeCustomLineHeight('decSame', 5, 5, 20);
256
manager.insertOrChangeCustomLineHeight('decSame', 6, 6, 25);
257
manager.commit();
258
259
// Delete one line that partially intersects the same decoration
260
manager.onLinesDeleted(6, 6);
261
262
// Check individual line heights
263
assert.strictEqual(manager.heightForLineNumber(5), 20);
264
assert.strictEqual(manager.heightForLineNumber(6), 10);
265
});
266
267
test('overlapping decorations use maximum line height', () => {
268
const manager = new LineHeightsManager(10, []);
269
manager.insertOrChangeCustomLineHeight('decA', 3, 5, 40);
270
manager.insertOrChangeCustomLineHeight('decB', 4, 6, 30);
271
manager.commit();
272
273
// Check individual line heights
274
assert.strictEqual(manager.heightForLineNumber(3), 40);
275
assert.strictEqual(manager.heightForLineNumber(4), 40);
276
assert.strictEqual(manager.heightForLineNumber(5), 40);
277
assert.strictEqual(manager.heightForLineNumber(6), 30);
278
});
279
});
280
281