Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/chronicle/common/test/sessionStoreTracking.spec.ts
13405 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 { extractFilePath, extractRefsFromMcpTool, extractRefsFromTerminal, extractRepoFromMcpTool, isGitHubMcpTool } from '../sessionStoreTracking';
8
9
describe('extractFilePath', () => {
10
it('extracts filePath from replace_string_in_file', () => {
11
expect(extractFilePath('replace_string_in_file', { filePath: '/src/foo.ts', oldString: 'a', newString: 'b' }))
12
.toBe('/src/foo.ts');
13
});
14
15
it('extracts filePath from multi_replace_string_in_file replacements array', () => {
16
expect(extractFilePath('multi_replace_string_in_file', {
17
explanation: 'fix imports',
18
replacements: [
19
{ filePath: '/src/bar.ts', oldString: 'a', newString: 'b' },
20
{ filePath: '/src/baz.ts', oldString: 'c', newString: 'd' },
21
]
22
})).toBe('/src/bar.ts');
23
});
24
25
it('extracts filePath from insert_edit_into_file', () => {
26
expect(extractFilePath('insert_edit_into_file', { filePath: '/src/edit.ts', code: '// new' }))
27
.toBe('/src/edit.ts');
28
});
29
30
it('extracts filePath from create_file', () => {
31
expect(extractFilePath('create_file', { filePath: '/src/new.ts', content: '' }))
32
.toBe('/src/new.ts');
33
});
34
35
it('extracts filePath from edit_notebook_file', () => {
36
expect(extractFilePath('edit_notebook_file', { filePath: '/nb.ipynb', editType: 'edit', cellId: 'c1' }))
37
.toBe('/nb.ipynb');
38
});
39
40
it('extracts filePath from read_file', () => {
41
expect(extractFilePath('read_file', { filePath: '/src/read.ts', startLine: 1, endLine: 10 }))
42
.toBe('/src/read.ts');
43
});
44
45
it('extracts path from list_dir', () => {
46
expect(extractFilePath('list_dir', { path: '/src' }))
47
.toBe('/src');
48
});
49
50
it('extracts dirPath from create_directory', () => {
51
expect(extractFilePath('create_directory', { dirPath: '/src/new-dir' }))
52
.toBe('/src/new-dir');
53
});
54
55
it('extracts file path from apply_patch input text', () => {
56
const input = '*** Begin Patch\n*** Update File: /src/hello.ts\n@@class Foo\n- bar\n+ baz\n*** End Patch';
57
expect(extractFilePath('apply_patch', { input }))
58
.toBe('/src/hello.ts');
59
});
60
61
it('extracts file path from apply_patch Add File', () => {
62
const input = '*** Begin Patch\n*** Add File: /src/new.ts\n+export const x = 1;\n*** End Patch';
63
expect(extractFilePath('apply_patch', { input }))
64
.toBe('/src/new.ts');
65
});
66
67
it('extracts file path from apply_patch Delete File', () => {
68
const input = '*** Begin Patch\n*** Delete File: /src/old.ts\n*** End Patch';
69
expect(extractFilePath('apply_patch', { input }))
70
.toBe('/src/old.ts');
71
});
72
73
it('falls back to filePath arg for apply_patch when present', () => {
74
expect(extractFilePath('apply_patch', { filePath: '/from/arg.ts', input: '*** Update File: /from/input.ts' }))
75
.toBe('/from/arg.ts');
76
});
77
78
it('extracts path from CLI str_replace_editor (backward compat)', () => {
79
expect(extractFilePath('str_replace_editor', { path: '/cli/file.py' }))
80
.toBe('/cli/file.py');
81
});
82
83
it('extracts path from CLI create tool (backward compat)', () => {
84
expect(extractFilePath('create', { path: '/cli/new.py' }))
85
.toBe('/cli/new.py');
86
});
87
88
it('returns undefined for unknown tools', () => {
89
expect(extractFilePath('run_in_terminal', { command: 'ls' }))
90
.toBeUndefined();
91
expect(extractFilePath('file_search', { query: '**/*.ts' }))
92
.toBeUndefined();
93
});
94
95
it('returns undefined for null args', () => {
96
expect(extractFilePath('create_file', null))
97
.toBeUndefined();
98
});
99
100
it('returns undefined when filePath is not a string', () => {
101
expect(extractFilePath('create_file', { filePath: 42 }))
102
.toBeUndefined();
103
});
104
});
105
106
describe('isGitHubMcpTool', () => {
107
it('matches mcp_github_ prefix (VS Code)', () => {
108
expect(isGitHubMcpTool('mcp_github_issue_write')).toBe(true);
109
expect(isGitHubMcpTool('mcp_github_create_pull_request')).toBe(true);
110
expect(isGitHubMcpTool('mcp_github_search_issues')).toBe(true);
111
});
112
113
it('matches github-mcp-server- prefix (CLI)', () => {
114
expect(isGitHubMcpTool('github-mcp-server-create_issue')).toBe(true);
115
});
116
117
it('rejects non-GitHub MCP tools', () => {
118
expect(isGitHubMcpTool('read_file')).toBe(false);
119
expect(isGitHubMcpTool('mcp_perplexity_ask')).toBe(false);
120
expect(isGitHubMcpTool('run_in_terminal')).toBe(false);
121
});
122
});
123
124
describe('extractRefsFromMcpTool', () => {
125
it('extracts PR ref from mcp_github_pull_request_read', () => {
126
const refs = extractRefsFromMcpTool('mcp_github_pull_request_read', { pullNumber: 42, owner: 'ms', repo: 'vscode' });
127
expect(refs).toEqual([{ ref_type: 'pr', ref_value: '42' }]);
128
});
129
130
it('extracts issue ref from mcp_github_issue_write', () => {
131
const refs = extractRefsFromMcpTool('mcp_github_issue_write', { issue_number: 123, owner: 'ms', repo: 'vscode' });
132
expect(refs).toEqual([{ ref_type: 'issue', ref_value: '123' }]);
133
});
134
135
it('extracts commit ref from mcp_github_get_commit', () => {
136
const refs = extractRefsFromMcpTool('mcp_github_get_commit', { sha: 'abc123', owner: 'ms', repo: 'vscode' });
137
expect(refs).toEqual([{ ref_type: 'commit', ref_value: 'abc123' }]);
138
});
139
140
it('returns empty for non-matching tool name', () => {
141
expect(extractRefsFromMcpTool('mcp_github_search_code', { query: 'foo' })).toEqual([]);
142
});
143
});
144
145
describe('extractRepoFromMcpTool', () => {
146
it('extracts owner/repo', () => {
147
expect(extractRepoFromMcpTool({ owner: 'microsoft', repo: 'vscode' }))
148
.toBe('microsoft/vscode');
149
});
150
151
it('returns undefined when missing', () => {
152
expect(extractRepoFromMcpTool({ owner: 'microsoft' })).toBeUndefined();
153
expect(extractRepoFromMcpTool({})).toBeUndefined();
154
});
155
});
156
157
describe('extractRefsFromTerminal', () => {
158
it('extracts PR ref from gh pr create output', () => {
159
const refs = extractRefsFromTerminal(
160
{ command: 'gh pr create --title "fix"' },
161
'https://github.com/microsoft/vscode/pull/999',
162
);
163
expect(refs).toEqual([{ ref_type: 'pr', ref_value: '999' }]);
164
});
165
166
it('extracts issue ref from gh issue create output', () => {
167
const refs = extractRefsFromTerminal(
168
{ command: 'gh issue create --title "bug"' },
169
'https://github.com/microsoft/vscode/issues/456',
170
);
171
expect(refs).toEqual([{ ref_type: 'issue', ref_value: '456' }]);
172
});
173
174
it('extracts commit SHA from git commit output', () => {
175
const refs = extractRefsFromTerminal(
176
{ command: 'git commit -m "fix"' },
177
'[main abc1234] fix\n 1 file changed',
178
);
179
expect(refs).toEqual([{ ref_type: 'commit', ref_value: 'abc1234' }]);
180
});
181
182
it('returns empty for unrelated commands', () => {
183
expect(extractRefsFromTerminal({ command: 'ls -la' }, 'output')).toEqual([]);
184
});
185
});
186
187