Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/chatSessions/claude/node/test/claudeProjectFolders.spec.ts
13406 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 { describe, expect, it } from 'vitest';
7
import { TestWorkspaceService } from '../../../../../platform/test/node/testWorkspaceService';
8
import { URI } from '../../../../../util/vs/base/common/uri';
9
import { FolderRepositoryMRUEntry, IFolderRepositoryManager } from '../../../../chatSessions/common/folderRepositoryManager';
10
import { computeFolderSlug, getProjectFolders } from '../claudeProjectFolders';
11
12
// #region MockFolderRepositoryManager
13
14
class MockFolderRepositoryManager implements IFolderRepositoryManager {
15
declare _serviceBrand: undefined;
16
private _mruEntries: FolderRepositoryMRUEntry[] = [];
17
18
setMRUEntries(entries: FolderRepositoryMRUEntry[]): void {
19
this._mruEntries = entries;
20
}
21
22
setNewSessionFolder(): void { }
23
deleteNewSessionFolder(): void { }
24
async getFolderRepository(): Promise<{ folder: undefined; repository: undefined; worktree: undefined; worktreeProperties: undefined; trusted: undefined }> { return { folder: undefined, repository: undefined, worktree: undefined, worktreeProperties: undefined, trusted: undefined }; }
25
async initializeFolderRepository(): Promise<{ folder: undefined; repository: undefined; worktree: undefined; worktreeProperties: undefined; trusted: undefined }> { return { folder: undefined, repository: undefined, worktree: undefined, worktreeProperties: undefined, trusted: undefined }; }
26
async initializeMultiRootFolderRepositories(): Promise<{ primary: { folder: undefined; repository: undefined; worktree: undefined; worktreeProperties: undefined; trusted: undefined }; additional: never[] }> { return { primary: { folder: undefined, repository: undefined, worktree: undefined, worktreeProperties: undefined, trusted: undefined }, additional: [] }; }
27
async getRepositoryInfo(): Promise<any> { return undefined; }
28
async getFolderMRU(): Promise<FolderRepositoryMRUEntry[]> { return this._mruEntries; }
29
}
30
31
// #endregion
32
33
describe('computeFolderSlug', () => {
34
it('converts a simple Unix path', () => {
35
const uri = URI.file('/Users/test/project');
36
expect(computeFolderSlug(uri)).toBe('-Users-test-project');
37
});
38
39
it('converts a path with spaces', () => {
40
const uri = URI.file('/Users/test/my project');
41
expect(computeFolderSlug(uri)).toBe('-Users-test-my-project');
42
});
43
44
it('converts a path with dots', () => {
45
const uri = URI.file('/Users/test/my.project');
46
expect(computeFolderSlug(uri)).toBe('-Users-test-my-project');
47
});
48
49
it('converts a Windows-style drive letter path', () => {
50
// On Windows, URI.file('C:/Users/test/project') produces path '/c:/Users/test/project'
51
const uri = URI.from({ scheme: 'file', path: '/c:/Users/test/project' });
52
expect(computeFolderSlug(uri)).toBe('C--Users-test-project');
53
});
54
55
it('uppercases the Windows drive letter', () => {
56
const uri = URI.from({ scheme: 'file', path: '/d:/projects/my-app' });
57
expect(computeFolderSlug(uri)).toBe('D--projects-my-app');
58
});
59
});
60
61
describe('getProjectFolders', () => {
62
it('returns slugs for single-root workspace', async () => {
63
const folderUri = URI.file('/Users/test/project');
64
const workspace = new TestWorkspaceService([folderUri]);
65
const folderManager = new MockFolderRepositoryManager();
66
67
const result = await getProjectFolders(workspace, folderManager);
68
69
expect(result).toHaveLength(1);
70
expect(result[0].folderUri.toString()).toBe(folderUri.toString());
71
expect(result[0].slug).toBe(computeFolderSlug(folderUri));
72
});
73
74
it('returns slugs for all folders in a multi-root workspace', async () => {
75
const folderA = URI.file('/Users/test/project-a');
76
const folderB = URI.file('/Users/test/project-b');
77
const workspace = new TestWorkspaceService([folderA, folderB]);
78
const folderManager = new MockFolderRepositoryManager();
79
80
const result = await getProjectFolders(workspace, folderManager);
81
82
expect(result).toHaveLength(2);
83
expect(result[0].folderUri.toString()).toBe(folderA.toString());
84
expect(result[0].slug).toBe(computeFolderSlug(folderA));
85
expect(result[1].folderUri.toString()).toBe(folderB.toString());
86
expect(result[1].slug).toBe(computeFolderSlug(folderB));
87
});
88
89
it('falls back to MRU entries for an empty workspace', async () => {
90
const mruFolder = URI.file('/Users/test/recent-project');
91
const workspace = new TestWorkspaceService([]);
92
const folderManager = new MockFolderRepositoryManager();
93
folderManager.setMRUEntries([{ folder: mruFolder, repository: undefined, lastAccessed: Date.now() }]);
94
95
const result = await getProjectFolders(workspace, folderManager);
96
97
expect(result).toHaveLength(1);
98
expect(result[0].folderUri.toString()).toBe(mruFolder.toString());
99
expect(result[0].slug).toBe(computeFolderSlug(mruFolder));
100
});
101
102
it('returns empty array for empty workspace with no MRU entries', async () => {
103
const workspace = new TestWorkspaceService([]);
104
const folderManager = new MockFolderRepositoryManager();
105
106
const result = await getProjectFolders(workspace, folderManager);
107
108
expect(result).toHaveLength(0);
109
});
110
111
it('workspace folders take priority over MRU entries', async () => {
112
const workspaceFolder = URI.file('/Users/test/workspace');
113
const mruFolder = URI.file('/Users/test/mru-folder');
114
const workspace = new TestWorkspaceService([workspaceFolder]);
115
const folderManager = new MockFolderRepositoryManager();
116
folderManager.setMRUEntries([{ folder: mruFolder, repository: undefined, lastAccessed: Date.now() }]);
117
118
const result = await getProjectFolders(workspace, folderManager);
119
120
expect(result).toHaveLength(1);
121
expect(result[0].folderUri.toString()).toBe(workspaceFolder.toString());
122
});
123
});
124
125