- Script uploaded only the three portable binaries; v0.2.1 release was missing step-line-setup-0.2.1.exe and the AppImage. Now uploads the full set (extras when present), reuses existing releases (adds missing assets), and falls back to ~/.git-credentials basic auth when GITEA_TOKEN is unset - Back-filled both missing assets onto the live v0.2.1 release via API (release now carries all 5 artifacts) - TODO/RELEASING/MEMORY document the findings and the host admin steps for anonymous downloads ([service] REQUIRE_SIGNIN_VIEW)
110 lines
4.0 KiB
Python
110 lines
4.0 KiB
Python
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from PIL import Image
|
|
|
|
import asset_pipeline
|
|
|
|
|
|
class AssetPipelineTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.TemporaryDirectory()
|
|
self.root = Path(self.temp_dir.name)
|
|
|
|
def tearDown(self):
|
|
self.temp_dir.cleanup()
|
|
|
|
def test_crop_uses_center_and_exact_dimensions(self):
|
|
source = self.root / "source.png"
|
|
output = self.root / "crop.png"
|
|
Image.new("RGB", (80, 60), (20, 40, 60)).save(source)
|
|
|
|
asset_pipeline.crop_image(source, output, 32, 24)
|
|
|
|
with Image.open(output) as image:
|
|
self.assertEqual(image.size, (32, 24))
|
|
|
|
def test_resize_contain_preserves_aspect_and_exact_canvas(self):
|
|
source = self.root / "source.png"
|
|
output = self.root / "resized.png"
|
|
Image.new("RGB", (80, 40), (20, 40, 60)).save(source)
|
|
|
|
asset_pipeline.resize_image(source, output, 64, 64, "contain")
|
|
|
|
with Image.open(output) as image:
|
|
self.assertEqual(image.size, (64, 64))
|
|
self.assertEqual(image.getpixel((32, 0)), (0, 0, 0, 0))
|
|
|
|
def test_texture_audit_accepts_valid_tile_and_rejects_bad_seams(self):
|
|
good = self.root / "good.png"
|
|
bad = self.root / "bad.png"
|
|
Image.new("RGB", (512, 512), (80, 80, 80)).save(good)
|
|
mismatch = Image.new("RGB", (512, 512), (80, 80, 80))
|
|
for y in range(512):
|
|
mismatch.putpixel((0, y), (255, 0, 0))
|
|
mismatch.save(bad)
|
|
|
|
self.assertEqual(asset_pipeline.audit_image(
|
|
good, "tile")["quality"], "good")
|
|
self.assertEqual(asset_pipeline.audit_image(
|
|
bad, "tile")["quality"], "bad")
|
|
|
|
def test_background_audit_rejects_small_image(self):
|
|
image_path = self.root / "small.png"
|
|
Image.new("RGB", (640, 360)).save(image_path)
|
|
|
|
result = asset_pipeline.audit_image(image_path, "background")
|
|
|
|
self.assertEqual(result["quality"], "bad")
|
|
self.assertTrue(
|
|
any("too small" in error for error in result["errors"]))
|
|
|
|
def test_grayscale_vignette_is_valid_without_alpha(self):
|
|
image_path = self.root / "vignette.png"
|
|
Image.new("L", (512, 512), 0).save(image_path)
|
|
|
|
self.assertEqual(asset_pipeline.audit_image(
|
|
image_path, "overlay")["quality"], "good")
|
|
|
|
def test_icon_audit_rejects_opaque_rgba_images(self):
|
|
image_path = self.root / "opaque_icon.png"
|
|
Image.new("RGBA", (64, 64), (255, 255, 255, 255)).save(image_path)
|
|
|
|
result = asset_pipeline.audit_image(image_path, "icon")
|
|
|
|
self.assertEqual(result["quality"], "bad")
|
|
self.assertTrue(any("transparency required" in error
|
|
for error in result["errors"]))
|
|
|
|
def test_generation_reuses_existing_backend_and_targets_role_dimensions(self):
|
|
output = self.root / "background.png"
|
|
args = type("Args", (), {
|
|
"prompt": "Hollywood at night", "role": "background", "output": str(output),
|
|
"width": 1920, "height": 1080, "transparent": None,
|
|
"model": "test-model", "request_size": 2048,
|
|
})()
|
|
generated = Image.new("RGB", (256, 256), (20, 40, 60))
|
|
|
|
with patch.object(asset_pipeline.generate_textures, "generate_image",
|
|
return_value=generated) as backend:
|
|
asset_pipeline._generate(args)
|
|
|
|
self.assertIn("Hollywood at night", backend.call_args.args[0])
|
|
self.assertIn("wide 16:9", backend.call_args.args[0])
|
|
with Image.open(output) as image:
|
|
self.assertEqual(image.size, (1920, 1080))
|
|
|
|
def test_role_inference_uses_game_asset_paths(self):
|
|
self.assertEqual(asset_pipeline.infer_role(
|
|
Path("assets/textures/icons/wand.png")), "icon")
|
|
self.assertEqual(asset_pipeline.infer_role(
|
|
Path("assets/textures/cards/ticket.png")), "card")
|
|
self.assertEqual(asset_pipeline.infer_role(
|
|
Path("assets/textures/skyline.png")), "backdrop")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|