96 lines
3.0 KiB
JavaScript
96 lines
3.0 KiB
JavaScript
import { jest } from '@jest/globals';
|
|
|
|
// Mock the base provider to avoid circular dependencies
|
|
jest.unstable_mockModule('../../src/ai-providers/base-provider.js', () => ({
|
|
BaseAIProvider: class {
|
|
constructor() {
|
|
this.name = 'Base Provider';
|
|
}
|
|
handleError(context, error) {
|
|
throw error;
|
|
}
|
|
}
|
|
}));
|
|
|
|
// Mock the claude-code SDK to simulate it not being installed
|
|
jest.unstable_mockModule('@anthropic-ai/claude-code', () => {
|
|
throw new Error("Cannot find module '@anthropic-ai/claude-code'");
|
|
});
|
|
|
|
// Import after mocking
|
|
const { ClaudeCodeProvider } = await import(
|
|
'../../src/ai-providers/claude-code.js'
|
|
);
|
|
|
|
describe('Claude Code Optional Dependency Integration', () => {
|
|
describe('when @anthropic-ai/claude-code is not installed', () => {
|
|
it('should allow provider instantiation', () => {
|
|
// Provider should instantiate without error
|
|
const provider = new ClaudeCodeProvider();
|
|
expect(provider).toBeDefined();
|
|
expect(provider.name).toBe('Claude Code');
|
|
});
|
|
|
|
it('should allow client creation', () => {
|
|
const provider = new ClaudeCodeProvider();
|
|
// Client creation should work
|
|
const client = provider.getClient({});
|
|
expect(client).toBeDefined();
|
|
expect(typeof client).toBe('function');
|
|
});
|
|
|
|
it('should fail with clear error when trying to use the model', async () => {
|
|
const provider = new ClaudeCodeProvider();
|
|
const client = provider.getClient({});
|
|
const model = client('opus');
|
|
|
|
// The actual usage should fail with the lazy loading error
|
|
await expect(
|
|
model.doGenerate({
|
|
prompt: [{ role: 'user', content: 'Hello' }],
|
|
mode: { type: 'regular' }
|
|
})
|
|
).rejects.toThrow(
|
|
"Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
|
|
);
|
|
});
|
|
|
|
it('should provide helpful error message for streaming', async () => {
|
|
const provider = new ClaudeCodeProvider();
|
|
const client = provider.getClient({});
|
|
const model = client('sonnet');
|
|
|
|
await expect(
|
|
model.doStream({
|
|
prompt: [{ role: 'user', content: 'Hello' }],
|
|
mode: { type: 'regular' }
|
|
})
|
|
).rejects.toThrow(
|
|
"Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider."
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('provider behavior', () => {
|
|
it('should not require API key', () => {
|
|
const provider = new ClaudeCodeProvider();
|
|
// Should not throw
|
|
expect(() => provider.validateAuth()).not.toThrow();
|
|
expect(() => provider.validateAuth({ apiKey: null })).not.toThrow();
|
|
});
|
|
|
|
it('should work with ai-services-unified when provider is configured', async () => {
|
|
// This tests that the provider can be selected but will fail appropriately
|
|
// when the actual model is used
|
|
const provider = new ClaudeCodeProvider();
|
|
expect(provider).toBeDefined();
|
|
|
|
// In real usage, ai-services-unified would:
|
|
// 1. Get the provider instance (works)
|
|
// 2. Call provider.getClient() (works)
|
|
// 3. Create a model (works)
|
|
// 4. Try to generate (fails with clear error)
|
|
});
|
|
});
|
|
});
|