import subprocess import tempfile import unittest from pathlib import Path from deploy_tool.environment import check_environment, load_tool_paths, save_tool_paths class EnvironmentTests(unittest.TestCase): def test_reports_installed_command(self): def runner(command): return subprocess.CompletedProcess(command, 0, "java 21\n", "") results = check_environment(runner=runner, checks={"JDK": ["java", "-version"]}) self.assertTrue(results[0].installed) self.assertEqual(results[0].name, "JDK") self.assertEqual(results[0].source, "PATH") self.assertIn("java 21", results[0].version) def test_reports_missing_command(self): def runner(command): raise FileNotFoundError(command[0]) results = check_environment(runner=runner, checks={"MySQL": ["mysql", "--version"]}) self.assertFalse(results[0].installed) self.assertEqual(results[0].name, "MySQL") self.assertIn("未安装", results[0].message) def test_uses_manual_path_when_command_is_not_in_path(self): with tempfile.TemporaryDirectory() as tmp: mysql = Path(tmp) / "mysql.exe" mysql.write_text("", encoding="utf-8") def runner(command): if command[0] == "mysql": raise FileNotFoundError(command[0]) return subprocess.CompletedProcess(command, 0, "mysql 8.4\n", "") results = check_environment( runner=runner, checks={"MySQL": ["mysql", "--version"]}, manual_paths={"MySQL": mysql}, ) self.assertTrue(results[0].installed) self.assertEqual(results[0].source, "手动指定") self.assertEqual(results[0].command[0], str(mysql)) def test_discovers_executable_from_known_search_paths(self): with tempfile.TemporaryDirectory() as tmp: mysql = Path(tmp) / "MySQL" / "MySQL Server 8.4" / "bin" / "mysql.exe" mysql.parent.mkdir(parents=True) mysql.write_text("", encoding="utf-8") def runner(command): if command[0] == "mysql": raise FileNotFoundError(command[0]) return subprocess.CompletedProcess(command, 0, "mysql 8.4\n", "") results = check_environment( runner=runner, checks={"MySQL": ["mysql", "--version"]}, search_roots=[Path(tmp)], ) self.assertTrue(results[0].installed) self.assertEqual(results[0].source, "自动发现") self.assertEqual(results[0].command[0], str(mysql)) def test_does_not_recursively_scan_arbitrary_deep_directories(self): with tempfile.TemporaryDirectory() as tmp: mysql = Path(tmp) / "random" / "deep" / "folder" / "mysql.exe" mysql.parent.mkdir(parents=True) mysql.write_text("", encoding="utf-8") def runner(command): if command[0] == "mysql": raise FileNotFoundError(command[0]) return subprocess.CompletedProcess(command, 0, "mysql 8.4\n", "") results = check_environment( runner=runner, checks={"MySQL": ["mysql", "--version"]}, search_roots=[Path(tmp)], ) self.assertFalse(results[0].installed) def test_saves_and_loads_manual_paths(self): with tempfile.TemporaryDirectory() as tmp: config = Path(tmp) / "tool-paths.json" mysql = Path(tmp) / "mysql.exe" save_tool_paths({"MySQL": mysql}, config) loaded = load_tool_paths(config) self.assertEqual(loaded, {"MySQL": mysql}) if __name__ == "__main__": unittest.main()