Add extensive test suite for note-tools.ts covering all major operations and error paths. Improves statement coverage from 13.94% to 96.01%. Tests added: - readNote: success, errors, frontmatter parsing - createNote: success, conflict strategies (error/overwrite/rename), parent folder creation - updateNote: success, errors, waypoint protection - deleteNote: soft/permanent delete, dry run, version checking - renameFile: success, errors, version checking, parent folder creation - readExcalidraw: success, non-Excalidraw files, errors - updateFrontmatter: success, field removal, version checking - updateSections: success, invalid ranges, version checking - Path validation for all methods - Empty path validation for all methods Mock enhancements: - Added modify, delete, trash methods to VaultAdapter mock - Added parseYaml function to Obsidian mock for frontmatter testing Coverage improvements for note-tools.ts: - Statements: 13.94% -> 96.01% (+82.07%) - Branches: 5.1% -> 88.44% (+83.34%) - Functions: 27.27% -> 90.9% (+63.63%) - Lines: 13.94% -> 96.4% (+82.46%)
100 lines
2.2 KiB
TypeScript
100 lines
2.2 KiB
TypeScript
/**
|
|
* Mock Obsidian API for testing
|
|
* This provides minimal mocks for the Obsidian types used in tests
|
|
*/
|
|
|
|
export class TFile {
|
|
path: string;
|
|
basename: string;
|
|
extension: string;
|
|
|
|
constructor(path: string) {
|
|
this.path = path;
|
|
const parts = path.split('/');
|
|
const filename = parts[parts.length - 1];
|
|
const dotIndex = filename.lastIndexOf('.');
|
|
this.basename = dotIndex > 0 ? filename.substring(0, dotIndex) : filename;
|
|
this.extension = dotIndex > 0 ? filename.substring(dotIndex + 1) : '';
|
|
}
|
|
}
|
|
|
|
export class TFolder {
|
|
path: string;
|
|
name: string;
|
|
|
|
constructor(path: string) {
|
|
this.path = path;
|
|
const parts = path.split('/');
|
|
this.name = parts[parts.length - 1];
|
|
}
|
|
}
|
|
|
|
export class TAbstractFile {
|
|
path: string;
|
|
name: string;
|
|
|
|
constructor(path: string) {
|
|
this.path = path;
|
|
const parts = path.split('/');
|
|
this.name = parts[parts.length - 1];
|
|
}
|
|
}
|
|
|
|
export class Vault {
|
|
private files: Map<string, TFile | TFolder> = new Map();
|
|
|
|
getAbstractFileByPath(path: string): TFile | TFolder | null {
|
|
return this.files.get(path) || null;
|
|
}
|
|
|
|
// Helper method for tests to add mock files
|
|
_addMockFile(path: string, isFolder = false) {
|
|
this.files.set(path, isFolder ? new TFolder(path) : new TFile(path));
|
|
}
|
|
|
|
// Helper method for tests to clear mock files
|
|
_clearMockFiles() {
|
|
this.files.clear();
|
|
}
|
|
}
|
|
|
|
export class App {
|
|
vault: Vault;
|
|
|
|
constructor() {
|
|
this.vault = new Vault();
|
|
}
|
|
}
|
|
|
|
// Export other commonly used types as empty classes/interfaces
|
|
export class Plugin {}
|
|
export class Notice {}
|
|
export class PluginSettingTab {}
|
|
export class Setting {}
|
|
|
|
// Mock parseYaml function
|
|
export function parseYaml(yaml: string): any {
|
|
// Simple YAML parser mock for testing
|
|
const result: any = {};
|
|
const lines = yaml.split('\n');
|
|
|
|
for (const line of lines) {
|
|
if (line.trim() && !line.startsWith('#')) {
|
|
const colonIndex = line.indexOf(':');
|
|
if (colonIndex > 0) {
|
|
const key = line.substring(0, colonIndex).trim();
|
|
let value = line.substring(colonIndex + 1).trim();
|
|
|
|
// Handle arrays
|
|
if (value.startsWith('[') && value.endsWith(']')) {
|
|
value = value.slice(1, -1).split(',').map(v => v.trim());
|
|
}
|
|
|
|
result[key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|