Files
kunail0804-ComfyUI-Scene-Co…/tests/resolver/test_resolver_node.py
T
de5edd7064 fix(nodes): resolve KB path against the package and add raw debug outputs (#78)
Two ComfyUI issues found while testing.

1. Empty output with no error: the Knowledge Base Loader resolved a relative
   `path` against ComfyUI's working directory, not this package, so the default
   `knowledge_base/` loaded 0 entries (an empty KB is valid) and every concept
   became unknown -> empty prompts. Relative paths now resolve against the
   package root, and the loader warns when the Knowledge Base is empty.

2. Add a `raw` string output (a JSON dump of the node's data) to the Scene
   Analyzer, Scene Validator, Resolver, Category Splitter, and Prompt Builder
   nodes, plus a summary `raw` on the Knowledge Base Loader, for inspecting the
   pipeline in the graph. Adds a shared to_raw_json helper.

Tests: package-relative path resolution (independent of cwd), empty-KB warning,
raw output content, and updated node metadata/return-arity expectations.

Co-authored-by: kunail0804 <kunail0804@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 18:54:40 +02:00

90 lines
2.9 KiB
Python

"""Tests for the Resolver ComfyUI node (issue #21). No Ollama."""
from __future__ import annotations
import nodes
import nodes.resolver_node as node_module
from compiler.common.config import Config
from compiler.common.knowledge_base import KnowledgeBase, KnowledgeBaseEntry
from compiler.common.message_codes import message
from compiler.common.result import CompilerResult
from nodes.resolver_node import ResolverNode
from schemas.models import Scene
def kb() -> KnowledgeBase:
return KnowledgeBase(
[
KnowledgeBaseEntry(
id="female", tags=("1girl",), category="character", aliases=("girl",)
),
KnowledgeBaseEntry(id="long_hair", tags=("long hair",), category="hair"),
]
)
def scene() -> Scene:
return Scene.from_json(
{
"characters": [
{
"id": 0,
"identity": ["girl"],
"appearance": ["long hair"],
"clothing": [],
"accessories": [],
"pose": [],
"expression": [],
"actions": [],
}
],
"interactions": [],
"objects": [],
"environment": [],
"camera": [],
"lighting": [],
"metadata": {"schema_version": "1.0"},
}
)
def test_node_metadata() -> None:
assert ResolverNode.RETURN_TYPES == ("RESOLVED_TAGS", "STRING", "STRING", "STRING")
assert ResolverNode.RETURN_NAMES == ("resolved_tags", "warnings", "errors", "raw")
inputs = ResolverNode.INPUT_TYPES()
assert set(inputs["required"]) == {"scene", "knowledge_base"}
assert "config" in inputs["optional"]
def test_resolves_tags_with_real_resolver() -> None:
resolved, warnings, errors, *_ = ResolverNode().run(scene(), kb())
assert [t.tag for t in resolved] == ["1girl", "long hair"]
assert errors == ""
def test_delegates_and_surfaces_messages(monkeypatch) -> None:
def fake_resolve(scene_arg, knowledge_base, config):
return CompilerResult(data=()).add_warning(message("SC0001", "unknown 'x'"))
monkeypatch.setattr(node_module, "resolve_scene", fake_resolve)
resolved, warnings, errors, *_ = ResolverNode().run(scene(), kb())
assert resolved == ()
assert "SC0001: unknown 'x'" in warnings
def test_default_config_used_when_absent(monkeypatch) -> None:
captured = {}
def fake_resolve(scene_arg, knowledge_base, config):
captured["config"] = config
return CompilerResult(data=())
monkeypatch.setattr(node_module, "resolve_scene", fake_resolve)
ResolverNode().run(scene(), kb())
assert isinstance(captured["config"], Config)
def test_registered_for_comfyui() -> None:
assert nodes.NODE_CLASS_MAPPINGS["SceneCompilerResolver"] is ResolverNode
assert nodes.NODE_DISPLAY_NAME_MAPPINGS["SceneCompilerResolver"] == "Resolver"