"""Coverage tests for settings/base.py targeting ~9 missing statements. Uncovered functions/branches: - ISettingsManager abstract methods (get_setting, set_setting, etc.) - Verifying ABC contract prevents instantiation - Partial subclass instantiation failures - Keyword argument usage for all methods """ from abc import ABC from typing import Any, Dict import pytest from local_deep_research.settings.base import ISettingsManager MODULE = "local_deep_research.settings.base" class ConcreteSettingsManager(ISettingsManager): """Minimal concrete implementation for testing ABC contract.""" def __init__(self): self._store: Dict[str, Any] = {} def get_setting(self, key, default=None, check_env=True): return self._store.get(key, default) def set_setting(self, key, value, commit=True): self._store[key] = value return True def get_all_settings(self): return dict(self._store) def create_or_update_setting(self, setting, commit=True): if isinstance(setting, dict): self._store[setting.get("key", "")] = setting.get("value") return setting def delete_setting(self, key, commit=True): if key in self._store: del self._store[key] return True return False def get_bool_setting(self, key, default=False, check_env=True): return bool(self._store.get(key, default)) def get_settings_snapshot(self): return dict(self._store) def load_from_defaults_file(self, commit=True, **kwargs): pass def import_settings( self, settings_data, commit=True, overwrite=True, delete_extra=False ): for k, v in settings_data.items(): if overwrite or k not in self._store: self._store[k] = v class TestISettingsManagerABC: """Tests for the abstract base class contract.""" def test_cannot_instantiate_abc_directly(self): """ISettingsManager cannot be instantiated without implementing all methods.""" with pytest.raises(TypeError): ISettingsManager() def test_is_abc_subclass(self): """ISettingsManager inherits from ABC.""" assert issubclass(ISettingsManager, ABC) def test_has_nine_abstract_methods(self): """All 9 public methods are declared abstract.""" expected = { "get_setting", "set_setting", "get_all_settings", "create_or_update_setting", "delete_setting", "get_bool_setting", "get_settings_snapshot", "load_from_defaults_file", "import_settings", } assert expected <= ISettingsManager.__abstractmethods__ def test_concrete_implementation_instantiates(self): """Concrete implementation can be instantiated.""" mgr = ConcreteSettingsManager() assert isinstance(mgr, ISettingsManager) def test_get_setting_returns_default(self): """get_setting returns default when key not found.""" mgr = ConcreteSettingsManager() assert mgr.get_setting("missing", "fallback") == "fallback" def test_set_and_get_roundtrip(self): """set_setting and get_setting are consistent.""" mgr = ConcreteSettingsManager() mgr.set_setting("mykey", "myval") assert mgr.get_setting("mykey") == "myval" def test_set_setting_returns_true(self): """set_setting returns True on success.""" mgr = ConcreteSettingsManager() assert mgr.set_setting("k", "v") is True def test_get_all_settings_returns_dict(self): """get_all_settings returns empty dict.""" mgr = ConcreteSettingsManager() assert mgr.get_all_settings() == {} def test_delete_setting_returns_true_when_present(self): """delete_setting returns True when key exists.""" mgr = ConcreteSettingsManager() mgr.set_setting("k", "v") assert mgr.delete_setting("k") is True def test_delete_setting_returns_false_when_missing(self): """delete_setting returns False when key is absent.""" mgr = ConcreteSettingsManager() assert mgr.delete_setting("no_such_key") is False def test_get_bool_setting_returns_default(self): """get_bool_setting returns default.""" mgr = ConcreteSettingsManager() assert mgr.get_bool_setting("missing", True) is True def test_get_settings_snapshot_returns_dict(self): """get_settings_snapshot returns a dict snapshot.""" mgr = ConcreteSettingsManager() mgr.set_setting("snap_key", "snap_val") snap = mgr.get_settings_snapshot() assert isinstance(snap, dict) assert snap.get("snap_key") == "snap_val" def test_import_settings_populates_store(self): """import_settings adds keys to the store.""" mgr = ConcreteSettingsManager() mgr.import_settings({"key": "val", "num": 42}) assert mgr.get_setting("key") == "val" assert mgr.get_setting("num") == 42 def test_load_from_defaults_file_does_not_raise(self): """load_from_defaults_file runs without error.""" mgr = ConcreteSettingsManager() mgr.load_from_defaults_file(commit=False) def test_missing_single_method_raises_on_instantiation(self): """A subclass missing one abstract method cannot be instantiated.""" class Incomplete(ISettingsManager): def get_setting(self, key, default=None, check_env=True): return default def set_setting(self, key, value, commit=True): return True def get_all_settings(self): return {} def create_or_update_setting(self, setting, commit=True): return None def delete_setting(self, key, commit=True): return False def get_bool_setting(self, key, default=False, check_env=True): return default def get_settings_snapshot(self): return {} def load_from_defaults_file(self, commit=True, **kwargs): pass # import_settings intentionally omitted with pytest.raises(TypeError): Incomplete()