Path: blob/main/src/vs/editor/contrib/folding/test/browser/syntaxFold.test.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import assert from 'assert';5import { CancellationToken } from '../../../../../base/common/cancellation.js';6import { ITextModel } from '../../../../common/model.js';7import { FoldingContext, FoldingRange, FoldingRangeProvider, ProviderResult } from '../../../../common/languages.js';8import { SyntaxRangeProvider } from '../../browser/syntaxRangeProvider.js';9import { createTextModel } from '../../../../test/common/testTextModel.js';10import { FoldingLimitReporter } from '../../browser/folding.js';11import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';1213interface IndentRange {14start: number;15end: number;16}1718class TestFoldingRangeProvider implements FoldingRangeProvider {19constructor(private model: ITextModel, private ranges: IndentRange[]) {20}2122provideFoldingRanges(model: ITextModel, context: FoldingContext, token: CancellationToken): ProviderResult<FoldingRange[]> {23if (model === this.model) {24return this.ranges;25}26return null;27}28}2930suite('Syntax folding', () => {31ensureNoDisposablesAreLeakedInTestSuite();3233function r(start: number, end: number): IndentRange {34return { start, end };35}3637test('Limit by nesting level', async () => {38const lines = [39/* 1*/ '{',40/* 2*/ ' A',41/* 3*/ ' {',42/* 4*/ ' {',43/* 5*/ ' B',44/* 6*/ ' }',45/* 7*/ ' {',46/* 8*/ ' A',47/* 9*/ ' {',48/* 10*/ ' A',49/* 11*/ ' }',50/* 12*/ ' {',51/* 13*/ ' {',52/* 14*/ ' {',53/* 15*/ ' A',54/* 16*/ ' }',55/* 17*/ ' }',56/* 18*/ ' }',57/* 19*/ ' }',58/* 20*/ ' }',59/* 21*/ '}',60/* 22*/ '{',61/* 23*/ ' A',62/* 24*/ '}',63];6465const r1 = r(1, 20); //066const r2 = r(3, 19); //167const r3 = r(4, 5); //268const r4 = r(7, 18); //269const r5 = r(9, 10); //370const r6 = r(12, 17); //471const r7 = r(13, 16); //572const r8 = r(14, 15); //673const r9 = r(22, 23); //07475const model = createTextModel(lines.join('\n'));76const ranges = [r1, r2, r3, r4, r5, r6, r7, r8, r9];77const providers = [new TestFoldingRangeProvider(model, ranges)];7879async function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {80let reported: number | false = false;81const foldingRangesLimit: FoldingLimitReporter = { limit: maxEntries, update: (computed, limited) => reported = limited };82const syntaxRangeProvider = new SyntaxRangeProvider(model, providers, () => { }, foldingRangesLimit, undefined);83try {84const indentRanges = await syntaxRangeProvider.compute(CancellationToken.None);85const actual: IndentRange[] = [];86if (indentRanges) {87for (let i = 0; i < indentRanges.length; i++) {88actual.push({ start: indentRanges.getStartLineNumber(i), end: indentRanges.getEndLineNumber(i) });89}90assert.equal(reported, 9 <= maxEntries ? false : maxEntries, 'limited');91}92assert.deepStrictEqual(actual, expectedRanges, message);93} finally {94syntaxRangeProvider.dispose();95}9697}9899await assertLimit(1000, [r1, r2, r3, r4, r5, r6, r7, r8, r9], '1000');100await assertLimit(9, [r1, r2, r3, r4, r5, r6, r7, r8, r9], '9');101await assertLimit(8, [r1, r2, r3, r4, r5, r6, r7, r9], '8');102await assertLimit(7, [r1, r2, r3, r4, r5, r6, r9], '7');103await assertLimit(6, [r1, r2, r3, r4, r5, r9], '6');104await assertLimit(5, [r1, r2, r3, r4, r9], '5');105await assertLimit(4, [r1, r2, r3, r9], '4');106await assertLimit(3, [r1, r2, r9], '3');107await assertLimit(2, [r1, r9], '2');108await assertLimit(1, [r1], '1');109await assertLimit(0, [], '0');110111model.dispose();112});113});114115116