"""Tests for services.file_service path resolution — no GUI dependency.""" import os import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent / "src")) import services.file_service as fs class TestGetDataDir(unittest.TestCase): """get_data_dir() three-tier fallback (docs/10-lan-update.md §5).""" def setUp(self): self._env = os.environ.get("CMBOT_DATA_DIR") self._frozen = getattr(sys, "frozen", None) os.environ.pop("CMBOT_DATA_DIR", None) if hasattr(sys, "frozen"): del sys.frozen def tearDown(self): if self._env is None: os.environ.pop("CMBOT_DATA_DIR", None) else: os.environ["CMBOT_DATA_DIR"] = self._env if self._frozen is None: if hasattr(sys, "frozen"): del sys.frozen else: sys.frozen = self._frozen def test_env_override_wins(self): os.environ["CMBOT_DATA_DIR"] = r"X:\custom\data" self.assertEqual(fs.get_data_dir(), Path(r"X:\custom\data")) def test_env_override_wins_even_when_frozen(self): sys.frozen = True os.environ["CMBOT_DATA_DIR"] = r"X:\custom\data" self.assertEqual(fs.get_data_dir(), Path(r"X:\custom\data")) def test_packaged_uses_home_dotcmbot(self): sys.frozen = True self.assertEqual(fs.get_data_dir(), Path.home() / ".cmbot") def test_dev_uses_project_root(self): # not frozen, no env -> same as program/app dir (project root in dev) self.assertEqual(fs.get_data_dir(), fs.get_app_dir()) def test_blank_env_is_ignored(self): os.environ["CMBOT_DATA_DIR"] = " " self.assertEqual(fs.get_data_dir(), fs.get_app_dir()) class TestGetOutputDir(unittest.TestCase): """get_output_dir() default location (docs/10-lan-update.md §5).""" def setUp(self): import tempfile self.tmp = Path(tempfile.mkdtemp()) self._env = os.environ.get("CMBOT_DATA_DIR") self._frozen = getattr(sys, "frozen", None) os.environ["CMBOT_DATA_DIR"] = str(self.tmp / "data") if hasattr(sys, "frozen"): del sys.frozen self._orig_app_dir = fs.get_app_dir def tearDown(self): import shutil fs.get_app_dir = self._orig_app_dir if self._env is None: os.environ.pop("CMBOT_DATA_DIR", None) else: os.environ["CMBOT_DATA_DIR"] = self._env if self._frozen is None: if hasattr(sys, "frozen"): del sys.frozen else: sys.frozen = self._frozen shutil.rmtree(str(self.tmp), ignore_errors=True) def test_dev_uses_data_output(self): # not frozen -> /output self.assertEqual(fs.get_output_dir(), Path(os.environ["CMBOT_DATA_DIR"]) / "output") def test_frozen_uses_install_root(self): app = self.tmp / "install" / "app" app.mkdir(parents=True) fs.get_app_dir = lambda: app sys.frozen = True self.assertEqual(fs.get_output_dir(), self.tmp / "install" / "合并后的图片") def test_frozen_falls_back_when_not_writable(self): app = self.tmp / "install" / "app" app.mkdir(parents=True) fs.get_app_dir = lambda: app sys.frozen = True orig = fs._is_dir_writable fs._is_dir_writable = lambda p: False try: self.assertEqual(fs.get_output_dir(), Path(os.environ["CMBOT_DATA_DIR"]) / "output") finally: fs._is_dir_writable = orig class TestGetOutfitOutputDir(unittest.TestCase): """get_outfit_output_dir() default location (docs/11 §9).""" def setUp(self): import tempfile self.tmp = Path(tempfile.mkdtemp()) self._env = os.environ.get("CMBOT_DATA_DIR") self._frozen = getattr(sys, "frozen", None) os.environ["CMBOT_DATA_DIR"] = str(self.tmp / "data") if hasattr(sys, "frozen"): del sys.frozen self._orig_app_dir = fs.get_app_dir def tearDown(self): import shutil fs.get_app_dir = self._orig_app_dir if self._env is None: os.environ.pop("CMBOT_DATA_DIR", None) else: os.environ["CMBOT_DATA_DIR"] = self._env if self._frozen is None: if hasattr(sys, "frozen"): del sys.frozen else: sys.frozen = self._frozen shutil.rmtree(str(self.tmp), ignore_errors=True) def test_dev_uses_project_outfit_folder(self): app = self.tmp / "project" app.mkdir() fs.get_app_dir = lambda: app self.assertEqual(fs.get_outfit_output_dir(), app / "穿搭图片") def test_frozen_uses_install_root_outfit_folder(self): app = self.tmp / "install" / "app" app.mkdir(parents=True) fs.get_app_dir = lambda: app sys.frozen = True self.assertEqual(fs.get_outfit_output_dir(), self.tmp / "install" / "穿搭图片") def test_frozen_falls_back_when_not_writable(self): app = self.tmp / "install" / "app" app.mkdir(parents=True) fs.get_app_dir = lambda: app sys.frozen = True orig = fs._is_dir_writable fs._is_dir_writable = lambda p: False try: self.assertEqual( fs.get_outfit_output_dir(), Path(os.environ["CMBOT_DATA_DIR"]) / "output" / "穿搭图片", ) finally: fs._is_dir_writable = orig if __name__ == "__main__": unittest.main()