from pathlib import Path import pytest from spriteforge.manifest import ManifestInvalid, load_library, load_manifest VALID="""\ defaults: dirs: 8 fps: 12 pivot: bottom_center tags: [monster] skeleton_warrior: backend: blender rig: rigs/humanoid.blend parts: {torso: ribcage, head: skull} anims: [idle, walk] palettes: [bone_pale, bone_charred] crypt_wall: backend: procedural generator: tileset_wall params: {material: stone_cracked, height: 96, variants: 6} dirs: 1 health_potion: backend: import source: items/health_potion.png size: 32x32 palette: items_common """ def write(tmp_path: Path,text: str,name="assets.yaml")->Path: path=tmp_path/name;path.write_text(text,encoding="utf-8");return path def test_flat_manifest_and_defaults(tmp_path): manifest=load_manifest(write(tmp_path,VALID)) assert [x.id for x in manifest.assets]==["skeleton_warrior","crypt_wall","health_potion"] assert manifest.assets[0].spec.dirs==8 and manifest.assets[1].spec.dirs==1 assert manifest.assets[2].spec.size=="32x32" def test_nested_assets_supported(tmp_path): path=write(tmp_path,"defaults: {fps: 10}\nassets:\n floor_a:\n backend: procedural\n generator: floor\n") assert load_manifest(path).assets[0].spec.fps==10 def test_error_has_exact_file_and_line(tmp_path): path=write(tmp_path,"bad_asset:\n backend: procedural\n generatr: floor\n") with pytest.raises(ManifestInvalid) as caught: load_manifest(path) rendered="\n".join(map(str,caught.value.errors)) assert f"{path.resolve()}:3:3" in rendered and "generatr" in rendered def test_backend_contract_and_size(tmp_path): path=write(tmp_path,"potion:\n backend: import\n source: potion.png\n size: 32-32\n") with pytest.raises(ManifestInvalid) as caught: load_manifest(path) assert "WIDTHxHEIGHT" in str(caught.value) missing=write(tmp_path,"potion:\n backend: import\n","missing.yaml") with pytest.raises(ManifestInvalid,match="requires 'source'"): load_manifest(missing) def test_duplicate_ids_across_manifests(tmp_path): a=write(tmp_path,"floor:\n backend: procedural\n generator: floor\n","a.yaml") b=write(tmp_path,"floor:\n backend: import\n source: floor.png\n","b.yaml") with pytest.raises(ManifestInvalid,match="duplicate asset id"): load_library([a,b])