@real1ty-obsidian-plugins/utils 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async-utils.d.ts +69 -0
- package/dist/async-utils.d.ts.map +1 -0
- package/dist/async-utils.js +108 -0
- package/dist/async-utils.js.map +1 -0
- package/dist/batch-operations.d.ts +11 -0
- package/dist/batch-operations.d.ts.map +1 -0
- package/dist/batch-operations.js +31 -0
- package/dist/batch-operations.js.map +1 -0
- package/dist/child-reference-utils.d.ts +9 -0
- package/dist/child-reference-utils.d.ts.map +1 -0
- package/dist/child-reference-utils.js +57 -0
- package/dist/child-reference-utils.js.map +1 -0
- package/dist/date-recurrence-utils.d.ts +30 -0
- package/dist/date-recurrence-utils.d.ts.map +1 -0
- package/dist/date-recurrence-utils.js +167 -0
- package/dist/date-recurrence-utils.js.map +1 -0
- package/dist/date-utils.d.ts +21 -0
- package/dist/date-utils.d.ts.map +1 -0
- package/dist/date-utils.js +105 -0
- package/dist/date-utils.js.map +1 -0
- package/dist/evaluator-base.d.ts +52 -0
- package/dist/evaluator-base.d.ts.map +1 -0
- package/dist/evaluator-base.js +84 -0
- package/dist/evaluator-base.js.map +1 -0
- package/dist/file-operations.d.ts +31 -0
- package/dist/file-operations.d.ts.map +1 -0
- package/dist/file-operations.js +160 -0
- package/dist/file-operations.js.map +1 -0
- package/dist/file-utils.d.ts +6 -0
- package/dist/file-utils.d.ts.map +1 -0
- package/dist/file-utils.js +25 -0
- package/dist/file-utils.js.map +1 -0
- package/dist/frontmatter-utils.d.ts +15 -0
- package/dist/frontmatter-utils.d.ts.map +1 -0
- package/dist/frontmatter-utils.js +68 -0
- package/dist/frontmatter-utils.js.map +1 -0
- package/dist/generate.d.ts +7 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +13 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/link-parser.d.ts +9 -0
- package/dist/link-parser.d.ts.map +1 -0
- package/dist/link-parser.js +19 -0
- package/dist/link-parser.js.map +1 -0
- package/dist/settings-store.d.ts +19 -0
- package/dist/settings-store.d.ts.map +1 -0
- package/dist/settings-store.js +79 -0
- package/dist/settings-store.js.map +1 -0
- package/dist/settings-ui-builder.d.ts +58 -0
- package/dist/settings-ui-builder.d.ts.map +1 -0
- package/dist/settings-ui-builder.js +218 -0
- package/dist/settings-ui-builder.js.map +1 -0
- package/dist/string-utils.d.ts +5 -0
- package/dist/string-utils.d.ts.map +1 -0
- package/dist/string-utils.js +25 -0
- package/dist/string-utils.js.map +1 -0
- package/dist/templater-utils.d.ts +4 -0
- package/dist/templater-utils.d.ts.map +1 -0
- package/dist/templater-utils.js +51 -0
- package/dist/templater-utils.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +6 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mocks/obsidian.d.ts +149 -0
- package/dist/testing/mocks/obsidian.d.ts.map +1 -0
- package/dist/testing/mocks/obsidian.js +220 -0
- package/dist/testing/mocks/obsidian.js.map +1 -0
- package/dist/testing/mocks/utils.d.ts +14 -0
- package/dist/testing/mocks/utils.d.ts.map +1 -0
- package/dist/testing/mocks/utils.js +85 -0
- package/dist/testing/mocks/utils.js.map +1 -0
- package/dist/testing/setup.d.ts +2 -0
- package/dist/testing/setup.d.ts.map +1 -0
- package/dist/testing/setup.js +18 -0
- package/dist/testing/setup.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Notice, normalizePath } from "obsidian";
|
|
3
|
+
const TEMPLATER_ID = "templater-obsidian";
|
|
4
|
+
function waitForTemplater(app_1) {
|
|
5
|
+
return __awaiter(this, arguments, void 0, function* (app, timeoutMs = 8000) {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
yield new Promise((resolve) => app.workspace.onLayoutReady(resolve));
|
|
8
|
+
const started = Date.now();
|
|
9
|
+
while (Date.now() - started < timeoutMs) {
|
|
10
|
+
const plug = (_b = (_a = app.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin) === null || _b === void 0 ? void 0 : _b.call(_a, TEMPLATER_ID);
|
|
11
|
+
const api = (_c = plug === null || plug === void 0 ? void 0 : plug.templater) !== null && _c !== void 0 ? _c : null;
|
|
12
|
+
const createFn = (_d = api === null || api === void 0 ? void 0 : api.create_new_note_from_template) === null || _d === void 0 ? void 0 : _d.bind(api);
|
|
13
|
+
if (typeof createFn === "function") {
|
|
14
|
+
return { create_new_note_from_template: createFn };
|
|
15
|
+
}
|
|
16
|
+
yield new Promise((r) => setTimeout(r, 150));
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function isTemplaterAvailable(app) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
const instance = (_b = (_a = app.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin) === null || _b === void 0 ? void 0 : _b.call(_a, TEMPLATER_ID);
|
|
24
|
+
return !!instance;
|
|
25
|
+
}
|
|
26
|
+
export function createFromTemplate(app_1, templatePath_1, targetFolder_1, filename_1) {
|
|
27
|
+
return __awaiter(this, arguments, void 0, function* (app, templatePath, targetFolder, filename, openNewNote = false) {
|
|
28
|
+
const templater = yield waitForTemplater(app);
|
|
29
|
+
if (!templater) {
|
|
30
|
+
console.warn("Templater isn't ready yet (or not installed/enabled).");
|
|
31
|
+
new Notice("Templater plugin is not available or enabled. Please ensure it is installed and enabled.");
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const templateFile = app.vault.getFileByPath(normalizePath(templatePath));
|
|
35
|
+
if (!templateFile) {
|
|
36
|
+
console.error(`Template not found: ${templatePath}`);
|
|
37
|
+
new Notice(`Template file not found: ${templatePath}. Please ensure the template file exists.`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const newFile = yield templater.create_new_note_from_template(templateFile, targetFolder, filename, openNewNote);
|
|
42
|
+
return newFile !== null && newFile !== void 0 ? newFile : null;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error("Error creating file from template:", error);
|
|
46
|
+
new Notice("Error creating file from template. Please ensure the template file is valid.");
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=templater-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templater-utils.js","sourceRoot":"","sources":["../src/templater-utils.ts"],"names":[],"mappings":";AAAA,OAAO,EAAY,MAAM,EAAE,aAAa,EAAc,MAAM,UAAU,CAAC;AAEvE,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAa1C,SAAe,gBAAgB;yDAAC,GAAQ,EAAE,SAAS,GAAG,IAAI;;QACzD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAE3E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,SAAS,EAAE,CAAC;YACzC,MAAM,IAAI,GAAQ,MAAA,MAAC,GAAW,CAAC,OAAO,0CAAE,SAAS,mDAAG,YAAY,CAAC,CAAC;YAClE,MAAM,GAAG,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,mCAAI,IAAI,CAAC;YAEpC,MAAM,QAAQ,GAAyB,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,6BAA6B,0CAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACrF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACpC,OAAO,EAAE,6BAA6B,EAAE,QAAQ,EAAE,CAAC;YACpD,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAQ;;IAC5C,MAAM,QAAQ,GAAG,MAAA,MAAC,GAAW,CAAC,OAAO,0CAAE,SAAS,mDAAG,YAAY,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,QAAQ,CAAC;AACnB,CAAC;AAED,MAAM,UAAgB,kBAAkB;yDACvC,GAAQ,EACR,YAAoB,EACpB,YAAqB,EACrB,QAAiB,EACjB,WAAW,GAAG,KAAK;QAEnB,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;YACtE,IAAI,MAAM,CACT,0FAA0F,CAC1F,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,YAAY,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;YACrD,IAAI,MAAM,CAAC,4BAA4B,YAAY,2CAA2C,CAAC,CAAC;YAChG,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,6BAA6B,CAC5D,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,WAAW,CACX,CAAC;YAEF,OAAO,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,IAAI,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC3D,IAAI,MAAM,CAAC,8EAA8E,CAAC,CAAC;YAC3F,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;CAAA","sourcesContent":["import { type App, Notice, normalizePath, type TFile } from \"obsidian\";\n\nconst TEMPLATER_ID = \"templater-obsidian\";\n\ntype CreateFn = (\n\ttemplateFile: TFile,\n\tfolder?: string,\n\tfilename?: string,\n\topenNewNote?: boolean\n) => Promise<TFile | undefined>;\n\ninterface TemplaterLike {\n\tcreate_new_note_from_template: CreateFn;\n}\n\nasync function waitForTemplater(app: App, timeoutMs = 8000): Promise<TemplaterLike | null> {\n\tawait new Promise<void>((resolve) => app.workspace.onLayoutReady(resolve));\n\n\tconst started = Date.now();\n\twhile (Date.now() - started < timeoutMs) {\n\t\tconst plug: any = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\t\tconst api = plug?.templater ?? null;\n\n\t\tconst createFn: CreateFn | undefined = api?.create_new_note_from_template?.bind(api);\n\t\tif (typeof createFn === \"function\") {\n\t\t\treturn { create_new_note_from_template: createFn };\n\t\t}\n\t\tawait new Promise((r) => setTimeout(r, 150));\n\t}\n\treturn null;\n}\n\nexport function isTemplaterAvailable(app: App): boolean {\n\tconst instance = (app as any).plugins?.getPlugin?.(TEMPLATER_ID);\n\treturn !!instance;\n}\n\nexport async function createFromTemplate(\n\tapp: App,\n\ttemplatePath: string,\n\ttargetFolder?: string,\n\tfilename?: string,\n\topenNewNote = false\n): Promise<TFile | null> {\n\tconst templater = await waitForTemplater(app);\n\tif (!templater) {\n\t\tconsole.warn(\"Templater isn't ready yet (or not installed/enabled).\");\n\t\tnew Notice(\n\t\t\t\"Templater plugin is not available or enabled. Please ensure it is installed and enabled.\"\n\t\t);\n\t\treturn null;\n\t}\n\n\tconst templateFile = app.vault.getFileByPath(normalizePath(templatePath));\n\tif (!templateFile) {\n\t\tconsole.error(`Template not found: ${templatePath}`);\n\t\tnew Notice(`Template file not found: ${templatePath}. Please ensure the template file exists.`);\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst newFile = await templater.create_new_note_from_template(\n\t\t\ttemplateFile,\n\t\t\ttargetFolder,\n\t\t\tfilename,\n\t\t\topenNewNote\n\t\t);\n\n\t\treturn newFile ?? null;\n\t} catch (error) {\n\t\tconsole.error(\"Error creating file from template:\", error);\n\t\tnew Notice(\"Error creating file from template. Please ensure the template file is valid.\");\n\t\treturn null;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from "./mocks/obsidian";
|
|
2
|
+
export { createMockApp, createMockFile, createMockFileCache, Modal, Notice, Plugin, PluginSettingTab, Setting, TFile, } from "./mocks/obsidian";
|
|
3
|
+
export * from "./mocks/utils";
|
|
4
|
+
export { mockFileOperations, mockLinkParser, resetAllMocks, setupDefaultMockImplementations, setupMockImplementation, setupMockReturnValue, verifyMockCalls, } from "./mocks/utils";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EACN,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,OAAO,EACP,KAAK,GACL,MAAM,kBAAkB,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,+BAA+B,EAC/B,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,GACf,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./mocks/obsidian";
|
|
2
|
+
// Re-export commonly used combinations
|
|
3
|
+
export { createMockApp, createMockFile, createMockFileCache, Modal, Notice, Plugin, PluginSettingTab, Setting, TFile, } from "./mocks/obsidian";
|
|
4
|
+
export * from "./mocks/utils";
|
|
5
|
+
export { mockFileOperations, mockLinkParser, resetAllMocks, setupDefaultMockImplementations, setupMockImplementation, setupMockReturnValue, verifyMockCalls, } from "./mocks/utils";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,uCAAuC;AACvC,OAAO,EACN,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,OAAO,EACP,KAAK,GACL,MAAM,kBAAkB,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,+BAA+B,EAC/B,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,GACf,MAAM,eAAe,CAAC","sourcesContent":["export * from \"./mocks/obsidian\";\n// Re-export commonly used combinations\nexport {\n\tcreateMockApp,\n\tcreateMockFile,\n\tcreateMockFileCache,\n\tModal,\n\tNotice,\n\tPlugin,\n\tPluginSettingTab,\n\tSetting,\n\tTFile,\n} from \"./mocks/obsidian\";\nexport * from \"./mocks/utils\";\nexport {\n\tmockFileOperations,\n\tmockLinkParser,\n\tresetAllMocks,\n\tsetupDefaultMockImplementations,\n\tsetupMockImplementation,\n\tsetupMockReturnValue,\n\tverifyMockCalls,\n} from \"./mocks/utils\";\n"]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
export declare class Plugin {
|
|
3
|
+
app: any;
|
|
4
|
+
manifest: any;
|
|
5
|
+
settings: any;
|
|
6
|
+
constructor(app: any, manifest: any);
|
|
7
|
+
addSettingTab: import("vitest").Mock<(...args: any[]) => any>;
|
|
8
|
+
registerEvent: import("vitest").Mock<(...args: any[]) => any>;
|
|
9
|
+
loadData: import("vitest").Mock<(...args: any[]) => any>;
|
|
10
|
+
saveData: import("vitest").Mock<(...args: any[]) => any>;
|
|
11
|
+
onload: import("vitest").Mock<(...args: any[]) => any>;
|
|
12
|
+
onunload: import("vitest").Mock<(...args: any[]) => any>;
|
|
13
|
+
addRibbonIcon: import("vitest").Mock<(...args: any[]) => any>;
|
|
14
|
+
addStatusBarItem: import("vitest").Mock<(...args: any[]) => any>;
|
|
15
|
+
addCommand: import("vitest").Mock<(...args: any[]) => any>;
|
|
16
|
+
removeCommand: import("vitest").Mock<(...args: any[]) => any>;
|
|
17
|
+
registerDomEvent: import("vitest").Mock<(...args: any[]) => any>;
|
|
18
|
+
registerCodeMirror: import("vitest").Mock<(...args: any[]) => any>;
|
|
19
|
+
registerEditorExtension: import("vitest").Mock<(...args: any[]) => any>;
|
|
20
|
+
registerMarkdownPostProcessor: import("vitest").Mock<(...args: any[]) => any>;
|
|
21
|
+
registerMarkdownCodeBlockProcessor: import("vitest").Mock<(...args: any[]) => any>;
|
|
22
|
+
registerObsidianProtocolHandler: import("vitest").Mock<(...args: any[]) => any>;
|
|
23
|
+
registerEditorSuggest: import("vitest").Mock<(...args: any[]) => any>;
|
|
24
|
+
registerHoverLinkSource: import("vitest").Mock<(...args: any[]) => any>;
|
|
25
|
+
registerInterval: import("vitest").Mock<(...args: any[]) => any>;
|
|
26
|
+
registerView: import("vitest").Mock<(...args: any[]) => any>;
|
|
27
|
+
registerExtensions: import("vitest").Mock<(...args: any[]) => any>;
|
|
28
|
+
onUserEnable: import("vitest").Mock<(...args: any[]) => any>;
|
|
29
|
+
load: import("vitest").Mock<(...args: any[]) => any>;
|
|
30
|
+
unload: import("vitest").Mock<(...args: any[]) => any>;
|
|
31
|
+
addChild: import("vitest").Mock<(...args: any[]) => any>;
|
|
32
|
+
removeChild: import("vitest").Mock<(...args: any[]) => any>;
|
|
33
|
+
register: import("vitest").Mock<(...args: any[]) => any>;
|
|
34
|
+
}
|
|
35
|
+
export declare class PluginSettingTab {
|
|
36
|
+
app: any;
|
|
37
|
+
plugin: any;
|
|
38
|
+
containerEl: HTMLElement;
|
|
39
|
+
constructor(app: any, plugin: any);
|
|
40
|
+
display: import("vitest").Mock<(...args: any[]) => any>;
|
|
41
|
+
}
|
|
42
|
+
export declare class ItemView {
|
|
43
|
+
app: any;
|
|
44
|
+
leaf: any;
|
|
45
|
+
containerEl: HTMLElement;
|
|
46
|
+
constructor(leaf: any);
|
|
47
|
+
getViewType(): string;
|
|
48
|
+
getDisplayText(): string;
|
|
49
|
+
getIcon(): string;
|
|
50
|
+
getState: import("vitest").Mock<(...args: any[]) => any>;
|
|
51
|
+
setState: import("vitest").Mock<(...args: any[]) => any>;
|
|
52
|
+
}
|
|
53
|
+
export declare class Setting {
|
|
54
|
+
settingEl: HTMLElement;
|
|
55
|
+
nameEl: HTMLElement;
|
|
56
|
+
descEl: HTMLElement;
|
|
57
|
+
controlEl: HTMLElement;
|
|
58
|
+
constructor(_containerEl: HTMLElement);
|
|
59
|
+
setName: import("vitest").Mock<(...args: any[]) => any>;
|
|
60
|
+
setDesc: import("vitest").Mock<(...args: any[]) => any>;
|
|
61
|
+
addText: import("vitest").Mock<(...args: any[]) => any>;
|
|
62
|
+
addTextArea: import("vitest").Mock<(...args: any[]) => any>;
|
|
63
|
+
}
|
|
64
|
+
export declare class TFolder {
|
|
65
|
+
path: string;
|
|
66
|
+
name: string;
|
|
67
|
+
children: any[];
|
|
68
|
+
vault: any;
|
|
69
|
+
parent: TFolder | null;
|
|
70
|
+
constructor(path: string);
|
|
71
|
+
isRoot(): boolean;
|
|
72
|
+
}
|
|
73
|
+
export declare class TFile {
|
|
74
|
+
path: string;
|
|
75
|
+
name: string;
|
|
76
|
+
basename: string;
|
|
77
|
+
extension: string;
|
|
78
|
+
stat: any;
|
|
79
|
+
vault: any;
|
|
80
|
+
parent: TFolder | null;
|
|
81
|
+
constructor(path: string, parentPath?: string);
|
|
82
|
+
}
|
|
83
|
+
export declare class Modal {
|
|
84
|
+
app: any;
|
|
85
|
+
containerEl: HTMLElement;
|
|
86
|
+
titleEl: HTMLElement;
|
|
87
|
+
contentEl: HTMLElement;
|
|
88
|
+
constructor(app: any);
|
|
89
|
+
open: import("vitest").Mock<(...args: any[]) => any>;
|
|
90
|
+
close: import("vitest").Mock<(...args: any[]) => any>;
|
|
91
|
+
onOpen: import("vitest").Mock<(...args: any[]) => any>;
|
|
92
|
+
onClose: import("vitest").Mock<(...args: any[]) => any>;
|
|
93
|
+
}
|
|
94
|
+
export declare class Notice {
|
|
95
|
+
constructor(message: string);
|
|
96
|
+
}
|
|
97
|
+
export declare const MarkdownRenderer: {
|
|
98
|
+
render: import("vitest").Mock<(...args: any[]) => any>;
|
|
99
|
+
};
|
|
100
|
+
export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number, immediate?: boolean): T;
|
|
101
|
+
export declare const App: import("vitest").Mock<(...args: any[]) => any>;
|
|
102
|
+
export interface MockApp {
|
|
103
|
+
fileManager: {
|
|
104
|
+
processFrontMatter: ReturnType<typeof vi.fn>;
|
|
105
|
+
};
|
|
106
|
+
metadataCache: {
|
|
107
|
+
getFileCache: ReturnType<typeof vi.fn>;
|
|
108
|
+
};
|
|
109
|
+
vault: {
|
|
110
|
+
getAbstractFileByPath: ReturnType<typeof vi.fn>;
|
|
111
|
+
on: ReturnType<typeof vi.fn>;
|
|
112
|
+
read: ReturnType<typeof vi.fn>;
|
|
113
|
+
modify: ReturnType<typeof vi.fn>;
|
|
114
|
+
create: ReturnType<typeof vi.fn>;
|
|
115
|
+
delete: ReturnType<typeof vi.fn>;
|
|
116
|
+
rename: ReturnType<typeof vi.fn>;
|
|
117
|
+
getFiles: ReturnType<typeof vi.fn>;
|
|
118
|
+
getMarkdownFiles: ReturnType<typeof vi.fn>;
|
|
119
|
+
getFolderByPath: ReturnType<typeof vi.fn>;
|
|
120
|
+
};
|
|
121
|
+
workspace: {
|
|
122
|
+
getActiveFile: ReturnType<typeof vi.fn>;
|
|
123
|
+
on: ReturnType<typeof vi.fn>;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export declare function createMockApp(): MockApp;
|
|
127
|
+
export declare function createMockFile(path: string, options?: {
|
|
128
|
+
basename?: string;
|
|
129
|
+
parentPath?: string;
|
|
130
|
+
extension?: string;
|
|
131
|
+
}): TFile;
|
|
132
|
+
export declare function createMockFileCache(frontmatter?: Record<string, any>): {
|
|
133
|
+
frontmatter: Record<string, any>;
|
|
134
|
+
frontmatterPosition: {
|
|
135
|
+
start: {
|
|
136
|
+
line: number;
|
|
137
|
+
};
|
|
138
|
+
end: {
|
|
139
|
+
line: number;
|
|
140
|
+
};
|
|
141
|
+
} | null;
|
|
142
|
+
sections: never[];
|
|
143
|
+
headings: never[];
|
|
144
|
+
links: never[];
|
|
145
|
+
embeds: never[];
|
|
146
|
+
tags: never[];
|
|
147
|
+
listItems: never[];
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=obsidian.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obsidian.d.ts","sourceRoot":"","sources":["../../../src/testing/mocks/obsidian.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
// Base Plugin class mock
|
|
3
|
+
export class Plugin {
|
|
4
|
+
constructor(app, manifest) {
|
|
5
|
+
// Core plugin methods
|
|
6
|
+
this.addSettingTab = vi.fn();
|
|
7
|
+
this.registerEvent = vi.fn();
|
|
8
|
+
this.loadData = vi.fn().mockResolvedValue({});
|
|
9
|
+
this.saveData = vi.fn().mockResolvedValue(undefined);
|
|
10
|
+
this.onload = vi.fn();
|
|
11
|
+
this.onunload = vi.fn();
|
|
12
|
+
// UI methods
|
|
13
|
+
this.addRibbonIcon = vi.fn();
|
|
14
|
+
this.addStatusBarItem = vi.fn();
|
|
15
|
+
this.addCommand = vi.fn();
|
|
16
|
+
this.removeCommand = vi.fn();
|
|
17
|
+
// Event methods
|
|
18
|
+
this.registerDomEvent = vi.fn();
|
|
19
|
+
this.registerCodeMirror = vi.fn();
|
|
20
|
+
this.registerEditorExtension = vi.fn();
|
|
21
|
+
this.registerMarkdownPostProcessor = vi.fn();
|
|
22
|
+
this.registerMarkdownCodeBlockProcessor = vi.fn();
|
|
23
|
+
this.registerObsidianProtocolHandler = vi.fn();
|
|
24
|
+
this.registerEditorSuggest = vi.fn();
|
|
25
|
+
this.registerHoverLinkSource = vi.fn();
|
|
26
|
+
// Interval methods
|
|
27
|
+
this.registerInterval = vi.fn();
|
|
28
|
+
// View and extension methods
|
|
29
|
+
this.registerView = vi.fn();
|
|
30
|
+
this.registerExtensions = vi.fn();
|
|
31
|
+
// Lifecycle methods
|
|
32
|
+
this.onUserEnable = vi.fn();
|
|
33
|
+
this.load = vi.fn();
|
|
34
|
+
this.unload = vi.fn();
|
|
35
|
+
// Other methods
|
|
36
|
+
this.addChild = vi.fn();
|
|
37
|
+
this.removeChild = vi.fn();
|
|
38
|
+
this.register = vi.fn();
|
|
39
|
+
this.app = app;
|
|
40
|
+
this.manifest = manifest;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// PluginSettingTab mock
|
|
44
|
+
export class PluginSettingTab {
|
|
45
|
+
constructor(app, plugin) {
|
|
46
|
+
this.display = vi.fn();
|
|
47
|
+
this.app = app;
|
|
48
|
+
this.plugin = plugin;
|
|
49
|
+
this.containerEl = document.createElement("div");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ItemView mock
|
|
53
|
+
export class ItemView {
|
|
54
|
+
constructor(leaf) {
|
|
55
|
+
this.getState = vi.fn().mockReturnValue({});
|
|
56
|
+
this.setState = vi.fn().mockResolvedValue(undefined);
|
|
57
|
+
this.leaf = leaf;
|
|
58
|
+
this.app = leaf === null || leaf === void 0 ? void 0 : leaf.app;
|
|
59
|
+
this.containerEl = document.createElement("div");
|
|
60
|
+
}
|
|
61
|
+
// Don't override onOpen/onClose - let subclasses implement them
|
|
62
|
+
// These methods are implemented by MountableView mixin
|
|
63
|
+
// Don't provide default implementations for these methods
|
|
64
|
+
// Let subclasses implement them
|
|
65
|
+
getViewType() {
|
|
66
|
+
return "mock-view";
|
|
67
|
+
}
|
|
68
|
+
getDisplayText() {
|
|
69
|
+
return "Mock View";
|
|
70
|
+
}
|
|
71
|
+
getIcon() {
|
|
72
|
+
return "mock-icon";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Setting component mock
|
|
76
|
+
export class Setting {
|
|
77
|
+
constructor(_containerEl) {
|
|
78
|
+
this.setName = vi.fn().mockReturnThis();
|
|
79
|
+
this.setDesc = vi.fn().mockReturnThis();
|
|
80
|
+
this.addText = vi.fn().mockReturnThis();
|
|
81
|
+
this.addTextArea = vi.fn().mockReturnThis();
|
|
82
|
+
this.settingEl = document.createElement("div");
|
|
83
|
+
this.nameEl = document.createElement("div");
|
|
84
|
+
this.descEl = document.createElement("div");
|
|
85
|
+
this.controlEl = document.createElement("div");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// TFolder mock
|
|
89
|
+
export class TFolder {
|
|
90
|
+
constructor(path) {
|
|
91
|
+
this.path = path;
|
|
92
|
+
this.name = path.split("/").pop() || "";
|
|
93
|
+
this.children = [];
|
|
94
|
+
this.vault = {};
|
|
95
|
+
this.parent = null;
|
|
96
|
+
}
|
|
97
|
+
isRoot() {
|
|
98
|
+
return this.path === "" || this.path === "/";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// TFile mock with full interface
|
|
102
|
+
export class TFile {
|
|
103
|
+
constructor(path, parentPath) {
|
|
104
|
+
this.path = path;
|
|
105
|
+
this.name = path.split("/").pop() || "";
|
|
106
|
+
this.basename = this.name.replace(/\.[^/.]+$/, ""); // Remove extension
|
|
107
|
+
this.extension = path.split(".").pop() || "md";
|
|
108
|
+
this.stat = {};
|
|
109
|
+
this.vault = {};
|
|
110
|
+
// Set parent based on path or explicit parentPath
|
|
111
|
+
if (parentPath !== undefined) {
|
|
112
|
+
this.parent = parentPath ? new TFolder(parentPath) : null;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Derive parent from path
|
|
116
|
+
const lastSlash = path.lastIndexOf("/");
|
|
117
|
+
if (lastSlash > 0) {
|
|
118
|
+
this.parent = new TFolder(path.substring(0, lastSlash));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
this.parent = null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Modal mock
|
|
127
|
+
export class Modal {
|
|
128
|
+
constructor(app) {
|
|
129
|
+
this.open = vi.fn();
|
|
130
|
+
this.close = vi.fn();
|
|
131
|
+
this.onOpen = vi.fn();
|
|
132
|
+
this.onClose = vi.fn();
|
|
133
|
+
this.app = app;
|
|
134
|
+
this.containerEl = document.createElement("div");
|
|
135
|
+
this.titleEl = document.createElement("div");
|
|
136
|
+
this.contentEl = document.createElement("div");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Notice mock
|
|
140
|
+
export class Notice {
|
|
141
|
+
constructor(message) {
|
|
142
|
+
console.log(`Notice: ${message}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// MarkdownRenderer mock
|
|
146
|
+
export const MarkdownRenderer = {
|
|
147
|
+
render: vi.fn().mockResolvedValue(undefined),
|
|
148
|
+
};
|
|
149
|
+
// Debounce function mock
|
|
150
|
+
export function debounce(func, wait, immediate) {
|
|
151
|
+
let timeout = null;
|
|
152
|
+
return ((...args) => {
|
|
153
|
+
const later = () => {
|
|
154
|
+
timeout = null;
|
|
155
|
+
if (!immediate)
|
|
156
|
+
func(...args);
|
|
157
|
+
};
|
|
158
|
+
const callNow = immediate && !timeout;
|
|
159
|
+
if (timeout !== null) {
|
|
160
|
+
clearTimeout(timeout);
|
|
161
|
+
}
|
|
162
|
+
timeout = setTimeout(later, wait);
|
|
163
|
+
if (callNow)
|
|
164
|
+
func(...args);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// App mock
|
|
168
|
+
export const App = vi.fn();
|
|
169
|
+
// Helper function to create a fully mocked app
|
|
170
|
+
export function createMockApp() {
|
|
171
|
+
return {
|
|
172
|
+
fileManager: {
|
|
173
|
+
processFrontMatter: vi.fn(),
|
|
174
|
+
},
|
|
175
|
+
metadataCache: {
|
|
176
|
+
getFileCache: vi.fn(),
|
|
177
|
+
},
|
|
178
|
+
vault: {
|
|
179
|
+
getAbstractFileByPath: vi.fn(),
|
|
180
|
+
on: vi.fn(),
|
|
181
|
+
read: vi.fn(),
|
|
182
|
+
modify: vi.fn(),
|
|
183
|
+
create: vi.fn(),
|
|
184
|
+
delete: vi.fn(),
|
|
185
|
+
rename: vi.fn(),
|
|
186
|
+
getFiles: vi.fn().mockReturnValue([]),
|
|
187
|
+
getMarkdownFiles: vi.fn().mockReturnValue([]),
|
|
188
|
+
getFolderByPath: vi.fn(),
|
|
189
|
+
},
|
|
190
|
+
workspace: {
|
|
191
|
+
getActiveFile: vi.fn(),
|
|
192
|
+
on: vi.fn(),
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// Helper to create mock TFile instances
|
|
197
|
+
export function createMockFile(path, options) {
|
|
198
|
+
const file = new TFile(path, options === null || options === void 0 ? void 0 : options.parentPath);
|
|
199
|
+
if (options === null || options === void 0 ? void 0 : options.basename) {
|
|
200
|
+
file.basename = options.basename;
|
|
201
|
+
}
|
|
202
|
+
if (options === null || options === void 0 ? void 0 : options.extension) {
|
|
203
|
+
file.extension = options.extension;
|
|
204
|
+
}
|
|
205
|
+
return file;
|
|
206
|
+
}
|
|
207
|
+
// Helper to create mock file cache
|
|
208
|
+
export function createMockFileCache(frontmatter) {
|
|
209
|
+
return {
|
|
210
|
+
frontmatter: frontmatter || {},
|
|
211
|
+
frontmatterPosition: frontmatter ? { start: { line: 0 }, end: { line: 3 } } : null,
|
|
212
|
+
sections: [],
|
|
213
|
+
headings: [],
|
|
214
|
+
links: [],
|
|
215
|
+
embeds: [],
|
|
216
|
+
tags: [],
|
|
217
|
+
listItems: [],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=obsidian.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obsidian.js","sourceRoot":"","sources":["../../../src/testing/mocks/obsidian.ts"],"names":[],"mappings":"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","sourcesContent":["import { vi } from \"vitest\";\n\n// Base Plugin class mock\nexport class Plugin {\n\tapp: any;\n\tmanifest: any;\n\tsettings: any;\n\n\tconstructor(app: any, manifest: any) {\n\t\tthis.app = app;\n\t\tthis.manifest = manifest;\n\t}\n\n\t// Core plugin methods\n\taddSettingTab = vi.fn();\n\tregisterEvent = vi.fn();\n\tloadData = vi.fn().mockResolvedValue({});\n\tsaveData = vi.fn().mockResolvedValue(undefined);\n\tonload = vi.fn();\n\tonunload = vi.fn();\n\n\t// UI methods\n\taddRibbonIcon = vi.fn();\n\taddStatusBarItem = vi.fn();\n\taddCommand = vi.fn();\n\tremoveCommand = vi.fn();\n\n\t// Event methods\n\tregisterDomEvent = vi.fn();\n\tregisterCodeMirror = vi.fn();\n\tregisterEditorExtension = vi.fn();\n\tregisterMarkdownPostProcessor = vi.fn();\n\tregisterMarkdownCodeBlockProcessor = vi.fn();\n\tregisterObsidianProtocolHandler = vi.fn();\n\tregisterEditorSuggest = vi.fn();\n\tregisterHoverLinkSource = vi.fn();\n\n\t// Interval methods\n\tregisterInterval = vi.fn();\n\n\t// View and extension methods\n\tregisterView = vi.fn();\n\tregisterExtensions = vi.fn();\n\n\t// Lifecycle methods\n\tonUserEnable = vi.fn();\n\tload = vi.fn();\n\tunload = vi.fn();\n\n\t// Other methods\n\taddChild = vi.fn();\n\tremoveChild = vi.fn();\n\tregister = vi.fn();\n}\n\n// PluginSettingTab mock\nexport class PluginSettingTab {\n\tapp: any;\n\tplugin: any;\n\tcontainerEl: HTMLElement;\n\n\tconstructor(app: any, plugin: any) {\n\t\tthis.app = app;\n\t\tthis.plugin = plugin;\n\t\tthis.containerEl = document.createElement(\"div\");\n\t}\n\n\tdisplay = vi.fn();\n}\n\n// ItemView mock\nexport class ItemView {\n\tapp: any;\n\tleaf: any;\n\tcontainerEl: HTMLElement;\n\n\tconstructor(leaf: any) {\n\t\tthis.leaf = leaf;\n\t\tthis.app = leaf?.app;\n\t\tthis.containerEl = document.createElement(\"div\");\n\t}\n\n\t// Don't override onOpen/onClose - let subclasses implement them\n\t// These methods are implemented by MountableView mixin\n\n\t// Don't provide default implementations for these methods\n\t// Let subclasses implement them\n\tgetViewType(): string {\n\t\treturn \"mock-view\";\n\t}\n\n\tgetDisplayText(): string {\n\t\treturn \"Mock View\";\n\t}\n\n\tgetIcon(): string {\n\t\treturn \"mock-icon\";\n\t}\n\n\tgetState = vi.fn().mockReturnValue({});\n\tsetState = vi.fn().mockResolvedValue(undefined);\n}\n\n// Setting component mock\nexport class Setting {\n\tsettingEl: HTMLElement;\n\tnameEl: HTMLElement;\n\tdescEl: HTMLElement;\n\tcontrolEl: HTMLElement;\n\n\tconstructor(_containerEl: HTMLElement) {\n\t\tthis.settingEl = document.createElement(\"div\");\n\t\tthis.nameEl = document.createElement(\"div\");\n\t\tthis.descEl = document.createElement(\"div\");\n\t\tthis.controlEl = document.createElement(\"div\");\n\t}\n\n\tsetName = vi.fn().mockReturnThis();\n\tsetDesc = vi.fn().mockReturnThis();\n\taddText = vi.fn().mockReturnThis();\n\taddTextArea = vi.fn().mockReturnThis();\n}\n\n// TFolder mock\nexport class TFolder {\n\tpath: string;\n\tname: string;\n\tchildren: any[];\n\tvault: any;\n\tparent: TFolder | null;\n\n\tconstructor(path: string) {\n\t\tthis.path = path;\n\t\tthis.name = path.split(\"/\").pop() || \"\";\n\t\tthis.children = [];\n\t\tthis.vault = {};\n\t\tthis.parent = null;\n\t}\n\n\tisRoot(): boolean {\n\t\treturn this.path === \"\" || this.path === \"/\";\n\t}\n}\n\n// TFile mock with full interface\nexport class TFile {\n\tpath: string;\n\tname: string;\n\tbasename: string;\n\textension: string;\n\tstat: any;\n\tvault: any;\n\tparent: TFolder | null;\n\n\tconstructor(path: string, parentPath?: string) {\n\t\tthis.path = path;\n\t\tthis.name = path.split(\"/\").pop() || \"\";\n\t\tthis.basename = this.name.replace(/\\.[^/.]+$/, \"\"); // Remove extension\n\t\tthis.extension = path.split(\".\").pop() || \"md\";\n\t\tthis.stat = {};\n\t\tthis.vault = {};\n\n\t\t// Set parent based on path or explicit parentPath\n\t\tif (parentPath !== undefined) {\n\t\t\tthis.parent = parentPath ? new TFolder(parentPath) : null;\n\t\t} else {\n\t\t\t// Derive parent from path\n\t\t\tconst lastSlash = path.lastIndexOf(\"/\");\n\t\t\tif (lastSlash > 0) {\n\t\t\t\tthis.parent = new TFolder(path.substring(0, lastSlash));\n\t\t\t} else {\n\t\t\t\tthis.parent = null;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Modal mock\nexport class Modal {\n\tapp: any;\n\tcontainerEl: HTMLElement;\n\ttitleEl: HTMLElement;\n\tcontentEl: HTMLElement;\n\n\tconstructor(app: any) {\n\t\tthis.app = app;\n\t\tthis.containerEl = document.createElement(\"div\");\n\t\tthis.titleEl = document.createElement(\"div\");\n\t\tthis.contentEl = document.createElement(\"div\");\n\t}\n\n\topen = vi.fn();\n\tclose = vi.fn();\n\tonOpen = vi.fn();\n\tonClose = vi.fn();\n}\n\n// Notice mock\nexport class Notice {\n\tconstructor(message: string) {\n\t\tconsole.log(`Notice: ${message}`);\n\t}\n}\n\n// MarkdownRenderer mock\nexport const MarkdownRenderer = {\n\trender: vi.fn().mockResolvedValue(undefined),\n};\n\n// Debounce function mock\nexport function debounce<T extends (...args: any[]) => any>(\n\tfunc: T,\n\twait: number,\n\timmediate?: boolean\n): T {\n\tlet timeout: ReturnType<typeof setTimeout> | null = null;\n\n\treturn ((...args: Parameters<T>) => {\n\t\tconst later = () => {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func(...args);\n\t\t};\n\n\t\tconst callNow = immediate && !timeout;\n\n\t\tif (timeout !== null) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\n\t\ttimeout = setTimeout(later, wait);\n\n\t\tif (callNow) func(...args);\n\t}) as T;\n}\n\n// App mock\nexport const App = vi.fn();\n\n// Mock interfaces for TypeScript\nexport interface MockApp {\n\tfileManager: {\n\t\tprocessFrontMatter: ReturnType<typeof vi.fn>;\n\t};\n\tmetadataCache: {\n\t\tgetFileCache: ReturnType<typeof vi.fn>;\n\t};\n\tvault: {\n\t\tgetAbstractFileByPath: ReturnType<typeof vi.fn>;\n\t\ton: ReturnType<typeof vi.fn>;\n\t\tread: ReturnType<typeof vi.fn>;\n\t\tmodify: ReturnType<typeof vi.fn>;\n\t\tcreate: ReturnType<typeof vi.fn>;\n\t\tdelete: ReturnType<typeof vi.fn>;\n\t\trename: ReturnType<typeof vi.fn>;\n\t\tgetFiles: ReturnType<typeof vi.fn>;\n\t\tgetMarkdownFiles: ReturnType<typeof vi.fn>;\n\t\tgetFolderByPath: ReturnType<typeof vi.fn>;\n\t};\n\tworkspace: {\n\t\tgetActiveFile: ReturnType<typeof vi.fn>;\n\t\ton: ReturnType<typeof vi.fn>;\n\t};\n}\n\n// Helper function to create a fully mocked app\nexport function createMockApp(): MockApp {\n\treturn {\n\t\tfileManager: {\n\t\t\tprocessFrontMatter: vi.fn(),\n\t\t},\n\t\tmetadataCache: {\n\t\t\tgetFileCache: vi.fn(),\n\t\t},\n\t\tvault: {\n\t\t\tgetAbstractFileByPath: vi.fn(),\n\t\t\ton: vi.fn(),\n\t\t\tread: vi.fn(),\n\t\t\tmodify: vi.fn(),\n\t\t\tcreate: vi.fn(),\n\t\t\tdelete: vi.fn(),\n\t\t\trename: vi.fn(),\n\t\t\tgetFiles: vi.fn().mockReturnValue([]),\n\t\t\tgetMarkdownFiles: vi.fn().mockReturnValue([]),\n\t\t\tgetFolderByPath: vi.fn(),\n\t\t},\n\t\tworkspace: {\n\t\t\tgetActiveFile: vi.fn(),\n\t\t\ton: vi.fn(),\n\t\t},\n\t};\n}\n\n// Helper to create mock TFile instances\nexport function createMockFile(\n\tpath: string,\n\toptions?: {\n\t\tbasename?: string;\n\t\tparentPath?: string;\n\t\textension?: string;\n\t}\n): TFile {\n\tconst file = new TFile(path, options?.parentPath);\n\tif (options?.basename) {\n\t\tfile.basename = options.basename;\n\t}\n\tif (options?.extension) {\n\t\tfile.extension = options.extension;\n\t}\n\treturn file;\n}\n\n// Helper to create mock file cache\nexport function createMockFileCache(frontmatter?: Record<string, any>) {\n\treturn {\n\t\tfrontmatter: frontmatter || {},\n\t\tfrontmatterPosition: frontmatter ? { start: { line: 0 }, end: { line: 3 } } : null,\n\t\tsections: [],\n\t\theadings: [],\n\t\tlinks: [],\n\t\tembeds: [],\n\t\ttags: [],\n\t\tlistItems: [],\n\t};\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const mockFileOperations: {
|
|
2
|
+
arraysEqual: import("vitest").Mock<(...args: any[]) => any>;
|
|
3
|
+
normalizeArray: import("vitest").Mock<(...args: any[]) => any>;
|
|
4
|
+
createFileLink: import("vitest").Mock<(...args: any[]) => any>;
|
|
5
|
+
};
|
|
6
|
+
export declare const mockLinkParser: {
|
|
7
|
+
extractFilePathFromLink: import("vitest").Mock<(...args: any[]) => any>;
|
|
8
|
+
};
|
|
9
|
+
export declare function setupDefaultMockImplementations(): void;
|
|
10
|
+
export declare function resetAllMocks(): void;
|
|
11
|
+
export declare function setupMockImplementation(mockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser, implementation: (...args: any[]) => any): void;
|
|
12
|
+
export declare function setupMockReturnValue(mockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser, value: any): void;
|
|
13
|
+
export declare function verifyMockCalls(mockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser, expectedCalls: any[][]): void;
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/testing/mocks/utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAGF,eAAO,MAAM,cAAc;;CAE1B,CAAC;AAGF,wBAAgB,+BAA+B,SA+C9C;AAGD,wBAAgB,aAAa,SAO5B;AAGD,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,MAAM,OAAO,kBAAkB,GAAG,MAAM,OAAO,cAAc,EACvE,cAAc,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,QAOvC;AAGD,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,MAAM,OAAO,kBAAkB,GAAG,MAAM,OAAO,cAAc,EACvE,KAAK,EAAE,GAAG,QAOV;AAGD,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,MAAM,OAAO,kBAAkB,GAAG,MAAM,OAAO,cAAc,EACvE,aAAa,EAAE,GAAG,EAAE,EAAE,QAWtB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { expect, vi } from "vitest";
|
|
2
|
+
// File operations mocks
|
|
3
|
+
export const mockFileOperations = {
|
|
4
|
+
arraysEqual: vi.fn(),
|
|
5
|
+
normalizeArray: vi.fn(),
|
|
6
|
+
createFileLink: vi.fn(),
|
|
7
|
+
};
|
|
8
|
+
// Link parser mocks
|
|
9
|
+
export const mockLinkParser = {
|
|
10
|
+
extractFilePathFromLink: vi.fn(),
|
|
11
|
+
};
|
|
12
|
+
// Default mock implementations that match the actual behavior
|
|
13
|
+
export function setupDefaultMockImplementations() {
|
|
14
|
+
// Set up file operations mocks
|
|
15
|
+
mockFileOperations.normalizeArray.mockImplementation((arr) => Array.isArray(arr) ? arr : arr ? [arr] : []);
|
|
16
|
+
mockFileOperations.arraysEqual.mockImplementation((a, b) => JSON.stringify(a) === JSON.stringify(b));
|
|
17
|
+
mockFileOperations.createFileLink.mockImplementation((file) => {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
if (!file)
|
|
20
|
+
return "[[Unknown File]]";
|
|
21
|
+
const basename = file.basename ||
|
|
22
|
+
((_b = (_a = file.path) === null || _a === void 0 ? void 0 : _a.split("/").pop()) === null || _b === void 0 ? void 0 : _b.replace(/\.[^/.]+$/, "")) ||
|
|
23
|
+
"";
|
|
24
|
+
const parentPath = (_c = file.parent) === null || _c === void 0 ? void 0 : _c.path;
|
|
25
|
+
if (!parentPath || parentPath === "/" || parentPath === "") {
|
|
26
|
+
return `[[${basename}]]`;
|
|
27
|
+
}
|
|
28
|
+
return `[[${parentPath}/${basename}|${basename}]]`;
|
|
29
|
+
});
|
|
30
|
+
// Set up link parser mocks
|
|
31
|
+
mockLinkParser.extractFilePathFromLink.mockImplementation((link) => {
|
|
32
|
+
if (!link || typeof link !== "string")
|
|
33
|
+
return null;
|
|
34
|
+
// Handle text that contains a link
|
|
35
|
+
const linkMatch = link.match(/\[\[([^\]]+)\]\]/);
|
|
36
|
+
if (linkMatch) {
|
|
37
|
+
const content = linkMatch[1];
|
|
38
|
+
// Remove display name if present
|
|
39
|
+
const filePart = content.split("|")[0].trim();
|
|
40
|
+
if (!filePart)
|
|
41
|
+
return null;
|
|
42
|
+
// Add .md extension if not present
|
|
43
|
+
return filePart.endsWith(".md") ? filePart : `${filePart}.md`;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Reset all mocks
|
|
49
|
+
export function resetAllMocks() {
|
|
50
|
+
Object.values(mockFileOperations).forEach((mock) => {
|
|
51
|
+
mock.mockReset();
|
|
52
|
+
});
|
|
53
|
+
Object.values(mockLinkParser).forEach((mock) => {
|
|
54
|
+
mock.mockReset();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Helper to setup mocks with specific implementations
|
|
58
|
+
export function setupMockImplementation(mockName, implementation) {
|
|
59
|
+
if (mockName in mockFileOperations) {
|
|
60
|
+
mockFileOperations[mockName].mockImplementation(implementation);
|
|
61
|
+
}
|
|
62
|
+
else if (mockName in mockLinkParser) {
|
|
63
|
+
mockLinkParser[mockName].mockImplementation(implementation);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Helper to setup mock return values
|
|
67
|
+
export function setupMockReturnValue(mockName, value) {
|
|
68
|
+
if (mockName in mockFileOperations) {
|
|
69
|
+
mockFileOperations[mockName].mockReturnValue(value);
|
|
70
|
+
}
|
|
71
|
+
else if (mockName in mockLinkParser) {
|
|
72
|
+
mockLinkParser[mockName].mockReturnValue(value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Helper to verify mock calls
|
|
76
|
+
export function verifyMockCalls(mockName, expectedCalls) {
|
|
77
|
+
const mock = mockName in mockFileOperations
|
|
78
|
+
? mockFileOperations[mockName]
|
|
79
|
+
: mockLinkParser[mockName];
|
|
80
|
+
expect(mock).toHaveBeenCalledTimes(expectedCalls.length);
|
|
81
|
+
expectedCalls.forEach((args, index) => {
|
|
82
|
+
expect(mock).toHaveBeenNthCalledWith(index + 1, ...args);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/testing/mocks/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, vi } from \"vitest\";\n\n// File operations mocks\nexport const mockFileOperations = {\n\tarraysEqual: vi.fn(),\n\tnormalizeArray: vi.fn(),\n\tcreateFileLink: vi.fn(),\n};\n\n// Link parser mocks\nexport const mockLinkParser = {\n\textractFilePathFromLink: vi.fn(),\n};\n\n// Default mock implementations that match the actual behavior\nexport function setupDefaultMockImplementations() {\n\t// Set up file operations mocks\n\tmockFileOperations.normalizeArray.mockImplementation((arr) =>\n\t\tArray.isArray(arr) ? arr : arr ? [arr] : []\n\t);\n\n\tmockFileOperations.arraysEqual.mockImplementation(\n\t\t(a, b) => JSON.stringify(a) === JSON.stringify(b)\n\t);\n\n\tmockFileOperations.createFileLink.mockImplementation((file) => {\n\t\tif (!file) return \"[[Unknown File]]\";\n\n\t\tconst basename =\n\t\t\tfile.basename ||\n\t\t\tfile.path\n\t\t\t\t?.split(\"/\")\n\t\t\t\t.pop()\n\t\t\t\t?.replace(/\\.[^/.]+$/, \"\") ||\n\t\t\t\"\";\n\t\tconst parentPath = file.parent?.path;\n\n\t\tif (!parentPath || parentPath === \"/\" || parentPath === \"\") {\n\t\t\treturn `[[${basename}]]`;\n\t\t}\n\n\t\treturn `[[${parentPath}/${basename}|${basename}]]`;\n\t});\n\n\t// Set up link parser mocks\n\tmockLinkParser.extractFilePathFromLink.mockImplementation((link) => {\n\t\tif (!link || typeof link !== \"string\") return null;\n\n\t\t// Handle text that contains a link\n\t\tconst linkMatch = link.match(/\\[\\[([^\\]]+)\\]\\]/);\n\t\tif (linkMatch) {\n\t\t\tconst content = linkMatch[1];\n\t\t\t// Remove display name if present\n\t\t\tconst filePart = content.split(\"|\")[0].trim();\n\t\t\tif (!filePart) return null;\n\n\t\t\t// Add .md extension if not present\n\t\t\treturn filePart.endsWith(\".md\") ? filePart : `${filePart}.md`;\n\t\t}\n\n\t\treturn null;\n\t});\n}\n\n// Reset all mocks\nexport function resetAllMocks() {\n\tObject.values(mockFileOperations).forEach((mock) => {\n\t\tmock.mockReset();\n\t});\n\tObject.values(mockLinkParser).forEach((mock) => {\n\t\tmock.mockReset();\n\t});\n}\n\n// Helper to setup mocks with specific implementations\nexport function setupMockImplementation(\n\tmockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser,\n\timplementation: (...args: any[]) => any\n) {\n\tif (mockName in mockFileOperations) {\n\t\t(mockFileOperations as any)[mockName].mockImplementation(implementation);\n\t} else if (mockName in mockLinkParser) {\n\t\t(mockLinkParser as any)[mockName].mockImplementation(implementation);\n\t}\n}\n\n// Helper to setup mock return values\nexport function setupMockReturnValue(\n\tmockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser,\n\tvalue: any\n) {\n\tif (mockName in mockFileOperations) {\n\t\t(mockFileOperations as any)[mockName].mockReturnValue(value);\n\t} else if (mockName in mockLinkParser) {\n\t\t(mockLinkParser as any)[mockName].mockReturnValue(value);\n\t}\n}\n\n// Helper to verify mock calls\nexport function verifyMockCalls(\n\tmockName: keyof typeof mockFileOperations | keyof typeof mockLinkParser,\n\texpectedCalls: any[][]\n) {\n\tconst mock =\n\t\tmockName in mockFileOperations\n\t\t\t? (mockFileOperations as any)[mockName]\n\t\t\t: (mockLinkParser as any)[mockName];\n\n\texpect(mock).toHaveBeenCalledTimes(expectedCalls.length);\n\texpectedCalls.forEach((args, index) => {\n\t\texpect(mock).toHaveBeenNthCalledWith(index + 1, ...args);\n\t});\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/testing/setup.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,eAcnC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
import { mockFileOperations, mockLinkParser } from "./mocks/utils";
|
|
3
|
+
// Global test setup that can be imported once per test file
|
|
4
|
+
export function setupTestEnvironment() {
|
|
5
|
+
// Mock the utils modules
|
|
6
|
+
vi.mock("@obsidian-plugins/utils/file-operations", () => mockFileOperations);
|
|
7
|
+
vi.mock("@obsidian-plugins/utils/link-parser", () => mockLinkParser);
|
|
8
|
+
// Mock any plugin-specific components
|
|
9
|
+
vi.mock("../src/components/settings-tab", () => ({
|
|
10
|
+
TreePropertiesManagerSettingTab: class MockSettingTab {
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
// Return cleanup function
|
|
14
|
+
return () => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/testing/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,4DAA4D;AAC5D,MAAM,UAAU,oBAAoB;IACnC,yBAAyB;IACzB,EAAE,CAAC,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAC7E,EAAE,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC;IAErE,sCAAsC;IACtC,EAAE,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChD,+BAA+B,EAAE,MAAM,cAAc;SAAG;KACxD,CAAC,CAAC,CAAC;IAEJ,0BAA0B;IAC1B,OAAO,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACpB,CAAC,CAAC;AACH,CAAC","sourcesContent":["import { vi } from \"vitest\";\nimport { mockFileOperations, mockLinkParser } from \"./mocks/utils\";\n\n// Global test setup that can be imported once per test file\nexport function setupTestEnvironment() {\n\t// Mock the utils modules\n\tvi.mock(\"@obsidian-plugins/utils/file-operations\", () => mockFileOperations);\n\tvi.mock(\"@obsidian-plugins/utils/link-parser\", () => mockLinkParser);\n\n\t// Mock any plugin-specific components\n\tvi.mock(\"../src/components/settings-tab\", () => ({\n\t\tTreePropertiesManagerSettingTab: class MockSettingTab {},\n\t}));\n\n\t// Return cleanup function\n\treturn () => {\n\t\tvi.clearAllMocks();\n\t};\n}\n"]}
|