mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-15 04:52:31 +08:00
Preserve legacy string-node search during Text rename
The string-node rename updated display names for discoverability, but `StringLength` lost the exact legacy `Length` alias. This restores that alias and adds focused tests for the renamed schema metadata so future renames keep old search paths intact. Constraint: Keep scope limited to the recent string-node rename surface Rejected: Broad schema metadata audit across unrelated nodes | exceeds the changed-area scope for this automation Confidence: high Scope-risk: narrow Reversibility: clean Directive: When renaming nodes for search/discoverability, preserve the previous display name as an alias and lock it with a schema test Tested: uvx pytest tests-unit/comfy_extras_test/nodes_string_test.py Not-tested: Ruff lint, because uvx temporary download stalled in this environment
This commit is contained in:
parent
55e6478526
commit
e9bfff44ce
@ -55,7 +55,7 @@ class StringLength(io.ComfyNode):
|
||||
def define_schema(cls):
|
||||
return io.Schema(
|
||||
node_id="StringLength",
|
||||
search_aliases=["character count", "text size", "string length"],
|
||||
search_aliases=["Length", "character count", "text size", "string length"],
|
||||
display_name="Text Length",
|
||||
category="utils/string",
|
||||
inputs=[
|
||||
|
||||
109
tests-unit/comfy_extras_test/nodes_string_test.py
Normal file
109
tests-unit/comfy_extras_test/nodes_string_test.py
Normal file
@ -0,0 +1,109 @@
|
||||
from dataclasses import dataclass, field
|
||||
from types import ModuleType, SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
|
||||
@dataclass
|
||||
class _Schema:
|
||||
node_id: str
|
||||
display_name: str | None = None
|
||||
category: str = "sd"
|
||||
inputs: list = field(default_factory=list)
|
||||
outputs: list = field(default_factory=list)
|
||||
hidden: list = field(default_factory=list)
|
||||
description: str = ""
|
||||
search_aliases: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
class _FieldFactory:
|
||||
@staticmethod
|
||||
def Input(*args, **kwargs):
|
||||
return {"args": args, "kwargs": kwargs}
|
||||
|
||||
@staticmethod
|
||||
def Output(*args, **kwargs):
|
||||
return {"args": args, "kwargs": kwargs}
|
||||
|
||||
|
||||
def _import_nodes_string():
|
||||
fake_io = SimpleNamespace(
|
||||
Schema=_Schema,
|
||||
String=_FieldFactory,
|
||||
Int=_FieldFactory,
|
||||
Boolean=_FieldFactory,
|
||||
Combo=_FieldFactory,
|
||||
NodeOutput=lambda value: (value,),
|
||||
ComfyNode=object,
|
||||
)
|
||||
fake_latest = ModuleType("comfy_api.latest")
|
||||
fake_latest.ComfyExtension = object
|
||||
fake_latest.io = fake_io
|
||||
|
||||
fake_comfy_api = ModuleType("comfy_api")
|
||||
fake_comfy_api.latest = fake_latest
|
||||
fake_typing_extensions = ModuleType("typing_extensions")
|
||||
fake_typing_extensions.override = lambda func: func
|
||||
|
||||
with patch.dict(
|
||||
sys.modules,
|
||||
{
|
||||
"comfy_api": fake_comfy_api,
|
||||
"comfy_api.latest": fake_latest,
|
||||
"typing_extensions": fake_typing_extensions,
|
||||
},
|
||||
):
|
||||
sys.modules.pop("comfy_extras.nodes_string", None)
|
||||
return importlib.import_module("comfy_extras.nodes_string")
|
||||
|
||||
|
||||
nodes_string = _import_nodes_string()
|
||||
|
||||
|
||||
class TestStringNodeSchemaRenames:
|
||||
def test_text_prefix_display_names_are_exposed(self):
|
||||
cases = [
|
||||
(nodes_string.StringConcatenate, "Text Concatenate"),
|
||||
(nodes_string.StringSubstring, "Text Substring"),
|
||||
(nodes_string.StringLength, "Text Length"),
|
||||
(nodes_string.CaseConverter, "Text Case Converter"),
|
||||
(nodes_string.StringTrim, "Text Trim"),
|
||||
(nodes_string.StringReplace, "Text Replace"),
|
||||
(nodes_string.StringContains, "Text Contains"),
|
||||
(nodes_string.StringCompare, "Text Compare"),
|
||||
(nodes_string.RegexMatch, "Text Match"),
|
||||
(nodes_string.RegexExtract, "Text Extract Substring"),
|
||||
(nodes_string.RegexReplace, "Text Replace (Regex)"),
|
||||
]
|
||||
|
||||
for node_cls, expected_name in cases:
|
||||
assert node_cls.define_schema().display_name == expected_name
|
||||
|
||||
def test_old_display_names_remain_searchable(self):
|
||||
cases = [
|
||||
(nodes_string.StringConcatenate, "Concatenate"),
|
||||
(nodes_string.StringSubstring, "Substring"),
|
||||
(nodes_string.StringLength, "Length"),
|
||||
(nodes_string.CaseConverter, "Case Converter"),
|
||||
(nodes_string.StringTrim, "Trim"),
|
||||
(nodes_string.StringReplace, "Replace"),
|
||||
(nodes_string.StringContains, "Contains"),
|
||||
(nodes_string.StringCompare, "Compare"),
|
||||
(nodes_string.RegexMatch, "Regex Match"),
|
||||
(nodes_string.RegexExtract, "Regex Extract"),
|
||||
(nodes_string.RegexReplace, "Regex Replace"),
|
||||
]
|
||||
|
||||
for node_cls, expected_alias in cases:
|
||||
assert expected_alias in node_cls.define_schema().search_aliases
|
||||
|
||||
def test_regex_nodes_keep_regex_search_keyword(self):
|
||||
regex_nodes = [
|
||||
nodes_string.RegexMatch,
|
||||
nodes_string.RegexExtract,
|
||||
nodes_string.RegexReplace,
|
||||
]
|
||||
|
||||
for node_cls in regex_nodes:
|
||||
assert "regex" in node_cls.define_schema().search_aliases
|
||||
Loading…
Reference in New Issue
Block a user