Skip to content

Commit 26354ef

Browse files
authored
Refactor commands as int enums. (#66)
* Refactor commands as an enum. * Refactor network state as an int enum. * Refactor DEVICE_STATE as an int enum. * Sort TX/RX_COMMANDS. * Adhere to CamelCase convention for enum classes.
1 parent f196f2c commit 26354ef

File tree

3 files changed

+115
-112
lines changed

3 files changed

+115
-112
lines changed

tests/test_api.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,15 @@ def test_close(api):
3636

3737

3838
def test_commands():
39-
import string
40-
anum = string.ascii_letters + string.digits + '_'
41-
for cmd_name, cmd_opts in deconz_api.RX_COMMANDS.items():
42-
assert isinstance(cmd_name, str) is True
43-
assert all([c in anum for c in cmd_name]), cmd_name
44-
assert len(cmd_opts) == 3
45-
cmd_id, schema, reply = cmd_opts
46-
assert isinstance(cmd_id, int) is True
39+
for cmd, cmd_opts in deconz_api.RX_COMMANDS.items():
40+
assert len(cmd_opts) == 2
41+
schema, solicited = cmd_opts
42+
assert isinstance(cmd, int) is True
4743
assert isinstance(schema, tuple) is True
48-
assert reply is None or isinstance(reply, bool)
44+
assert isinstance(solicited, bool)
4945

50-
for cmd_name, cmd_opts in deconz_api.TX_COMMANDS.items():
51-
assert isinstance(cmd_name, str) is True
52-
assert all([c in anum for c in cmd_name]), cmd_name
53-
assert len(cmd_opts) == 2
54-
cmd_id, schema = cmd_opts
55-
assert isinstance(cmd_id, int) is True
46+
for cmd, schema in deconz_api.TX_COMMANDS.items():
47+
assert isinstance(cmd, int) is True
5648
assert isinstance(schema, tuple) is True
5749

5850

@@ -67,11 +59,11 @@ async def mock_fut():
6759
return mock.sentinel.cmd_result
6860
monkeypatch.setattr(asyncio, 'Future', mock_fut)
6961

70-
for cmd_name, cmd_opts in deconz_api.TX_COMMANDS.items():
71-
ret = await api._command(cmd_name, mock.sentinel.cmd_data)
62+
for cmd, cmd_opts in deconz_api.TX_COMMANDS.items():
63+
ret = await api._command(cmd, mock.sentinel.cmd_data)
7264
assert ret is mock.sentinel.cmd_result
7365
assert api._api_frame.call_count == 1
74-
assert api._api_frame.call_args[0][0] == cmd_name
66+
assert api._api_frame.call_args[0][0] == cmd
7567
assert api._api_frame.call_args[0][1] == mock.sentinel.cmd_data
7668
assert api._uart.send.call_count == 1
7769
assert api._uart.send.call_args[0][0] == mock.sentinel.api_frame_data
@@ -88,11 +80,11 @@ def mock_api_frame(name, *args):
8880

8981
monkeypatch.setattr(deconz_api, 'COMMAND_TIMEOUT', 0.1)
9082

91-
for cmd_name, cmd_opts in deconz_api.TX_COMMANDS.items():
83+
for cmd, cmd_opts in deconz_api.TX_COMMANDS.items():
9284
with pytest.raises(asyncio.TimeoutError):
93-
await api._command(cmd_name, mock.sentinel.cmd_data)
85+
await api._command(cmd, mock.sentinel.cmd_data)
9486
assert api._api_frame.call_count == 1
95-
assert api._api_frame.call_args[0][0] == cmd_name
87+
assert api._api_frame.call_args[0][0] == cmd
9688
assert api._api_frame.call_args[0][1] == mock.sentinel.cmd_data
9789
assert api._uart.send.call_count == 1
9890
assert api._uart.send.call_args[0][0] == mock.sentinel.api_frame_data
@@ -105,13 +97,12 @@ def test_api_frame(api):
10597
addr.address_mode = t.ADDRESS_MODE.NWK
10698
addr.address = t.uint8_t(0)
10799
addr.endpoint = t.uint8_t(0)
108-
for cmd_name, cmd_opts in deconz_api.TX_COMMANDS.items():
109-
_, schema = cmd_opts
100+
for cmd, schema in deconz_api.TX_COMMANDS.items():
110101
if schema:
111102
args = [addr if isinstance(a(), t.DeconzAddressEndpoint) else a() for a in schema]
112-
api._api_frame(cmd_name, *args)
103+
api._api_frame(cmd, *args)
113104
else:
114-
api._api_frame(cmd_name)
105+
api._api_frame(cmd)
115106

116107

117108
def test_data_received(api, monkeypatch):
@@ -120,10 +111,9 @@ def test_data_received(api, monkeypatch):
120111
my_handler = mock.MagicMock()
121112

122113
for cmd, cmd_opts in deconz_api.RX_COMMANDS.items():
123-
cmd_id = cmd_opts[0]
124114
payload = b'\x01\x02\x03\x04'
125-
data = cmd_id.to_bytes(1, 'big') + b'\x00\x00\x00\x00' + payload
126-
setattr(api, '_handle_{}'.format(cmd), my_handler)
115+
data = cmd.serialize() + b'\x00\x00\x00\x00' + payload
116+
setattr(api, '_handle_{}'.format(cmd.name), my_handler)
127117
api._awaiting[0] = mock.MagicMock()
128118
api.data_received(data)
129119
assert t.deserialize.call_count == 1
@@ -140,12 +130,11 @@ def test_data_received_unk_status(api, monkeypatch):
140130
my_handler = mock.MagicMock()
141131

142132
for cmd, cmd_opts in deconz_api.RX_COMMANDS.items():
143-
cmd_id, unsolicited = cmd_opts[0], cmd_opts[2]
133+
_, unsolicited = cmd_opts
144134
payload = b'\x01\x02\x03\x04'
145135
status = t.uint8_t(0xfe).serialize()
146-
data = cmd_id.to_bytes(1, 'big') + b'\x00' + \
147-
status + b'\x00\x00' + payload
148-
setattr(api, '_handle_{}'.format(cmd), my_handler)
136+
data = cmd.serialize() + b'\x00' + status + b'\x00\x00' + payload
137+
setattr(api, '_handle_{}'.format(cmd.name), my_handler)
149138
api._awaiting[0] = mock.MagicMock()
150139
api.data_received(data)
151140
assert t.deserialize.call_count == 1
@@ -162,9 +151,7 @@ def test_data_received_unk_cmd(api, monkeypatch):
162151
monkeypatch.setattr(t, 'deserialize', mock.MagicMock(
163152
return_value=(mock.sentinel.deserialize_data, b'')))
164153

165-
for cmd_id in range(0, 255):
166-
if cmd_id in api._commands_by_id:
167-
continue
154+
for cmd_id in range(253, 255):
168155
payload = b'\x01\x02\x03\x04'
169156
status = t.uint8_t(0x00).serialize()
170157
data = cmd_id.to_bytes(1, 'big') + b'\x00' + \
@@ -290,7 +277,7 @@ async def test_aps_data_request_busy(api, monkeypatch):
290277
]
291278

292279
res = asyncio.Future()
293-
exc = zigpy_deconz.exception.CommandError(deconz_api.STATUS.BUSY, 'busy')
280+
exc = zigpy_deconz.exception.CommandError(deconz_api.Status.BUSY, 'busy')
294281
res.set_exception(exc)
295282
mock_cmd = mock.MagicMock(return_value=res)
296283

0 commit comments

Comments
 (0)