mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-10-12 10:28:01 +00:00
Add precommit hooks & tox env to enforce code structure, add azure pipelines
Instead of leveraging hound & travis, add an option for azure pipelines, which may replace the former in the future. This also streamlines the contributing guidelines by: * Adding pre-commit hooks to run isort, black, flake8, mypy * Adding lint environment to allow checks to be run `tox -e lint` This also contains a major cleanup to the SmartStrip handling which was due. After seeing #184 I thought I should push this in as it is for comments before the codebase diverges too much.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import pytest
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
from .newfakes import FakeTransportProtocol
|
||||
from os.path import basename
|
||||
from pyHS100 import SmartPlug, SmartBulb, SmartStrip, Discover
|
||||
|
||||
import pytest
|
||||
|
||||
from pyHS100 import Discover, SmartBulb, SmartPlug, SmartStrip
|
||||
|
||||
from .newfakes import FakeTransportProtocol
|
||||
|
||||
SUPPORTED_DEVICES = glob.glob(
|
||||
os.path.dirname(os.path.abspath(__file__)) + "/fixtures/*.json"
|
||||
|
@@ -1,8 +1,10 @@
|
||||
from ..protocol import TPLinkSmartHomeProtocol
|
||||
from .. import SmartDeviceException
|
||||
import logging
|
||||
import re
|
||||
from voluptuous import Schema, Range, All, Any, Coerce, Invalid, Optional, REMOVE_EXTRA
|
||||
|
||||
from voluptuous import REMOVE_EXTRA, All, Any, Coerce, Invalid, Optional, Range, Schema
|
||||
|
||||
from .. import SmartDeviceException
|
||||
from ..protocol import TPLinkSmartHomeProtocol
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -1,31 +1,31 @@
|
||||
import datetime
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from pyHS100 import DeviceType, SmartStripException, SmartDeviceException
|
||||
from .newfakes import (
|
||||
BULB_SCHEMA,
|
||||
PLUG_SCHEMA,
|
||||
FakeTransportProtocol,
|
||||
CURRENT_CONSUMPTION_SCHEMA,
|
||||
TZ_SCHEMA,
|
||||
)
|
||||
from pyHS100 import DeviceType, SmartDeviceException
|
||||
|
||||
from .conftest import (
|
||||
turn_on,
|
||||
handle_turn_on,
|
||||
plug,
|
||||
strip,
|
||||
bulb,
|
||||
color_bulb,
|
||||
non_color_bulb,
|
||||
dimmable,
|
||||
handle_turn_on,
|
||||
has_emeter,
|
||||
no_emeter,
|
||||
dimmable,
|
||||
non_color_bulb,
|
||||
non_dimmable,
|
||||
variable_temp,
|
||||
non_variable_temp,
|
||||
plug,
|
||||
strip,
|
||||
turn_on,
|
||||
variable_temp,
|
||||
)
|
||||
from .newfakes import (
|
||||
BULB_SCHEMA,
|
||||
CURRENT_CONSUMPTION_SCHEMA,
|
||||
PLUG_SCHEMA,
|
||||
TZ_SCHEMA,
|
||||
FakeTransportProtocol,
|
||||
)
|
||||
|
||||
|
||||
@@ -436,67 +436,44 @@ def test_deprecated_hsv(dev, turn_on):
|
||||
dev.hsv = (1, 1, 1)
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_is_on(dev):
|
||||
is_on = dev.get_is_on()
|
||||
for i in range(dev.num_children):
|
||||
assert is_on[i] == dev.get_is_on(index=i)
|
||||
|
||||
|
||||
@strip
|
||||
@turn_on
|
||||
def test_children_change_state(dev, turn_on):
|
||||
handle_turn_on(dev, turn_on)
|
||||
for i in range(dev.num_children):
|
||||
orig_state = dev.get_is_on(index=i)
|
||||
for plug in dev.plugs:
|
||||
orig_state = plug.is_on
|
||||
if orig_state:
|
||||
dev.turn_off(index=i)
|
||||
assert not dev.get_is_on(index=i)
|
||||
assert dev.get_is_off(index=i)
|
||||
plug.turn_off()
|
||||
assert not plug.is_on
|
||||
assert plug.is_off
|
||||
|
||||
dev.turn_on(index=i)
|
||||
assert dev.get_is_on(index=i)
|
||||
assert not dev.get_is_off(index=i)
|
||||
plug.turn_on()
|
||||
assert plug.is_on
|
||||
assert not plug.is_off
|
||||
else:
|
||||
dev.turn_on(index=i)
|
||||
assert dev.get_is_on(index=i)
|
||||
assert not dev.get_is_off(index=i)
|
||||
dev.turn_off(index=i)
|
||||
assert not dev.get_is_on(index=i)
|
||||
assert dev.get_is_off(index=i)
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_bounds(dev):
|
||||
out_of_bounds = dev.num_children + 100
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.turn_off(index=out_of_bounds)
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.turn_on(index=out_of_bounds)
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_is_on(index=out_of_bounds)
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_alias(index=out_of_bounds)
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_on_since(index=out_of_bounds)
|
||||
plug.turn_on()
|
||||
assert plug.is_on
|
||||
assert not plug.is_off
|
||||
plug.turn_off()
|
||||
assert not plug.is_on
|
||||
assert plug.is_off
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_alias(dev):
|
||||
original = dev.get_alias()
|
||||
test_alias = "TEST1234"
|
||||
for idx in range(dev.num_children):
|
||||
dev.set_alias(alias=test_alias, index=idx)
|
||||
assert dev.get_alias(index=idx) == test_alias
|
||||
dev.set_alias(alias=original[idx], index=idx)
|
||||
assert dev.get_alias(index=idx) == original[idx]
|
||||
for plug in dev.plugs:
|
||||
original = plug.get_alias()
|
||||
plug.set_alias(alias=test_alias)
|
||||
assert plug.get_alias() == test_alias
|
||||
plug.set_alias(alias=original)
|
||||
assert plug.get_alias() == original
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_on_since(dev):
|
||||
for idx in range(dev.num_children):
|
||||
assert dev.get_on_since(index=idx)
|
||||
for plug in dev.plugs:
|
||||
assert plug.get_on_since()
|
||||
|
||||
|
||||
@pytest.mark.skip("this test will wear out your relays")
|
||||
@@ -548,78 +525,61 @@ def test_all_binary_states(dev):
|
||||
def test_children_get_emeter_realtime(dev):
|
||||
assert dev.has_emeter
|
||||
# test with index
|
||||
for plug_index in range(dev.num_children):
|
||||
emeter = dev.get_emeter_realtime(index=plug_index)
|
||||
for plug in dev.plugs:
|
||||
emeter = plug.get_emeter_realtime()
|
||||
CURRENT_CONSUMPTION_SCHEMA(emeter)
|
||||
|
||||
# test without index
|
||||
for index, emeter in dev.get_emeter_realtime().items():
|
||||
CURRENT_CONSUMPTION_SCHEMA(emeter)
|
||||
# TODO test that sum matches the sum of individiaul plugs.
|
||||
|
||||
# out of bounds
|
||||
with pytest.raises(SmartStripException):
|
||||
dev.get_emeter_realtime(index=dev.num_children + 100)
|
||||
# for index, emeter in dev.get_emeter_realtime().items():
|
||||
# CURRENT_CONSUMPTION_SCHEMA(emeter)
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_get_emeter_daily(dev):
|
||||
assert dev.has_emeter
|
||||
# test with index
|
||||
for plug_index in range(dev.num_children):
|
||||
emeter = dev.get_emeter_daily(year=1900, month=1, index=plug_index)
|
||||
# test individual emeters
|
||||
for plug in dev.plugs:
|
||||
emeter = plug.get_emeter_daily(year=1900, month=1)
|
||||
assert emeter == {}
|
||||
|
||||
emeter = dev.get_emeter_daily(index=plug_index)
|
||||
emeter = plug.get_emeter_daily()
|
||||
assert len(emeter) > 0
|
||||
|
||||
k, v = emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
# test without index
|
||||
# test sum of emeters
|
||||
all_emeter = dev.get_emeter_daily(year=1900, month=1)
|
||||
for plug_index, emeter in all_emeter.items():
|
||||
assert emeter == {}
|
||||
|
||||
emeter = dev.get_emeter_daily(index=plug_index)
|
||||
|
||||
k, v = emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
# out of bounds
|
||||
with pytest.raises(SmartStripException):
|
||||
dev.get_emeter_daily(year=1900, month=1, index=dev.num_children + 100)
|
||||
k, v = all_emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
|
||||
@strip
|
||||
def test_children_get_emeter_monthly(dev):
|
||||
assert dev.has_emeter
|
||||
# test with index
|
||||
for plug_index in range(dev.num_children):
|
||||
emeter = dev.get_emeter_monthly(year=1900, index=plug_index)
|
||||
# test individual emeters
|
||||
for plug in dev.plugs:
|
||||
emeter = plug.get_emeter_monthly(year=1900)
|
||||
assert emeter == {}
|
||||
|
||||
emeter = dev.get_emeter_monthly()
|
||||
emeter = plug.get_emeter_monthly()
|
||||
assert len(emeter) > 0
|
||||
|
||||
k, v = emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
# test without index
|
||||
# test sum of emeters
|
||||
all_emeter = dev.get_emeter_monthly(year=1900)
|
||||
for index, emeter in all_emeter.items():
|
||||
assert emeter == {}
|
||||
assert len(emeter) > 0
|
||||
|
||||
k, v = emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
# out of bounds
|
||||
with pytest.raises(SmartStripException):
|
||||
dev.get_emeter_monthly(year=1900, index=dev.num_children + 100)
|
||||
k, v = all_emeter.popitem()
|
||||
assert isinstance(k, int)
|
||||
assert isinstance(v, float)
|
||||
|
||||
|
||||
def test_cache(dev):
|
||||
@@ -658,6 +618,6 @@ def test_cache_invalidates(dev):
|
||||
|
||||
def test_representation(dev):
|
||||
import re
|
||||
|
||||
pattern = re.compile("<.* model .* at .* (.*), is_on: .* - dev specific: .*>")
|
||||
assert pattern.match(str(dev))
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
from unittest import TestCase
|
||||
from ..protocol import TPLinkSmartHomeProtocol
|
||||
import json
|
||||
from unittest import TestCase
|
||||
|
||||
from ..protocol import TPLinkSmartHomeProtocol
|
||||
|
||||
|
||||
class TestTPLinkSmartHomeProtocol(TestCase):
|
||||
|
Reference in New Issue
Block a user