85 lines
3 KiB
Python
85 lines
3 KiB
Python
"""Integration tests for hokusai.config."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import yaml
|
|
|
|
from hokusai.config import GenerateTargetConfig, load_config
|
|
|
|
|
|
class TestLoadConfig:
|
|
"""Test loading and validating YAML config files end-to-end."""
|
|
|
|
def test_minimal_config(self, project_dir: Path) -> None:
|
|
config_path = project_dir / "test.hokusai.yaml"
|
|
_ = config_path.write_text(
|
|
yaml.dump({"targets": {"out.txt": {"prompt": "hello"}}})
|
|
)
|
|
config = load_config(config_path)
|
|
|
|
assert "out.txt" in config.targets
|
|
target = config.targets["out.txt"]
|
|
assert isinstance(target, GenerateTargetConfig)
|
|
assert target.prompt == "hello"
|
|
assert config.defaults.text_model == "pixtral-large-latest"
|
|
assert config.defaults.image_model == "flux-2-pro"
|
|
|
|
def test_full_config_with_all_fields(self, project_dir: Path) -> None:
|
|
raw = {
|
|
"defaults": {
|
|
"text_model": "custom-text",
|
|
"image_model": "custom-image",
|
|
},
|
|
"targets": {
|
|
"banner.png": {
|
|
"prompt": "A wide banner",
|
|
"model": "flux-dev",
|
|
"width": 1920,
|
|
"height": 480,
|
|
"inputs": ["ref.png"],
|
|
"reference_images": ["ref.png"],
|
|
"control_images": ["ctrl.png"],
|
|
},
|
|
"story.md": {
|
|
"prompt": "Write a story",
|
|
"inputs": ["banner.png"],
|
|
},
|
|
},
|
|
}
|
|
config_path = project_dir / "full.hokusai.yaml"
|
|
_ = config_path.write_text(yaml.dump(raw, default_flow_style=False))
|
|
|
|
config = load_config(config_path)
|
|
|
|
assert config.defaults.text_model == "custom-text"
|
|
assert config.defaults.image_model == "custom-image"
|
|
|
|
banner = config.targets["banner.png"]
|
|
assert isinstance(banner, GenerateTargetConfig)
|
|
assert banner.model == "flux-dev"
|
|
assert banner.width == 1920
|
|
assert banner.height == 480
|
|
assert banner.reference_images == ["ref.png"]
|
|
assert banner.control_images == ["ctrl.png"]
|
|
|
|
story = config.targets["story.md"]
|
|
assert isinstance(story, GenerateTargetConfig)
|
|
assert story.model is None
|
|
assert story.inputs == ["banner.png"]
|
|
|
|
def test_empty_targets_rejected(self, project_dir: Path) -> None:
|
|
config_path = project_dir / "empty.hokusai.yaml"
|
|
_ = config_path.write_text(yaml.dump({"targets": {}}))
|
|
|
|
with pytest.raises(Exception, match="At least one target"):
|
|
_ = load_config(config_path)
|
|
|
|
def test_missing_prompt_rejected(self, project_dir: Path) -> None:
|
|
config_path = project_dir / "bad.hokusai.yaml"
|
|
_ = config_path.write_text(yaml.dump({"targets": {"out.txt": {}}}))
|
|
|
|
with pytest.raises(Exception):
|
|
_ = load_config(config_path)
|