Files
DumiFlex-ComfyUI-Wildcard-P…/tests/engine/modules/test_constraint_reach.py
T

142 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""SP3 reach selector — `apply_constraints_for_target` applies EVERY
constraint whose `target_select` covers a firing target instance
(no more one-shot / consumed-set). A per-constraint hit counter
(`__wp_constraint_hits__`) drives first/next/all/pick coverage.
"""
from __future__ import annotations
from engine.modules._constraints import apply_constraints_for_target
def _src():
return {"picks": [{"value": "rain", "tags": ["rainy"]}]}
def _c(cid, mode, count=None, factor=2.0):
ts = {"mode": mode} if count is None else {"mode": mode, "count": count}
return {
"target_wildcard_id": "T",
"source_wildcard_id": "S",
"__constraint_module_id__": cid,
"target_select": ts,
"matrix": {"rainy": {"somber": {"mode": "boost", "factor": factor}}},
"exceptions": [],
}
def _o():
return [{"value": "blue", "sub_categories": ["somber"], "weight": 1.0}]
def test_all_applies_every_instance():
hits = {}
picks = {"S": _src()}
c = [_c("c1", "all")]
for _ in range(3):
out, applied = apply_constraints_for_target(
_o(), "T", c, picks, [], hits=hits, firing_uid="u"
)
assert applied and out[0]["weight"] == 2.0
def test_first_applies_only_first():
hits = {}
picks = {"S": _src()}
c = [_c("c1", "first")]
w = [
apply_constraints_for_target(
_o(), "T", c, picks, [], hits=hits, firing_uid="u"
)[0][0]["weight"]
for _ in range(3)
]
assert w == [2.0, 1.0, 1.0]
def test_next_n_applies_first_n():
hits = {}
picks = {"S": _src()}
c = [_c("c1", "next", count=2)]
w = [
apply_constraints_for_target(
_o(), "T", c, picks, [], hits=hits, firing_uid="u"
)[0][0]["weight"]
for _ in range(3)
]
assert w == [2.0, 2.0, 1.0]
def test_two_constraints_stack_on_one_instance():
hits = {}
picks = {"S": _src()}
c = [_c("c1", "all", factor=2.0), _c("c2", "all", factor=3.0)]
out, applied = apply_constraints_for_target(
_o(), "T", c, picks, [], hits=hits, firing_uid="u"
)
assert applied and out[0]["weight"] == 6.0
def test_pick_direct_matches_bare_uid_not_rowkey():
"""Round-trip identity guard (holistic-review C1).
The reach modal persists a direct `pick` as the BARE per-instance
`_uid` — NOT the badge-layer rowKey (`${nodeId}#${_uid}`). The engine
fires with `firing_uid = ctx["__wp_current_module_uid__"]`, which is
the bare `_uid` (see pipeline.py: `_module_uid` carries no node
prefix). So a pick authored in the UI must match by the bare uid and
MUST NOT match the rowKey-prefixed form. This locks the contract in
both directions: bare-uid pick covers, rowKey-prefixed pick misses.
"""
picks = {"S": _src()}
c = [{
"target_wildcard_id": "T",
"source_wildcard_id": "S",
"__constraint_module_id__": "c1",
"target_select": {
"mode": "pick",
"picks": [{"kind": "direct", "uid": "mood-a"}], # BARE _uid
},
"matrix": {"rainy": {"somber": {"mode": "boost", "factor": 2.0}}},
"exceptions": [],
}]
# Bare uid fired → pick covers → boost ×2 (the shape the UI now emits).
out, applied = apply_constraints_for_target(
_o(), "T", c, picks, [], hits={}, firing_uid="mood-a",
)
assert applied and out[0]["weight"] == 2.0
# rowKey-prefixed firing uid → pick MISSES (the old buggy format the
# UI used to persist; would never fire at runtime).
out2, applied2 = apply_constraints_for_target(
_o(), "T", c, picks, [], hits={}, firing_uid="1#mood-a",
)
assert not applied2 and out2[0]["weight"] == 1.0
def test_pick_nested_occurrence_matches_carrier_option():
from engine.modules._constraints import apply_constraints_for_target
picks = {"S": {"picks": [{"value": "rain", "tags": ["rainy"]}]}}
c = [{
"target_wildcard_id": "T",
"source_wildcard_id": "S",
"__constraint_module_id__": "c1",
"target_select": {
"mode": "pick",
"picks": [{"kind": "nested", "carrier_uid": "carrUID", "option_id": "optA"}],
},
"matrix": {"rainy": {"somber": {"mode": "boost", "factor": 2.0}}},
"exceptions": [],
}]
opts = [{"value": "blue", "sub_categories": ["somber"], "weight": 1.0}]
# Wrong carrier_uid → nested pick misses → weight untouched.
out, _ = apply_constraints_for_target(
opts, "T", c, picks, [], hits={},
carrier_ctx={"carrier_uid": "other", "option_id": "optA"},
)
assert out[0]["weight"] == 1.0
# Matching (carrier_uid, option_id) → nested pick covers → boost ×2.
opts2 = [{"value": "blue", "sub_categories": ["somber"], "weight": 1.0}]
out, _ = apply_constraints_for_target(
opts2, "T", c, picks, [], hits={},
carrier_ctx={"carrier_uid": "carrUID", "option_id": "optA"},
)
assert out[0]["weight"] == 2.0