UNPKG

insta-toc

Version:

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

129 lines (104 loc) 5.16 kB
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { FileKey, FoldKey } from "../src/types"; import { createUiStateManagerMock } from "./mocks/pluginClassMocks"; describe("UiStateManager", () => { const persistedUiStateSaveDelayMs = 500; beforeEach(() => { vi.useFakeTimers(); vi.stubGlobal("app", { plugins: { getPlugin: vi.fn(() => ({ settings: { updateDelay: 1000 } })) } }); }); afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); vi.useRealTimers(); }); test("returns cloned persisted ui state snapshots", () => { // Arrange const foldKey: FoldKey = "note.md::1"; const fileKey: FileKey = "note.md"; const { uiStateManager } = createUiStateManagerMock({ tocBlockCollapseState: { [fileKey]: true }, tocFoldState: { [foldKey]: true } }); // Act const snapshot = uiStateManager.getPersistedUiState(); snapshot.tocFoldState.set(foldKey, false); snapshot.tocBlockCollapseState.set(fileKey, false); // Assert expect(uiStateManager.getTocFoldState(foldKey)).toBe(true); expect(uiStateManager.getTocBlockCollapsed(fileKey)).toBe(true); }); test("persists fold state changes only when the value changes", () => { // Arrange const foldKey: FoldKey = "note.md::1"; const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock(); // Act uiStateManager.setTocFoldState(foldKey, true); uiStateManager.setTocFoldState(foldKey, true); // Assert expect(uiStateManager.getTocFoldState(foldKey)).toBe(true); expect(savePersistedDataSpy).not.toHaveBeenCalled(); }); test("batches rapid fold state updates into a single debounced save", async () => { // Arrange const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock(); // Act uiStateManager.setTocFoldState("note.md::1", true); uiStateManager.setTocFoldState("note.md::2", true); await vi.advanceTimersByTimeAsync(persistedUiStateSaveDelayMs); // Assert expect(savePersistedDataSpy).toHaveBeenCalledTimes(1); }); test("persists block collapse changes only when the value changes", () => { // Arrange const fileKey = "note.md" as FileKey; const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock(); // Act uiStateManager.setTocBlockCollapsed(fileKey, true); uiStateManager.setTocBlockCollapsed(fileKey, true); // Assert expect(uiStateManager.getTocBlockCollapsed(fileKey)).toBe(true); expect(savePersistedDataSpy).not.toHaveBeenCalled(); }); test("flushPersistedData saves immediately and cancels a pending debounce", async () => { // Arrange const foldKey: FoldKey = "note.md::1"; const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock(); // Act uiStateManager.setTocFoldState(foldKey, true); await uiStateManager.flushPersistedData(); await vi.runAllTimersAsync(); // Assert expect(savePersistedDataSpy).toHaveBeenCalledTimes(1); }); test("prunes inactive fold keys for a file path and keeps active modern keys", async () => { // Arrange const activeFoldKey: FoldKey = "note.md::2"; const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock({ tocFoldState: new Map([ [ "note.md::1", true ], [ activeFoldKey, false ], [ "other.md::1", true ] ]) }); // Act uiStateManager.pruneTocFoldStateForPath("note.md", { activeModernFoldKeys: new Set([ activeFoldKey ]) }); // Assert expect(uiStateManager.getTocFoldState("note.md::1" as FoldKey)).toBeUndefined(); expect(uiStateManager.getTocFoldState(activeFoldKey)).toBe(false); expect(uiStateManager.getTocFoldState("other.md::1" as FoldKey)).toBe(true); await vi.advanceTimersByTimeAsync(persistedUiStateSaveDelayMs); expect(savePersistedDataSpy).toHaveBeenCalledTimes(1); }); test("moves fold state to the replacement file on rename", async () => { // Arrange const { savePersistedDataSpy, uiStateManager } = createUiStateManagerMock({ tocFoldState: new Map([ [ "old-note.md::1", true ], [ "old-note.md::2", false ] ]) }); // Act uiStateManager.pruneTocFoldStateForPath("old-note.md", { replacementFile: "new-note.md" }); // Assert expect(uiStateManager.getTocFoldState("old-note.md::1" as FoldKey)).toBeUndefined(); expect(uiStateManager.getTocFoldState("old-note.md::2" as FoldKey)).toBeUndefined(); expect(uiStateManager.getTocFoldState("new-note.md::1" as FoldKey)).toBe(true); expect(uiStateManager.getTocFoldState("new-note.md::2" as FoldKey)).toBe(false); await vi.advanceTimersByTimeAsync(persistedUiStateSaveDelayMs); expect(savePersistedDataSpy).toHaveBeenCalledTimes(1); }); });