193 lines
7 KiB
Python
193 lines
7 KiB
Python
"""Tests for POV template engine."""
|
|
|
|
from dataclasses import dataclass
|
|
|
|
import pytest
|
|
|
|
from mudlib.render.pov import render_pov
|
|
|
|
|
|
@dataclass
|
|
class MockEntity:
|
|
"""Simple entity for testing."""
|
|
|
|
name: str
|
|
|
|
|
|
@pytest.fixture
|
|
def jared():
|
|
"""Attacker entity."""
|
|
return MockEntity(name="Jared")
|
|
|
|
|
|
@pytest.fixture
|
|
def goku():
|
|
"""Defender entity."""
|
|
return MockEntity(name="Goku")
|
|
|
|
|
|
@pytest.fixture
|
|
def vegeta():
|
|
"""Bystander entity."""
|
|
return MockEntity(name="Vegeta")
|
|
|
|
|
|
def test_attacker_pov_basic(jared, goku):
|
|
"""Attacker sees 'You' for self, defender name for target."""
|
|
template = "{attacker} hit{s} {defender}"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You hit Goku"
|
|
|
|
|
|
def test_defender_pov_basic(jared, goku):
|
|
"""Defender sees attacker name, 'You' for self."""
|
|
template = "{attacker} hit{s} {defender}"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "Jared hits You"
|
|
|
|
|
|
def test_bystander_pov_basic(jared, goku, vegeta):
|
|
"""Bystander sees both entity names."""
|
|
template = "{attacker} hits {defender}"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared hits Goku"
|
|
|
|
|
|
def test_verb_s_conjugation_you(jared, goku):
|
|
"""Verb with {s} after You gets no suffix."""
|
|
template = "{attacker} punch{s} {defender}"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You punch Goku"
|
|
|
|
|
|
def test_verb_s_conjugation_third_person(jared, goku, vegeta):
|
|
"""Verb with {s} after name gets 's' suffix."""
|
|
template = "{attacker} punch{s} {defender}"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared punches Goku"
|
|
|
|
|
|
def test_verb_es_conjugation_you(jared, goku):
|
|
"""Verb with {es} after You gets no suffix."""
|
|
template = "{attacker} lurch{es} forward"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You lurch forward"
|
|
|
|
|
|
def test_verb_es_conjugation_third_person(jared, goku, vegeta):
|
|
"""Verb with {es} after name gets 'es' suffix."""
|
|
template = "{attacker} lurch{es} forward"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared lurches forward"
|
|
|
|
|
|
def test_irregular_verb_y_ies_you(jared, goku):
|
|
"""Irregular verb {y|ies} after You uses left form."""
|
|
template = "{attacker} parr{y|ies} the blow"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You parry the blow"
|
|
|
|
|
|
def test_irregular_verb_y_ies_third_person(jared, goku, vegeta):
|
|
"""Irregular verb {y|ies} after name uses right form."""
|
|
template = "{attacker} parr{y|ies} the blow"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared parries the blow"
|
|
|
|
|
|
def test_pronoun_his_you(jared, goku):
|
|
"""{his} after You becomes 'your'."""
|
|
template = "{attacker} raise{s} {his} fist"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You raise your fist"
|
|
|
|
|
|
def test_pronoun_his_third_person(jared, goku, vegeta):
|
|
"""{his} after name becomes 'his'."""
|
|
template = "{attacker} raise{s} {his} fist"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared raises his fist"
|
|
|
|
|
|
def test_pronoun_him_you(jared, goku):
|
|
"""{him} after You becomes 'you'."""
|
|
template = "{attacker} brace{s} {him}self"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You brace yourself"
|
|
|
|
|
|
def test_pronoun_him_third_person(jared, goku, vegeta):
|
|
"""{him} after name becomes 'him'."""
|
|
template = "{attacker} brace{s} {him}self"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared braces himself"
|
|
|
|
|
|
def test_mixed_template_attacker_pov(jared, goku):
|
|
"""Complex template with multiple substitutions, attacker POV."""
|
|
template = "{attacker} slam{s} {his} fist into {defender}"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You slam your fist into Goku"
|
|
|
|
|
|
def test_mixed_template_defender_pov(jared, goku):
|
|
"""Complex template with multiple substitutions, defender POV."""
|
|
template = "{attacker} slam{s} {his} fist into {defender}"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "Jared slams his fist into You"
|
|
|
|
|
|
def test_mixed_template_bystander_pov(jared, goku, vegeta):
|
|
"""Complex template with multiple substitutions, bystander POV."""
|
|
template = "{attacker} slam{s} {his} fist into {defender}"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Jared slams his fist into Goku"
|
|
|
|
|
|
def test_defender_contextual_tags(jared, goku):
|
|
"""Contextual tags apply to defender when they precede them."""
|
|
template = "{defender} brace{s} {him}self against {attacker}"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "You brace yourself against Jared"
|
|
|
|
|
|
def test_defender_contextual_third_person(jared, goku, vegeta):
|
|
"""Contextual tags apply to defender in third person."""
|
|
template = "{defender} brace{s} {him}self against {attacker}"
|
|
result = render_pov(template, viewer=vegeta, attacker=jared, defender=goku)
|
|
assert result == "Goku braces himself against Jared"
|
|
|
|
|
|
def test_plain_text_passthrough():
|
|
"""Template with no POV tags passes through unchanged."""
|
|
template = "The battle rages on!"
|
|
result = render_pov(template, viewer=None, attacker=None, defender=None)
|
|
assert result == "The battle rages on!"
|
|
|
|
|
|
def test_you_capitalization_mid_sentence(jared, goku):
|
|
"""'You' is capitalized even when not at start of sentence."""
|
|
template = "The blow strikes {defender} hard"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "The blow strikes You hard"
|
|
|
|
|
|
def test_multiple_entity_references(jared, goku):
|
|
"""Context switches between entities correctly."""
|
|
template = "{attacker} throw{s} a punch at {defender}, but {defender} dodge{s} it"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "Jared throws a punch at You, but You dodge it"
|
|
|
|
|
|
def test_multiple_entity_references_attacker_pov(jared, goku):
|
|
"""Context switches correctly from attacker POV."""
|
|
template = "{attacker} throw{s} a punch at {defender}, but {defender} dodg{es} it"
|
|
result = render_pov(template, viewer=jared, attacker=jared, defender=goku)
|
|
assert result == "You throw a punch at Goku, but Goku dodges it"
|
|
|
|
|
|
def test_you_capitalized_after_comma(jared, goku):
|
|
"""'You' stays capitalized after comma/conjunction."""
|
|
template = "{attacker} strikes, and {defender} fall{s}"
|
|
result = render_pov(template, viewer=goku, attacker=jared, defender=goku)
|
|
assert result == "Jared strikes, and You fall"
|