from codesnap.output.llm_formatter import LLMFormatter class TestLLMFormatter: def setup_method(self) -> None: self.formatter = LLMFormatter(max_tokens=1000) def test_format_valid_result(self) -> None: result = { "files": [ { "file": "test.py", "language": "python", "lines": 50, "functions": [{"name": "test_func", "start_line": 1, "end_line": 10, "parameters": [], "return_type": "str"}], "classes": [], "complexity": {"score": 5, "rating": "low"} } ], "dependency_graph": { "total_dependencies": 0, "orphaned_files": 0, "cycles_detected": 0, "cycle_details": [], "orphaned_details": [], "edges": [], "statistics": {} } } output = self.formatter.format(result) assert "## Codebase Summary" in output assert "### Key Files" in output assert "### Classes and Functions" in output assert "### Dependencies" in output def test_respects_token_limit(self) -> None: result = { "files": [], "dependency_graph": { "total_dependencies": 0, "orphaned_files": 0, "cycles_detected": 0, "cycle_details": [], "orphaned_details": [], "edges": [], "statistics": {} } } output = self.formatter.format(result) max_chars = 1000 * 4 assert len(output) <= max_chars + 100 def test_includes_high_level_summary(self) -> None: result = { "files": [ {"file": "a.py", "language": "python", "lines": 50, "functions": [], "classes": [], "complexity": {}}, {"file": "b.py", "language": "python", "lines": 30, "functions": [], "classes": [], "complexity": {}}, {"file": "c.js", "language": "javascript", "lines": 20, "functions": [], "classes": [], "complexity": {}} ], "dependency_graph": { "total_dependencies": 0, "orphaned_files": 0, "cycles_detected": 0, "cycle_details": [], "orphaned_details": [], "edges": [], "statistics": {} } } output = self.formatter.format(result) assert "python" in output.lower() assert "3 files" in output or "files" in output def test_compresses_detailed_file_list(self) -> None: result = { "files": [ {"file": f"file{i}.py", "language": "python", "lines": 10, "functions": [{"name": f"func{i}a"}, {"name": f"func{i}b"}, {"name": f"func{i}c"}], "classes": [], "complexity": {}} for i in range(10) ], "dependency_graph": { "total_dependencies": 0, "orphaned_files": 0, "cycles_detected": 0, "cycle_details": [], "orphaned_details": [], "edges": [], "statistics": {} } } output = self.formatter.format(result) assert "Detailed File List (compressed)" in output def test_warns_about_cycles(self) -> None: result = { "files": [ {"file": "a.py", "language": "python", "lines": 10, "functions": [], "classes": [], "complexity": {}}, {"file": "b.py", "language": "python", "lines": 10, "functions": [], "classes": [], "complexity": {}} ], "dependency_graph": { "total_dependencies": 2, "orphaned_files": 0, "cycles_detected": 1, "cycle_details": [["a.py", "b.py", "a.py"]], "orphaned_details": [], "edges": [], "statistics": {} } } output = self.formatter.format(result) assert "circular" in output.lower() or "cycle" in output.lower()