Testing setup: - Add pyproject.toml with mypy and pytest configuration - Add requirements-dev.txt for development dependencies - Create tests/ directory with test fixtures - Add 17 unit tests for DAG transformation pipeline Type annotations: - Add app/types.py with TypedDict definitions for node configs - Add typed helper functions: transform_node, build_input_name_mapping, bind_inputs, prepare_dag_for_execution - Refactor run_recipe to use the new typed helpers Regression tests for today's bugs: - test_effect_cid_key_not_effect_hash: Verifies CID uses 'cid' key - test_source_cid_binding_persists: Verifies bound CIDs in final DAG Run tests with: pytest tests/ -v Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
94 lines
2.4 KiB
Python
94 lines
2.4 KiB
Python
"""
|
|
Pytest fixtures for art-celery tests.
|
|
"""
|
|
|
|
import pytest
|
|
from typing import Any, Dict, List
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_compiled_nodes() -> List[Dict[str, Any]]:
|
|
"""Sample nodes as produced by the S-expression compiler."""
|
|
return [
|
|
{
|
|
"id": "source_1",
|
|
"type": "SOURCE",
|
|
"config": {"asset": "cat"},
|
|
"inputs": [],
|
|
"name": None,
|
|
},
|
|
{
|
|
"id": "source_2",
|
|
"type": "SOURCE",
|
|
"config": {
|
|
"input": True,
|
|
"name": "Second Video",
|
|
"description": "A user-provided video",
|
|
},
|
|
"inputs": [],
|
|
"name": "second-video",
|
|
},
|
|
{
|
|
"id": "effect_1",
|
|
"type": "EFFECT",
|
|
"config": {"effect": "identity"},
|
|
"inputs": ["source_1"],
|
|
"name": None,
|
|
},
|
|
{
|
|
"id": "effect_2",
|
|
"type": "EFFECT",
|
|
"config": {"effect": "invert", "intensity": 1.0},
|
|
"inputs": ["source_2"],
|
|
"name": None,
|
|
},
|
|
{
|
|
"id": "sequence_1",
|
|
"type": "SEQUENCE",
|
|
"config": {},
|
|
"inputs": ["effect_1", "effect_2"],
|
|
"name": None,
|
|
},
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_registry() -> Dict[str, Dict[str, Any]]:
|
|
"""Sample registry with assets and effects."""
|
|
return {
|
|
"assets": {
|
|
"cat": {
|
|
"cid": "QmXrj6tSSn1vQXxxEY2Tyoudvt4CeeqR9gGQwSt7WFrhMZ",
|
|
"url": "https://example.com/cat.jpg",
|
|
},
|
|
},
|
|
"effects": {
|
|
"identity": {
|
|
"cid": "QmcWhw6wbHr1GDmorM2KDz8S3yCGTfjuyPR6y8khS2tvko",
|
|
},
|
|
"invert": {
|
|
"cid": "QmPWaW5E5WFrmDjT6w8enqvtJhM8c5jvQu7XN1doHA3Z7J",
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_recipe(
|
|
sample_compiled_nodes: List[Dict[str, Any]],
|
|
sample_registry: Dict[str, Dict[str, Any]],
|
|
) -> Dict[str, Any]:
|
|
"""Sample compiled recipe."""
|
|
return {
|
|
"name": "test-recipe",
|
|
"version": "1.0",
|
|
"description": "A test recipe",
|
|
"owner": "@test@example.com",
|
|
"registry": sample_registry,
|
|
"dag": {
|
|
"nodes": sample_compiled_nodes,
|
|
"output": "sequence_1",
|
|
},
|
|
"recipe_id": "Qmtest123",
|
|
}
|