test(comfyui): reubicar test de pixeloe_downscale a tests/
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""Tests de pixeloe_downscale — tolerantes al entorno.
|
||||
|
||||
El venv del registry NO trae `pixeloe`, asi que estas pruebas ejercitan el
|
||||
"bridge" de interprete (subprocess al python de ComfyUI, que si la tiene). Si
|
||||
tampoco hay ningun interprete con pixeloe disponible, la funcion debe degradar
|
||||
limpiamente: ok=False con error no vacio y SIN lanzar excepcion.
|
||||
|
||||
Por eso cada test PASA en los dos escenarios:
|
||||
- pixeloe disponible (inproc o via bridge): assert sobre el resultado real.
|
||||
- pixeloe ausente en todos lados: assert sobre la degradacion no-throw.
|
||||
Asi la suite es verde tanto en este PC (ComfyUI presente) como en uno sin ComfyUI,
|
||||
y el contrato "no-throw" queda cubierto en ambos.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from ml.pixeloe_downscale import pixeloe_downscale # noqa: E402
|
||||
|
||||
|
||||
def _shapes_png(path, w=256, h=256):
|
||||
"""PNG 256x256 RGB con un gradiente + formas (contraste con silueta clara)."""
|
||||
yy, xx = np.mgrid[0:h, 0:w]
|
||||
arr = np.zeros((h, w, 3), dtype=np.uint8)
|
||||
arr[..., 0] = (xx * 255 // max(1, w - 1)).astype(np.uint8) # gradiente rojo
|
||||
arr[..., 1] = (yy * 255 // max(1, h - 1)).astype(np.uint8) # gradiente verde
|
||||
# Bloque azul central: borde duro para que el modo "contrast" tenga silueta.
|
||||
arr[h // 4:3 * h // 4, w // 4:3 * w // 4, 2] = 255
|
||||
Image.fromarray(arr, "RGB").save(path)
|
||||
return path
|
||||
|
||||
|
||||
def test_golden_downscale_64_or_clean_degrade(tmp_path):
|
||||
"""Golden: 256x256 -> grid 64x64 (no_upscale). Si pixeloe no esta -> ok=False limpio."""
|
||||
src = _shapes_png(str(tmp_path / "raw.png"))
|
||||
dst = str(tmp_path / "grid64.png")
|
||||
res = pixeloe_downscale(src, dst, target_size=64, no_upscale=True)
|
||||
assert isinstance(res, dict)
|
||||
if res["ok"]:
|
||||
assert os.path.isfile(dst)
|
||||
assert res["size"] == [64, 64] # no_upscale=True -> grid real
|
||||
assert res["error"] == ""
|
||||
assert res["via"] in ("inproc", "bridge")
|
||||
assert res["mode"] == "contrast"
|
||||
assert res["target_size"] == 64
|
||||
else:
|
||||
# Degradacion limpia: sin pixeloe en ningun interprete.
|
||||
assert res["error"] != ""
|
||||
assert res["via"] in ("", "bridge", "inproc")
|
||||
|
||||
|
||||
def test_edge_target_size_32(tmp_path):
|
||||
"""Edge: grid de 32 (iconos). size==[32,32] cuando pixeloe esta presente."""
|
||||
src = _shapes_png(str(tmp_path / "raw.png"))
|
||||
dst = str(tmp_path / "grid32.png")
|
||||
res = pixeloe_downscale(src, dst, target_size=32, no_upscale=True)
|
||||
if res["ok"]:
|
||||
assert res["size"] == [32, 32]
|
||||
assert res["target_size"] == 32
|
||||
assert os.path.isfile(dst)
|
||||
else:
|
||||
assert res["error"] != ""
|
||||
|
||||
|
||||
def test_edge_mode_nearest_no_color_matching(tmp_path):
|
||||
"""Edge: otro modo + color_matching off; debe seguir produciendo el grid o degradar."""
|
||||
src = _shapes_png(str(tmp_path / "raw.png"))
|
||||
dst = str(tmp_path / "near.png")
|
||||
res = pixeloe_downscale(
|
||||
src, dst, mode="nearest", target_size=64,
|
||||
color_matching=False, no_upscale=True,
|
||||
)
|
||||
assert isinstance(res, dict)
|
||||
if res["ok"]:
|
||||
assert res["mode"] == "nearest"
|
||||
assert res["size"] == [64, 64]
|
||||
else:
|
||||
assert res["error"] != ""
|
||||
|
||||
|
||||
def test_error_missing_src_no_throw(tmp_path):
|
||||
"""Error path: src inexistente -> ok=False, error explica, sin excepcion."""
|
||||
res = pixeloe_downscale(
|
||||
str(tmp_path / "nope.png"), str(tmp_path / "o.png"), target_size=64,
|
||||
)
|
||||
assert res["ok"] is False
|
||||
assert "no existe" in res["error"]
|
||||
assert res["size"] == [0, 0]
|
||||
|
||||
|
||||
def test_error_no_interpreter_with_pixeloe(tmp_path):
|
||||
"""Error path: forzar comfy_python invalido cuando el actual no tiene pixeloe.
|
||||
|
||||
Si el interprete que corre el test YA tiene pixeloe (inproc), el comfy_python
|
||||
invalido se ignora y la llamada puede salir ok=True; el test sigue siendo
|
||||
valido (no-throw). Si NO lo tiene, no hay ningun interprete con pixeloe y debe
|
||||
devolver ok=False con error, nunca lanzar.
|
||||
"""
|
||||
src = _shapes_png(str(tmp_path / "raw.png"))
|
||||
dst = str(tmp_path / "o.png")
|
||||
res = pixeloe_downscale(
|
||||
src, dst, target_size=64, comfy_python="/no/such/python-interpreter",
|
||||
)
|
||||
assert isinstance(res, dict)
|
||||
try:
|
||||
import pixeloe # noqa: F401
|
||||
has_local = True
|
||||
except Exception: # noqa: BLE001
|
||||
has_local = False
|
||||
if has_local:
|
||||
# pixeloe en el interprete del test -> ruta inproc, comfy_python ignorado.
|
||||
assert res["ok"] is True
|
||||
else:
|
||||
# comfy_python invalido + env vacio: si ~/ComfyUI/.venv existe, puede
|
||||
# bridgear y salir ok; si no, ok=False con error. Ambos no-throw.
|
||||
assert res["ok"] in (True, False)
|
||||
if not res["ok"]:
|
||||
assert res["error"] != ""
|
||||
Reference in New Issue
Block a user