Add missing test modules for previously untested core areas: - console: ForegroundColorEnum, BackgroundColorEnum, Console methods - errors: dependency_error, module_dependency_error - log: LogLevel ordering/values, LogSettings, Logger (should_log, format, file write, fatal) - service: HostedService, StartupTask, CronjobABC (start/stop/loop/task cancellation) - time: TimeFormatSettings properties and setters - utils: Benchmark.time / .memory / .all call-count and output Also fix existing test files: environment cleanup, cron exception specificity, json_processor kwargs bug doc, configuration_model_abc to_dict bug doc. All 199 tests pass, black clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
import json
|
|
import os
|
|
import pytest
|
|
from cpl.core.configuration.configuration import Configuration
|
|
from cpl.core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
|
|
|
|
class AppSettings(ConfigurationModelABC):
|
|
def __init__(self, src: dict = None):
|
|
ConfigurationModelABC.__init__(self, src or {})
|
|
self.option("app_name", str, default="default-app")
|
|
self.option("version", str, default="0.0.0")
|
|
|
|
|
|
class ServerSettings(ConfigurationModelABC):
|
|
def __init__(self, src: dict = None):
|
|
ConfigurationModelABC.__init__(self, src or {})
|
|
self.option("host", str, default="localhost")
|
|
self.option("port", int, default=8080)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def clear_config():
|
|
"""Reset Configuration state before each test."""
|
|
Configuration._config.clear()
|
|
yield
|
|
Configuration._config.clear()
|
|
|
|
|
|
# --- set / get ---
|
|
|
|
|
|
def test_set_and_get_by_class():
|
|
settings = AppSettings({"app_name": "TestApp", "version": "1.0.0"})
|
|
Configuration.set(AppSettings, settings)
|
|
result = Configuration.get(AppSettings)
|
|
assert result.app_name == "TestApp"
|
|
assert result.version == "1.0.0"
|
|
|
|
|
|
def test_set_and_get_by_string_key():
|
|
Configuration.set("my_key", "my_value")
|
|
assert Configuration.get("my_key") == "my_value"
|
|
|
|
|
|
def test_get_missing_returns_default():
|
|
assert Configuration.get("nonexistent", "fallback") == "fallback"
|
|
|
|
|
|
def test_get_missing_returns_none():
|
|
assert Configuration.get("nonexistent") is None
|
|
|
|
|
|
def test_get_model_auto_instantiates():
|
|
# Getting an unregistered ConfigurationModelABC subclass should auto-create it
|
|
result = Configuration.get(ServerSettings)
|
|
assert isinstance(result, ServerSettings)
|
|
assert result.host == "localhost"
|
|
assert result.port == 8080
|
|
|
|
|
|
def test_overwrite_existing():
|
|
Configuration.set("key", "first")
|
|
Configuration.set("key", "second")
|
|
assert Configuration.get("key") == "second"
|
|
|
|
|
|
def test_multiple_models():
|
|
Configuration.set(AppSettings, AppSettings({"app_name": "App"}))
|
|
Configuration.set(ServerSettings, ServerSettings({"port": 9000}))
|
|
assert Configuration.get(AppSettings).app_name == "App"
|
|
assert Configuration.get(ServerSettings).port == 9000
|
|
|
|
|
|
# --- add_json_file ---
|
|
|
|
|
|
def test_add_json_file_loads_model(tmp_path):
|
|
config_data = {"AppSettings": {"app_name": "FromFile", "version": "2.0.0"}}
|
|
config_file = tmp_path / "appsettings.json"
|
|
config_file.write_text(json.dumps(config_data), encoding="utf-8")
|
|
|
|
Configuration.add_json_file(str(config_file), output=False)
|
|
|
|
result = Configuration.get(AppSettings)
|
|
assert result.app_name == "FromFile"
|
|
assert result.version == "2.0.0"
|
|
|
|
|
|
def test_add_json_file_not_found_exits(tmp_path):
|
|
with pytest.raises(SystemExit):
|
|
Configuration.add_json_file(str(tmp_path / "missing.json"), output=False)
|
|
|
|
|
|
def test_add_json_file_optional_missing_returns_none(tmp_path):
|
|
result = Configuration.add_json_file(str(tmp_path / "missing.json"), optional=True, output=False)
|
|
assert result is None
|
|
|
|
|
|
def test_add_json_file_invalid_json(tmp_path):
|
|
# _load_json_file catches parse errors and returns {} — no SystemExit.
|
|
# add_json_file then proceeds with an empty config (no models loaded).
|
|
bad_file = tmp_path / "bad.json"
|
|
bad_file.write_text("not valid json", encoding="utf-8")
|
|
Configuration.add_json_file(str(bad_file), output=False)
|
|
# No model should be registered since the file was invalid
|
|
assert Configuration.get("AppSettings") is None
|