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/claudeRuntimeDataService.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 type { AgentInfo, Query } from '@anthropic-ai/claude-agent-sdk';
7
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
import { ILogService } from '../../../../../platform/log/common/logService';
9
import { mock } from '../../../../../util/common/test/simpleMock';
10
import { DisposableStore } from '../../../../../util/vs/base/common/lifecycle';
11
import { ClaudeRuntimeDataService } from '../claudeRuntimeDataService';
12
13
class TestLogService extends mock<ILogService>() {
14
override trace() { }
15
override error() { }
16
}
17
18
function createMockQuery(agents: AgentInfo[]): Pick<Query, 'supportedAgents'> {
19
return {
20
supportedAgents: vi.fn().mockResolvedValue(agents),
21
};
22
}
23
24
describe('ClaudeRuntimeDataService', () => {
25
let disposables: DisposableStore;
26
let service: ClaudeRuntimeDataService;
27
28
beforeEach(() => {
29
disposables = new DisposableStore();
30
service = disposables.add(new ClaudeRuntimeDataService(new TestLogService()));
31
});
32
33
afterEach(() => {
34
disposables.dispose();
35
});
36
37
it('returns empty agents before first update', () => {
38
expect(service.getAgents()).toEqual([]);
39
});
40
41
it('caches agents after update', async () => {
42
const agents: AgentInfo[] = [
43
{ name: 'Explore', description: 'Fast exploration' },
44
{ name: 'Review', description: 'Code review', model: 'claude-3.5-sonnet' },
45
];
46
await service.update(createMockQuery(agents) as Query);
47
48
expect(service.getAgents()).toEqual(agents);
49
});
50
51
it('fires onDidChange after update', async () => {
52
let fired = false;
53
disposables.add(service.onDidChange(() => { fired = true; }));
54
55
await service.update(createMockQuery([]) as Query);
56
expect(fired).toBe(true);
57
});
58
59
it('fires onDidChange even when supportedAgents fails', async () => {
60
let fired = false;
61
disposables.add(service.onDidChange(() => { fired = true; }));
62
63
const query = {
64
supportedAgents: vi.fn().mockRejectedValue(new Error('SDK error')),
65
};
66
await service.update(query as unknown as Query);
67
68
expect(fired).toBe(true);
69
// Previous cache should be preserved (empty in this case)
70
expect(service.getAgents()).toEqual([]);
71
});
72
73
it('preserves previous cache on error', async () => {
74
const agents: AgentInfo[] = [{ name: 'Explore', description: 'Agent' }];
75
await service.update(createMockQuery(agents) as Query);
76
77
const failingQuery = {
78
supportedAgents: vi.fn().mockRejectedValue(new Error('fail')),
79
};
80
await service.update(failingQuery as unknown as Query);
81
82
expect(service.getAgents()).toEqual(agents);
83
});
84
85
it('overwrites cache on subsequent updates', async () => {
86
await service.update(createMockQuery([{ name: 'A', description: 'First' }]) as Query);
87
expect(service.getAgents()).toHaveLength(1);
88
89
await service.update(createMockQuery([{ name: 'B', description: 'Second' }, { name: 'C', description: 'Third' }]) as Query);
90
expect(service.getAgents()).toHaveLength(2);
91
expect(service.getAgents()[0].name).toBe('B');
92
});
93
});
94
95