diff --git a/tests/test_config/.gitignore b/tests/test_config/.gitignore new file mode 100644 index 0000000..ac19afe --- /dev/null +++ b/tests/test_config/.gitignore @@ -0,0 +1 @@ +plyngent-edit-*.toml diff --git a/tests/test_config/plyngent-bad.toml b/tests/test_config/plyngent-bad.toml new file mode 100644 index 0000000..bbeb840 --- /dev/null +++ b/tests/test_config/plyngent-bad.toml @@ -0,0 +1,15 @@ +[providers.test1] +preset = "closeai" +access_key_or_token = "sk-1145141919810" + +[providers.test2] +preset = "openai-compatible" + +[providers.test3] +preset = "nanthropic" +access_key_or_token = "sk-1145141919810" + +[providers.foo1] +preset = "deepseek" +access_key_or_token = "sk-1145141919810" +convention = "anthropic" diff --git a/tests/test_config/plyngent-empty.toml b/tests/test_config/plyngent-empty.toml new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_config/plyngent-invalid.toml b/tests/test_config/plyngent-invalid.toml new file mode 100644 index 0000000..2a55b0c --- /dev/null +++ b/tests/test_config/plyngent-invalid.toml @@ -0,0 +1,3 @@ +[providers.test1] +preset = "openai" +access_key_or_token = "sk-1145141919810 \ No newline at end of file diff --git a/tests/test_config/plyngent-valid.toml b/tests/test_config/plyngent-valid.toml new file mode 100644 index 0000000..6a9b15c --- /dev/null +++ b/tests/test_config/plyngent-valid.toml @@ -0,0 +1,22 @@ +[providers.test1] +preset = "openai" +access_key_or_token = "sk-1145141919810" + +[providers.test2] +preset = "openai-compatible" +url = "https://www.example.com/v1" +access_key_or_token = "sk-1145141919810" + +[providers.test2.models] +"glm-5.2" = { text = true, image_in = false, image_out = false, audio_in = false, audio_out = false, video_in = false, video_out = false, cost_factor = 5 } + +[providers.test3] +preset = "anthropic" +access_key_or_token = "sk-1145141919810" + +[providers.foo1] +preset = "deepseek" +access_key_or_token = "sk-1145141919810" + +[providers.foo1.extras] +convention = "anthropic" diff --git a/tests/test_config/test_config.py b/tests/test_config/test_config.py new file mode 100644 index 0000000..172d968 --- /dev/null +++ b/tests/test_config/test_config.py @@ -0,0 +1,99 @@ +import shutil +from collections.abc import Mapping +from pathlib import Path + +import pytest + +import plyngent +from plyngent.config import ( + AnthropicProvider, + ConfigFormatError, + DeepseekProvider, + OpenAICompatibleProvider, + OpenAIProvider, +) + + +@pytest.fixture +def default_config_source(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr(plyngent.config, "default_config_source", Path(__file__).parent / "plyngent-valid.toml") + + +def test_read_default_config(default_config_source: None) -> None: + _ = default_config_source + config = plyngent.config.load() + providers = config.providers + assert isinstance(providers, Mapping) + assert isinstance(providers["test1"], OpenAIProvider) + assert isinstance(providers["test2"], OpenAICompatibleProvider) + assert isinstance(providers["test3"], AnthropicProvider) + assert isinstance(providers["foo1"], DeepseekProvider) + + +def test_read_valid_config() -> None: + config = plyngent.config.load(Path(__file__).parent / "plyngent-valid.toml") + providers = config.providers + assert isinstance(providers, Mapping) + assert isinstance(providers["test1"], OpenAIProvider) + assert isinstance(providers["test2"], OpenAICompatibleProvider) + assert isinstance(providers["test3"], AnthropicProvider) + assert isinstance(providers["foo1"], DeepseekProvider) + + +def test_read_empty_config() -> None: + config = plyngent.config.load(Path(__file__).parent / "plyngent-empty.toml") + assert isinstance(config.providers, Mapping) + assert not config.providers + + +def test_read_bad_config() -> None: + config = plyngent.config.load(Path(__file__).parent / "plyngent-bad.toml") + assert isinstance(config.providers, Mapping) + assert not config.providers + assert isinstance(config.bad_providers, Mapping) + + +def test_read_invalid_config() -> None: + with pytest.raises(ConfigFormatError): + _ = plyngent.config.load(Path(__file__).parent / "plyngent-invalid.toml") + + +def test_write_new_config() -> None: + file = Path(__file__).parent / "plyngent-edit-1.toml" + file.unlink(missing_ok=True) + config = plyngent.config.load(file) + assert isinstance(config.providers, Mapping) + config.providers = { + "foo1": OpenAIProvider(access_key_or_token="sk-00301212"), + "foo2": DeepseekProvider(access_key_or_token="sk-00301212"), + } + assert isinstance(config.providers, Mapping) + config.write() + assert isinstance(config.providers["foo1"], OpenAIProvider) + assert config.providers["foo1"].access_key_or_token == "sk-00301212" + assert isinstance(config.providers["foo2"], DeepseekProvider) + assert config.providers["foo2"].access_key_or_token == "sk-00301212" + config.reload() + assert isinstance(config.providers["foo1"], OpenAIProvider) + assert config.providers["foo1"].access_key_or_token == "sk-00301212" + assert isinstance(config.providers["foo2"], DeepseekProvider) + assert config.providers["foo2"].access_key_or_token == "sk-00301212" + + +def test_update_config() -> None: + file = Path(__file__).parent / "plyngent-edit-2.toml" + _ = shutil.copy(Path(__file__).parent / "plyngent-valid.toml", file) + config = plyngent.config.load(file) + assert isinstance(config.providers, Mapping) + config.providers = config.providers | {"foo2": DeepseekProvider(access_key_or_token="sk-00301212")} + assert isinstance(config.providers, Mapping) + config.write() + assert isinstance(config.providers["foo1"], DeepseekProvider) + assert config.providers["foo1"].access_key_or_token == "sk-1145141919810" + assert isinstance(config.providers["foo2"], DeepseekProvider) + assert config.providers["foo2"].access_key_or_token == "sk-00301212" + config.reload() + assert isinstance(config.providers["foo1"], DeepseekProvider) + assert config.providers["foo1"].access_key_or_token == "sk-1145141919810" + assert isinstance(config.providers["foo2"], DeepseekProvider) + assert config.providers["foo2"].access_key_or_token == "sk-00301212"