first commit
This commit is contained in:
207
tests/test_todo_parser.py
Normal file
207
tests/test_todo_parser.py
Normal file
@@ -0,0 +1,207 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user