1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
import pytest
from miio import Huizuo, MiotDevice
from miio.miot_device import MiotValueType
MIOT_DEVICES = MiotDevice.__subclasses__()
# TODO: huizuo needs to be refactored to use _mappings,
# until then, just disable the tests on it.
MIOT_DEVICES.remove(Huizuo) # type: ignore
@pytest.fixture(scope="module")
def dev(module_mocker):
DUMMY_MAPPING = {}
device = MiotDevice(
"127.0.0.1", "68ffffffffffffffffffffffffffffff", mapping=DUMMY_MAPPING
)
module_mocker.patch.object(device, "send")
return device
def test_missing_mapping(caplog):
"""Make sure ctor raises exception if neither class nor parameter defines the
mapping."""
_ = MiotDevice("127.0.0.1", "68ffffffffffffffffffffffffffffff")
assert "Neither the class nor the parameter defines the mapping" in caplog.text
def test_ctor_mapping():
"""Make sure the constructor accepts the mapping parameter."""
test_mapping = {}
dev2 = MiotDevice(
"127.0.0.1", "68ffffffffffffffffffffffffffffff", mapping=test_mapping
)
assert dev2.mapping == test_mapping
def test_get_property_by(dev):
siid = 1
piid = 2
_ = dev.get_property_by(siid, piid)
dev.send.assert_called_with(
"get_properties", [{"did": f"{siid}-{piid}", "siid": siid, "piid": piid}]
)
@pytest.mark.parametrize(
"value_type,value",
[
(None, 1),
(MiotValueType.Int, "1"),
(MiotValueType.Float, "1.2"),
(MiotValueType.Str, "str"),
(MiotValueType.Bool, "1"),
],
)
def test_set_property_by(dev, value_type, value):
siid = 1
piid = 1
_ = dev.set_property_by(siid, piid, value, value_type)
if value_type is not None:
value = value_type.value(value)
dev.send.assert_called_with(
"set_properties",
[{"did": f"set-{siid}-{piid}", "siid": siid, "piid": piid, "value": value}],
)
def test_call_action_by(dev):
siid = 1
aiid = 1
_ = dev.call_action_by(siid, aiid)
dev.send.assert_called_with(
"action",
{
"did": f"call-{siid}-{aiid}",
"siid": siid,
"aiid": aiid,
"in": [],
},
)
params = {"test_param": 1}
_ = dev.call_action_by(siid, aiid, params)
dev.send.assert_called_with(
"action",
{
"did": f"call-{siid}-{aiid}",
"siid": siid,
"aiid": aiid,
"in": params,
},
)
@pytest.mark.parametrize(
"model,expected_mapping,expected_log",
[
("some_model", {"x": {"y": 1}}, ""),
("unknown_model", {"x": {"y": 1}}, "Unable to find mapping"),
],
)
def test_get_mapping(dev, caplog, model, expected_mapping, expected_log):
"""Test _get_mapping logic for fallbacks."""
dev._mappings["some_model"] = {"x": {"y": 1}}
dev._model = model
assert dev._get_mapping() == expected_mapping
assert expected_log in caplog.text
def test_get_mapping_backwards_compat(dev):
"""Test that the backwards compat works."""
# as dev is mocked on module level, need to empty manually
dev._mappings = {}
assert dev._get_mapping() == {}
@pytest.mark.parametrize("cls", MIOT_DEVICES)
def test_mapping_deprecation(cls):
"""Check that deprecated mapping is not used."""
# TODO: this can be removed in the future.
assert not hasattr(cls, "mapping")
@pytest.mark.parametrize("cls", MIOT_DEVICES)
def test_mapping_structure(cls):
"""Check that mappings are structured correctly."""
assert cls._mappings
model, contents = next(iter(cls._mappings.items()))
# model must contain a dot
assert "." in model
method, piid_siid = next(iter(contents.items()))
assert isinstance(method, str)
# mapping should be a dict with piid, siid
assert "piid" in piid_siid
assert "siid" in piid_siid
@pytest.mark.parametrize("cls", MIOT_DEVICES)
def test_supported_models(cls):
assert cls.supported_models == cls._mappings.keys()
# make sure that that _supported_models is not defined
assert not cls._supported_models
|