from __future__ import annotations import io from PIL import Image from spriteforge.reader import decode_sfa from spriteforge.studio.export import export_project from spriteforge.studio.models import Asset, GenerationRecipe from spriteforge.studio.store import ProjectStore def test_approved_shots_export_to_runtime_asset(tmp_path): store = ProjectStore.create(tmp_path/"studio", "ops", "Ops") store.add_asset(Asset(id="agent", name="Agent", kind="character", target_width=60, target_height=60)) recipe = GenerationRecipe(provider="test", model="fake", seed=1, prompt="x", width=256, height=256) for direction in range(2): for frame in range(2): _, shot = store.add_shot("agent", "idle", direction, frame) image = Image.new("RGBA", (64, 80), (50+direction*40, 20+frame*40, 30, 255)) data=io.BytesIO(); image.save(data,"PNG") media=store.import_png(data.getvalue(),"candidate") _, candidate=store.add_candidate("agent",shot.id,media,recipe) store.decide("agent",shot.id,candidate.id,"approved") files=export_project(store,tmp_path/"build") assert {p.name for p in files} == {"agent.sfa","palettes.sfp","index.json","spriteforge_assets.h","reload.json"} asset=decode_sfa((tmp_path/"build"/"agent.sfa").read_bytes()) assert len(asset.frames)==4 and len(asset.directions)==2 assert all(f.width<=60 and f.height<=60 for f in asset.frames) assert "SF_ASSET_AGENT" in (tmp_path/"build"/"spriteforge_assets.h").read_text()