test_frontmatter_obsidian_compatible.py•5.7 kB
"""Tests for Obsidian-compatible YAML frontmatter formatting."""
import frontmatter
from basic_memory.file_utils import dump_frontmatter
def test_tags_formatted_as_yaml_list():
"""Test that tags are formatted as YAML list instead of JSON array."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["type"] = "note"
post.metadata["tags"] = ["system", "overview", "reference"]
result = dump_frontmatter(post)
# Should use YAML list format
assert "tags:" in result
assert "- system" in result
assert "- overview" in result
assert "- reference" in result
# Should NOT use JSON array format
assert '["system"' not in result
assert '"overview"' not in result
assert '"reference"]' not in result
def test_empty_tags_list():
"""Test that empty tags list is handled correctly."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["tags"] = []
result = dump_frontmatter(post)
# Should have empty list representation
assert "tags: []" in result
def test_single_tag():
"""Test that single tag is still formatted as list."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["tags"] = ["single-tag"]
result = dump_frontmatter(post)
assert "tags:" in result
assert "- single-tag" in result
def test_no_tags_metadata():
"""Test that posts without tags work normally."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["type"] = "note"
result = dump_frontmatter(post)
assert "title: Test Note" in result
assert "type: note" in result
assert "tags:" not in result
def test_no_frontmatter():
"""Test that posts with no frontmatter just return content."""
post = frontmatter.Post("Test content only")
result = dump_frontmatter(post)
assert result == "Test content only"
def test_complex_tags_with_special_characters():
"""Test tags with hyphens, underscores, and other valid characters."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["tags"] = ["python-test", "api_integration", "v2.0", "nested/tag"]
result = dump_frontmatter(post)
assert "- python-test" in result
assert "- api_integration" in result
assert "- v2.0" in result
assert "- nested/tag" in result
def test_tags_order_preserved():
"""Test that tag order is preserved in output."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["tags"] = ["zebra", "apple", "banana"]
result = dump_frontmatter(post)
# Find the positions of each tag in the output
zebra_pos = result.find("- zebra")
apple_pos = result.find("- apple")
banana_pos = result.find("- banana")
# They should appear in the same order as input
assert zebra_pos < apple_pos < banana_pos
def test_non_tags_lists_also_formatted():
"""Test that other lists in metadata are also formatted properly."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["authors"] = ["John Doe", "Jane Smith"]
post.metadata["keywords"] = ["AI", "machine learning"]
result = dump_frontmatter(post)
# Authors should be formatted as YAML list
assert "authors:" in result
assert "- John Doe" in result
assert "- Jane Smith" in result
# Keywords should be formatted as YAML list
assert "keywords:" in result
assert "- AI" in result
assert "- machine learning" in result
def test_mixed_metadata_types():
"""Test that mixed metadata types are handled correctly."""
post = frontmatter.Post("Test content")
post.metadata["title"] = "Test Note"
post.metadata["tags"] = ["tag1", "tag2"]
post.metadata["created"] = "2024-01-01"
post.metadata["priority"] = 5
post.metadata["draft"] = True
result = dump_frontmatter(post)
# Lists should use YAML format
assert "tags:" in result
assert "- tag1" in result
assert "- tag2" in result
# Other types should be normal
assert "title: Test Note" in result
assert "created: '2024-01-01'" in result or "created: 2024-01-01" in result
assert "priority: 5" in result
assert "draft: true" in result or "draft: True" in result
def test_empty_content():
"""Test posts with empty content but with frontmatter."""
post = frontmatter.Post("")
post.metadata["title"] = "Empty Note"
post.metadata["tags"] = ["empty", "test"]
result = dump_frontmatter(post)
# Should have frontmatter delimiter
assert result.startswith("---")
assert result.endswith("---\n")
# Should have proper tag formatting
assert "- empty" in result
assert "- test" in result
def test_roundtrip_compatibility():
"""Test that the formatted output can be parsed back by frontmatter."""
original_post = frontmatter.Post("Test content")
original_post.metadata["title"] = "Test Note"
original_post.metadata["tags"] = ["system", "test", "obsidian"]
original_post.metadata["type"] = "note"
# Format with our function
formatted = dump_frontmatter(original_post)
# Parse it back
parsed_post = frontmatter.loads(formatted)
# Should have same content and metadata
assert parsed_post.content == original_post.content
assert parsed_post.metadata["title"] == original_post.metadata["title"]
assert parsed_post.metadata["tags"] == original_post.metadata["tags"]
assert parsed_post.metadata["type"] == original_post.metadata["type"]