-
Notifications
You must be signed in to change notification settings - Fork 188
Expand file tree
/
Copy pathtest_markdown_processor.py
More file actions
186 lines (152 loc) · 5.59 KB
/
test_markdown_processor.py
File metadata and controls
186 lines (152 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
"""Tests for MarkdownProcessor.
Tests focus on the Read -> Modify -> Write pattern and content preservation.
"""
from datetime import datetime
from pathlib import Path
import pytest
from basic_memory.markdown.markdown_processor import DirtyFileError, MarkdownProcessor
from basic_memory.markdown.schemas import (
EntityFrontmatter,
EntityMarkdown,
Observation,
Relation,
)
@pytest.mark.asyncio
async def test_write_new_minimal_file(markdown_processor: MarkdownProcessor, tmp_path: Path):
"""Test creating new file with just title."""
path = tmp_path / "test.md"
# Create minimal markdown schema
metadata = {}
metadata["title"] = "Test Note"
metadata["type"] = "note"
metadata["permalink"] = "test"
metadata["created"] = datetime(2024, 1, 1)
metadata["modified"] = datetime(2024, 1, 1)
metadata["tags"] = ["test"]
markdown = EntityMarkdown(
frontmatter=EntityFrontmatter(
metadata=metadata,
),
content="",
)
# Write file
await markdown_processor.write_file(path, markdown)
# Read back and verify
content = path.read_text(encoding="utf-8")
assert "---" in content # Has frontmatter
assert "type: note" in content
assert "permalink: test" in content
assert "# Test Note" in content # Added title
assert "tags:" in content
assert "- test" in content
# Should not have empty sections
assert "## Observations" not in content
assert "## Relations" not in content
@pytest.mark.asyncio
async def test_write_new_file_with_content(markdown_processor: MarkdownProcessor, tmp_path: Path):
"""Test creating new file with content and sections."""
path = tmp_path / "test.md"
# Create markdown with content and sections
markdown = EntityMarkdown(
frontmatter=EntityFrontmatter(
type="note",
permalink="test",
title="Test Note",
created=datetime(2024, 1, 1),
modified=datetime(2024, 1, 1),
),
content="# Custom Title\n\nMy content here.\nMultiple lines.",
observations=[
Observation(
content="Test observation #test",
category="tech",
tags=["test"],
context="test context",
),
],
relations=[
Relation(
type="relates_to",
target="other-note",
context="test relation",
),
],
)
# Write file
await markdown_processor.write_file(path, markdown)
# Read back and verify
content = path.read_text(encoding="utf-8")
# Check content preserved exactly
assert "# Custom Title" in content
assert "My content here." in content
assert "Multiple lines." in content
# Check sections formatted correctly
assert "- [tech] Test observation #test (test context)" in content
assert "- relates_to [[other-note]] (test relation)" in content
@pytest.mark.asyncio
async def test_update_preserves_content(markdown_processor: MarkdownProcessor, tmp_path: Path):
"""Test that updating file preserves existing content."""
path = tmp_path / "test.md"
# Create initial file
initial = EntityMarkdown(
frontmatter=EntityFrontmatter(
type="note",
permalink="test",
title="Test Note",
created=datetime(2024, 1, 1),
modified=datetime(2024, 1, 1),
),
content="# My Note\n\nOriginal content here.",
observations=[
Observation(content="First observation", category="note"),
],
)
checksum = await markdown_processor.write_file(path, initial)
# Update with new observation
updated = EntityMarkdown(
frontmatter=initial.frontmatter,
content=initial.content, # Preserve original content
observations=[
initial.observations[0], # Keep original observation
Observation(content="Second observation", category="tech"), # Add new one
],
)
# Update file
await markdown_processor.write_file(path, updated, expected_checksum=checksum)
# Read back and verify
result = await markdown_processor.read_file(path)
# Original content preserved
assert "Original content here." in result.content
# Both observations present
assert len(result.observations) == 2
assert any(o.content == "First observation" for o in result.observations)
assert any(o.content == "Second observation" for o in result.observations)
@pytest.mark.asyncio
async def test_dirty_file_detection(markdown_processor: MarkdownProcessor, tmp_path: Path):
"""Test detection of file modifications."""
path = tmp_path / "test.md"
# Create initial file
initial = EntityMarkdown(
frontmatter=EntityFrontmatter(
type="note",
permalink="test",
title="Test Note",
created=datetime(2024, 1, 1),
modified=datetime(2024, 1, 1),
),
content="Initial content",
)
checksum = await markdown_processor.write_file(path, initial)
# Modify file directly
path.write_text(path.read_text(encoding="utf-8") + "\nModified!")
# Try to update with old checksum
update = EntityMarkdown(
frontmatter=initial.frontmatter,
content="New content",
)
# Should raise DirtyFileError
with pytest.raises(DirtyFileError):
await markdown_processor.write_file(path, update, expected_checksum=checksum)
# Should succeed without checksum
new_checksum = await markdown_processor.write_file(path, update)
assert new_checksum != checksum