Files
gitmost/packages/git-sync/test/page-file.test.ts
claude code agent 227 a91405632e feat(git-sync): native-Obsidian format — phase 1 = page-file (frontmatter gitmost_id)
Pivot the thin-meta design to "the vault IS a native Obsidian vault": clean
markdown + a minimal YAML frontmatter `gitmost_id:` (the durable pageId, travels
with the file so identity survives any move); folders mirror the page tree with
the parent's body as a folder-note `<Folder>/<Folder>.md` (LostPaul Folder Notes
convention); links as `[[wikilinks]]` (basename-resolved → reparent never breaks a
link, only retitle does); collisions disambiguated Obsidian-style; `.obsidian/`
and non-page files left untouched (no .gitignore). Verified the conventions
against the Obsidian/Folder-Notes docs.

Replaces the abandoned `.gitmost/index.json` sidecar (path-keyed → fragile to
git-undetected renames; the in-file id is self-sufficient): removes vault-index.ts.
Adds lib/page-file.ts — parsePageFile/serializePageFile (frontmatter id + clean
body) with a LEGACY `docmost:meta` fallback for migration. 6 unit tests; engine
suite green. Not yet wired into pull/push — no behavior change. Design doc
rewritten to the native-Obsidian format.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 15:10:10 +03:00

44 lines
1.7 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { parsePageFile, serializePageFile } from "../src/lib/page-file";
import { serializeDocmostMarkdownBody } from "../src/lib/index";
describe("page-file thin format", () => {
it("round-trips id frontmatter + clean body", () => {
const text = serializePageFile("019ef6fc-2638", "# Hello\n\nbody text");
expect(text.startsWith("---\ngitmost_id: 019ef6fc-2638\n---\n")).toBe(true);
const { id, body } = parsePageFile(text);
expect(id).toBe("019ef6fc-2638");
expect(body).toBe("# Hello\n\nbody text");
});
it("serialization is deterministic (byte-identical for the same input)", () => {
expect(serializePageFile("p", "x")).toBe(serializePageFile("p", "x"));
});
it("reads id from frontmatter with quotes / extra fields", () => {
expect(parsePageFile('---\ngitmost_id: "abc"\ntitle: ignored\n---\nbody').id).toBe("abc");
expect(parsePageFile("---\ngitmost_id: 'xyz'\n---\nbody").id).toBe("xyz");
});
it("MIGRATION: falls back to a legacy docmost:meta block for the id", () => {
const legacy = serializeDocmostMarkdownBody(
{ version: 1, pageId: "legacy-1", title: "T", spaceId: "sp" },
"old body",
);
const { id, body } = parsePageFile(legacy);
expect(id).toBe("legacy-1");
expect(body).toContain("old body");
});
it("ADOPT: a plain hand-written file has no id and keeps its whole body", () => {
const { id, body } = parsePageFile("# Just a note\n\nwritten in Obsidian");
expect(id).toBeNull();
expect(body).toBe("# Just a note\n\nwritten in Obsidian");
});
it("tolerates empty / whitespace input", () => {
expect(parsePageFile("").id).toBeNull();
expect(parsePageFile(" \n ").body).toBe("");
});
});