"""BGM工具函数单元测试。""" from __future__ import annotations from domain.bgm_utils import merge_bgm_config class TestMergeBgmConfigBothEmpty: """两边都为空的情况。""" def test_both_empty(self): result = merge_bgm_config({}, {}) assert result == {} # 返回新字典(值已通过 == 验证,is not {} 无实际意义(每次{}每次新建对象) def test_user_none_returns_template_copy(self): """用户传 None 视为空配置,返回模板副本。""" result = merge_bgm_config({}, None) assert result == {} class TestMergeBgmConfigOnlyTemplate: """只有模板配置。""" def test_only_template_returns_copy(self): template = {"enabled": True, "volume": 0.5, "track": "default.mp3"} result = merge_bgm_config(template, {}) assert result == template # 确保是副本,不是同一引用 result["volume"] = 0.9 assert template["volume"] == 0.5 def test_only_template_with_none_user(self): template = {"enabled": True, "volume": 0.5} result = merge_bgm_config(template, None) assert result == template class TestMergeBgmConfigOnlyUser: """只有用户配置。""" def test_only_user_returns_copy(self): user = {"enabled": False, "volume": 0.8} result = merge_bgm_config({}, user) assert result == user # 确保是副本 result["volume"] = 0.1 assert user["volume"] == 0.8 def test_only_user_with_none_template(self): user = {"enabled": False} result = merge_bgm_config(None, user) assert result == user class TestMergeBgmConfigBasicOverride: """用户配置覆盖模板配置。""" def test_volume_override(self): template = {"enabled": True, "volume": 0.5} user = {"volume": 0.8} result = merge_bgm_config(template, user) assert result["volume"] == 0.8 assert result["enabled"] is True # 用户没传,保留模板 def test_track_override(self): template = {"track": "default.mp3", "volume": 0.5} user = {"track": "custom.mp3"} result = merge_bgm_config(template, user) assert result["track"] == "custom.mp3" assert result["volume"] == 0.5 def test_multiple_fields_override(self): template = {"enabled": True, "volume": 0.5, "track": "a.mp3", "fade_in": 2} user = {"volume": 0.9, "track": "b.mp3"} result = merge_bgm_config(template, user) assert result["volume"] == 0.9 assert result["track"] == "b.mp3" assert result["fade_in"] == 2 assert result["enabled"] is True class TestMergeBgmConfigEnabledSpecialHandling: """enabled 字段的特殊处理:用户没传就保留模板的。""" def test_user_does_not_pass_enabled_keeps_template_true(self): template = {"enabled": True, "volume": 0.5} user = {"volume": 0.8} result = merge_bgm_config(template, user) assert result["enabled"] is True def test_user_does_not_pass_enabled_keeps_template_false(self): template = {"enabled": False, "volume": 0.5} user = {"volume": 0.8} result = merge_bgm_config(template, user) assert result["enabled"] is False def test_user_explicitly_sets_enabled_true(self): template = {"enabled": False, "volume": 0.5} user = {"enabled": True} result = merge_bgm_config(template, user) assert result["enabled"] is True def test_user_explicitly_sets_enabled_false(self): template = {"enabled": True, "volume": 0.5} user = {"enabled": False} result = merge_bgm_config(template, user) assert result["enabled"] is False def test_template_no_enabled_user_no_enabled(self): template = {"volume": 0.5} user = {"track": "a.mp3"} result = merge_bgm_config(template, user) assert "enabled" not in result def test_template_no_enabled_user_has_enabled(self): template = {"volume": 0.5} user = {"enabled": True} result = merge_bgm_config(template, user) assert result["enabled"] is True def test_user_sets_enabled_none_explicitly(self): """用户显式传 None 也视为传了,会覆盖模板。""" template = {"enabled": True, "volume": 0.5} user = {"enabled": None} result = merge_bgm_config(template, user) assert result["enabled"] is None class TestMergeBgmConfigNewFields: """用户配置新增模板没有的字段。""" def test_user_adds_new_field(self): template = {"volume": 0.5} user = {"fade_out": 3} result = merge_bgm_config(template, user) assert result["volume"] == 0.5 assert result["fade_out"] == 3 def test_user_adds_multiple_new_fields(self): template = {"enabled": True} user = {"volume": 0.7, "track": "x.mp3", "loop": True} result = merge_bgm_config(template, user) assert result["enabled"] is True assert result["volume"] == 0.7 assert result["track"] == "x.mp3" assert result["loop"] is True class TestMergeBgmConfigImmutableInput: """确保输入字典不被修改。""" def test_template_not_modified(self): template = {"enabled": True, "volume": 0.5} original = dict(template) merge_bgm_config(template, {"volume": 0.9}) assert template == original def test_user_not_modified(self): user = {"enabled": False, "track": "x.mp3"} original = dict(user) merge_bgm_config({"volume": 0.5}, user) assert user == original