protocol/types.py and arsdk/types.py are the interfaces the parallel streams build against: command/arg/enum/expectation specs and the safety tiers on one side, frame encoding and the buffer conventions on the other. Logging goes to stderr throughout, since stdout carries JSON-RPC. That is also why this package will speak ARSDK itself rather than through pyparrot, which prints from its receive thread.
41 lines
1.3 KiB
Python
41 lines
1.3 KiB
Python
"""Guards that the package stays coherent as the streams land."""
|
|
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
import mcbebop
|
|
from mcbebop.server import build_server
|
|
|
|
|
|
def _pyproject() -> dict:
|
|
return tomllib.loads((Path(__file__).parent.parent / "pyproject.toml").read_text())
|
|
|
|
|
|
def test_version_matches_pyproject():
|
|
# importlib normalises 2026.10.02 to 2026.10.2; compare as release tuples.
|
|
declared = _pyproject()["project"]["version"]
|
|
assert tuple(int(p) for p in declared.split(".")) == tuple(int(p) for p in mcbebop.__version__.split("."))
|
|
|
|
|
|
def test_entry_point_is_importable():
|
|
module, _, attr = _pyproject()["project"]["scripts"]["mcbebop"].partition(":")
|
|
mod = __import__(module, fromlist=[attr])
|
|
assert callable(getattr(mod, attr))
|
|
|
|
|
|
def test_server_builds():
|
|
assert build_server() is not None
|
|
|
|
|
|
def test_vendored_xml_present_and_parses():
|
|
import xml.etree.ElementTree as ET
|
|
|
|
root = Path(__file__).parent.parent / "arsdk-xml"
|
|
total = 0
|
|
for name in ("common.xml", "ardrone3.xml"):
|
|
proj = ET.parse(root / name).getroot()
|
|
# Parrot's element is <class>; pyparrot renamed it and we reverted that.
|
|
assert proj.find("class") is not None, f"{name} has no <class> elements"
|
|
total += sum(len(c.findall("cmd")) for c in proj.iter("class"))
|
|
assert total == 264, f"expected 264 commands, found {total}"
|