""" test_pet_window.py ================== ui/pet_window 模块单元测试(使用 DummyPetWindow,headless 无 Qt 依赖)。 运行 ---- cd /Users/e2hang/hermes/code/ezvibe python -m ui.test_pet_window """ import sys from pathlib import Path _ROOT = Path(__file__).parent.parent.resolve() sys.path.insert(0, str(_ROOT)) import unittest # ============================================================================ # DummyPetWindow Tests # ============================================================================ class TestDummyPetWindow(unittest.TestCase): """DummyPetWindow API 契约测试。""" def test_init_does_not_crash(self): """初始化不崩溃。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() self.assertIsInstance(w, DummyPetWindow) def test_show_hide(self): """show/hide 控制可见性。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.show() self.assertTrue(w.is_visible()) w.hide() self.assertFalse(w.is_visible()) def test_close(self): """close 停止窗口。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.close() self.assertFalse(w.is_visible()) def test_update_emotion_valid(self): """update_emotion 接受有效情绪。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.update_emotion("happy") self.assertEqual(w.get_current_emotion(), "happy") w.update_emotion("sleepy") self.assertEqual(w.get_current_emotion(), "sleepy") def test_update_emotion_invalid_defaults_to_idle(self): """update_emotion 忽略无效情绪,保持 idle。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.update_emotion("unknown_emotion") self.assertEqual(w.get_current_emotion(), "idle") def test_show_reminder_stores_message(self): """show_reminder 存储提醒消息。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.show_reminder("该喝水了!", priority=0) w.show_reminder("站起来伸展一下!", priority=1) self.assertEqual(len(w._reminders), 2) self.assertIn("该喝水了!", w._reminders) def test_position_get_set(self): """位置 get/set。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.set_position(200, 300) x, y = w.get_position() self.assertEqual((x, y), (200, 300)) def test_play_animation_no_exception(self): """play_animation 不抛异常。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() w.play_animation("bounce") w.play_animation("wave") w.play_animation("spin") # 无断言——只要不崩溃即可 def test_repr(self): """repr 包含状态信息。""" from ui.pet_window import DummyPetWindow w = DummyPetWindow() r = repr(w) self.assertIn("DummyPetWindow", r) self.assertIn("idle", r) # ============================================================================ # create_pet_window Factory Tests # ============================================================================ class TestCreatePetWindow(unittest.TestCase): """create_pet_window 工厂函数测试。""" def test_force_dummy_returns_dummy(self): """force_dummy=True 强制返回 DummyPetWindow。""" from ui.pet_window import create_pet_window, DummyPetWindow w = create_pet_window(force_dummy=True) self.assertIsInstance(w, DummyPetWindow) def test_default_returns_pet_window_or_dummy(self): """默认情况下返回 PetWindow 或 DummyPetWindow。""" from ui.pet_window import create_pet_window, DummyPetWindow w = create_pet_window() # force_dummy 模式必定返回 DummyPetWindow w2 = create_pet_window(force_dummy=True) self.assertIsInstance(w2, DummyPetWindow) def test_emotion_engine_wired(self): """emotion_engine 被正确传入。""" from ui.pet_window import create_pet_window mock_engine = object() w = create_pet_window(emotion_engine=mock_engine) self.assertIs(w._emotion, mock_engine) def test_brain_wired(self): """brain 被正确传入。""" from ui.pet_window import create_pet_window mock_brain = object() w = create_pet_window(brain=mock_brain) self.assertIs(w._brain, mock_brain) def test_scheduler_wired(self): """scheduler 被正确传入。""" from ui.pet_window import create_pet_window mock_scheduler = object() w = create_pet_window(scheduler=mock_scheduler) self.assertIs(w._scheduler, mock_scheduler) # ============================================================================ # Emotion Emojis Mapping Tests # ============================================================================ class TestEmotionEmojis(unittest.TestCase): """PetWindow.EMOTION_EMOJIS 完整性测试(通过 DummyPetWindow 访问)。""" def test_all_emotions_have_emoji(self): """所有标准情绪都有 emoji 映射。""" from ui.pet_window import DummyPetWindow emotions = DummyPetWindow.EMOTIONS emojis = DummyPetWindow.EMOTION_EMOJIS for e in emotions: self.assertIn(e, emojis, f"{e} 缺少 emoji 映射") self.assertIsInstance(emojis[e], str) self.assertGreater(len(emojis[e]), 0) # ============================================================================ # Main # ============================================================================ if __name__ == "__main__": print("Running pet_window tests (headless, no Qt required) ...") unittest.main(verbosity=2)