Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/folding/test/browser/indentRangeProvider.test.ts
4780 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 { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
8
import { FoldingMarkers } from '../../../../common/languages/languageConfiguration.js';
9
import { computeRanges } from '../../browser/indentRangeProvider.js';
10
import { createTextModel } from '../../../../test/common/testTextModel.js';
11
12
interface ExpectedIndentRange {
13
startLineNumber: number;
14
endLineNumber: number;
15
parentIndex: number;
16
}
17
18
function assertRanges(lines: string[], expected: ExpectedIndentRange[], offside: boolean, markers?: FoldingMarkers): void {
19
const model = createTextModel(lines.join('\n'));
20
const actual = computeRanges(model, offside, markers);
21
22
const actualRanges: ExpectedIndentRange[] = [];
23
for (let i = 0; i < actual.length; i++) {
24
actualRanges[i] = r(actual.getStartLineNumber(i), actual.getEndLineNumber(i), actual.getParentIndex(i));
25
}
26
assert.deepStrictEqual(actualRanges, expected);
27
model.dispose();
28
}
29
30
function r(startLineNumber: number, endLineNumber: number, parentIndex: number, marker = false): ExpectedIndentRange {
31
return { startLineNumber, endLineNumber, parentIndex };
32
}
33
34
suite('Indentation Folding', () => {
35
ensureNoDisposablesAreLeakedInTestSuite();
36
test('Fold one level', () => {
37
const range = [
38
'A',
39
' A',
40
' A',
41
' A'
42
];
43
assertRanges(range, [r(1, 4, -1)], true);
44
assertRanges(range, [r(1, 4, -1)], false);
45
});
46
47
test('Fold two levels', () => {
48
const range = [
49
'A',
50
' A',
51
' A',
52
' A',
53
' A'
54
];
55
assertRanges(range, [r(1, 5, -1), r(3, 5, 0)], true);
56
assertRanges(range, [r(1, 5, -1), r(3, 5, 0)], false);
57
});
58
59
test('Fold three levels', () => {
60
const range = [
61
'A',
62
' A',
63
' A',
64
' A',
65
'A'
66
];
67
assertRanges(range, [r(1, 4, -1), r(2, 4, 0), r(3, 4, 1)], true);
68
assertRanges(range, [r(1, 4, -1), r(2, 4, 0), r(3, 4, 1)], false);
69
});
70
71
test('Fold decreasing indent', () => {
72
const range = [
73
' A',
74
' A',
75
'A'
76
];
77
assertRanges(range, [], true);
78
assertRanges(range, [], false);
79
});
80
81
test('Fold Java', () => {
82
assertRanges([
83
/* 1*/ 'class A {',
84
/* 2*/ ' void foo() {',
85
/* 3*/ ' console.log();',
86
/* 4*/ ' console.log();',
87
/* 5*/ ' }',
88
/* 6*/ '',
89
/* 7*/ ' void bar() {',
90
/* 8*/ ' console.log();',
91
/* 9*/ ' }',
92
/*10*/ '}',
93
/*11*/ 'interface B {',
94
/*12*/ ' void bar();',
95
/*13*/ '}',
96
], [r(1, 9, -1), r(2, 4, 0), r(7, 8, 0), r(11, 12, -1)], false);
97
});
98
99
test('Fold Javadoc', () => {
100
assertRanges([
101
/* 1*/ '/**',
102
/* 2*/ ' * Comment',
103
/* 3*/ ' */',
104
/* 4*/ 'class A {',
105
/* 5*/ ' void foo() {',
106
/* 6*/ ' }',
107
/* 7*/ '}',
108
], [r(1, 3, -1), r(4, 6, -1)], false);
109
});
110
test('Fold Whitespace Java', () => {
111
assertRanges([
112
/* 1*/ 'class A {',
113
/* 2*/ '',
114
/* 3*/ ' void foo() {',
115
/* 4*/ ' ',
116
/* 5*/ ' return 0;',
117
/* 6*/ ' }',
118
/* 7*/ ' ',
119
/* 8*/ '}',
120
], [r(1, 7, -1), r(3, 5, 0)], false);
121
});
122
123
test('Fold Whitespace Python', () => {
124
assertRanges([
125
/* 1*/ 'def a:',
126
/* 2*/ ' pass',
127
/* 3*/ ' ',
128
/* 4*/ ' def b:',
129
/* 5*/ ' pass',
130
/* 6*/ ' ',
131
/* 7*/ ' ',
132
/* 8*/ 'def c: # since there was a deintent here'
133
], [r(1, 5, -1), r(4, 5, 0)], true);
134
});
135
136
test('Fold Tabs', () => {
137
assertRanges([
138
/* 1*/ 'class A {',
139
/* 2*/ '\t\t',
140
/* 3*/ '\tvoid foo() {',
141
/* 4*/ '\t \t//hello',
142
/* 5*/ '\t return 0;',
143
/* 6*/ ' \t}',
144
/* 7*/ ' ',
145
/* 8*/ '}',
146
], [r(1, 7, -1), r(3, 5, 0)], false);
147
});
148
});
149
150
const markers: FoldingMarkers = {
151
start: /^\s*#region\b/,
152
end: /^\s*#endregion\b/
153
};
154
155
suite('Folding with regions', () => {
156
ensureNoDisposablesAreLeakedInTestSuite();
157
test('Inside region, indented', () => {
158
assertRanges([
159
/* 1*/ 'class A {',
160
/* 2*/ ' #region',
161
/* 3*/ ' void foo() {',
162
/* 4*/ ' ',
163
/* 5*/ ' return 0;',
164
/* 6*/ ' }',
165
/* 7*/ ' #endregion',
166
/* 8*/ '}',
167
], [r(1, 7, -1), r(2, 7, 0, true), r(3, 5, 1)], false, markers);
168
});
169
test('Inside region, not indented', () => {
170
assertRanges([
171
/* 1*/ 'var x;',
172
/* 2*/ '#region',
173
/* 3*/ 'void foo() {',
174
/* 4*/ ' ',
175
/* 5*/ ' return 0;',
176
/* 6*/ ' }',
177
/* 7*/ '#endregion',
178
/* 8*/ '',
179
], [r(2, 7, -1, true), r(3, 6, 0)], false, markers);
180
});
181
test('Empty Regions', () => {
182
assertRanges([
183
/* 1*/ 'var x;',
184
/* 2*/ '#region',
185
/* 3*/ '#endregion',
186
/* 4*/ '#region',
187
/* 5*/ '',
188
/* 6*/ '#endregion',
189
/* 7*/ 'var y;',
190
], [r(2, 3, -1, true), r(4, 6, -1, true)], false, markers);
191
});
192
test('Nested Regions', () => {
193
assertRanges([
194
/* 1*/ 'var x;',
195
/* 2*/ '#region',
196
/* 3*/ '#region',
197
/* 4*/ '',
198
/* 5*/ '#endregion',
199
/* 6*/ '#endregion',
200
/* 7*/ 'var y;',
201
], [r(2, 6, -1, true), r(3, 5, 0, true)], false, markers);
202
});
203
test('Nested Regions 2', () => {
204
assertRanges([
205
/* 1*/ 'class A {',
206
/* 2*/ ' #region',
207
/* 3*/ '',
208
/* 4*/ ' #region',
209
/* 5*/ '',
210
/* 6*/ ' #endregion',
211
/* 7*/ ' // comment',
212
/* 8*/ ' #endregion',
213
/* 9*/ '}',
214
], [r(1, 8, -1), r(2, 8, 0, true), r(4, 6, 1, true)], false, markers);
215
});
216
test('Incomplete Regions', () => {
217
assertRanges([
218
/* 1*/ 'class A {',
219
/* 2*/ '#region',
220
/* 3*/ ' // comment',
221
/* 4*/ '}',
222
], [r(2, 3, -1)], false, markers);
223
});
224
test('Incomplete Regions 2', () => {
225
assertRanges([
226
/* 1*/ '',
227
/* 2*/ '#region',
228
/* 3*/ '#region',
229
/* 4*/ '#region',
230
/* 5*/ ' // comment',
231
/* 6*/ '#endregion',
232
/* 7*/ '#endregion',
233
/* 8*/ ' // hello',
234
], [r(3, 7, -1, true), r(4, 6, 0, true)], false, markers);
235
});
236
test('Indented region before', () => {
237
assertRanges([
238
/* 1*/ 'if (x)',
239
/* 2*/ ' return;',
240
/* 3*/ '',
241
/* 4*/ '#region',
242
/* 5*/ ' // comment',
243
/* 6*/ '#endregion',
244
], [r(1, 3, -1), r(4, 6, -1, true)], false, markers);
245
});
246
test('Indented region before 2', () => {
247
assertRanges([
248
/* 1*/ 'if (x)',
249
/* 2*/ ' log();',
250
/* 3*/ '',
251
/* 4*/ ' #region',
252
/* 5*/ ' // comment',
253
/* 6*/ ' #endregion',
254
], [r(1, 6, -1), r(2, 6, 0), r(4, 6, 1, true)], false, markers);
255
});
256
test('Indented region in-between', () => {
257
assertRanges([
258
/* 1*/ '#region',
259
/* 2*/ ' // comment',
260
/* 3*/ ' if (x)',
261
/* 4*/ ' return;',
262
/* 5*/ '',
263
/* 6*/ '#endregion',
264
], [r(1, 6, -1, true), r(3, 5, 0)], false, markers);
265
});
266
test('Indented region after', () => {
267
assertRanges([
268
/* 1*/ '#region',
269
/* 2*/ ' // comment',
270
/* 3*/ '',
271
/* 4*/ '#endregion',
272
/* 5*/ ' if (x)',
273
/* 6*/ ' return;',
274
], [r(1, 4, -1, true), r(5, 6, -1)], false, markers);
275
});
276
test('With off-side', () => {
277
assertRanges([
278
/* 1*/ '#region',
279
/* 2*/ ' ',
280
/* 3*/ '',
281
/* 4*/ '#endregion',
282
/* 5*/ '',
283
], [r(1, 4, -1, true)], true, markers);
284
});
285
test('Nested with off-side', () => {
286
assertRanges([
287
/* 1*/ '#region',
288
/* 2*/ ' ',
289
/* 3*/ '#region',
290
/* 4*/ '',
291
/* 5*/ '#endregion',
292
/* 6*/ '',
293
/* 7*/ '#endregion',
294
/* 8*/ '',
295
], [r(1, 7, -1, true), r(3, 5, 0, true)], true, markers);
296
});
297
test('Issue 35981', () => {
298
assertRanges([
299
/* 1*/ 'function thisFoldsToEndOfPage() {',
300
/* 2*/ ' const variable = []',
301
/* 3*/ ' // #region',
302
/* 4*/ ' .reduce((a, b) => a,[]);',
303
/* 5*/ '}',
304
/* 6*/ '',
305
/* 7*/ 'function thisFoldsProperly() {',
306
/* 8*/ ' const foo = "bar"',
307
/* 9*/ '}',
308
], [r(1, 4, -1), r(2, 4, 0), r(7, 8, -1)], false, markers);
309
});
310
test('Misspelled Markers', () => {
311
assertRanges([
312
/* 1*/ '#Region',
313
/* 2*/ '#endregion',
314
/* 3*/ '#regionsandmore',
315
/* 4*/ '#endregion',
316
/* 5*/ '#region',
317
/* 6*/ '#end region',
318
/* 7*/ '#region',
319
/* 8*/ '#endregionff',
320
], [], true, markers);
321
});
322
test('Issue 79359', () => {
323
assertRanges([
324
/* 1*/ '#region',
325
/* 2*/ '',
326
/* 3*/ 'class A',
327
/* 4*/ ' foo',
328
/* 5*/ '',
329
/* 6*/ 'class A',
330
/* 7*/ ' foo',
331
/* 8*/ '',
332
/* 9*/ '#endregion',
333
], [r(1, 9, -1, true), r(3, 4, 0), r(6, 7, 0)], true, markers);
334
});
335
});
336
337