Files
basicmachines-co-basic-memory/tests/markdown/test_parser.py
T
2024-12-22 14:40:12 -06:00

145 lines
4.1 KiB
Python

"""Tests for entity markdown parser."""
import pytest
from pathlib import Path
from basic_memory.markdown.parser import EntityParser
from basic_memory.utils.file_utils import ParseError, FileError
from basic_memory.markdown.schemas import (
Entity,
EntityFrontmatter,
EntityContent,
EntityMetadata,
)
@pytest.fixture
def sample_entity_content():
"""Sample entity file content."""
return """---
type: test
id: test/test_entity
created: 2024-12-22T10:00:00Z
modified: 2024-12-22T10:00:00Z
tags: [entity, test]
metadata:
checksum: abc123
doc_id: 1
---
# Test Entity
A test entity for testing purposes.
## Observations
- [tech] First technical observation #tag1 (first context)
- [design] Second design observation #tag2 (second context)
## Relations
- depends_on [[Other Entity]] (Testing the relation parsing)
"""
@pytest.mark.asyncio
async def test_parse_valid_file(tmp_path: Path, sample_entity_content):
"""Test parsing valid entity file."""
# Create test file
test_file = tmp_path / "test.md"
test_file.write_text(sample_entity_content)
# Parse file
parser = EntityParser()
entity = await parser.parse_file(test_file)
# Verify frontmatter
assert isinstance(entity.frontmatter, EntityFrontmatter)
assert entity.frontmatter.type == "test"
assert entity.frontmatter.id == "test/test_entity"
# Verify content
assert isinstance(entity.content, EntityContent)
assert entity.content.title == "Test Entity"
assert entity.content.description == "A test entity for testing purposes."
# Verify observations
assert len(entity.content.observations) == 2
obs1 = entity.content.observations[0]
assert obs1.category == "tech"
assert obs1.content == "First technical observation"
assert obs1.tags == ["tag1"]
assert obs1.context == "first context"
obs2 = entity.content.observations[1]
assert obs2.category == "design"
assert obs2.content == "Second design observation"
assert obs2.tags == ["tag2"]
assert obs2.context == "second context"
# Verify relations
assert len(entity.content.relations) == 1
rel = entity.content.relations[0]
assert rel.target == "Other Entity"
assert rel.type == "depends_on"
assert rel.context == "Testing the relation parsing"
@pytest.mark.asyncio
async def test_parse_missing_file():
"""Test error on missing file."""
parser = EntityParser()
with pytest.raises(FileError):
await parser.parse_file(Path("nonexistent.md"))
@pytest.mark.asyncio
async def test_parse_invalid_frontmatter(tmp_path: Path):
"""Test error on invalid frontmatter."""
test_file = tmp_path / "test.md"
# Create invalid frontmatter by removing required field
content = """---
type: test
# missing id field
created: 2024-12-22T10:00:00Z
modified: 2024-12-22T10:00:00Z
tags: [entity]
---
# Test Entity"""
test_file.write_text(content)
parser = EntityParser()
with pytest.raises(ParseError):
await parser.parse_file(test_file)
@pytest.mark.asyncio
async def test_parse_no_frontmatter(tmp_path: Path):
"""Test file with no frontmatter."""
test_file = tmp_path / "test.md"
content = "Just content"
test_file.write_text(content)
parser = EntityParser()
with pytest.raises(ParseError):
await parser.parse_file(test_file)
@pytest.mark.asyncio
async def test_parse_content_str(sample_entity_content):
"""Test parsing content string directly."""
parser = EntityParser()
entity = await parser.parse_content_str(sample_entity_content)
assert isinstance(entity, Entity)
assert entity.frontmatter.type == "test"
assert entity.frontmatter.id == "test/test_entity"
assert entity.content.title == "Test Entity"
# Verify observations parsed correctly
assert len(entity.content.observations) == 2
assert entity.content.observations[0].category == "tech"
assert entity.content.observations[1].category == "design"
# Verify relation parsed correctly
assert len(entity.content.relations) == 1
assert entity.content.relations[0].type == "depends_on"
assert entity.content.relations[0].target == "Other Entity"