Initial commit: MUD client v0.2
This commit is contained in:
commit
0030fd7d82
26 files changed
+4421
No files matched your search
@@ -0,0 +1,119 @@
|
||||
"""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"
|
||||
Reference in new issue
Block a user