"""Shared fixtures for hokusai integration tests.""" from __future__ import annotations from collections.abc import Callable from pathlib import Path import pytest import yaml from hokusai.config import ProjectConfig, load_config WriteConfig = Callable[[dict[str, object]], ProjectConfig] @pytest.fixture def project_dir(tmp_path: Path) -> Path: """A temporary directory acting as the project root.""" return tmp_path @pytest.fixture def write_config(project_dir: Path) -> WriteConfig: """Write a hokusai YAML config and return the loaded ProjectConfig. Usage:: config = write_config({"targets": {"out.txt": {"prompt": "hello"}}}) """ def _write(raw: dict[str, object]) -> ProjectConfig: config_path = project_dir / "project.hokusai.yaml" _ = config_path.write_text(yaml.dump(raw, default_flow_style=False)) return load_config(config_path) return _write @pytest.fixture def simple_text_config(write_config: WriteConfig) -> ProjectConfig: """A minimal config with one text target.""" return write_config({"targets": {"output.txt": {"prompt": "Generate something"}}}) @pytest.fixture def multi_target_config(project_dir: Path, write_config: WriteConfig) -> ProjectConfig: """Config with multiple targets forming a dependency chain. input.txt (external file) -> summary.md -> final.txt Also has an independent image target: hero.png """ _ = (project_dir / "input.txt").write_text("Some input content") return write_config( { "targets": { "summary.md": { "prompt": "Summarize the input", "inputs": ["input.txt"], }, "final.txt": { "prompt": "Finalize the summary", "inputs": ["summary.md"], }, "hero.png": { "prompt": "A heroic landscape", "width": 1024, "height": 768, }, } } ) @pytest.fixture def prompt_file(project_dir: Path) -> Path: """Create a prompt file on disk and return its path.""" p = project_dir / "my_prompt.txt" _ = p.write_text("This prompt comes from a file") return p