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
|
import base64
import json
import os
from unittest import TestCase
import pytest
from miio import ChuangmiIr
from miio.chuangmi_ir import ChuangmiIrException
from .dummies import DummyDevice
with open(os.path.join(os.path.dirname(__file__), "test_chuangmi_ir.json")) as inp:
test_data = json.load(inp)
class DummyChuangmiIr(DummyDevice, ChuangmiIr):
def __init__(self, *args, **kwargs):
self.state = {"last_ir_played": None}
self.return_values = {
"miIO.ir_learn": lambda x: True,
"miIO.ir_read": lambda x: True,
"miIO.ir_play": self._ir_play_input_validation,
}
super().__init__(args, kwargs)
def _ir_play_input_validation(self, payload):
try:
base64.b64decode(payload["code"])
self._set_state("last_ir_played", [[payload["code"], payload.get("freq")]])
return True
except TypeError:
return False
@pytest.fixture(scope="class")
def chuangmiir(request):
request.cls.device = DummyChuangmiIr()
# TODO add ability to test on a real device
@pytest.mark.usefixtures("chuangmiir")
class TestChuangmiIr(TestCase):
def test_learn(self):
assert self.device.learn() is True
assert self.device.learn(30) is True
with pytest.raises(ChuangmiIrException):
self.device.learn(-1)
with pytest.raises(ChuangmiIrException):
self.device.learn(1000001)
def test_read(self):
assert self.device.read() is True
assert self.device.read(30) is True
with pytest.raises(ChuangmiIrException):
self.device.read(-1)
with pytest.raises(ChuangmiIrException):
self.device.read(1000001)
def test_play_raw(self):
for args in test_data["test_raw_ok"]:
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play_raw(*args["in"]))
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
def test_pronto_to_raw(self):
for args in test_data["test_pronto_ok"]:
with self.subTest():
self.assertSequenceEqual(
ChuangmiIr.pronto_to_raw(*args["in"]), args["out"]
)
for args in test_data["test_pronto_exception"]:
with self.subTest():
with pytest.raises(ChuangmiIrException):
ChuangmiIr.pronto_to_raw(*args["in"])
def test_play_pronto(self):
for args in test_data["test_pronto_ok"]:
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play_pronto(*args["in"]))
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
for args in test_data["test_pronto_exception"]:
with pytest.raises(ChuangmiIrException):
self.device.play_pronto(*args["in"])
def test_play_auto(self):
for args in test_data["test_raw_ok"] + test_data["test_pronto_ok"]:
if len(args["in"]) > 1: # autodetect doesn't take any extra args
continue
with self.subTest():
self.device._reset_state()
self.assertTrue(self.device.play(*args["in"]))
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
def test_play_with_type(self):
for type_, tests in [
("raw", test_data["test_raw_ok"]),
("pronto", test_data["test_pronto_ok"]),
]:
for args in tests:
with self.subTest():
command = "{}:{}".format(type_, ":".join(map(str, args["in"])))
self.assertTrue(self.device.play(command))
self.assertSequenceEqual(
self.device.state["last_ir_played"], args["out"]
)
with pytest.raises(ChuangmiIrException):
self.device.play("invalid:command")
with pytest.raises(ChuangmiIrException):
self.device.play("pronto:command:invalid:argument:count")
with pytest.raises(ChuangmiIrException):
self.device.play("pronto:command:invalidargument")
|