Initial commit: PROMETHEUS v0.1.0 - Prompt optimizer
- Clean architecture (domain/application/infrastructure) - DSPy-based evolution engine with scoring - CLI via pyproject.toml entry point - Unit + integration tests (~300 tests) - Configs for glm-5.1 and glm-4.5-air models - Z.AI endpoint integration
This commit is contained in:
99
tests/unit/test_file_io.py
Normal file
99
tests/unit/test_file_io.py
Normal file
@@ -0,0 +1,99 @@
|
||||
"""Unit tests for YamlPersistence file I/O."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from prometheus.infrastructure.file_io import YamlPersistence
|
||||
|
||||
|
||||
class TestYamlPersistenceReadConfig:
|
||||
"""Tests for read_config YAML loading."""
|
||||
|
||||
def test_roundtrip_write_and_read(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
data = {
|
||||
"seed_prompt": "You are helpful.",
|
||||
"task_description": "Answer questions.",
|
||||
"max_iterations": 30,
|
||||
"verbose": True,
|
||||
}
|
||||
config_file = tmp_path / "config.yaml"
|
||||
with open(config_file, "w") as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
result = persistence.read_config(str(config_file))
|
||||
|
||||
assert result == data
|
||||
|
||||
def test_reads_nested_yaml(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
data = {
|
||||
"model": {"name": "gpt-4o", "temperature": 0.7},
|
||||
"params": [1, 2, 3],
|
||||
}
|
||||
config_file = tmp_path / "nested.yaml"
|
||||
with open(config_file, "w") as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
result = persistence.read_config(str(config_file))
|
||||
|
||||
assert result["model"]["name"] == "gpt-4o"
|
||||
assert result["params"] == [1, 2, 3]
|
||||
|
||||
def test_missing_file_raises_error(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
missing = tmp_path / "nonexistent.yaml"
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
persistence.read_config(str(missing))
|
||||
|
||||
def test_malformed_yaml_raises_error(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
bad_file = tmp_path / "bad.yaml"
|
||||
bad_file.write_text(": [invalid: {yaml", encoding="utf-8")
|
||||
|
||||
with pytest.raises(yaml.YAMLError):
|
||||
persistence.read_config(str(bad_file))
|
||||
|
||||
|
||||
class TestYamlPersistenceWriteResult:
|
||||
"""Tests for write_result YAML output."""
|
||||
|
||||
def test_roundtrip_write_result(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
data = {
|
||||
"optimized_prompt": "Improved prompt.",
|
||||
"initial_score": 0.4,
|
||||
"final_score": 0.85,
|
||||
}
|
||||
output_file = tmp_path / "result.yaml"
|
||||
persistence.write_result(str(output_file), data)
|
||||
|
||||
with open(output_file) as f:
|
||||
loaded = yaml.safe_load(f)
|
||||
|
||||
assert loaded == data
|
||||
|
||||
def test_write_result_creates_valid_yaml(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
data = {"key": "value", "number": 42}
|
||||
output_file = tmp_path / "out.yaml"
|
||||
persistence.write_result(str(output_file), data)
|
||||
|
||||
content = output_file.read_text()
|
||||
assert "key: value" in content
|
||||
assert "number: 42" in content
|
||||
|
||||
def test_write_result_handles_unicode(self, tmp_path: Path) -> None:
|
||||
persistence = YamlPersistence()
|
||||
data = {"prompt": "Répondez en français. 中文测试"}
|
||||
output_file = tmp_path / "unicode.yaml"
|
||||
persistence.write_result(str(output_file), data)
|
||||
|
||||
with open(output_file, encoding="utf-8") as f:
|
||||
loaded = yaml.safe_load(f)
|
||||
|
||||
assert loaded["prompt"] == "Répondez en français. 中文测试"
|
||||
Reference in New Issue
Block a user