Skip to content

Commit a7a07ba

Browse files
authored
Merge pull request #31 from yozik04/tests_rewrite
Tests rewrite with help of AI #30 Drop of Python 3.6, 3.7 support
2 parents 2c59408 + a817076 commit a7a07ba

18 files changed

+613
-663
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
19+
python-version: ["3.8", "3.9", "3.10", "3.11"]
2020

2121
steps:
2222
- uses: actions/checkout@v3

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,9 @@ ENV/
9393
.idea
9494

9595
# other
96-
.DS_Store
96+
.DS_Store
97+
/html
98+
.mutmut-cache
99+
/Makefile
100+
/bin
101+
/service

.pre-commit-config.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.1.0
3+
rev: v4.4.0
44
hooks:
55
- id: check-added-large-files
66
- id: check-case-conflict
@@ -16,37 +16,37 @@ repos:
1616
- id: trailing-whitespace
1717

1818
- repo: https://github.com/asottile/pyupgrade
19-
rev: v2.31.1
19+
rev: v3.3.1
2020
hooks:
2121
- id: pyupgrade
2222
args: ["--py36-plus"]
2323

2424
- repo: https://github.com/psf/black
25-
rev: 22.3.0
25+
rev: 23.1.0
2626
hooks:
2727
- id: black
2828
args:
2929
- --safe
3030
- --quiet
3131

3232
- repo: https://github.com/pycqa/isort
33-
rev: 5.10.1
33+
rev: 5.12.0
3434
hooks:
3535
- id: isort
3636

3737
- repo: https://github.com/PyCQA/flake8
38-
rev: 4.0.1
38+
rev: 6.0.0
3939
hooks:
4040
- id: flake8
4141
additional_dependencies: [flake8-bugbear]
4242

4343
- repo: https://github.com/codespell-project/codespell
44-
rev: v2.1.0
44+
rev: v2.2.2
4545
hooks:
4646
- id: codespell
4747

