import { describe, expect, test } from 'bun:test'; import { bodyOf, frontmatter, patchFrontmatter } from './tree'; const FILE = `--- id: fleet/an-item title: "An item, with: punctuation" theme: fleet status: open created: 2026-08-21 order: 2 --- **The body.** Hand-written prose with --- inside it. - a list `; describe('frontmatter', () => { test('reads plain and JSON-quoted values', () => { const fm = frontmatter(FILE); expect(fm.id).toBe('fleet/an-item'); expect(fm.title).toBe('An item, with: punctuation'); expect(fm.order).toBe('2'); }); test('accepts prettier-style single quotes', () => { expect(frontmatter(`---\ntitle: 'A quoted title'\n---\n`).title).toBe('A quoted title'); }); test('no frontmatter → empty', () => { expect(frontmatter('just prose')).toEqual({}); }); }); describe('bodyOf', () => { test('returns everything after the fence, trimmed of leading blank lines', () => { expect(bodyOf(FILE).startsWith('**The body.**')).toBe(true); }); }); describe('patchFrontmatter', () => { test('replaces an existing key in place', () => { const out = patchFrontmatter(FILE, { status: 'done' }); expect(frontmatter(out).status).toBe('done'); expect(out.match(/^status:/gm)).toHaveLength(1); }); test('appends a key that was absent', () => { const out = patchFrontmatter(FILE, { priority: 'urgent' }); expect(frontmatter(out).priority).toBe('urgent'); }); test('never touches the body — byte for byte', () => { const out = patchFrontmatter(FILE, { status: 'doing', order: '9' }); expect(bodyOf(out)).toBe(bodyOf(FILE)); }); test('a --- inside the body is not mistaken for the fence', () => { const out = patchFrontmatter(FILE, { status: 'done' }); expect(out).toContain('with --- inside it'); }); });