/ tests / tools / test_todo_tool.py
test_todo_tool.py
  1  """Tests for the todo tool module."""
  2  
  3  import json
  4  
  5  from tools.todo_tool import TodoStore, todo_tool
  6  
  7  
  8  class TestWriteAndRead:
  9      def test_write_replaces_list(self):
 10          store = TodoStore()
 11          items = [
 12              {"id": "1", "content": "First task", "status": "pending"},
 13              {"id": "2", "content": "Second task", "status": "in_progress"},
 14          ]
 15          result = store.write(items)
 16          assert len(result) == 2
 17          assert result[0]["id"] == "1"
 18          assert result[1]["status"] == "in_progress"
 19  
 20      def test_read_returns_copy(self):
 21          store = TodoStore()
 22          store.write([{"id": "1", "content": "Task", "status": "pending"}])
 23          items = store.read()
 24          items[0]["content"] = "MUTATED"
 25          assert store.read()[0]["content"] == "Task"
 26  
 27      def test_write_deduplicates_duplicate_ids(self):
 28          store = TodoStore()
 29          result = store.write([
 30              {"id": "1", "content": "First version", "status": "pending"},
 31              {"id": "2", "content": "Other task", "status": "pending"},
 32              {"id": "1", "content": "Latest version", "status": "in_progress"},
 33          ])
 34          assert result == [
 35              {"id": "2", "content": "Other task", "status": "pending"},
 36              {"id": "1", "content": "Latest version", "status": "in_progress"},
 37          ]
 38  
 39  
 40  class TestHasItems:
 41      def test_empty_store(self):
 42          store = TodoStore()
 43          assert store.has_items() is False
 44  
 45      def test_non_empty_store(self):
 46          store = TodoStore()
 47          store.write([{"id": "1", "content": "x", "status": "pending"}])
 48          assert store.has_items() is True
 49  
 50  
 51  class TestFormatForInjection:
 52      def test_empty_returns_none(self):
 53          store = TodoStore()
 54          assert store.format_for_injection() is None
 55  
 56      def test_non_empty_has_markers(self):
 57          store = TodoStore()
 58          store.write([
 59              {"id": "1", "content": "Do thing", "status": "completed"},
 60              {"id": "2", "content": "Next", "status": "pending"},
 61              {"id": "3", "content": "Working", "status": "in_progress"},
 62          ])
 63          text = store.format_for_injection()
 64          # Completed items are filtered out of injection
 65          assert "[x]" not in text
 66          assert "Do thing" not in text
 67          # Active items are included
 68          assert "[ ]" in text
 69          assert "[>]" in text
 70          assert "Next" in text
 71          assert "Working" in text
 72          assert "context compression" in text.lower()
 73  
 74  
 75  class TestMergeMode:
 76      def test_update_existing_by_id(self):
 77          store = TodoStore()
 78          store.write([
 79              {"id": "1", "content": "Original", "status": "pending"},
 80          ])
 81          store.write(
 82              [{"id": "1", "status": "completed"}],
 83              merge=True,
 84          )
 85          items = store.read()
 86          assert len(items) == 1
 87          assert items[0]["status"] == "completed"
 88          assert items[0]["content"] == "Original"
 89  
 90      def test_merge_appends_new(self):
 91          store = TodoStore()
 92          store.write([{"id": "1", "content": "First", "status": "pending"}])
 93          store.write(
 94              [{"id": "2", "content": "Second", "status": "pending"}],
 95              merge=True,
 96          )
 97          items = store.read()
 98          assert len(items) == 2
 99  
100  
101  class TestTodoToolFunction:
102      def test_read_mode(self):
103          store = TodoStore()
104          store.write([{"id": "1", "content": "Task", "status": "pending"}])
105          result = json.loads(todo_tool(store=store))
106          assert result["summary"]["total"] == 1
107          assert result["summary"]["pending"] == 1
108  
109      def test_write_mode(self):
110          store = TodoStore()
111          result = json.loads(todo_tool(
112              todos=[{"id": "1", "content": "New", "status": "in_progress"}],
113              store=store,
114          ))
115          assert result["summary"]["in_progress"] == 1
116  
117      def test_no_store_returns_error(self):
118          result = json.loads(todo_tool())
119          assert "error" in result