Replace dynamicprompts.WildcardManager with a native implementation in src/wildcards.py that loads .txt, .yaml, and .json wildcard files from one or more directories using fnmatch pattern matching. EvaluationContext now types wildcard_manager as a WildcardProvider Protocol rather than the concrete class. Remove dynamicprompts from dependencies; add pyyaml>=6.0 and types-pyyaml as its replacement. Add explicit_package_bases = true to mypy config to resolve duplicate module path ambiguity from the root __init__.py. Update README and CLAUDE to reflect the native parser architecture and removal of the Jinja2 node. Remove completed plan documents. Ignore user-specific yaml wildcard files via .gitignore. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
import pytest
|
|
from pathlib import Path
|
|
import random
|
|
|
|
from src.evaluator.context import EvaluationContext
|
|
from src.evaluator.combinatorial_eval import evaluate_all
|
|
from src.parser.parser import parse
|
|
from src.wildcards import WildcardManager
|
|
|
|
|
|
@pytest.fixture
|
|
def ctx(wildcards_path: Path) -> EvaluationContext:
|
|
return EvaluationContext(
|
|
rng=random.Random(0),
|
|
wildcard_manager=WildcardManager(paths=[wildcards_path]),
|
|
)
|
|
|
|
|
|
def test_plain_text(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("hello"), ctx)
|
|
assert results == ["hello"]
|
|
|
|
|
|
def test_single_variant(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("{a|b|c}"), ctx)
|
|
assert sorted(results) == ["a", "b", "c"]
|
|
|
|
|
|
def test_cross_product(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("{a|b} {c|d}"), ctx)
|
|
assert sorted(results) == ["a c", "a d", "b c", "b d"]
|
|
|
|
|
|
def test_cross_product_count(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("{a|b} {c|d}"))
|
|
assert len(results) == 4
|
|
|
|
|
|
def test_nested_variant(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("{a|{b|c}}"), ctx)
|
|
assert sorted(results) == ["a", "b", "c"]
|
|
|
|
|
|
def test_wildcard_combinatorial(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse("__animals__"), ctx)
|
|
assert sorted(results) == ["bird", "cat", "dog"]
|
|
|
|
|
|
def test_variable_evaluated_once_per_branch(ctx: EvaluationContext) -> None:
|
|
# ${x=!{a|b}} creates branches; each branch fixes x for that branch
|
|
results = evaluate_all(parse("${x=!{a|b}} ${x} ${x}"), ctx)
|
|
# Each result should have the same word repeated
|
|
for r in results:
|
|
words = [w for w in r.split() if w]
|
|
assert words[0] == words[1]
|
|
|
|
|
|
def test_empty_template(ctx: EvaluationContext) -> None:
|
|
results = evaluate_all(parse(""), ctx)
|
|
assert results == [""]
|