Files
templates/python/tests/test_trends.py

88 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import ctypes
import json
import os
import unittest
from dataclasses import replace
from pathlib import Path
from protocan.trends import (
MAX_FILE_BYTES, MAX_POINTS, NativeTrends, TrendHistory, TrendSignal,
decode_settings, encode_settings, parse_address,
)
FIXTURE = Path(__file__).resolve().parents[2] / "c/set-protocol/tests/fixtures/trends-v1.json"
class TrendTests(unittest.TestCase):
def test_shared_kotlin_fixture_and_round_trip(self):
settings = decode_settings(FIXTURE.read_text(encoding="utf-8"))
self.assertEqual(5, sum(map(len, settings.values())))
self.assertEqual("Ток фазы А", settings["TMS2812"][0].name)
self.assertEqual(settings, decode_settings(encode_settings(settings)))
self.assertEqual(settings, decode_settings("\ufeff" + encode_settings(settings)))
def test_profile_specific_defaults(self):
self.assertEqual("SET_GAS", TrendSignal.new("SET_V1").source)
self.assertEqual("CAN_RAW", TrendSignal.new("BALZAM_CAN").source)
self.assertEqual("CAN_GAS", TrendSignal.new("SLCAN").source)
def test_invalid_import_and_types(self):
fixture = FIXTURE.read_text(encoding="utf-8")
for field, value in (("order", "1"), ("order", 1.5), ("order", True),
("visible", "true"), ("color", "red"),
("source", "CAN_GAS"), ("address", "0x100000000")):
with self.subTest(field=field, value=value), self.assertRaises(ValueError):
data = json.loads(fixture)
data["profiles"]["TMS2812"][0][field] = value
decode_settings(json.dumps(data))
for version in (2, "1", 1.5, True):
with self.assertRaises(ValueError):
data = json.loads(fixture)
data["version"] = version
decode_settings(json.dumps(data))
with self.assertRaises(ValueError):
decode_settings(" " * (MAX_FILE_BYTES + 1))
def test_duplicates_and_limits(self):
signal = TrendSignal("one")
for signals in ([signal, replace(signal, id="two")],
[signal, replace(signal, order=2)],
[replace(signal, id=str(i), order=i + 1) for i in range(65)]):
with self.assertRaises(ValueError):
encode_settings({"TMS2812": signals})
def test_addresses_and_signedness(self):
self.assertEqual(255, parse_address("0xFF", 255))
self.assertEqual(100, parse_address("100", 100))
for value in ("-1", "+1", "FF", "0x", "1.0", "256"):
with self.assertRaises(ValueError):
parse_address(value, 255)
self.assertEqual(-2.0, TrendSignal("s", valueType="INT16").word_value(65534))
def test_bounded_history(self):
history = TrendHistory()
for i in range(MAX_POINTS + 10):
history.append({"a": float(i), "bad": float("nan")}, i)
self.assertEqual(MAX_POINTS, len(history.series["a"]))
self.assertEqual((10, 10.0), history.series["a"][0])
self.assertNotIn("bad", history.series)
@unittest.skipUnless(os.environ.get("SETPROTOCOL_LIBRARY"), "Host DLL not supplied")
def test_actual_shared_c_core(self):
core = NativeTrends(ctypes.CDLL(os.environ["SETPROTOCOL_LIBRARY"]))
signal = TrendSignal("gas", source="CAN_GAS", address="0x1235", valueType="INT16")
frame_id = 0x1FD31234
data = bytes([1, 0, 254, 255])
self.assertEqual(-2.0, core.can_value(signal, frame_id, 1, data))
self.assertEqual(65534.0, core.can_value(replace(signal, valueType="UINT16"), frame_id, 1, data))
self.assertIsNone(core.can_value(replace(signal, device=12), frame_id, 1, data))
for flag in (2, 4, 8):
self.assertIsNone(core.can_value(signal, frame_id, 1 | flag, data))
self.assertIsNone(core.can_value(signal, frame_id ^ 0x08000000, 1, data))
raw = replace(signal, source="CAN_RAW", address="0x321", extended=False, byteOffset=2)
self.assertEqual(-2.0, core.can_value(raw, 0x321, 0, data))
if __name__ == "__main__":
unittest.main()