79 lines
2.8 KiB
Python
79 lines
2.8 KiB
Python
"""Tests for Frontmatter parser — TOML frontmatter parsing and serialisation."""
|
|||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from volumen.frontmatter import dump, parse
|
||
|
|
|
||
|
|
|
||
|
|
class TestParse:
|
||
|
|
def test_parse_extracts_metadata_and_body(self) -> None:
|
||
|
|
content = '+++\ntitle = "Hello"\ntags = ["a", "b"]\n+++\n\nBody text.\n'
|
||
|
|
metadata, body = parse(content)
|
||
|
|
assert metadata["title"] == "Hello"
|
||
|
|
assert metadata["tags"] == ["a", "b"]
|
||
|
|
assert body == "Body text.\n"
|
||
|
|
|
||
|
|
def test_parse_without_frontmatter(self) -> None:
|
||
|
|
metadata, body = parse("# Just markdown\n")
|
||
|
|
assert metadata == {}
|
||
|
|
assert body == "# Just markdown\n"
|
||
|
|
|
||
|
|
def test_parse_without_closing_delimiter(self) -> None:
|
||
|
|
content = '+++\ntitle = "x"\n\nbody'
|
||
|
|
metadata, body = parse(content)
|
||
|
|
assert metadata == {}
|
||
|
|
assert body == content
|
||
|
|
|
||
|
|
def test_parse_empty_frontmatter(self) -> None:
|
||
|
|
content = "+++\n+++\n\nBody here.\n"
|
||
|
|
metadata, body = parse(content)
|
||
|
|
assert metadata == {}
|
||
|
|
assert body == "Body here.\n"
|
||
|
|
|
||
|
|
def test_parse_draft_false(self) -> None:
|
||
|
|
content = '+++\ntitle = "X"\ndraft = false\n+++\n\nBody\n'
|
||
|
|
metadata, body = parse(content)
|
||
|
|
assert metadata["draft"] is False
|
||
|
|
|
||
|
|
def test_parse_nested_tables(self) -> None:
|
||
|
|
content = '+++\n[meta]\ntitle = "X"\n+++\n\nBody\n'
|
||
|
|
metadata, body = parse(content)
|
||
|
|
assert metadata["meta"]["title"] == "X"
|
||
|
|
|
||
|
|
def test_parse_normalises_crlf(self) -> None:
|
||
|
|
metadata, body = parse('+++\r\ntitle = "x"\r\n+++\r\n\r\nBody\r\n')
|
||
|
|
assert metadata["title"] == "x"
|
||
|
|
assert body == "Body\n"
|
||
|
|
|
||
|
|
|
||
|
|
class TestDump:
|
||
|
|
def test_dump_produces_valid_frontmatter(self) -> None:
|
||
|
|
result = dump({"title": "Hello", "tags": ["a"]}, "Body text.\n")
|
||
|
|
assert result.startswith("+++\n")
|
||
|
|
assert "+++\n\n" in result
|
||
|
|
assert "Body text." in result
|
||
|
|
|
||
|
|
def test_dump_empty_metadata(self) -> None:
|
||
|
|
result = dump({}, "Just body.\n")
|
||
|
|
assert "+++" in result
|
||
|
|
assert "Just body." in result
|
||
|
|
|
||
|
|
def test_round_trip(self) -> None:
|
||
|
|
metadata = {"title": "Hello", "tags": ["intro"], "draft": False}
|
||
|
|
dumped = dump(metadata, "Hello **world**.")
|
||
|
|
parsed_meta, parsed_body = parse(dumped)
|
||
|
|
assert parsed_meta == metadata
|
||
|
|
assert parsed_body.strip() == "Hello **world**."
|
||
|
|
|
||
|
|
def test_round_trip_with_empty_metadata(self) -> None:
|
||
|
|
dumped = dump({}, "Just body.\n")
|
||
|
|
parsed_meta, parsed_body = parse(dumped)
|
||
|
|
assert parsed_meta == {}
|
||
|
|
assert parsed_body.strip() == "Just body."
|
||
|
|
|
||
|
|
def test_round_trip_preserves_dates(self) -> None:
|
||
|
|
metadata = {"title": "X", "date": "2026-01-15"}
|
||
|
|
dumped = dump(metadata, "Body\n")
|
||
|
|
parsed_meta, _ = parse(dumped)
|
||
|
|
assert parsed_meta["date"] == "2026-01-15"
|