Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/test/browser/notebookFolding.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 { CellKind } from '../../common/notebookCommon.js';
8
import { setupInstantiationService, withTestNotebook } from './testNotebookEditor.js';
9
import { IUndoRedoService } from '../../../../../platform/undoRedo/common/undoRedo.js';
10
import { FoldingModel, updateFoldingStateAtIndex } from '../../browser/viewModel/foldingModel.js';
11
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
12
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
13
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
14
15
suite('Notebook Folding', () => {
16
let disposables: DisposableStore;
17
let instantiationService: TestInstantiationService;
18
19
teardown(() => disposables.dispose());
20
21
ensureNoDisposablesAreLeakedInTestSuite();
22
23
setup(() => {
24
disposables = new DisposableStore();
25
instantiationService = setupInstantiationService(disposables);
26
instantiationService.spy(IUndoRedoService, 'pushElement');
27
});
28
29
30
test('Folding based on markdown cells', async function () {
31
await withTestNotebook(
32
[
33
['# header 1', 'markdown', CellKind.Markup, [], {}],
34
['body', 'markdown', CellKind.Markup, [], {}],
35
['## header 2.1', 'markdown', CellKind.Markup, [], {}],
36
['body 2', 'markdown', CellKind.Markup, [], {}],
37
['body 3', 'markdown', CellKind.Markup, [], {}],
38
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
39
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
40
],
41
(editor, viewModel, ds) => {
42
const foldingController = ds.add(new FoldingModel());
43
foldingController.attachViewModel(viewModel);
44
45
assert.strictEqual(foldingController.regions.findRange(1), 0);
46
assert.strictEqual(foldingController.regions.findRange(2), 0);
47
assert.strictEqual(foldingController.regions.findRange(3), 1);
48
assert.strictEqual(foldingController.regions.findRange(4), 1);
49
assert.strictEqual(foldingController.regions.findRange(5), 1);
50
assert.strictEqual(foldingController.regions.findRange(6), 2);
51
assert.strictEqual(foldingController.regions.findRange(7), 2);
52
}
53
);
54
});
55
56
test('Folding not based on code cells', async function () {
57
await withTestNotebook(
58
[
59
['# header 1', 'markdown', CellKind.Markup, [], {}],
60
['body', 'markdown', CellKind.Markup, [], {}],
61
['# comment 1', 'python', CellKind.Code, [], {}],
62
['body 2', 'markdown', CellKind.Markup, [], {}],
63
['body 3\n```\n## comment 2\n```', 'markdown', CellKind.Markup, [], {}],
64
['body 4', 'markdown', CellKind.Markup, [], {}],
65
['## header 2.1', 'markdown', CellKind.Markup, [], {}],
66
['var e = 7;', 'python', CellKind.Code, [], {}],
67
],
68
(editor, viewModel, ds) => {
69
const foldingController = ds.add(new FoldingModel());
70
foldingController.attachViewModel(viewModel);
71
72
assert.strictEqual(foldingController.regions.findRange(1), 0);
73
assert.strictEqual(foldingController.regions.findRange(2), 0);
74
assert.strictEqual(foldingController.regions.findRange(3), 0);
75
assert.strictEqual(foldingController.regions.findRange(4), 0);
76
assert.strictEqual(foldingController.regions.findRange(5), 0);
77
assert.strictEqual(foldingController.regions.findRange(6), 0);
78
assert.strictEqual(foldingController.regions.findRange(7), 1);
79
assert.strictEqual(foldingController.regions.findRange(8), 1);
80
}
81
);
82
});
83
84
test('Top level header in a cell wins', async function () {
85
await withTestNotebook(
86
[
87
['# header 1', 'markdown', CellKind.Markup, [], {}],
88
['body', 'markdown', CellKind.Markup, [], {}],
89
['## header 2.1\n# header3', 'markdown', CellKind.Markup, [], {}],
90
['body 2', 'markdown', CellKind.Markup, [], {}],
91
['body 3', 'markdown', CellKind.Markup, [], {}],
92
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
93
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
94
],
95
(editor, viewModel, ds) => {
96
const foldingController = ds.add(new FoldingModel());
97
foldingController.attachViewModel(viewModel);
98
99
assert.strictEqual(foldingController.regions.findRange(1), 0);
100
assert.strictEqual(foldingController.regions.findRange(2), 0);
101
assert.strictEqual(foldingController.regions.getEndLineNumber(0), 2);
102
103
assert.strictEqual(foldingController.regions.findRange(3), 1);
104
assert.strictEqual(foldingController.regions.findRange(4), 1);
105
assert.strictEqual(foldingController.regions.findRange(5), 1);
106
assert.strictEqual(foldingController.regions.getEndLineNumber(1), 7);
107
108
assert.strictEqual(foldingController.regions.findRange(6), 2);
109
assert.strictEqual(foldingController.regions.findRange(7), 2);
110
assert.strictEqual(foldingController.regions.getEndLineNumber(2), 7);
111
}
112
);
113
});
114
115
test('Folding', async function () {
116
await withTestNotebook(
117
[
118
['# header 1', 'markdown', CellKind.Markup, [], {}],
119
['body', 'markdown', CellKind.Markup, [], {}],
120
['## header 2.1', 'markdown', CellKind.Markup, [], {}],
121
['body 2', 'markdown', CellKind.Markup, [], {}],
122
['body 3', 'markdown', CellKind.Markup, [], {}],
123
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
124
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
125
],
126
(editor, viewModel, ds) => {
127
const foldingModel = ds.add(new FoldingModel());
128
foldingModel.attachViewModel(viewModel);
129
updateFoldingStateAtIndex(foldingModel, 0, true);
130
viewModel.updateFoldingRanges(foldingModel.regions);
131
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
132
{ start: 1, end: 6 }
133
]);
134
}
135
);
136
137
await withTestNotebook(
138
[
139
['# header 1', 'markdown', CellKind.Markup, [], {}],
140
['body', 'markdown', CellKind.Markup, [], {}],
141
['## header 2.1\n', 'markdown', CellKind.Markup, [], {}],
142
['body 2', 'markdown', CellKind.Markup, [], {}],
143
['body 3', 'markdown', CellKind.Markup, [], {}],
144
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
145
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
146
],
147
(editor, viewModel, ds) => {
148
const foldingModel = ds.add(new FoldingModel());
149
foldingModel.attachViewModel(viewModel);
150
updateFoldingStateAtIndex(foldingModel, 2, true);
151
viewModel.updateFoldingRanges(foldingModel.regions);
152
153
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
154
{ start: 3, end: 4 }
155
]);
156
}
157
);
158
159
await withTestNotebook(
160
[
161
['# header 1', 'markdown', CellKind.Markup, [], {}],
162
['body', 'markdown', CellKind.Markup, [], {}],
163
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
164
['body 2', 'markdown', CellKind.Markup, [], {}],
165
['body 3', 'markdown', CellKind.Markup, [], {}],
166
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
167
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
168
],
169
(editor, viewModel, ds) => {
170
const foldingModel = ds.add(new FoldingModel());
171
foldingModel.attachViewModel(viewModel);
172
updateFoldingStateAtIndex(foldingModel, 2, true);
173
viewModel.updateFoldingRanges(foldingModel.regions);
174
175
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
176
{ start: 3, end: 6 }
177
]);
178
}
179
);
180
});
181
182
test('Nested Folding', async function () {
183
await withTestNotebook(
184
[
185
['# header 1', 'markdown', CellKind.Markup, [], {}],
186
['body', 'markdown', CellKind.Markup, [], {}],
187
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
188
['body 2', 'markdown', CellKind.Markup, [], {}],
189
['body 3', 'markdown', CellKind.Markup, [], {}],
190
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
191
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
192
],
193
(editor, viewModel, ds) => {
194
const foldingModel = ds.add(new FoldingModel());
195
foldingModel.attachViewModel(viewModel);
196
updateFoldingStateAtIndex(foldingModel, 0, true);
197
viewModel.updateFoldingRanges(foldingModel.regions);
198
199
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
200
{ start: 1, end: 1 }
201
]);
202
203
updateFoldingStateAtIndex(foldingModel, 5, true);
204
updateFoldingStateAtIndex(foldingModel, 2, true);
205
viewModel.updateFoldingRanges(foldingModel.regions);
206
207
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
208
{ start: 1, end: 1 },
209
{ start: 3, end: 6 }
210
]);
211
212
updateFoldingStateAtIndex(foldingModel, 2, false);
213
viewModel.updateFoldingRanges(foldingModel.regions);
214
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
215
{ start: 1, end: 1 },
216
{ start: 6, end: 6 }
217
]);
218
219
// viewModel.insertCell(7, new TestCell(viewModel.viewType, 7, ['var c = 8;'], 'markdown', CellKind.Code, []), true);
220
221
// assert.deepStrictEqual(viewModel.getHiddenRanges(), [
222
// { start: 1, end: 1 },
223
// { start: 6, end: 7 }
224
// ]);
225
226
// viewModel.insertCell(1, new TestCell(viewModel.viewType, 8, ['var c = 9;'], 'markdown', CellKind.Code, []), true);
227
// assert.deepStrictEqual(viewModel.getHiddenRanges(), [
228
// // the first collapsed range is now expanded as we insert content into it.
229
// // { start: 1,},
230
// { start: 7, end: 8 }
231
// ]);
232
}
233
);
234
});
235
236
test('Folding Memento', async function () {
237
await withTestNotebook(
238
[
239
['# header 1', 'markdown', CellKind.Markup, [], {}],
240
['body', 'markdown', CellKind.Markup, [], {}],
241
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
242
['body 2', 'markdown', CellKind.Markup, [], {}],
243
['body 3', 'markdown', CellKind.Markup, [], {}],
244
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
245
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
246
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
247
['body 2', 'markdown', CellKind.Markup, [], {}],
248
['body 3', 'markdown', CellKind.Markup, [], {}],
249
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
250
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
251
],
252
(editor, viewModel, ds) => {
253
const foldingModel = ds.add(new FoldingModel());
254
foldingModel.attachViewModel(viewModel);
255
foldingModel.applyMemento([{ start: 2, end: 6 }]);
256
viewModel.updateFoldingRanges(foldingModel.regions);
257
258
// Note that hidden ranges !== folding ranges
259
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
260
{ start: 3, end: 6 }
261
]);
262
}
263
);
264
265
await withTestNotebook(
266
[
267
['# header 1', 'markdown', CellKind.Markup, [], {}],
268
['body', 'markdown', CellKind.Markup, [], {}],
269
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
270
['body 2', 'markdown', CellKind.Markup, [], {}],
271
['body 3', 'markdown', CellKind.Markup, [], {}],
272
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
273
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
274
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
275
['body 2', 'markdown', CellKind.Markup, [], {}],
276
['body 3', 'markdown', CellKind.Markup, [], {}],
277
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
278
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
279
],
280
(editor, viewModel, ds) => {
281
const foldingModel = ds.add(new FoldingModel());
282
foldingModel.attachViewModel(viewModel);
283
foldingModel.applyMemento([
284
{ start: 5, end: 6 },
285
{ start: 10, end: 11 },
286
]);
287
viewModel.updateFoldingRanges(foldingModel.regions);
288
289
// Note that hidden ranges !== folding ranges
290
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
291
{ start: 6, end: 6 },
292
{ start: 11, end: 11 }
293
]);
294
}
295
);
296
297
await withTestNotebook(
298
[
299
['# header 1', 'markdown', CellKind.Markup, [], {}],
300
['body', 'markdown', CellKind.Markup, [], {}],
301
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
302
['body 2', 'markdown', CellKind.Markup, [], {}],
303
['body 3', 'markdown', CellKind.Markup, [], {}],
304
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
305
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
306
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
307
['body 2', 'markdown', CellKind.Markup, [], {}],
308
['body 3', 'markdown', CellKind.Markup, [], {}],
309
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
310
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
311
],
312
(editor, viewModel, ds) => {
313
const foldingModel = ds.add(new FoldingModel());
314
foldingModel.attachViewModel(viewModel);
315
foldingModel.applyMemento([
316
{ start: 5, end: 6 },
317
{ start: 7, end: 11 },
318
]);
319
viewModel.updateFoldingRanges(foldingModel.regions);
320
321
// Note that hidden ranges !== folding ranges
322
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
323
{ start: 6, end: 6 },
324
{ start: 8, end: 11 }
325
]);
326
}
327
);
328
});
329
330
test('View Index', async function () {
331
await withTestNotebook(
332
[
333
['# header 1', 'markdown', CellKind.Markup, [], {}],
334
['body', 'markdown', CellKind.Markup, [], {}],
335
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
336
['body 2', 'markdown', CellKind.Markup, [], {}],
337
['body 3', 'markdown', CellKind.Markup, [], {}],
338
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
339
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
340
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
341
['body 2', 'markdown', CellKind.Markup, [], {}],
342
['body 3', 'markdown', CellKind.Markup, [], {}],
343
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
344
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
345
],
346
(editor, viewModel, ds) => {
347
const foldingModel = ds.add(new FoldingModel());
348
foldingModel.attachViewModel(viewModel);
349
foldingModel.applyMemento([{ start: 2, end: 6 }]);
350
viewModel.updateFoldingRanges(foldingModel.regions);
351
352
// Note that hidden ranges !== folding ranges
353
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
354
{ start: 3, end: 6 }
355
]);
356
357
assert.strictEqual(viewModel.getNextVisibleCellIndex(1), 2);
358
assert.strictEqual(viewModel.getNextVisibleCellIndex(2), 7);
359
assert.strictEqual(viewModel.getNextVisibleCellIndex(3), 7);
360
assert.strictEqual(viewModel.getNextVisibleCellIndex(4), 7);
361
assert.strictEqual(viewModel.getNextVisibleCellIndex(5), 7);
362
assert.strictEqual(viewModel.getNextVisibleCellIndex(6), 7);
363
assert.strictEqual(viewModel.getNextVisibleCellIndex(7), 8);
364
}
365
);
366
367
await withTestNotebook(
368
[
369
['# header 1', 'markdown', CellKind.Markup, [], {}],
370
['body', 'markdown', CellKind.Markup, [], {}],
371
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
372
['body 2', 'markdown', CellKind.Markup, [], {}],
373
['body 3', 'markdown', CellKind.Markup, [], {}],
374
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
375
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
376
['# header 2.1\n', 'markdown', CellKind.Markup, [], {}],
377
['body 2', 'markdown', CellKind.Markup, [], {}],
378
['body 3', 'markdown', CellKind.Markup, [], {}],
379
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
380
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
381
],
382
(editor, viewModel, ds) => {
383
const foldingModel = ds.add(new FoldingModel());
384
foldingModel.attachViewModel(viewModel);
385
foldingModel.applyMemento([
386
{ start: 5, end: 6 },
387
{ start: 10, end: 11 },
388
]);
389
390
viewModel.updateFoldingRanges(foldingModel.regions);
391
392
// Note that hidden ranges !== folding ranges
393
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
394
{ start: 6, end: 6 },
395
{ start: 11, end: 11 }
396
]);
397
398
// folding ranges
399
// [5, 6]
400
// [10, 11]
401
assert.strictEqual(viewModel.getNextVisibleCellIndex(4), 5);
402
assert.strictEqual(viewModel.getNextVisibleCellIndex(5), 7);
403
assert.strictEqual(viewModel.getNextVisibleCellIndex(6), 7);
404
405
assert.strictEqual(viewModel.getNextVisibleCellIndex(9), 10);
406
assert.strictEqual(viewModel.getNextVisibleCellIndex(10), 12);
407
assert.strictEqual(viewModel.getNextVisibleCellIndex(11), 12);
408
}
409
);
410
});
411
});
412
413