Files
myorg-assistant/tests/test_todo_parser.py

208 lines
8.1 KiB
Python
Raw Normal View History

2026-02-03 23:50:19 +01:00
"""Unit tests for TodoParser."""
import pytest
from datetime import datetime
from src.parsers.todo_parser import TodoParser, Task
class TestTodoParser:
"""Tests for TodoParser class."""
def test_parse_simple_task(self) -> None:
"""Test parsing a simple task without metadata."""
line = "Buy milk"
task = TodoParser.parse_line(line)
assert task is not None
assert task.description == "Buy milk"
assert task.completed == False
assert task.priority is None
assert len(task.projects) == 0
assert len(task.contexts) == 0
def test_parse_task_with_priority(self) -> None:
"""Test parsing a task with priority."""
line = "(A) Write blog post"
task = TodoParser.parse_line(line)
assert task is not None
assert task.priority == "A"
assert task.description == "Write blog post"
def test_parse_task_with_creation_date(self) -> None:
"""Test parsing a task with creation date."""
line = "(B) 2026-01-31 Finish implementation"
task = TodoParser.parse_line(line)
assert task is not None
assert task.priority == "B"
assert task.creation_date == datetime(2026, 1, 31)
assert task.description == "Finish implementation"
def test_parse_task_with_projects(self) -> None:
"""Test parsing a task with project tags."""
line = "Write tests +myorg-assistant +testing"
task = TodoParser.parse_line(line)
assert task is not None
assert "myorg-assistant" in task.projects
assert "testing" in task.projects
assert task.description == "Write tests"
def test_parse_task_with_contexts(self) -> None:
"""Test parsing a task with context tags."""
line = "Call dentist @telefon @recados"
task = TodoParser.parse_line(line)
assert task is not None
assert "telefon" in task.contexts
assert "recados" in task.contexts
assert task.description == "Call dentist"
def test_parse_task_with_due_date(self) -> None:
"""Test parsing a task with due date metadata."""
line = "(A) Submit report +work due:2026-02-15"
task = TodoParser.parse_line(line)
assert task is not None
assert task.due_date == datetime(2026, 2, 15)
assert "due" in task.metadata
assert task.metadata["due"] == "2026-02-15"
def test_parse_completed_task(self) -> None:
"""Test parsing a completed task."""
line = "x 2026-01-31 Buy groceries"
task = TodoParser.parse_line(line)
assert task is not None
assert task.completed == True
assert task.completion_date == datetime(2026, 1, 31)
assert task.description == "Buy groceries"
def test_parse_complex_task(self) -> None:
"""Test parsing a complex task with all features."""
line = "(A) 2026-01-31 Write observability blog post +observability-blog @computer-deep due:2026-02-15 priority:high"
task = TodoParser.parse_line(line)
assert task is not None
assert task.priority == "A"
assert task.creation_date == datetime(2026, 1, 31)
assert task.description == "Write observability blog post"
assert "observability-blog" in task.projects
assert "computer-deep" in task.contexts
assert task.due_date == datetime(2026, 2, 15)
assert task.metadata["priority"] == "high"
def test_parse_empty_line(self) -> None:
"""Test parsing an empty line returns None."""
task = TodoParser.parse_line("")
assert task is None
def test_parse_comment_line(self) -> None:
"""Test parsing a comment line returns None."""
task = TodoParser.parse_line("# This is a comment")
assert task is None
def test_format_simple_task(self) -> None:
"""Test formatting a simple task."""
formatted = TodoParser.format_task(description="Buy milk")
assert formatted == "Buy milk"
def test_format_task_with_priority(self) -> None:
"""Test formatting a task with priority."""
formatted = TodoParser.format_task(
description="Write tests",
priority="A"
)
assert formatted == "(A) Write tests"
def test_format_task_with_all_features(self) -> None:
"""Test formatting a complex task."""
formatted = TodoParser.format_task(
description="Write blog post",
priority="B",
creation_date=datetime(2026, 1, 31),
projects=["observability-blog"],
contexts=["computer-deep"],
metadata={"due": "2026-02-15"}
)
assert "(B)" in formatted
assert "2026-01-31" in formatted
assert "Write blog post" in formatted
assert "+observability-blog" in formatted
assert "@computer-deep" in formatted
assert "due:2026-02-15" in formatted
def test_format_completed_task(self) -> None:
"""Test formatting a completed task."""
formatted = TodoParser.format_task(
description="Buy groceries",
completed=True,
completion_date=datetime(2026, 1, 31)
)
assert formatted.startswith("x 2026-01-31")
assert "Buy groceries" in formatted
def test_parse_file(self) -> None:
"""Test parsing multiple tasks from file content."""
content = """# Tasks
(A) Write tests +myorg-assistant
Buy milk @recados
x 2026-01-30 Completed task
(B) 2026-01-31 Another task +project due:2026-02-01"""
tasks = TodoParser.parse_file(content)
assert len(tasks) == 4
assert tasks[0].description == "Write tests"
assert tasks[1].description == "Buy milk"
assert tasks[2].completed == True
assert tasks[3].priority == "B"
def test_filter_tasks_by_completion(self) -> None:
"""Test filtering tasks by completion status."""
tasks = [
Task(raw_line="x Task 1", line_number=1, completed=True, description="Task 1"),
Task(raw_line="Task 2", line_number=2, completed=False, description="Task 2"),
Task(raw_line="Task 3", line_number=3, completed=False, description="Task 3"),
]
active = TodoParser.filter_tasks(tasks, completed=False)
assert len(active) == 2
completed = TodoParser.filter_tasks(tasks, completed=True)
assert len(completed) == 1
def test_filter_tasks_by_priority(self) -> None:
"""Test filtering tasks by priority."""
tasks = [
Task(raw_line="(A) Task 1", line_number=1, priority="A", description="Task 1"),
Task(raw_line="(B) Task 2", line_number=2, priority="B", description="Task 2"),
Task(raw_line="Task 3", line_number=3, description="Task 3"),
]
high_priority = TodoParser.filter_tasks(tasks, priority="A")
assert len(high_priority) == 1
assert high_priority[0].description == "Task 1"
def test_filter_tasks_by_project(self) -> None:
"""Test filtering tasks by project tag."""
tasks = [
Task(raw_line="Task 1 +project1", line_number=1, description="Task 1", projects=["project1"]),
Task(raw_line="Task 2 +project2", line_number=2, description="Task 2", projects=["project2"]),
Task(raw_line="Task 3 +project1", line_number=3, description="Task 3", projects=["project1"]),
]
project1_tasks = TodoParser.filter_tasks(tasks, project="project1")
assert len(project1_tasks) == 2
def test_filter_tasks_by_context(self) -> None:
"""Test filtering tasks by context tag."""
tasks = [
Task(raw_line="Task 1 @home", line_number=1, description="Task 1", contexts=["home"]),
Task(raw_line="Task 2 @work", line_number=2, description="Task 2", contexts=["work"]),
Task(raw_line="Task 3 @home", line_number=3, description="Task 3", contexts=["home"]),
]
home_tasks = TodoParser.filter_tasks(tasks, context="home")
assert len(home_tasks) == 2