Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts
5260 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 { MAX_FOLDING_REGIONS, FoldRange, FoldingRegions, FoldSource } from '../../browser/foldingRanges.js';
10
import { RangesCollector, computeRanges } from '../../browser/indentRangeProvider.js';
11
import { createTextModel } from '../../../../test/common/testTextModel.js';
12
13
const markers: FoldingMarkers = {
14
start: /^#region$/,
15
end: /^#endregion$/
16
};
17
18
suite('FoldingRanges', () => {
19
ensureNoDisposablesAreLeakedInTestSuite();
20
const foldRange = (from: number, to: number, collapsed: boolean | undefined = undefined, source: FoldSource = FoldSource.provider, type: string | undefined = undefined) =>
21
<FoldRange>{
22
startLineNumber: from,
23
endLineNumber: to,
24
type: type,
25
isCollapsed: collapsed || false,
26
source
27
};
28
const assertEqualRanges = (range1: FoldRange, range2: FoldRange, msg: string) => {
29
assert.strictEqual(range1.startLineNumber, range2.startLineNumber, msg + ' start');
30
assert.strictEqual(range1.endLineNumber, range2.endLineNumber, msg + ' end');
31
assert.strictEqual(range1.type, range2.type, msg + ' type');
32
assert.strictEqual(range1.isCollapsed, range2.isCollapsed, msg + ' collapsed');
33
assert.strictEqual(range1.source, range2.source, msg + ' source');
34
};
35
36
test('test max folding regions', () => {
37
const lines: string[] = [];
38
const nRegions = MAX_FOLDING_REGIONS;
39
const collector = new RangesCollector({ limit: MAX_FOLDING_REGIONS, update: () => { } });
40
for (let i = 0; i < nRegions; i++) {
41
const startLineNumber = lines.length;
42
lines.push('#region');
43
const endLineNumber = lines.length;
44
lines.push('#endregion');
45
collector.insertFirst(startLineNumber, endLineNumber, 0);
46
}
47
const model = createTextModel(lines.join('\n'));
48
const actual = collector.toIndentRanges(model);
49
assert.strictEqual(actual.length, nRegions, 'len');
50
model.dispose();
51
52
});
53
54
test('findRange', () => {
55
const lines = [
56
/* 1*/ '#region',
57
/* 2*/ '#endregion',
58
/* 3*/ 'class A {',
59
/* 4*/ ' void foo() {',
60
/* 5*/ ' if (true) {',
61
/* 6*/ ' return;',
62
/* 7*/ ' }',
63
/* 8*/ '',
64
/* 9*/ ' if (true) {',
65
/* 10*/ ' return;',
66
/* 11*/ ' }',
67
/* 12*/ ' }',
68
/* 13*/ '}'];
69
70
const textModel = createTextModel(lines.join('\n'));
71
try {
72
const actual = computeRanges(textModel, false, markers);
73
// let r0 = r(1, 2);
74
// let r1 = r(3, 12);
75
// let r2 = r(4, 11);
76
// let r3 = r(5, 6);
77
// let r4 = r(9, 10);
78
79
assert.strictEqual(actual.findRange(1), 0, '1');
80
assert.strictEqual(actual.findRange(2), 0, '2');
81
assert.strictEqual(actual.findRange(3), 1, '3');
82
assert.strictEqual(actual.findRange(4), 2, '4');
83
assert.strictEqual(actual.findRange(5), 3, '5');
84
assert.strictEqual(actual.findRange(6), 3, '6');
85
assert.strictEqual(actual.findRange(7), 2, '7');
86
assert.strictEqual(actual.findRange(8), 2, '8');
87
assert.strictEqual(actual.findRange(9), 4, '9');
88
assert.strictEqual(actual.findRange(10), 4, '10');
89
assert.strictEqual(actual.findRange(11), 2, '11');
90
assert.strictEqual(actual.findRange(12), 1, '12');
91
assert.strictEqual(actual.findRange(13), -1, '13');
92
} finally {
93
textModel.dispose();
94
}
95
96
97
});
98
99
test('setCollapsed', () => {
100
const lines: string[] = [];
101
const nRegions = 500;
102
for (let i = 0; i < nRegions; i++) {
103
lines.push('#region');
104
}
105
for (let i = 0; i < nRegions; i++) {
106
lines.push('#endregion');
107
}
108
const model = createTextModel(lines.join('\n'));
109
const actual = computeRanges(model, false, markers);
110
assert.strictEqual(actual.length, nRegions, 'len');
111
for (let i = 0; i < nRegions; i++) {
112
actual.setCollapsed(i, i % 3 === 0);
113
}
114
for (let i = 0; i < nRegions; i++) {
115
assert.strictEqual(actual.isCollapsed(i), i % 3 === 0, 'line' + i);
116
}
117
model.dispose();
118
});
119
120
test('sanitizeAndMerge1', () => {
121
const regionSet1: FoldRange[] = [
122
foldRange(0, 100), // invalid, should be removed
123
foldRange(1, 100, false, FoldSource.provider, 'A'), // valid
124
foldRange(1, 100, false, FoldSource.provider, 'Z'), // invalid, duplicate start
125
foldRange(10, 10, false), // invalid, should be removed
126
foldRange(20, 80, false, FoldSource.provider, 'C1'), // valid inside 'B'
127
foldRange(22, 80, true, FoldSource.provider, 'D1'), // valid inside 'C1'
128
foldRange(90, 101), // invalid, should be removed
129
];
130
const regionSet2: FoldRange[] = [
131
foldRange(20, 80, true), // should merge with C1
132
foldRange(18, 80, true), // invalid, out of order
133
foldRange(21, 81, true, FoldSource.provider, 'Z'), // invalid, overlapping
134
foldRange(22, 80, true, FoldSource.provider, 'D2'), // should merge with D1
135
];
136
const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100);
137
assert.strictEqual(result.length, 3, 'result length1');
138
assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'A'), 'A1');
139
assertEqualRanges(result[1], foldRange(20, 80, true, FoldSource.provider, 'C1'), 'C1');
140
assertEqualRanges(result[2], foldRange(22, 80, true, FoldSource.provider, 'D1'), 'D1');
141
});
142
143
test('sanitizeAndMerge2', () => {
144
const regionSet1: FoldRange[] = [
145
foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid
146
foldRange(2, 100, false, FoldSource.provider, 'a2'), // valid
147
foldRange(3, 19, false, FoldSource.provider, 'a3'), // valid
148
foldRange(20, 71, false, FoldSource.provider, 'a4'), // overlaps b3
149
foldRange(21, 29, false, FoldSource.provider, 'a5'), // valid
150
foldRange(81, 91, false, FoldSource.provider, 'a6'), // overlaps b4
151
];
152
const regionSet2: FoldRange[] = [
153
foldRange(30, 39, true, FoldSource.provider, 'b1'), // valid, will be recovered
154
foldRange(40, 49, true, FoldSource.userDefined, 'b2'), // valid
155
foldRange(50, 100, true, FoldSource.userDefined, 'b3'), // overlaps a4
156
foldRange(80, 90, true, FoldSource.userDefined, 'b4'), // overlaps a6
157
foldRange(92, 100, true, FoldSource.userDefined, 'b5'), // valid
158
];
159
const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100);
160
assert.strictEqual(result.length, 9, 'result length1');
161
assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'P1');
162
assertEqualRanges(result[1], foldRange(2, 100, false, FoldSource.provider, 'a2'), 'P2');
163
assertEqualRanges(result[2], foldRange(3, 19, false, FoldSource.provider, 'a3'), 'P3');
164
assertEqualRanges(result[3], foldRange(21, 29, false, FoldSource.provider, 'a5'), 'P4');
165
assertEqualRanges(result[4], foldRange(30, 39, true, FoldSource.recovered, 'b1'), 'P5');
166
assertEqualRanges(result[5], foldRange(40, 49, true, FoldSource.userDefined, 'b2'), 'P6');
167
assertEqualRanges(result[6], foldRange(50, 100, true, FoldSource.userDefined, 'b3'), 'P7');
168
assertEqualRanges(result[7], foldRange(80, 90, true, FoldSource.userDefined, 'b4'), 'P8');
169
assertEqualRanges(result[8], foldRange(92, 100, true, FoldSource.userDefined, 'b5'), 'P9');
170
});
171
172
test('sanitizeAndMerge3', () => {
173
const regionSet1: FoldRange[] = [
174
foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid
175
foldRange(10, 29, false, FoldSource.provider, 'a2'), // matches manual hidden
176
foldRange(35, 39, true, FoldSource.recovered, 'a3'), // valid
177
];
178
const regionSet2: FoldRange[] = [
179
foldRange(10, 29, true, FoldSource.recovered, 'b1'), // matches a
180
foldRange(20, 28, true, FoldSource.provider, 'b2'), // should remain
181
foldRange(30, 39, true, FoldSource.recovered, 'b3'), // should remain
182
];
183
const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100);
184
assert.strictEqual(result.length, 5, 'result length3');
185
assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'R1');
186
assertEqualRanges(result[1], foldRange(10, 29, true, FoldSource.provider, 'a2'), 'R2');
187
assertEqualRanges(result[2], foldRange(20, 28, true, FoldSource.recovered, 'b2'), 'R3');
188
assertEqualRanges(result[3], foldRange(30, 39, true, FoldSource.recovered, 'b3'), 'R3');
189
assertEqualRanges(result[4], foldRange(35, 39, true, FoldSource.recovered, 'a3'), 'R4');
190
});
191
192
test('sanitizeAndMerge4', () => {
193
const regionSet1: FoldRange[] = [
194
foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid
195
];
196
const regionSet2: FoldRange[] = [
197
foldRange(20, 28, true, FoldSource.provider, 'b1'), // hidden
198
foldRange(30, 38, true, FoldSource.provider, 'b2'), // hidden
199
];
200
const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100);
201
assert.strictEqual(result.length, 3, 'result length4');
202
assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'R1');
203
assertEqualRanges(result[1], foldRange(20, 28, true, FoldSource.recovered, 'b1'), 'R2');
204
assertEqualRanges(result[2], foldRange(30, 38, true, FoldSource.recovered, 'b2'), 'R3');
205
});
206
207
});
208
209