spriteforge/tests/test_import_composite.py

56 lines
2.6 KiB
Python

from pathlib import Path
import numpy as np
from PIL import Image
from spriteforge.backends import BackendContext, create_backend, implemented_backends
from spriteforge.build import build_assets
from spriteforge.manifest import AssetSpec, load_library
from spriteforge.reader import decode_sfa
def _png(path: Path, rgba: np.ndarray) -> None:
Image.fromarray(rgba, "RGBA").save(path)
def test_import_splits_sheet_and_sets_directions(tmp_path: Path):
sheet = np.zeros((4, 8, 4), dtype=np.uint8)
sheet[:, :4] = (255, 0, 0, 255); sheet[:, 4:] = (0, 255, 0, 255)
_png(tmp_path / "sheet.png", sheet)
spec = AssetSpec(backend="import", source="sheet.png", dirs=2, fps=10,
params={"frame_width": 4, "frame_height": 4})
backend = create_backend("import")
assert backend.dependencies(spec, BackendContext(tmp_path, "hero")) == (tmp_path / "sheet.png",)
asset = backend.generate(spec, BackendContext(tmp_path, "hero"))
assert len(asset.frames) == 2 and asset.directions_centidegrees == (0, 18000)
assert asset.frames[0].duration_ms == 100
def test_composite_alpha_blends_in_manifest_order(tmp_path: Path):
bottom = np.zeros((2, 2, 4), dtype=np.uint8); bottom[:] = (200, 0, 0, 255)
top = np.zeros((2, 2, 4), dtype=np.uint8); top[:] = (0, 0, 200, 128)
_png(tmp_path / "bottom.png", bottom); _png(tmp_path / "top.png", top)
spec = AssetSpec(backend="composite", layers=["bottom.png", "top.png"], dirs=1)
asset = create_backend("composite").generate(spec, BackendContext(tmp_path, "layered"))
pixel = asset.frames[0].rgba[0, 0]
assert tuple(pixel) == (100, 0, 100, 255)
assert asset.layer_count == 2
def test_all_local_backends_are_registered():
assert {"procedural", "blender", "import", "composite"} <= set(implemented_backends())
assert "image_api" not in implemented_backends()
def test_import_and_composite_build_real_sfa_files(tmp_path: Path):
red = np.zeros((4, 4, 4), dtype=np.uint8); red[:] = (200, 20, 20, 255)
blue = np.zeros((4, 4, 4), dtype=np.uint8); blue[1:3, 1:3] = (20, 20, 200, 255)
_png(tmp_path / "red.png", red); _png(tmp_path / "blue.png", blue)
manifest = tmp_path / "assets.yaml"
manifest.write_text("imported:\n backend: import\n source: red.png\nlayered:\n backend: composite\n layers: [red.png, blue.png]\n")
result = build_assets(load_library([manifest]), tmp_path / "build", cache_dir=tmp_path / "cache")
assert result.asset_count == 2
assert decode_sfa((tmp_path / "build" / "imported.sfa").read_bytes()).frames
layered = decode_sfa((tmp_path / "build" / "layered.sfa").read_bytes())
assert layered.layer_orders == ((0, 1),)