Path: blob/main/extensions/git-base/src/test/foldingProvider.test.ts
4774 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*--------------------------------------------------------------------------------------------*/45import 'mocha';6import * as assert from 'assert';7import * as vscode from 'vscode';8import { GitCommitFoldingProvider } from '../foldingProvider';910suite('GitCommitFoldingProvider', () => {1112function createMockDocument(content: string): vscode.TextDocument {13const lines = content.split('\n');14return {15lineCount: lines.length,16lineAt: (index: number) => ({17text: lines[index] || '',18lineNumber: index19}),20} as vscode.TextDocument;21}2223const mockContext: vscode.FoldingContext = {} as vscode.FoldingContext;24const mockToken: vscode.CancellationToken = { isCancellationRequested: false } as vscode.CancellationToken;2526test('empty document returns no folding ranges', () => {27const provider = new GitCommitFoldingProvider();28const doc = createMockDocument('');29const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken);3031assert.strictEqual(Array.isArray(ranges) ? ranges.length : 0, 0);32});3334test('single line document returns no folding ranges', () => {35const provider = new GitCommitFoldingProvider();36const doc = createMockDocument('commit message');37const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken);3839assert.strictEqual(Array.isArray(ranges) ? ranges.length : 0, 0);40});4142test('single comment line returns no folding ranges', () => {43const provider = new GitCommitFoldingProvider();44const doc = createMockDocument('# Comment');45const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken);4647assert.strictEqual(Array.isArray(ranges) ? ranges.length : 0, 0);48});4950test('two comment lines create one folding range', () => {51const provider = new GitCommitFoldingProvider();52const content = '# Comment 1\n# Comment 2';53const doc = createMockDocument(content);54const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];5556assert.strictEqual(ranges.length, 1);57assert.strictEqual(ranges[0].start, 0);58assert.strictEqual(ranges[0].end, 1);59assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);60});6162test('multiple comment lines create one folding range', () => {63const provider = new GitCommitFoldingProvider();64const content = '# Comment 1\n# Comment 2\n# Comment 3\n# Comment 4';65const doc = createMockDocument(content);66const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];6768assert.strictEqual(ranges.length, 1);69assert.strictEqual(ranges[0].start, 0);70assert.strictEqual(ranges[0].end, 3);71assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);72});7374test('comment block followed by content', () => {75const provider = new GitCommitFoldingProvider();76const content = '# Comment 1\n# Comment 2\nCommit message';77const doc = createMockDocument(content);78const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];7980assert.strictEqual(ranges.length, 1);81assert.strictEqual(ranges[0].start, 0);82assert.strictEqual(ranges[0].end, 1);83assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);84});8586test('comment block at end of document', () => {87const provider = new GitCommitFoldingProvider();88const content = 'Commit message\n\n# Comment 1\n# Comment 2';89const doc = createMockDocument(content);90const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];9192assert.strictEqual(ranges.length, 1);93assert.strictEqual(ranges[0].start, 2);94assert.strictEqual(ranges[0].end, 3);95assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);96});9798test('multiple separated comment blocks', () => {99const provider = new GitCommitFoldingProvider();100const content = '# Comment 1\n# Comment 2\n\nCommit message\n\n# Comment 3\n# Comment 4';101const doc = createMockDocument(content);102const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];103104assert.strictEqual(ranges.length, 2);105assert.strictEqual(ranges[0].start, 0);106assert.strictEqual(ranges[0].end, 1);107assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);108assert.strictEqual(ranges[1].start, 5);109assert.strictEqual(ranges[1].end, 6);110assert.strictEqual(ranges[1].kind, vscode.FoldingRangeKind.Comment);111});112113test('single diff line returns no folding ranges', () => {114const provider = new GitCommitFoldingProvider();115const doc = createMockDocument('diff --git a/file.txt b/file.txt');116const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken);117118assert.strictEqual(Array.isArray(ranges) ? ranges.length : 0, 0);119});120121test('diff block with content creates folding range', () => {122const provider = new GitCommitFoldingProvider();123const content = 'diff --git a/file.txt b/file.txt\nindex 1234..5678\n--- a/file.txt\n+++ b/file.txt';124const doc = createMockDocument(content);125const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];126127assert.strictEqual(ranges.length, 1);128assert.strictEqual(ranges[0].start, 0);129assert.strictEqual(ranges[0].end, 3);130assert.strictEqual(ranges[0].kind, undefined); // Diff blocks don't have a specific kind131});132133test('multiple diff blocks', () => {134const provider = new GitCommitFoldingProvider();135const content = [136'diff --git a/file1.txt b/file1.txt',137'--- a/file1.txt',138'+++ b/file1.txt',139'diff --git a/file2.txt b/file2.txt',140'--- a/file2.txt',141'+++ b/file2.txt'142].join('\n');143const doc = createMockDocument(content);144const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];145146assert.strictEqual(ranges.length, 2);147assert.strictEqual(ranges[0].start, 0);148assert.strictEqual(ranges[0].end, 2);149assert.strictEqual(ranges[1].start, 3);150assert.strictEqual(ranges[1].end, 5);151});152153test('diff block at end of document', () => {154const provider = new GitCommitFoldingProvider();155const content = [156'Commit message',157'',158'diff --git a/file.txt b/file.txt',159'--- a/file.txt',160'+++ b/file.txt'161].join('\n');162const doc = createMockDocument(content);163const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];164165assert.strictEqual(ranges.length, 1);166assert.strictEqual(ranges[0].start, 2);167assert.strictEqual(ranges[0].end, 4);168});169170test('realistic git commit message with comments and verbose diff', () => {171const provider = new GitCommitFoldingProvider();172const content = [173'Add folding support for git commit messages',174'',175'# Please enter the commit message for your changes. Lines starting',176'# with \'#\' will be ignored, and an empty message aborts the commit.',177'#',178'# On branch main',179'# Changes to be committed:',180'#\tmodified: extension.ts',181'#\tnew file: foldingProvider.ts',182'#',183'# ------------------------ >8 ------------------------',184'# Do not modify or remove the line above.',185'# Everything below it will be ignored.',186'diff --git a/extensions/git-base/src/extension.ts b/extensions/git-base/src/extension.ts',187'index 17ffb89..453d8f7 100644',188'--- a/extensions/git-base/src/extension.ts',189'+++ b/extensions/git-base/src/extension.ts',190'@@ -3,14 +3,20 @@',191' * Licensed under the MIT License.',192'-import { ExtensionContext } from \'vscode\';',193'+import { ExtensionContext, languages } from \'vscode\';',194'diff --git a/extensions/git-base/src/foldingProvider.ts b/extensions/git-base/src/foldingProvider.ts',195'new file mode 100644',196'index 0000000..2c4a9c3',197'--- /dev/null',198'+++ b/extensions/git-base/src/foldingProvider.ts'199].join('\n');200const doc = createMockDocument(content);201const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];202203// Should have one comment block and two diff blocks204assert.strictEqual(ranges.length, 3);205206// Comment block (lines 2-12)207assert.strictEqual(ranges[0].start, 2);208assert.strictEqual(ranges[0].end, 12);209assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);210211// First diff block (lines 13-20)212assert.strictEqual(ranges[1].start, 13);213assert.strictEqual(ranges[1].end, 20);214assert.strictEqual(ranges[1].kind, undefined);215216// Second diff block (lines 21-25)217assert.strictEqual(ranges[2].start, 21);218assert.strictEqual(ranges[2].end, 25);219assert.strictEqual(ranges[2].kind, undefined);220});221222test('mixed comment and diff content', () => {223const provider = new GitCommitFoldingProvider();224const content = [225'Fix bug in parser',226'',227'# Comment 1',228'# Comment 2',229'',230'diff --git a/file.txt b/file.txt',231'--- a/file.txt',232'+++ b/file.txt',233'',234'# Comment 3',235'# Comment 4'236].join('\n');237const doc = createMockDocument(content);238const ranges = provider.provideFoldingRanges(doc, mockContext, mockToken) as vscode.FoldingRange[];239240assert.strictEqual(ranges.length, 3);241242// First comment block243assert.strictEqual(ranges[0].start, 2);244assert.strictEqual(ranges[0].end, 3);245assert.strictEqual(ranges[0].kind, vscode.FoldingRangeKind.Comment);246247// Diff block248assert.strictEqual(ranges[1].start, 5);249assert.strictEqual(ranges[1].end, 8);250assert.strictEqual(ranges[1].kind, undefined);251252// Second comment block253assert.strictEqual(ranges[2].start, 9);254assert.strictEqual(ranges[2].end, 10);255assert.strictEqual(ranges[2].kind, vscode.FoldingRangeKind.Comment);256});257});258259260