import tempfile from click.testing import CliRunner from unittest.mock import patch, MagicMock from pathlib import Path from src.cli.main import cli, visualize, complexity, deps, export class TestCLI: def setup_method(self): self.runner = CliRunner() def test_cli_help(self): result = self.runner.invoke(cli, ["--help"]) assert result.exit_code == 0 assert "Usage:" in result.output @patch("src.cli.main._parse_files") @patch("src.cli.main._get_parser") def test_analyze_command(self, mock_get_parser, mock_parse_files): mock_parser = MagicMock() mock_get_parser.return_value = mock_parser mock_result = MagicMock() mock_result.file_path = Path("/test.py") mock_result.entities = [] mock_result.imports = [] mock_parse_files.return_value = [mock_result] mock_graph_builder = MagicMock() mock_graph_builder.get_nodes.return_value = [] with patch("src.cli.main.GraphBuilder") as MockGraphBuilder: MockGraphBuilder.return_value = mock_graph_builder with tempfile.TemporaryDirectory() as tmpdir: result = self.runner.invoke(cli, ["analyze", tmpdir]) assert result.exit_code == 0 @patch("src.cli.main._parse_files") @patch("src.cli.main._get_parser") def test_visualize_command(self, mock_get_parser, mock_parse_files): mock_parser = MagicMock() mock_get_parser.return_value = mock_parser mock_result = MagicMock() mock_result.file_path = Path("/test.py") mock_result.entities = [] mock_result.imports = [] mock_parse_files.return_value = [mock_result] mock_graph_builder = MagicMock() mock_graph_builder.get_nodes.return_value = [] with patch("src.cli.main.GraphBuilder") as MockGraphBuilder: MockGraphBuilder.return_value = mock_graph_builder with tempfile.TemporaryDirectory() as tmpdir: result = self.runner.invoke(visualize, [tmpdir]) assert result.exit_code == 0 @patch("src.cli.main._parse_files") @patch("src.cli.main._get_parser") def test_complexity_command(self, mock_get_parser, mock_parse_files): mock_parser = MagicMock() mock_get_parser.return_value = mock_parser mock_result = MagicMock() mock_result.file_path = Path("/test.py") mock_result.entities = [] mock_result.imports = [] mock_parse_files.return_value = [mock_result] with tempfile.TemporaryDirectory() as tmpdir: result = self.runner.invoke(complexity, [tmpdir]) assert result.exit_code == 0 @patch("src.cli.main._parse_files") @patch("src.cli.main._get_parser") def test_deps_command(self, mock_get_parser, mock_parse_files): mock_parser = MagicMock() mock_get_parser.return_value = mock_parser mock_result = MagicMock() mock_result.file_path = Path("/test.py") mock_result.entities = [] mock_result.imports = [] mock_parse_files.return_value = [mock_result] mock_graph_builder = MagicMock() mock_graph_builder.get_nodes.return_value = [] mock_graph_builder.edges = [] with patch("src.cli.main.GraphBuilder") as MockGraphBuilder: MockGraphBuilder.return_value = mock_graph_builder with tempfile.TemporaryDirectory() as tmpdir: result = self.runner.invoke(deps, [tmpdir]) assert result.exit_code == 0 @patch("src.cli.main._parse_files") @patch("src.cli.main._get_parser") def test_export_command(self, mock_get_parser, mock_parse_files): mock_parser = MagicMock() mock_get_parser.return_value = mock_parser mock_result = MagicMock() mock_result.file_path = Path("/test.py") mock_result.entities = [] mock_result.imports = [] mock_parse_files.return_value = [mock_result] mock_graph_builder = MagicMock() mock_graph_builder.get_nodes.return_value = [] mock_graph_builder.edges = [] with patch("src.cli.main.GraphBuilder") as MockGraphBuilder: MockGraphBuilder.return_value = mock_graph_builder with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f: output_path = f.name try: result = self.runner.invoke(export, ["/test", "-o", output_path]) assert result.exit_code == 0 or "Error" in result.output finally: Path(output_path).unlink(missing_ok=True) def test_verbose_flag(self): result = self.runner.invoke(cli, ["--verbose", "--help"]) assert result.exit_code == 0 class TestHelperFunctions: def test_get_parser_auto_python(self): from src.cli.main import _get_parser with patch("pathlib.Path.glob") as mock_glob: mock_glob.return_value = [Path("/test.py")] parser = _get_parser("auto", Path("/test")) assert parser is not None def test_parse_files_returns_empty_for_no_matches(self): from src.cli.main import _parse_files mock_parser = MagicMock() mock_result = MagicMock() mock_result.entities = [] mock_result.errors = [] mock_parser.SUPPORTED_EXTENSIONS = [".py"] mock_parser.parse.return_value = mock_result with patch("pathlib.Path.rglob") as mock_rglob: mock_rglob.return_value = [] results = _parse_files(Path("/test"), mock_parser, False) assert results == [] def test_display_summary(self): from src.cli.main import _display_summary mock_graph_builder = MagicMock() mock_graph_builder.get_nodes.return_value = [] mock_results = [] _display_summary(mock_graph_builder, mock_results, False)