Refactor error handling, client, and tests for Ollama integration
This commit is contained in:
+92
-29
@@ -1,50 +1,113 @@
|
||||
// Enhanced Obsidian mock for testing
|
||||
|
||||
// Mock Vault
|
||||
export class Vault {
|
||||
getMarkdownFiles() {
|
||||
return [];
|
||||
}
|
||||
getMarkdownFiles: () => any[];
|
||||
read: (file: any) => Promise<string>;
|
||||
create: (path: string, content: string) => Promise<any>;
|
||||
|
||||
async read(file: any) {
|
||||
return '';
|
||||
}
|
||||
|
||||
async create(path: string, content: string) {
|
||||
return null;
|
||||
constructor() {
|
||||
this.getMarkdownFiles = () => [];
|
||||
this.read = async () => '';
|
||||
this.create = async () => null;
|
||||
}
|
||||
}
|
||||
|
||||
// Mock Workspace
|
||||
export class Workspace {
|
||||
getLeaf() {
|
||||
return {
|
||||
getLeaf: () => any;
|
||||
|
||||
constructor() {
|
||||
this.getLeaf = () => ({
|
||||
setViewState: jest.fn(),
|
||||
};
|
||||
revealLeaf: jest.fn(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Mock App
|
||||
export class App {
|
||||
vault = new Vault();
|
||||
workspace = new Workspace();
|
||||
vault: Vault;
|
||||
workspace: Workspace;
|
||||
|
||||
constructor() {
|
||||
this.vault = new Vault();
|
||||
this.workspace = new Workspace();
|
||||
}
|
||||
}
|
||||
|
||||
// Mock WorkspaceLeaf
|
||||
export class WorkspaceLeaf {
|
||||
app: App;
|
||||
view: any;
|
||||
setViewState: jest.Mock;
|
||||
|
||||
constructor() {
|
||||
this.app = new App();
|
||||
this.view = null;
|
||||
this.setViewState = jest.fn();
|
||||
}
|
||||
}
|
||||
|
||||
// Mock ItemView - accepts a leaf and derives app from it
|
||||
export class ItemView {
|
||||
contentEl: HTMLElement = document.createElement('div');
|
||||
contentEl: HTMLElement;
|
||||
app: App;
|
||||
|
||||
constructor(leaf?: WorkspaceLeaf) {
|
||||
this.contentEl = document.createElement('div');
|
||||
if (leaf && leaf.app) {
|
||||
this.app = leaf.app;
|
||||
} else {
|
||||
this.app = new App();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mock Notice - can be called with `new Notice(msg)` or as a function
|
||||
export class Notice {
|
||||
message: string;
|
||||
|
||||
constructor(message: string) {
|
||||
this.message = message;
|
||||
// Also record via jest for testing
|
||||
(Notice as any).lastMessage = message;
|
||||
}
|
||||
}
|
||||
(Notice as any).lastMessage = '';
|
||||
|
||||
// Mock Setting
|
||||
export class Setting {
|
||||
containerEl: HTMLElement;
|
||||
|
||||
constructor(containerEl: HTMLElement) {
|
||||
this.containerEl = containerEl;
|
||||
}
|
||||
|
||||
setName(_name: string): this {
|
||||
return this;
|
||||
}
|
||||
|
||||
setDesc(_desc: string): this {
|
||||
return this;
|
||||
}
|
||||
|
||||
addText(_callback: (text: any) => void): this {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// TFile type
|
||||
export interface TFile {
|
||||
basename: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
// Plugin class (used by main.ts)
|
||||
export class Plugin {
|
||||
app: App;
|
||||
|
||||
constructor() {
|
||||
this.app = new App();
|
||||
}
|
||||
}
|
||||
|
||||
export class Notice {
|
||||
static create(message: string) {}
|
||||
}
|
||||
|
||||
// Mock types for DOM elements
|
||||
export type TFile = {
|
||||
basename: string;
|
||||
};
|
||||
|
||||
// Export additional types that might be used in tests
|
||||
export const Plugin: any = jest.fn();
|
||||
export const WorkspaceLeaf: any = jest.fn();
|
||||
export const Setting: any = jest.fn();
|
||||
|
||||
+20
-25
@@ -1,49 +1,44 @@
|
||||
// Mock for ollama-client for testing
|
||||
import { OllamaMessage, ToolCall } from '../src/types';
|
||||
import type { APIError } from '../src/error-handler';
|
||||
import type { OllamaMessage, OllamaTool } from '../src/types';
|
||||
|
||||
export class OllamaClient {
|
||||
private url: string;
|
||||
private model: string;
|
||||
|
||||
// Mock fetch function for testing
|
||||
private fetchFn: jest.Mock<Promise<Response>, [string, RequestInit?]>> = jest.fn();
|
||||
private fetchFn: typeof fetch;
|
||||
|
||||
constructor(url: string, model: string, fetchFn?: typeof fetch) {
|
||||
this.url = url;
|
||||
this.model = model;
|
||||
if (fetchFn) this.fetchFn = jest.fn(fetchFn);
|
||||
this.fetchFn = fetchFn ?? (jest.fn() as typeof fetch);
|
||||
}
|
||||
|
||||
async *streamChatMessages(
|
||||
prompt: string,
|
||||
options: { abortSignal?: AbortSignal } = {}
|
||||
async *streamChat(
|
||||
_messages: OllamaMessage[],
|
||||
_tools: OllamaTool[] = []
|
||||
): AsyncGenerator<OllamaMessage, void, unknown> {
|
||||
// Mock implementation - simulate streaming response
|
||||
const mockResponse = [
|
||||
{ role: 'assistant', content: 'Part 1' },
|
||||
{ role: 'assistant', content: 'Part 2' }
|
||||
const mockMessages: OllamaMessage[] = [
|
||||
{ role: 'assistant', content: 'Part 1', tool_calls: [] },
|
||||
{ role: 'assistant', content: 'Part 2', tool_calls: [] },
|
||||
];
|
||||
|
||||
for (const message of mockResponse) {
|
||||
for (const message of mockMessages) {
|
||||
yield message;
|
||||
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate delay
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
}
|
||||
|
||||
async *streamToolMessages(
|
||||
toolCall: ToolCall,
|
||||
options: { abortSignal?: AbortSignal } = {}
|
||||
): AsyncGenerator<OllamaMessage, void, unknown> {
|
||||
// Mock implementation - simulate streaming response for tool
|
||||
const mockResponse = [
|
||||
{ role: 'assistant', content: `Tool ${toolCall.tool_name} Part 1` },
|
||||
{ role: 'assistant', content: `Tool ${toolCall.tool_name} Part 2` }
|
||||
];
|
||||
async chat(_messages: OllamaMessage[], _tools: OllamaTool[] = []): Promise<OllamaMessage> {
|
||||
return {
|
||||
role: 'assistant',
|
||||
content: 'Mock response',
|
||||
tool_calls: [],
|
||||
};
|
||||
}
|
||||
|
||||
for (const message of mockResponse) {
|
||||
yield message;
|
||||
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate delay
|
||||
}
|
||||
cancelStream(): void {
|
||||
// No-op in mock
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user