Files
jiapuapp/design-pipeline/tests/test_asset_quality.py
T
2026-07-16 18:13:03 +08:00

101 lines
3.5 KiB
Python

import sys
import tempfile
import unittest
from pathlib import Path
from PIL import Image
SCRIPTS = Path(__file__).resolve().parents[1] / "scripts"
sys.path.insert(0, str(SCRIPTS))
from asset_quality import analyze_asset
class AssetQualityTests(unittest.TestCase):
def setUp(self):
self.directory = tempfile.TemporaryDirectory()
self.addCleanup(self.directory.cleanup)
self.root = Path(self.directory.name)
def spec(self):
return {
"id": "test-button",
"outputPixels": {"width": 32, "height": 16},
"alpha": {"required": True, "transparentOuterPadding": 2, "cornerMaxAlpha": 0},
"edge": {
"forbidChromaResidue": True,
"forbidLightFringe": True,
"premultipliedAlphaCheck": True,
},
"quality": {"maxBytes": 10000, "colorSpace": "sRGB"},
}
def clean_image(self):
image = Image.new("RGBA", (32, 16), (0, 0, 0, 0))
for y in range(2, 14):
for x in range(2, 30):
image.putpixel((x, y), (150, 20, 12, 255))
return image
def save(self, image, name="asset.png"):
path = self.root / name
image.save(path, format="PNG")
return path
def error_text(self, report):
return " ".join(report["errors"])
def test_accepts_clean_rgba_asset(self):
report = analyze_asset(self.save(self.clean_image()), self.spec())
self.assertEqual([], report["errors"])
self.assertEqual(32, report["width"])
self.assertEqual(16, report["height"])
def test_accepts_indexed_png_with_real_transparency(self):
indexed = self.clean_image().quantize(
colors=16,
method=Image.Quantize.FASTOCTREE,
dither=Image.Dither.NONE,
)
report = analyze_asset(self.save(indexed), self.spec())
self.assertEqual([], report["errors"])
self.assertEqual("P", report["mode"])
def test_rejects_wrong_dimensions(self):
report = analyze_asset(self.save(Image.new("RGBA", (31, 16), (0, 0, 0, 0))), self.spec())
self.assertIn("dimensions", self.error_text(report))
def test_rejects_opaque_outer_padding(self):
image = self.clean_image()
image.putpixel((0, 0), (120, 30, 20, 255))
report = analyze_asset(self.save(image), self.spec())
self.assertIn("outer padding", self.error_text(report))
def test_rejects_visible_green_residue(self):
image = self.clean_image()
image.putpixel((16, 8), (0, 255, 0, 255))
report = analyze_asset(self.save(image), self.spec())
self.assertIn("chroma residue", self.error_text(report))
def test_rejects_light_partially_transparent_fringe(self):
image = self.clean_image()
image.putpixel((2, 8), (250, 250, 250, 128))
report = analyze_asset(self.save(image), self.spec())
self.assertIn("light fringe", self.error_text(report))
def test_rejects_hidden_rgb_in_fully_transparent_pixels(self):
image = self.clean_image()
image.putpixel((0, 0), (255, 255, 255, 0))
report = analyze_asset(self.save(image), self.spec())
self.assertIn("transparent RGB", self.error_text(report))
def test_rejects_file_over_max_bytes(self):
spec = self.spec()
spec["quality"]["maxBytes"] = 8
report = analyze_asset(self.save(self.clean_image()), spec)
self.assertIn("maxBytes", self.error_text(report))
if __name__ == "__main__":
unittest.main()