4848
- repo: https://github.com/pre-commit/pygrep-hooks
49-
rev: v1.9.0
49+
rev: v1.10.0
5050
hooks:
5151
- id: python-check-blanket-noqa
5252
- id: python-check-blanket-type-ignore

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Old sync version is available [1.5.x](https://pypi.org/project/vallox-websocket-
1414
Release notes for the new versions are [here](https://github.com/yozik04/vallox_websocket_api/releases)
1515

1616
## Requirements
17-
Python 3.6.0+
17+
Python 3.8.0+
1818

1919
If you want to use Python 2.7, then use old sync version [1.5.x](https://pypi.org/project/vallox-websocket-api/1.5.2/)
2020

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ forced_separate = [
1919
"tests",
2020
]
2121
combine_as_imports = true
22+
23+
[tool.pytest.ini_options]
24+
asyncio_mode = "auto"

setup.cfg

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ classifiers =
1717
Operating System :: OS Independent
1818
Programming Language :: Python
1919
Programming Language :: Python :: 3 :: Only
20-
Programming Language :: Python :: 3.6
21-
Programming Language :: Python :: 3.7
2220
Programming Language :: Python :: 3.8
2321
Programming Language :: Python :: 3.9
2422
Programming Language :: Python :: 3.10
23+
Programming Language :: Python :: 3.11
2524
license = LGPL 3
2625

2726
[options]
@@ -33,11 +32,9 @@ python_requires = >=3.6.0, <4
3332
install_requires =
3433
websockets >= 9.1, < 11.0
3534
construct >= 2.9.0, < 3.0.0
36-
setup_requires =
37-
wheel
3835
tests_require =
39-
mock
40-
asynctest
36+
pytest
37+
pytest-asyncio
4138

4239
[flake8]
4340
exclude = .venv,.git,.tox,docs,venv,bin,lib,deps,build

tests/conftest.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from unittest.mock import AsyncMock, patch
2+
3+
import pytest
4+
import websockets
5+
6+
from vallox_websocket_api.client import Client
7+
from vallox_websocket_api.vallox import Vallox
8+
9+
10+
@pytest.fixture
11+
def client():
12+
return Client("127.0.0.1")
13+
14+
15+
@pytest.fixture
16+
def vallox():
17+
return Vallox("127.0.0.1")
18+
19+
20+
@pytest.fixture
21+
def ws():
22+
with patch("websockets.connect") as connect:
23+
protocol_mock = AsyncMock(spec=websockets.WebSocketCommonProtocol)
24+
connect.return_value.__aenter__.side_effect = protocol_mock
25+
26+
yield protocol_mock.return_value

tests/decorators.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/test_client.py

Lines changed: 64 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import binascii
2+
from unittest.mock import AsyncMock
23

3-
import asynctest
4-
from asynctest import CoroutineMock
4+
import pytest
55
from websockets.exceptions import InvalidMessage
66

77
from vallox_websocket_api.client import Client
@@ -10,125 +10,103 @@
1010
ValloxWebsocketException,
1111
)
1212

13-
from tests.decorators import with_client
1413

14+
async def test_fetch_metric(client: Client, ws):
15+
ws.recv.return_value = binascii.unhexlify(
16+
"0024000000000000000000000000000001000800030000000000000061df98b100030003203fb9500331000000000000000000560000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b000f732a6ca969a171d1730800010000022700000028000000000000000001a6029e000100000028ffffffffffffffffffffffffffffffffffffffffffffffff000000000000000057c503e8ffffffffffff000000190000000000010000000000000000000300001b98012000a50000000000000000001e00010000000100000000000000000007001b000f001700010012000200070044000000010000000000000007003200320001000000000000001e0000c0a80501ffffff0000000000000000000000000000000000000000000000000000000000c0a8050c86076097f78844b7ac4db61e502fe4f2004c004c000100c00101001c001e000a00320000003703840000708f00320032000a0000000000010000000a721f0000000000010000000f728300000000000000000064715700000000000000000000000000000000000000010037001e000000000000000068bf71bb000083910000002600b4000000010001000000010001001e000f00080001001200000003000000000000000000000017000003e90000000000000001000100010000000a003200010000000000000000000000000000000000000000001000000000000000000000000000540048000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
17+
)
1518

16-
class TestClient(asynctest.TestCase):
17-
@with_client
18-
async def testFetchMetric(self, client: Client, ws):
19-
ws.recv.return_value = binascii.unhexlify(
20-
"0024000000000000000000000000000001000800030000000000000061df98b100030003203fb9500331000000000000000000560000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b000f732a6ca969a171d1730800010000022700000028000000000000000001a6029e000100000028ffffffffffffffffffffffffffffffffffffffffffffffff000000000000000057c503e8ffffffffffff000000190000000000010000000000000000000300001b98012000a50000000000000000001e00010000000100000000000000000007001b000f001700010012000200070044000000010000000000000007003200320001000000000000001e0000c0a80501ffffff0000000000000000000000000000000000000000000000000000000000c0a8050c86076097f78844b7ac4db61e502fe4f2004c004c000100c00101001c001e000a00320000003703840000708f00320032000a0000000000010000000a721f0000000000010000000f728300000000000000000064715700000000000000000000000000000000000000010037001e000000000000000068bf71bb000083910000002600b4000000010001000000010001001e000f00080001001200000003000000000000000000000017000003e90000000000000001000100010000000a003200010000000000000000000000000000000000000000001000000000000000000000000000540048000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
21-
)
19+
result = await client.fetch_metric("A_CYC_ENABLED")
2220

23-
result = await client.fetch_metric("A_CYC_ENABLED")
21+
assert result == 1
22+
ws.send.assert_called_once_with(binascii.unhexlify("0300f6000000f900"))
2423

25-
self.assertEqual(1, result)
2624

27-
ws.send.assert_called_once_with(binascii.unhexlify("0300f6000000f900"))
25+
async def test_set_temp_value(client: Client, ws):
26+
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19"})
2827

29-
@with_client
30-
async def testSetTempValue(self, client: Client, ws):
31-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
28+
ws.send.assert_called_once_with(binascii.unhexlify("0400f90022501f723ec3"))
3229

33-
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19"})
3430

35-
ws.send.assert_called_once_with(binascii.unhexlify("0400f90022501f723ec3"))
31+
async def test_set_temp_value_fraction(client: Client, ws):
32+
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19.1"})
3633

37-
@with_client
38-
async def testSetTempValueFraction(self, client: Client, ws):
39-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
34+
ws.send.assert_called_once_with(binascii.unhexlify("0400f9002250297248c3"))
4035

41-
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19.1"})
4236

43-
ws.send.assert_called_once_with(binascii.unhexlify("0400f9002250297248c3"))
37+
async def test_set_temp_value_fraction_rounding1(client: Client, ws):
38+
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19.145"})
4439

45-
@with_client
46-
async def testSetTempValueFractionRounding1(self, client: Client, ws):
47-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
40+
ws.send.assert_called_once_with(binascii.unhexlify("0400f9002250297248c3"))
4841

49-
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "19.145"})
5042

51-
ws.send.assert_called_once_with(binascii.unhexlify("0400f9002250297248c3"))
43+
async def test_set_temp_value_fraction_rounding2(client: Client, ws):
44+
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "18.991"})
5245

53-
@with_client
54-
async def testSetTempValueFractionRounding2(self, client: Client, ws):
55-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
46+
ws.send.assert_called_once_with(binascii.unhexlify("0400f90022501f723ec3"))
5647

57-
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "18.991"})
5848

59-
ws.send.assert_called_once_with(binascii.unhexlify("0400f90022501f723ec3"))
49+
async def test_set_value(client: Client, ws):
50+
await client.set_values(
51+
{
52+
"A_CYC_STATE": 0,
53+
"A_CYC_BOOST_TIMER": 0,
54+
"A_CYC_FIREPLACE_TIMER": 0,
55+
"A_CYC_EXTRA_TIMER": 0,
56+
}
57+
)
6058

