UNPKG

insta-toc

Version:

Simultaneously generate, update, and maintain a table of contents for your notes in real time.

148 lines (125 loc) 5.88 kB
import type { PluginManifest } from "obsidian"; import { describe, expect, test, vi } from "vitest"; vi.mock("obsidian-dev-utils/obsidian/plugin/plugin-settings-manager-base", () => { return { PluginSettingsManagerBase: class PluginSettingsManagerBase { public app: unknown; public defaultSettings: Record<string, unknown>; public plugin: { app: unknown; loadData: () => Promise<Record<string, unknown> | null | undefined>; }; public settingsWrapper: { settings: Record<string, unknown>; }; public constructor( plugin: { app: unknown; loadData: () => Promise<Record<string, unknown> | null | undefined>; } ) { this.app = plugin.app; this.defaultSettings = this.createDefaultSettings(); this.plugin = plugin; this.settingsWrapper = { settings: { ...this.defaultSettings } }; this.registerValidators(); } public async loadFromFile(_isInitialLoad: boolean): Promise<void> { const data = await this.plugin.loadData(); const rawRecord = JSON.parse(JSON.stringify(data ?? {})) as Record<string, unknown>; await this.onLoadRecord(rawRecord); this.settingsWrapper = { settings: { ...this.defaultSettings, ...rawRecord } }; } public async saveToFile(): Promise<void> {} public registerValidators(): void {} protected createDefaultSettings(): Record<string, unknown> { return {}; } protected async onLoadRecord(_rawRecord: Record<string, unknown>): Promise<void> {} protected async onSavingRecord(_rawRecord: Record<string, unknown>): Promise<void> {} protected registerValidator(_key: string, _validator: (value: any) => string | void): void {} } }; }); vi.mock("obsidian-dev-utils/obsidian/plugin/plugin-base", () => ({ PluginBase: class PluginBase { public app: unknown; public manifest: unknown; public constructor(app?: unknown, manifest?: unknown) { this.app = app; this.manifest = manifest; } public registerEvent(): void {} public registerMarkdownCodeBlockProcessor(): void {} public addCommand(): void {} public addRibbonIcon(): void {} public async onloadImpl(): Promise<void> {} public async onunloadImpl(): Promise<void> {} } })); vi.mock("obsidian-dev-utils/obsidian/plugin/plugin-context", () => ({ initPluginContext: vi.fn() })); vi.mock("../src/settings/SettingsTab", () => ({ SettingTab: class SettingTab {} })); vi.mock( "../src/svelte", () => ({ CodeBlockComponent: class CodeBlockComponent {}, LocalSettingsModal: class LocalSettingsModal { public async open(): Promise<void> {} }, MarkdownComponentMounter: class MarkdownComponentMounter {} }) ); import InstaTocPlugin from "../src/Plugin"; import { injectGlobals } from "../src/globals/globalFuncs"; import type { PluginSettingsManager } from "../src/settings/PluginSettingManager"; injectGlobals(); function createPluginWithPersistedData( data: Record<string, unknown> ): InstaTocPlugin & { loadData: ReturnType<typeof vi.fn>; saveData: ReturnType<typeof vi.fn>; } { return Object.assign(Object.create(InstaTocPlugin.prototype), { app: {}, loadData: vi .fn(async () => JSON.parse(JSON.stringify(data)) as Record<string, unknown>), manifest: { author: "Nick C.", description: "Simultaneously generate, update, and maintain a table of contents for your notes.", id: "insta-toc", minAppVersion: "0.15.0", name: "Insta TOC", version: "7.0.0" } satisfies PluginManifest, saveData: vi.fn(async () => undefined) }); } function createSettingsManager(plugin: InstaTocPlugin): PluginSettingsManager { const createSettingsManager = Reflect.get(InstaTocPlugin.prototype as object, "createSettingsManager") as ( this: InstaTocPlugin ) => PluginSettingsManager; return createSettingsManager.call(plugin); } describe("InstaTocPlugin settings initialization", () => { test("loads persisted ui state through the settings manager without requiring onloadImpl", async () => { // Arrange const persistedData = { settings: { excludedChars: [ "*", "_", "#" ], excludedHeadingLevels: [ 2 ], excludedHeadingText: [ "Draft" ], tocTitle: "Contents", tocTitleCentered: false, tocTitleLevel: 2, updateDelay: 1000 }, tocBlockCollapseState: { "folder/note.md": true }, tocFoldState: { "folder/note.md::1": true, "folder/note.md::2": false } }; const plugin = createPluginWithPersistedData(persistedData); const settingsManager = createSettingsManager(plugin); // Act await settingsManager.loadFromFile(true); await settingsManager.savePersistedData(); // Assert expect(plugin.uiStateManager.getPersistedUiState()).toEqual({ tocBlockCollapseState: new Map([ [ "folder/note.md", true ] ]), tocFoldState: new Map([ [ "folder/note.md::1", true ], [ "folder/note.md::2", false ] ]) }); expect(settingsManager.settingsWrapper.settings.tocTitle).toBe("Contents"); expect(plugin.saveData).toHaveBeenCalledWith({ settings: persistedData.settings, tocBlockCollapseState: { "folder/note.md": true }, tocFoldState: { "folder/note.md::1": true, "folder/note.md::2": false } }); }); });