79 lines
3.5 KiB
Python
79 lines
3.5 KiB
Python
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
_PKG = Path(__file__).resolve().parents[1]
|
|
_REPO = _PKG.parents[1]
|
|
sys.path.insert(0, str(_PKG)) # flat-import van het node-pakket
|
|
|
|
import compose_logic as node_compose # noqa: E402
|
|
import prompt_node # noqa: E402
|
|
|
|
# app-compose bestaat alleen binnen de Character Studio-monorepo; in een standalone repo overslaan.
|
|
try:
|
|
sys.path.insert(0, str(_REPO / "orchestrator"))
|
|
import compose as app_compose # noqa: E402 (orchestrator/compose.py)
|
|
except Exception: # noqa: BLE001
|
|
app_compose = None
|
|
|
|
MINI_CB = {
|
|
"template": "A {origin} {gender}. Wardrobe: {wardrobe}. {mood}.",
|
|
"fields": [
|
|
{"key": "origin", "type": "enum", "options": ["Dutch", "Japanese"], "default": "Dutch"},
|
|
{"key": "gender", "type": "enum", "options": ["woman", "man"], "default": "woman"},
|
|
{"key": "mood", "type": "text", "default": "calm"},
|
|
{"key": "wardrobe", "type": "wardrobe"},
|
|
],
|
|
}
|
|
|
|
|
|
def test_ported_compose_form_fills_and_defaults():
|
|
p = node_compose.compose_form(MINI_CB, {"fields": {"gender": "man"}, "wardrobe": {"mode": "free", "text": "a suit"}})
|
|
assert p == "A Dutch man. Wardrobe: a suit. calm."
|
|
|
|
|
|
def test_ported_compose_form_empty_wardrobe_cleans_up():
|
|
p = node_compose.compose_form(MINI_CB, {"fields": {}, "wardrobe": None})
|
|
# leeg wardrobe → _cleanup verwijdert de spatie vóór de punt ("Wardrobe: ." → "Wardrobe:.")
|
|
assert p == "A Dutch woman. Wardrobe:. calm."
|
|
|
|
|
|
def test_input_types_from_builds_widgets():
|
|
it = prompt_node._input_types_from(MINI_CB)
|
|
req = it["required"]
|
|
assert req["origin"] == (["Dutch", "Japanese"], {"default": "Dutch"})
|
|
assert req["mood"][0] == "STRING" and req["mood"][1]["default"] == "calm"
|
|
assert req["wardrobe"][0] == "STRING" # wardrobe = vrije tekst
|
|
assert it["optional"]["extra"][0] == "STRING" and it["optional"]["extra"][1]["multiline"] is True
|
|
|
|
|
|
def test_input_types_no_manifest_shows_error():
|
|
it = prompt_node._input_types_from(None)
|
|
assert "error" in it["required"]
|
|
|
|
|
|
def test_wardrobe_default_fallback_and_override():
|
|
cb = {"template": "Wardrobe: {wardrobe}.",
|
|
"fields": [{"key": "wardrobe", "type": "wardrobe", "default": "casual everyday clothing"}]}
|
|
# leeg → terugval op de default; eigen invoer overruled
|
|
assert node_compose.compose_form(cb, {"fields": {}, "wardrobe": None}) == "Wardrobe: casual everyday clothing."
|
|
assert node_compose.compose_form(cb, {"fields": {}, "wardrobe": {"mode": "free", "text": "a red gown"}}) == "Wardrobe: a red gown."
|
|
|
|
|
|
def test_compose_preserves_paragraph_breaks():
|
|
cb = {"template": "{a}\n\n{b}\n\n{c}",
|
|
"fields": [{"key": "a", "type": "text", "default": "first block"},
|
|
{"key": "b", "type": "text", "default": ""},
|
|
{"key": "c", "type": "text", "default": "third block"}]}
|
|
# witregels blijven tussen blokken; een leeg blok wordt weggelaten
|
|
assert node_compose.compose_form(cb, {"fields": {}, "wardrobe": None}) == "first block\n\nthird block"
|
|
|
|
|
|
@pytest.mark.skipif(app_compose is None, reason="orchestrator/compose.py niet beschikbaar (standalone repo)")
|
|
def test_parity_with_app_compose():
|
|
# De geporte kopie moet exact hetzelfde produceren als orchestrator/compose.py.
|
|
val = {"fields": {"origin": "Japanese", "gender": "man", "mood": "serious"},
|
|
"wardrobe": {"mode": "free", "text": "a wool coat"}}
|
|
assert node_compose.compose_form(MINI_CB, val) == app_compose.compose_form(MINI_CB, val)
|