61-
@with_client
62-
async def testSetValue(self, client: Client, ws):
63-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
59+
ws.send.assert_called_once_with(
60+
binascii.unhexlify("0a00f900011200000412000005120000061200001349")
61+
)
6462

65-
await client.set_values(
66-
{
67-
"A_CYC_STATE": 0,
68-
"A_CYC_BOOST_TIMER": 0,
69-
"A_CYC_FIREPLACE_TIMER": 0,
70-
"A_CYC_EXTRA_TIMER": 0,
71-
}
72-
)
7363

74-
ws.send.assert_called_once_with(
75-
binascii.unhexlify("0a00f900011200000412000005120000061200001349")
76-
)
64+
async def test_set_assertion(client: Client, ws):
65+
with pytest.raises(ValloxInvalidInputException):
66+
await client.set_values({"A_CYC_BOOST_TIMER": "11.2"})
7767

78-
@with_client
79-
async def testSetAssertion(self, client: Client, ws):
80-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
68+
with pytest.raises(ValloxInvalidInputException):
69+
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "11.a"})
8170

82-
with self.assertRaises(ValloxInvalidInputException):
83-
await client.set_values({"A_CYC_BOOST_TIMER": "11.2"})
71+
with pytest.raises(ValloxInvalidInputException):
72+
await client.set_values({"A_CYC_BOOST_SPEED_SETTING": "11.2"})
8473

85-
with self.assertRaises(ValloxInvalidInputException):
86-
await client.set_values({"A_CYC_BOOST_AIR_TEMP_TARGET": "11.a"})
74+
with pytest.raises(ValloxInvalidInputException):
75+
await client.set_values({"A_CYC_FIREPLACE_SUPP_FAN": "11.2"})
8776

88-
with self.assertRaises(ValloxInvalidInputException):
89-
await client.set_values({"A_CYC_BOOST_SPEED_SETTING": "11.2"})
77+
ws.send.assert_not_called()
9078

91-
with self.assertRaises(ValloxInvalidInputException):
92-
await client.set_values({"A_CYC_FIREPLACE_SUPP_FAN": "11.2"})
9379

94-
@with_client
95-
async def testSetMissing(self, client: Client, ws):
96-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
80+
async def test_set_missing(client: Client, ws):
81+
with pytest.raises(ValloxInvalidInputException):
82+
await client.set_values({"A_CYC_BOOSTER": 10})
9783

98-
with self.assertRaises(ValloxInvalidInputException):
99-
await client.set_values({"A_CYC_BOOSTER": 10})
84+
ws.send.assert_not_called()
10085

101-
@with_client
102-
async def testSetUnsettable(self, client: Client, ws):
103-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
10486

105-
with self.assertRaises(ValloxInvalidInputException):
106-
await client.set_values({"A_CYC_RH_VALUE": 22})
87+
async def test_set_unsettable(client: Client, ws):
88+
with pytest.raises(ValloxInvalidInputException):
89+
await client.set_values({"A_CYC_RH_VALUE": 22})
10790

108-
@with_client
109-
async def testSetNewSettableAddressByName(self, client: Client, ws):
110-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
91+
ws.send.assert_not_called()
11192

112-
client.set_settable_address("A_CYC_RH_VALUE", int)
11393

114-
await client.set_values({"A_CYC_RH_VALUE": 22})
94+
async def test_set_new_settable_address_by_name(client: Client, ws):
95+
client.set_settable_address("A_CYC_RH_VALUE", int)
11596

116-
@with_client
117-
async def testSetNewSettableAddressByAddress(self, client: Client, ws):
118-
ws.recv.return_value = binascii.unhexlify("0200f500f700")
97+
await client.set_values({"A_CYC_RH_VALUE": 22})
11998

120-
client.set_settable_address(4363, int)
12199

122-
await client.set_values({"A_CYC_RH_VALUE": 22})
100+
async def test_set_new_settable_address_by_address(client: Client, ws):
101+
client.set_settable_address(4363, int)
123102

124-
@with_client
125-
async def testSetNewSettableAddressByAddressException(self, client: Client, ws):
126-
ws.recv.side_effect = CoroutineMock(side_effect=InvalidMessage())
103+
await client.set_values({"A_CYC_RH_VALUE": 22})
127104

128-
client.set_settable_address(4363, int)
129105

130-
await self.assertAsyncRaisesRegex(
131-
ValloxWebsocketException,
132-
"Websocket handshake failed",
133-
client.set_values({"A_CYC_RH_VALUE": 22}),
134-
)
106+
async def test_set_new_settable_address_by_address_exception(client: Client, ws):
107+
ws.recv.side_effect = AsyncMock(side_effect=InvalidMessage())
108+
109+
client.set_settable_address(4363, int)
110+
111+
with pytest.raises(ValloxWebsocketException):
112+
await client.set_values({"A_CYC_RH_VALUE": 22})

0 commit comments

Comments
 (0)