Private
Public Access
0
0
Files
manual_slop/tests/test_conductor_tech_lead.py
T
ed 423f9a95b0 test(ai_client): rename send_result to send in test_conductor_tech_lead
11 references renamed (planned 8; the count grew with the @patch pattern + local var name).
Test file state: GREEN. 9 tests pass.
2026-06-17 00:33:36 -04:00

85 lines
3.4 KiB
Python

import unittest
from unittest.mock import patch
from src import conductor_tech_lead
from src.result_types import Result
import pytest
class TestConductorTechLead(unittest.TestCase):
def test_generate_tickets_retry_failure(self) -> None:
with patch('src.ai_client.send') as mock_send:
mock_send.return_value = Result(data="invalid json")
# conductor_tech_lead.generate_tickets now raises RuntimeError on error after 3 attempts
with pytest.raises(RuntimeError):
conductor_tech_lead.generate_tickets("brief", "skeletons")
assert mock_send.call_count == 3
def test_generate_tickets_retry_success(self) -> None:
with patch('src.ai_client.send') as mock_send:
mock_send.side_effect = [Result(data="invalid json"), Result(data='[{"Task": "Test"}]')]
tickets = conductor_tech_lead.generate_tickets("brief", "skeletons")
assert tickets == [{"Task": "Test"}]
assert mock_send.call_count == 2
def test_generate_tickets_success(self) -> None:
with patch('src.ai_client.send') as mock_send:
mock_send.return_value = Result(data='[{"id": "T1", "description": "desc", "depends_on": []}]')
tickets = conductor_tech_lead.generate_tickets("brief", "skeletons")
self.assertEqual(len(tickets), 1)
self.assertEqual(tickets[0]['id'], "T1")
class TestTopologicalSort(unittest.TestCase):
def test_topological_sort_linear(self) -> None:
tickets = [
{"id": "t2", "depends_on": ["t1"]},
{"id": "t1", "depends_on": []},
]
sorted_tickets = conductor_tech_lead.topological_sort(tickets)
self.assertEqual(sorted_tickets[0]['id'], "t1")
self.assertEqual(sorted_tickets[1]['id'], "t2")
def test_topological_sort_complex(self) -> None:
tickets = [
{"id": "t3", "depends_on": ["t1", "t2"]},
{"id": "t1", "depends_on": []},
{"id": "t2", "depends_on": ["t1"]},
]
sorted_tickets = conductor_tech_lead.topological_sort(tickets)
self.assertEqual(sorted_tickets[0]['id'], "t1")
self.assertEqual(sorted_tickets[1]['id'], "t2")
self.assertEqual(sorted_tickets[2]['id'], "t3")
def test_topological_sort_cycle(self) -> None:
tickets = [
{"id": "t1", "depends_on": ["t2"]},
{"id": "t2", "depends_on": ["t1"]},
]
with self.assertRaises(ValueError) as cm:
conductor_tech_lead.topological_sort(tickets)
# Match against our new standard ValueError message
self.assertIn("Dependency cycle detected", str(cm.exception))
def test_topological_sort_empty(self) -> None:
self.assertEqual(conductor_tech_lead.topological_sort([]), [])
def test_topological_sort_missing_dependency(self) -> None:
# If a ticket depends on something not in the list, we should handle it or let it fail.
# The TrackDAG silently ignores missing dependencies, causing cycle detection to trigger.
tickets = [
{"id": "t1", "depends_on": ["missing"]},
]
# Currently this raises ValueError due to cycle detection on incomplete sort
with self.assertRaises(ValueError):
conductor_tech_lead.topological_sort(tickets)
def test_topological_sort_vlog(vlogger) -> None:
tickets = [
{"id": "t2", "depends_on": ["t1"]},
{"id": "t1", "depends_on": []},
]
vlogger.log_state("Input Order", ["t2", "t1"], ["t2", "t1"])
sorted_tickets = conductor_tech_lead.topological_sort(tickets)
result_ids = [t['id'] for t in sorted_tickets]
vlogger.log_state("Sorted Order", "N/A", result_ids)
assert result_ids == ["t1", "t2"]
vlogger.finalize("Topological Sort Verification", "PASS", "Linear dependencies correctly ordered.")