import pytest from bmspy.classes import ( BMSScalarField, BMSMultiField, BMSInfoField, UPS, _field_from_dict, _UPSSnapshot, ) # --------------------------------------------------------------------------- # BMSScalarField # --------------------------------------------------------------------------- class TestBMSScalarField: def test_get_existing_attribute(self): f = BMSScalarField(help="Voltage", raw_value=52.0, value="52.00", units="V") assert f.get("help") == "Voltage" assert f.get("raw_value") == 52.0 assert f.get("units") == "V" def test_get_missing_attribute_returns_default(self): f = BMSScalarField(help="Voltage", raw_value=52.0, value="52.00") assert f.get("nonexistent") is None assert f.get("nonexistent", 42) == 42 def test_units_defaults_to_none(self): f = BMSScalarField(help="Cycles", raw_value=10, value="10") assert f.units is None assert f.get("units") is None def test_bool_raw_value(self): f = BMSScalarField(help="Flag", raw_value=True, value="1") assert f.raw_value is True # --------------------------------------------------------------------------- # BMSMultiField # --------------------------------------------------------------------------- class TestBMSMultiField: def test_get_existing_attribute(self): f = BMSMultiField( help="Cell Voltages", label="cell", raw_values={1: 3.6, 2: 3.61}, values={1: "3.600", 2: "3.610"}, units="V", ) assert f.get("label") == "cell" assert f.get("raw_values") == {1: 3.6, 2: 3.61} assert f.get("units") == "V" def test_get_missing_returns_default(self): f = BMSMultiField(help="h", label="l", raw_values={}, values={}) assert f.get("missing") is None assert f.get("missing", "fallback") == "fallback" # --------------------------------------------------------------------------- # BMSInfoField # --------------------------------------------------------------------------- class TestBMSInfoField: def test_get_existing_attribute(self): f = BMSInfoField(help="Date of Manufacture", info="2023-01-15") assert f.get("help") == "Date of Manufacture" assert f.get("info") == "2023-01-15" def test_get_missing_returns_none(self): f = BMSInfoField(help="h", info="i") assert f.get("units") is None # --------------------------------------------------------------------------- # _field_from_dict # --------------------------------------------------------------------------- class TestFieldFromDict: def test_scalar_field(self): d = {"help": "Voltage", "raw_value": 52.0, "value": "52.00", "units": "V"} f = _field_from_dict(d) assert isinstance(f, BMSScalarField) assert f.raw_value == 52.0 assert f.units == "V" def test_multi_field(self): d = { "help": "Cell Voltages", "label": "cell", "raw_values": {1: 3.6}, "values": {1: "3.600"}, "units": "V", } f = _field_from_dict(d) assert isinstance(f, BMSMultiField) assert f.label == "cell" assert f.raw_values == {1: 3.6} def test_info_field(self): d = {"help": "Date of Manufacture", "info": "2023-01-15"} f = _field_from_dict(d) assert isinstance(f, BMSInfoField) assert f.info == "2023-01-15" # --------------------------------------------------------------------------- # UPS / _UPSSnapshot # --------------------------------------------------------------------------- class TestUPS: def _snapshot(self): return UPS.from_dict({ "bms_voltage": {"help": "Voltage", "raw_value": 52.0, "value": "52.00", "units": "V"}, "bms_date": {"help": "Date", "info": "2023-01-15"}, "bms_temps": { "help": "Temperature", "label": "sensor", "raw_values": {1: 25.0}, "values": {1: "25.00"}, "units": "°C", }, }) def test_from_dict_returns_ups_instance(self): assert isinstance(self._snapshot(), UPS) def test_from_dict_scalar_field(self): ups = self._snapshot() items = dict(ups.items()) assert isinstance(items["bms_voltage"], BMSScalarField) assert items["bms_voltage"].raw_value == 52.0 def test_from_dict_info_field(self): ups = self._snapshot() items = dict(ups.items()) assert isinstance(items["bms_date"], BMSInfoField) assert items["bms_date"].info == "2023-01-15" def test_from_dict_multi_field(self): ups = self._snapshot() items = dict(ups.items()) assert isinstance(items["bms_temps"], BMSMultiField) assert items["bms_temps"].raw_values == {1: 25.0} def test_bool_true_when_populated(self): assert bool(self._snapshot()) is True def test_bool_false_when_empty(self): empty = UPS.from_dict({}) assert bool(empty) is False def test_items_yields_all_fields(self): ups = self._snapshot() keys = [k for k, _ in ups.items()] assert set(keys) == {"bms_voltage", "bms_date", "bms_temps"} def test_items_empty_snapshot(self): ups = UPS.from_dict({}) assert list(ups.items()) == []