docs(comfyui): consolidar las 5 funciones nuevas del grupo (tests + capability page)
Higiene del grupo comfyui sobre las 5 funciones de la sesión: comfyui_build_audio_workflow, comfyui_fetch_output_audio, comfyui_build_flux_workflow, comfyui_list_templates, comfyui_extract_template. - Tests nuevos para list_templates y extract_template (lógica pura: localización del intérprete, error-path sin el paquete instalado, contrato del dict; golden condicional con skip si no hay ComfyUI con comfyui-workflow-templates). 10 tests, todos verdes. - comfyui_list_templates.md / comfyui_extract_template.md: tested true + tests + test_file_path. - Fix drift de test_file_path en comfyui_fetch_output_audio.md (apuntaba a un *_test.py inexistente; corregido a tests/test_*.py). Elimina el WARN de fn index. - docs/capabilities/comfyui.md: subsecciones Audio (ACE-Step) y Templates oficiales. - docs/capabilities/comfyui-overview.md: sección 05b audio, fetch_output_audio en Outputs, Templates oficiales en Workflows I/O. (flux ya estaba documentada.) fn index limpio (las 5 sin WARN); sin drift nuevo en fn doctor uses-functions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""Tests para comfyui_extract_template.
|
||||
|
||||
Cubre, sin tocar red ni GPU:
|
||||
|
||||
- El camino de error legible cuando el paquete `comfyui-workflow-templates` no
|
||||
esta instalado: subprocess local contra el python del venv del registry (que no
|
||||
lo tiene) -> `ok=False` con mensaje accionable, sin lanzar.
|
||||
- El contrato del dict de retorno (claves presentes, nombre preservado) aun en
|
||||
fallo.
|
||||
|
||||
El golden path (extraer un template real con sus class_types) y el error
|
||||
'template inexistente -> sugerencias' solo se ejecutan si hay un ComfyUI con el
|
||||
paquete instalado; si no, se omiten con `pytest.skip`. Nunca dependen de GPU ni
|
||||
de un servidor ComfyUI vivo (la conversion to_api, que si necesita servidor, no
|
||||
se ejercita aqui).
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
from comfyui_extract_template import _find_comfyui_python, comfyui_extract_template
|
||||
|
||||
_PKG = "comfyui_workflow_templates_core"
|
||||
_RET_KEYS = {
|
||||
"ok", "name", "format", "class_types", "has_subgraphs", "n_nodes",
|
||||
"graph", "api_workflow", "api_error", "bundle", "version", "assets", "error",
|
||||
}
|
||||
|
||||
|
||||
def _python_con_paquete():
|
||||
"""Devuelve un interprete que importa el paquete, o None (para omitir el golden)."""
|
||||
py = _find_comfyui_python(None)
|
||||
if not py:
|
||||
return None
|
||||
r = subprocess.run([py, "-c", f"import {_PKG}"], capture_output=True)
|
||||
return py if r.returncode == 0 else None
|
||||
|
||||
|
||||
def test_extract_sin_paquete_error_legible():
|
||||
# El venv del registry no tiene el paquete -> ok=False con error que lo menciona.
|
||||
res = comfyui_extract_template("image_sdxl", comfyui_python=sys.executable)
|
||||
assert res["ok"] is False
|
||||
assert res["graph"] == {}
|
||||
assert res["class_types"] == []
|
||||
assert "comfyui-workflow-templates" in res["error"]
|
||||
|
||||
|
||||
def test_extract_preserva_nombre_y_claves():
|
||||
# El nombre pedido se preserva y el dict trae siempre todas sus claves.
|
||||
res = comfyui_extract_template("cualquier_nombre", comfyui_python=sys.executable)
|
||||
assert res["name"] == "cualquier_nombre"
|
||||
assert _RET_KEYS <= set(res)
|
||||
|
||||
|
||||
def test_extract_golden_template_real():
|
||||
py = _python_con_paquete()
|
||||
if not py:
|
||||
pytest.skip("no hay ComfyUI con comfyui-workflow-templates instalado")
|
||||
# Toma el primer template real del catalogo y extraelo (to_api=False: sin servidor).
|
||||
from comfyui_list_templates import comfyui_list_templates
|
||||
|
||||
cat = comfyui_list_templates(comfyui_python=py, with_nodes=False, limit=1)
|
||||
assert cat["ok"] and cat["count"] >= 1
|
||||
name = cat["templates"][0]["name"]
|
||||
|
||||
res = comfyui_extract_template(name, comfyui_python=py)
|
||||
assert res["ok"] is True
|
||||
assert res["name"] == name
|
||||
assert isinstance(res["graph"], dict) and res["graph"]
|
||||
assert len(res["class_types"]) > 0
|
||||
assert res["format"] in ("ui_graph", "api")
|
||||
|
||||
|
||||
def test_extract_nombre_inexistente_error_con_sugerencias():
|
||||
py = _python_con_paquete()
|
||||
if not py:
|
||||
pytest.skip("no hay ComfyUI con comfyui-workflow-templates instalado")
|
||||
res = comfyui_extract_template(
|
||||
"zzz_template_que_no_existe_jamas", comfyui_python=py
|
||||
)
|
||||
assert res["ok"] is False
|
||||
assert "no existe" in res["error"]
|
||||
@@ -0,0 +1,87 @@
|
||||
"""Tests para comfyui_list_templates.
|
||||
|
||||
Cubre dos cosas sin tocar red ni GPU:
|
||||
|
||||
- La localizacion del interprete (`_find_comfyui_python`), que solo consulta el
|
||||
sistema de ficheros.
|
||||
- El camino de error legible cuando el paquete `comfyui-workflow-templates` no
|
||||
esta instalado: se ejecuta un subprocess local contra el python indicado (el
|
||||
del propio venv del registry, que no tiene el paquete) y se comprueba que la
|
||||
funcion devuelve `ok=False` con un mensaje accionable, sin lanzar.
|
||||
|
||||
El golden path (catalogo de templates no vacio) y un edge de filtrado solo se
|
||||
ejecutan si hay un ComfyUI con el paquete instalado; si no, se omiten con
|
||||
`pytest.skip`. Nunca dependen de GPU ni de un servidor ComfyUI vivo.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
from comfyui_list_templates import _find_comfyui_python, comfyui_list_templates
|
||||
|
||||
_PKG = "comfyui_workflow_templates_core"
|
||||
_RET_KEYS = {"ok", "count", "package_version", "templates", "error"}
|
||||
|
||||
|
||||
def _python_con_paquete():
|
||||
"""Devuelve un interprete que importa el paquete, o None (para omitir el golden)."""
|
||||
py = _find_comfyui_python(None)
|
||||
if not py:
|
||||
return None
|
||||
r = subprocess.run([py, "-c", f"import {_PKG}"], capture_output=True)
|
||||
return py if r.returncode == 0 else None
|
||||
|
||||
|
||||
def test_find_comfyui_python_explicit_valido():
|
||||
# Un interprete que existe en disco se devuelve tal cual.
|
||||
assert _find_comfyui_python(sys.executable) == sys.executable
|
||||
|
||||
|
||||
def test_find_comfyui_python_inexistente_cae_a_fallback():
|
||||
# Una ruta inexistente no rompe: cae al siguiente candidato (sys.executable existe).
|
||||
got = _find_comfyui_python("/ruta/que/no/existe/python")
|
||||
assert got is not None and os.path.isfile(got)
|
||||
|
||||
|
||||
def test_list_sin_paquete_error_legible():
|
||||
# El venv del registry no tiene el paquete -> ok=False con error que lo menciona.
|
||||
res = comfyui_list_templates(comfyui_python=sys.executable)
|
||||
assert res["ok"] is False
|
||||
assert res["count"] == 0
|
||||
assert res["templates"] == []
|
||||
assert "comfyui-workflow-templates" in res["error"]
|
||||
|
||||
|
||||
def test_list_retorno_tiene_todas_las_claves():
|
||||
# El contrato del dict de retorno se mantiene aun en fallo.
|
||||
res = comfyui_list_templates(comfyui_python=sys.executable)
|
||||
assert _RET_KEYS <= set(res)
|
||||
|
||||
|
||||
def test_list_golden_catalogo_no_vacio():
|
||||
py = _python_con_paquete()
|
||||
if not py:
|
||||
pytest.skip("no hay ComfyUI con comfyui-workflow-templates instalado")
|
||||
res = comfyui_list_templates(comfyui_python=py, with_nodes=False, limit=5)
|
||||
assert res["ok"] is True
|
||||
assert res["count"] > 0
|
||||
assert len(res["templates"]) == res["count"]
|
||||
# Cada template trae al menos nombre y bundle.
|
||||
for t in res["templates"]:
|
||||
assert t.get("name")
|
||||
assert t.get("bundle")
|
||||
|
||||
|
||||
def test_list_golden_filtro_bundle_inexistente_vacio():
|
||||
py = _python_con_paquete()
|
||||
if not py:
|
||||
pytest.skip("no hay ComfyUI con comfyui-workflow-templates instalado")
|
||||
# Un bundle que no existe filtra a una lista vacia pero la llamada sigue siendo ok.
|
||||
res = comfyui_list_templates(comfyui_python=py, bundle="bundle-inexistente-xyz")
|
||||
assert res["ok"] is True
|
||||
assert res["count"] == 0
|
||||
assert res["templates"] == []
|
||||
Reference in New Issue
Block a user