Files
viandante/tests/test_gmcp.py
T

120 lines
3.2 KiB
Python

"""Tests for the GMCP parser."""
from __future__ import annotations
import json
from progetto2.gmcp import (
GmcpEvent,
extract_room_info,
extract_vitals,
parse_gmcp,
)
def test_parse_module_only() -> None:
ev = parse_gmcp(b"Char.Login")
assert ev == GmcpEvent("Char.Login", None)
def test_parse_with_json_object() -> None:
raw = b'Char.Vitals {"hp":100,"max_hp":100,"sp":50,"mv":80}'
ev = parse_gmcp(raw)
assert ev is not None
assert ev.module == "Char.Vitals"
assert ev.data == {"hp": 100, "max_hp": 100, "sp": 50, "mv": 80}
def test_parse_with_json_array() -> None:
raw = b"Room.Info " + json.dumps(
[{"name": "Foo"}, {"name": "Bar"}]
).encode()
ev = parse_gmcp(raw)
assert ev is not None
assert ev.module == "Room.Info"
assert isinstance(ev.data, list)
assert len(ev.data) == 2
def test_parse_garbage_returns_none_or_partial() -> None:
# Empty payload
assert parse_gmcp(b"") is None
# Whitespace only
assert parse_gmcp(b" \n") is None
# Bad module
assert parse_gmcp(b" .bad") is None
def test_parse_invalid_json_keeps_module() -> None:
ev = parse_gmcp(b"Char.Vitals {not valid")
assert ev is not None
assert ev.module == "Char.Vitals"
assert ev.data is None # JSON parse failure tolerated
def test_extract_vitals_basic() -> None:
v = extract_vitals(
{"hp": 100, "max_hp": 100, "sp": 50, "max_sp": 50, "mv": 80, "max_mv": 80}
)
assert v == {
"hp": 100, "max_hp": 100,
"sp": 50, "max_sp": 50,
"mv": 80, "max_mv": 80,
}
def test_extract_vitals_synonyms() -> None:
v = extract_vitals({"health": 50, "max_health": 100, "mana": 30, "move": 80})
assert v["hp"] == 50
assert v["max_hp"] == 100
assert v["sp"] == 30
assert v["mv"] == 80
def test_extract_vitals_partial() -> None:
v = extract_vitals({"hp": 100})
assert v == {"hp": 100}
def test_extract_vitals_empty_or_non_dict() -> None:
assert extract_vitals({}) == {}
assert extract_vitals(None) == {}
assert extract_vitals([1, 2, 3]) == {}
def test_extract_room_info_with_vnum() -> None:
info = extract_room_info(
{"name": "Outer Courtyard", "num": 1234, "exits": {"north": "vnum99"}}
)
assert info is not None
rid, name, body, num_id = info
assert name == "Outer Courtyard"
assert rid == "vnum1234"
assert num_id == "vnum1234"
def test_extract_room_info_without_vnum() -> None:
info = extract_room_info(
{"title": "Dungeon Entry", "description": "Stairs lead down.", "exits": ["n", "s"]}
)
assert info is not None
rid, name, _, num_id = info
assert name == "Dungeon Entry"
assert rid == "dungeon entry"
assert num_id is None
def test_extract_room_info_no_name_returns_none() -> None:
assert extract_room_info({"num": 1}) is None
assert extract_room_info({"exits": ["n"]}) is None
assert extract_room_info(None) is None
def test_extract_room_info_exits_canonicalised() -> None:
info = extract_room_info(
{"name": "X", "exits": ["north", "east", "up"]}
)
assert info is not None
# We didn't pull exits here — that happens in cli. Check that direct parsing
# still identifies room name + body.
assert info[1] == "X"