UNPKG

insta-toc

Version:

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

110 lines (90 loc) 3.86 kB
import { describe, expect, test } from "vitest"; import { TocModel } from "../src/tocModel"; import type { FileKey, FoldKey, TocBlockModel } from "../src/types"; import { createTocModelPluginMock } from "./mocks/pluginClassMocks"; type CreateModelOptions = { sourceFilePath?: FileKey; initialFoldState?: Partial<Record<FoldKey, boolean>>; settingsOverrides?: { tocTitle?: string; tocTitleLevel?: 1 | 2 | 3 | 4 | 5 | 6; tocTitleCentered?: boolean; excludedChars?: string[]; }; }; function createModel( source: string, { sourceFilePath = "notes/my-note.md", initialFoldState = {}, settingsOverrides = {} }: CreateModelOptions = {} ): { model: TocBlockModel; pruneSpy: ReturnType<typeof createTocModelPluginMock>["pruneSpy"]; } { const { app, pruneSpy, settings, uiStateManager } = createTocModelPluginMock(settingsOverrides, { tocFoldState: initialFoldState }); const model = new TocModel( uiStateManager, app, settings, { localSettings: source, sourceFilePath }, (key) => uiStateManager.getTocFoldState(key) ) .model; return { model, pruneSpy }; } describe("TocModel fold state", () => { test("assigns foldKey and initialCollapsed=false when no persisted state exists", () => { // Arrange const source = `- Heading 1\n - Heading 2`; // Act const { model, pruneSpy } = createModel(source); const [ parent ] = model.items; const [ child ] = parent.children; // Assert expect(parent.foldKey).toBe("notes/my-note.md::1"); expect(parent.initialCollapsed).toBe(false); expect(child.foldKey).toBeNull(); expect(pruneSpy).toHaveBeenCalledTimes(1); expect(pruneSpy).toHaveBeenCalledWith( "notes/my-note.md", expect.objectContaining({ activeModernFoldKeys: expect.any(Set) }) ); expect([ ...(pruneSpy.mock.calls[0]?.[1].activeModernFoldKeys ?? []) ]).toEqual([ "notes/my-note.md::1" ]); }); test("restores collapsed state from persisted modern fold key", () => { // Arrange const source = `- Heading 1\n - Heading 2`; // Act const { model } = createModel(source, { initialFoldState: { "notes/my-note.md::1": true } }); // Assert expect(model.items[0].initialCollapsed).toBe(true); }); test("does not leak fold state across different file paths", () => { // Arrange const source = `- Heading 1\n - Heading 2`; // Act const { model } = createModel(source, { sourceFilePath: "notes/file-b.md", initialFoldState: { "notes/file-a.md::1": true } }); // Assert expect(model.items[0].initialCollapsed).toBe(false); }); test("tracks foldParentIndex across nested items", () => { // Arrange const source = `- Heading 1\n - Heading 2\n - Heading 3`; // Act const { model, pruneSpy } = createModel(source, { sourceFilePath: "note.md" }); const [ parent ] = model.items; const [ child ] = parent.children; // Assert expect(parent.foldKey).toBe("note.md::1"); expect(child.foldKey).toBe("note.md::2"); expect([ ...(pruneSpy.mock.calls[0]?.[1].activeModernFoldKeys ?? []) ]).toEqual([ "note.md::1", "note.md::2" ]); }); test("resolves the rendered title from local settings while building the model", () => { // Arrange const source = `---\ntitle:\n name: Local TOC\n level: 2\n center: true\n---\n\n- Heading 1`; // Act const { model } = createModel(source); // Assert expect(model.title).toEqual({ text: "Local TOC", level: 2, centered: true, usesGlobalCentering: false }); }); });