RSI-PI/tests/test_xml_handler.py
Adam 7bfe5cccf1 Refactor core architecture and add test coverage
- Fix socket lifecycle: create in child process, add cleanup with try/finally
- Add ClientState enum with validated state transitions to prevent invalid operations
- Decouple CSV logging from network loop using queue-based CSVLogger process
- Fix broken imports: change absolute (src.RSIPI.x) to relative (.x) across 7 files
- Add missing @staticmethod decorator to generate_report()
- Add command queue for inter-process communication (logging control)
- Add 34 unit tests for XMLGenerator, SafetyManager, and trajectory_planner
- Add pytest configuration to pyproject.toml
- Add CLAUDE.md with architecture documentation
2026-01-16 20:09:56 +00:00

113 lines
3.5 KiB
Python

"""Tests for XMLGenerator."""
import pytest
import xml.etree.ElementTree as ET
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from RSIPI.xml_handler import XMLGenerator
class TestGenerateSendXML:
"""Tests for XMLGenerator.generate_send_xml()"""
def test_simple_values(self):
"""Test XML generation with simple scalar values."""
send_vars = {
"IPOC": 12345,
"DiL": 1
}
network_settings = {"sentype": "ImFree"}
xml_str = XMLGenerator.generate_send_xml(send_vars, network_settings)
# Parse and verify
root = ET.fromstring(xml_str)
assert root.tag == "Sen"
assert root.get("Type") == "ImFree"
assert root.find("IPOC").text == "12345"
assert root.find("DiL").text == "1"
def test_nested_dict_values(self):
"""Test XML generation with nested dictionary values (attributes)."""
send_vars = {
"RKorr": {"X": 100.5, "Y": -50.25, "Z": 0.0}
}
network_settings = {"sentype": "TestType"}
xml_str = XMLGenerator.generate_send_xml(send_vars, network_settings)
root = ET.fromstring(xml_str)
rkorr = root.find("RKorr")
assert rkorr is not None
assert float(rkorr.get("X")) == 100.50
assert float(rkorr.get("Y")) == -50.25
assert float(rkorr.get("Z")) == 0.0
def test_free_field_skipped(self):
"""Test that FREE field is skipped in XML output."""
send_vars = {
"IPOC": 1,
"FREE": 999
}
network_settings = {"sentype": "ImFree"}
xml_str = XMLGenerator.generate_send_xml(send_vars, network_settings)
root = ET.fromstring(xml_str)
assert root.find("FREE") is None
assert root.find("IPOC") is not None
def test_mixed_values(self):
"""Test XML generation with mixed scalar and nested values."""
send_vars = {
"IPOC": 5000,
"RKorr": {"X": 10.0, "Y": 20.0},
"Digout": {"o1": 1, "o2": 0}
}
network_settings = {"sentype": "Mixed"}
xml_str = XMLGenerator.generate_send_xml(send_vars, network_settings)
root = ET.fromstring(xml_str)
assert root.find("IPOC").text == "5000"
assert float(root.find("RKorr").get("X")) == 10.0
assert float(root.find("Digout").get("o1")) == 1.0
class TestGenerateReceiveXML:
"""Tests for XMLGenerator.generate_receive_xml()"""
def test_simple_receive(self):
"""Test receive XML generation with scalar values."""
receive_vars = {
"IPOC": 12345,
"BMode": "Active"
}
xml_str = XMLGenerator.generate_receive_xml(receive_vars)
root = ET.fromstring(xml_str)
assert root.tag == "Rob"
assert root.get("Type") == "KUKA"
assert root.find("IPOC").text == "12345"
assert root.find("BMode").text == "Active"
def test_nested_receive(self):
"""Test receive XML generation with position data."""
receive_vars = {
"RIst": {"X": 500.0, "Y": 100.0, "Z": 800.0},
"ASPos": {"A1": 0.0, "A2": -45.0, "A3": 90.0}
}
xml_str = XMLGenerator.generate_receive_xml(receive_vars)
root = ET.fromstring(xml_str)
rist = root.find("RIst")
assert float(rist.get("X")) == 500.0
assert float(rist.get("Z")) == 800.0
aspos = root.find("ASPos")
assert float(aspos.get("A2")) == -45.0