mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 10:44:04 +00:00
async++, small powerstrip improvements (#46)
* async++, small powerstrip improvements * use asyncclick instead of click, allows defining the commands with async def to avoid manual eventloop/asyncio.run handling * improve powerstrip support: * new powerstrip api: turn_{on,off}_by_{name,index} methods * cli: fix on/off for powerstrip using the new apis * add missing update()s for cli's hsv, led, temperature (fixes #43) * prettyprint the received payloads when debug mode in use * cli: debug mode can be activated now with '-d' * update requirements_test.txt * remove outdated click-datetime, replace click with asyncclick * debug is a flag * make smartstripplug to inherit the sysinfo from its parent, allows for simple access of general plug properties * proper bound checking for index accesses, allow controlling the plug at index 0 * remove the mess of turn_{on,off}_by_{name,index}, get_plug_by_{name,index} are enough. * adapt cli to use that * allow changing the alias per index * use f-strings consistently everywhere in the cli * add tests for get_plug_by_{index,name}
This commit is contained in:
@@ -92,13 +92,12 @@ def dev(request):
|
||||
Provides a device (given --ip) or parametrized fixture for the supported devices.
|
||||
The initial update is called automatically before returning the device.
|
||||
"""
|
||||
loop = asyncio.get_event_loop()
|
||||
file = request.param
|
||||
|
||||
ip = request.config.getoption("--ip")
|
||||
if ip:
|
||||
d = loop.run_until_complete(Discover.discover_single(ip))
|
||||
loop.run_until_complete(d.update())
|
||||
d = asyncio.run(Discover.discover_single(ip))
|
||||
asyncio.run(d.update())
|
||||
print(d.model)
|
||||
if d.model in file:
|
||||
return d
|
||||
@@ -125,7 +124,7 @@ def dev(request):
|
||||
model = basename(file)
|
||||
p = device_for_file(model)(host="123.123.123.123")
|
||||
p.protocol = FakeTransportProtocol(sysinfo)
|
||||
loop.run_until_complete(p.update())
|
||||
asyncio.run(p.update())
|
||||
yield p
|
||||
|
||||
|
||||
|
@@ -1,25 +1,26 @@
|
||||
import asyncio
|
||||
|
||||
from click.testing import CliRunner
|
||||
import pytest
|
||||
|
||||
from asyncclick.testing import CliRunner
|
||||
from kasa import SmartDevice
|
||||
from kasa.cli import alias, brightness, emeter, raw_command, state, sysinfo
|
||||
|
||||
from .conftest import handle_turn_on, turn_on
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
def test_sysinfo(dev):
|
||||
|
||||
async def test_sysinfo(dev):
|
||||
runner = CliRunner()
|
||||
res = runner.invoke(sysinfo, obj=dev)
|
||||
res = await runner.invoke(sysinfo, obj=dev)
|
||||
assert "System info" in res.output
|
||||
assert dev.alias in res.output
|
||||
|
||||
|
||||
@turn_on
|
||||
def test_state(dev, turn_on):
|
||||
asyncio.run(handle_turn_on(dev, turn_on))
|
||||
async def test_state(dev, turn_on):
|
||||
await handle_turn_on(dev, turn_on)
|
||||
runner = CliRunner()
|
||||
res = runner.invoke(state, obj=dev)
|
||||
res = await runner.invoke(state, obj=dev)
|
||||
print(res.output)
|
||||
|
||||
if dev.is_on:
|
||||
@@ -31,36 +32,36 @@ def test_state(dev, turn_on):
|
||||
assert "Device has no emeter" in res.output
|
||||
|
||||
|
||||
def test_alias(dev):
|
||||
async def test_alias(dev):
|
||||
runner = CliRunner()
|
||||
|
||||
res = runner.invoke(alias, obj=dev)
|
||||
res = await runner.invoke(alias, obj=dev)
|
||||
assert f"Alias: {dev.alias}" in res.output
|
||||
|
||||
new_alias = "new alias"
|
||||
res = runner.invoke(alias, [new_alias], obj=dev)
|
||||
res = await runner.invoke(alias, [new_alias], obj=dev)
|
||||
assert f"Setting alias to {new_alias}" in res.output
|
||||
|
||||
res = runner.invoke(alias, obj=dev)
|
||||
res = await runner.invoke(alias, obj=dev)
|
||||
assert f"Alias: {new_alias}" in res.output
|
||||
|
||||
|
||||
def test_raw_command(dev):
|
||||
async def test_raw_command(dev):
|
||||
runner = CliRunner()
|
||||
res = runner.invoke(raw_command, ["system", "get_sysinfo"], obj=dev)
|
||||
res = await runner.invoke(raw_command, ["system", "get_sysinfo"], obj=dev)
|
||||
|
||||
assert res.exit_code == 0
|
||||
assert dev.alias in res.output
|
||||
|
||||
res = runner.invoke(raw_command, obj=dev)
|
||||
res = await runner.invoke(raw_command, obj=dev)
|
||||
assert res.exit_code != 0
|
||||
assert "Usage" in res.output
|
||||
|
||||
|
||||
def test_emeter(dev: SmartDevice, mocker):
|
||||
async def test_emeter(dev: SmartDevice, mocker):
|
||||
runner = CliRunner()
|
||||
|
||||
res = runner.invoke(emeter, obj=dev)
|
||||
res = await runner.invoke(emeter, obj=dev)
|
||||
if not dev.has_emeter:
|
||||
assert "Device has no emeter" in res.output
|
||||
return
|
||||
@@ -68,52 +69,52 @@ def test_emeter(dev: SmartDevice, mocker):
|
||||
assert "Current State" in res.output
|
||||
|
||||
monthly = mocker.patch.object(dev, "get_emeter_monthly")
|
||||
res = runner.invoke(emeter, ["--year", "1900"], obj=dev)
|
||||
res = await runner.invoke(emeter, ["--year", "1900"], obj=dev)
|
||||
assert "For year" in res.output
|
||||
monthly.assert_called()
|
||||
|
||||
daily = mocker.patch.object(dev, "get_emeter_daily")
|
||||
res = runner.invoke(emeter, ["--month", "1900-12"], obj=dev)
|
||||
res = await runner.invoke(emeter, ["--month", "1900-12"], obj=dev)
|
||||
assert "For month" in res.output
|
||||
daily.assert_called()
|
||||
|
||||
|
||||
def test_brightness(dev):
|
||||
async def test_brightness(dev):
|
||||
runner = CliRunner()
|
||||
res = runner.invoke(brightness, obj=dev)
|
||||
res = await runner.invoke(brightness, obj=dev)
|
||||
if not dev.is_dimmable:
|
||||
assert "This device does not support brightness." in res.output
|
||||
return
|
||||
|
||||
res = runner.invoke(brightness, obj=dev)
|
||||
res = await runner.invoke(brightness, obj=dev)
|
||||
assert f"Brightness: {dev.brightness}" in res.output
|
||||
|
||||
res = runner.invoke(brightness, ["12"], obj=dev)
|
||||
res = await runner.invoke(brightness, ["12"], obj=dev)
|
||||
assert "Setting brightness" in res.output
|
||||
|
||||
res = runner.invoke(brightness, obj=dev)
|
||||
res = await runner.invoke(brightness, obj=dev)
|
||||
assert f"Brightness: 12" in res.output
|
||||
|
||||
|
||||
def test_temperature(dev):
|
||||
async def test_temperature(dev):
|
||||
pass
|
||||
|
||||
|
||||
def test_hsv(dev):
|
||||
async def test_hsv(dev):
|
||||
pass
|
||||
|
||||
|
||||
def test_led(dev):
|
||||
async def test_led(dev):
|
||||
pass
|
||||
|
||||
|
||||
def test_on(dev):
|
||||
async def test_on(dev):
|
||||
pass
|
||||
|
||||
|
||||
def test_off(dev):
|
||||
async def test_off(dev):
|
||||
pass
|
||||
|
||||
|
||||
def test_reboot(dev):
|
||||
async def test_reboot(dev):
|
||||
pass
|
||||
|
@@ -425,6 +425,26 @@ async def test_children_on_since(dev):
|
||||
assert plug.on_since
|
||||
|
||||
|
||||
@strip
|
||||
async def test_get_plug_by_name(dev: SmartStrip):
|
||||
name = dev.plugs[0].alias
|
||||
assert dev.get_plug_by_name(name) == dev.plugs[0]
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_plug_by_name("NONEXISTING NAME")
|
||||
|
||||
|
||||
@strip
|
||||
async def test_get_plug_by_index(dev: SmartStrip):
|
||||
assert dev.get_plug_by_index(0) == dev.plugs[0]
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_plug_by_index(-1)
|
||||
|
||||
with pytest.raises(SmartDeviceException):
|
||||
dev.get_plug_by_index(len(dev.plugs))
|
||||
|
||||
|
||||
@pytest.mark.skip("this test will wear out your relays")
|
||||
async def test_all_binary_states(dev):
|
||||
# test every binary state
|
||||
|
Reference in New Issue
Block a user