106abfa718
Replaces regex-based parsing of frontmatter and headings with Obsidian's metadataCache where available, falling back to regex when the cache is unavailable. Propagates App dependency through constructors to enable cache access. Key changes: - ContentExtractor accepts optional cache for frontmatter/headings - ToolExecutor uses cache for section replacement and frontmatter - NoteContextBuilder resolves titles/tags from cache - VaultVectorStore passes cache through indexing pipeline - AutoTagger checks cache for existing tags instead of content - Mock updated with metadataCache stubs for tests
128 lines
2.4 KiB
TypeScript
Executable File
128 lines
2.4 KiB
TypeScript
Executable File
// Enhanced Obsidian mock for testing
|
|
|
|
// Mock Vault
|
|
export class Vault {
|
|
getMarkdownFiles: () => any[];
|
|
read: (file: any) => Promise<string>;
|
|
create: (path: string, content: string) => Promise<any>;
|
|
|
|
constructor() {
|
|
this.getMarkdownFiles = () => [];
|
|
this.read = async () => '';
|
|
this.create = async () => null;
|
|
}
|
|
}
|
|
|
|
// Mock Workspace
|
|
export class Workspace {
|
|
getLeaf: () => any;
|
|
|
|
constructor() {
|
|
this.getLeaf = () => ({
|
|
setViewState: jest.fn(),
|
|
revealLeaf: jest.fn(),
|
|
});
|
|
}
|
|
}
|
|
|
|
// Mock App
|
|
export class App {
|
|
vault: Vault;
|
|
workspace: Workspace;
|
|
metadataCache: {
|
|
getFileCache: jest.Mock;
|
|
getFirstLinkpathDest: jest.Mock;
|
|
resolvedLinks: Record<string, Record<string, number>>;
|
|
};
|
|
|
|
constructor() {
|
|
this.vault = new Vault();
|
|
this.workspace = new Workspace();
|
|
this.metadataCache = {
|
|
getFileCache: jest.fn().mockReturnValue(null),
|
|
getFirstLinkpathDest: jest.fn().mockReturnValue(null),
|
|
resolvedLinks: {},
|
|
};
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
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();
|
|
}
|
|
|
|
addRibbonIcon(_icon: string, _title: string, _callback: () => void): HTMLElement {
|
|
return document.createElement('div');
|
|
}
|
|
}
|