Use voluptuous for input_slider, input_boolean, input_select (#3256)
* Use voluptuous for input slider * floats * _setup_component * Imperative mood * CONFIG_SCHEMA * None returns empty ensure_list * allow_extra * bool * restore ensure_list behaviourpull/3492/head
parent
de51cfbc07
commit
9631179126
|
@ -145,7 +145,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
|
|||
if hasattr(component, 'CONFIG_SCHEMA'):
|
||||
try:
|
||||
config = component.CONFIG_SCHEMA(config)
|
||||
except vol.MultipleInvalid as ex:
|
||||
except vol.Invalid as ex:
|
||||
log_exception(ex, domain, config)
|
||||
return None
|
||||
|
||||
|
@ -155,8 +155,8 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
|
|||
# Validate component specific platform schema
|
||||
try:
|
||||
p_validated = component.PLATFORM_SCHEMA(p_config)
|
||||
except vol.MultipleInvalid as ex:
|
||||
log_exception(ex, domain, p_config)
|
||||
except vol.Invalid as ex:
|
||||
log_exception(ex, domain, config)
|
||||
return None
|
||||
|
||||
# Not all platform components follow same pattern for platforms
|
||||
|
@ -176,7 +176,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
|
|||
if hasattr(platform, 'PLATFORM_SCHEMA'):
|
||||
try:
|
||||
p_validated = platform.PLATFORM_SCHEMA(p_validated)
|
||||
except vol.MultipleInvalid as ex:
|
||||
except vol.Invalid as ex:
|
||||
log_exception(ex, '{}.{}'.format(domain, p_name),
|
||||
p_validated)
|
||||
return None
|
||||
|
|
|
@ -9,12 +9,11 @@ import logging
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_TOGGLE,
|
||||
STATE_ON)
|
||||
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON,
|
||||
SERVICE_TOGGLE, STATE_ON)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.util import slugify
|
||||
|
||||
DOMAIN = 'input_boolean'
|
||||
|
||||
|
@ -22,14 +21,19 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_NAME = "name"
|
||||
CONF_INITIAL = "initial"
|
||||
CONF_ICON = "icon"
|
||||
CONF_INITIAL = 'initial'
|
||||
|
||||
SERVICE_SCHEMA = vol.Schema({
|
||||
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
})
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
cv.slug: {
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Optional(CONF_INITIAL): cv.boolean,
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
}}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
def is_on(hass, entity_id):
|
||||
"""Test if input_boolean is True."""
|
||||
|
@ -53,19 +57,11 @@ def toggle(hass, entity_id):
|
|||
|
||||
def setup(hass, config):
|
||||
"""Set up input boolean."""
|
||||
if not isinstance(config.get(DOMAIN), dict):
|
||||
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||
return False
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
entities = []
|
||||
|
||||
for object_id, cfg in config[DOMAIN].items():
|
||||
if object_id != slugify(object_id):
|
||||
_LOGGER.warning("Found invalid key for boolean input: %s. "
|
||||
"Use %s instead", object_id, slugify(object_id))
|
||||
continue
|
||||
if not cfg:
|
||||
cfg = {}
|
||||
|
||||
|
|
|
@ -8,19 +8,17 @@ import logging
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_ICON, CONF_NAME
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.util import slugify
|
||||
|
||||
|
||||
DOMAIN = 'input_select'
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_NAME = 'name'
|
||||
CONF_INITIAL = 'initial'
|
||||
CONF_ICON = 'icon'
|
||||
CONF_OPTIONS = 'options'
|
||||
|
||||
ATTR_OPTION = 'option'
|
||||
|
@ -34,6 +32,26 @@ SERVICE_SELECT_OPTION_SCHEMA = vol.Schema({
|
|||
})
|
||||
|
||||
|
||||
def _cv_input_select(cfg):
|
||||
"""Config validation helper for input select (Voluptuous)."""
|
||||
options = cfg[CONF_OPTIONS]
|
||||
state = cfg.get(CONF_INITIAL, options[0])
|
||||
if state not in options:
|
||||
raise vol.Invalid('initial state "{}" is not part of the options: {}'
|
||||
.format(state, ','.join(options)))
|
||||
return cfg
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({DOMAIN: {
|
||||
cv.slug: vol.All({
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_OPTIONS): vol.All(cv.ensure_list, vol.Length(min=1),
|
||||
[cv.string]),
|
||||
vol.Optional(CONF_INITIAL): cv.string,
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
}, _cv_input_select)}}, required=True, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
def select_option(hass, entity_id, option):
|
||||
"""Set input_select to False."""
|
||||
hass.services.call(DOMAIN, SERVICE_SELECT_OPTION, {
|
||||
|
@ -44,39 +62,15 @@ def select_option(hass, entity_id, option):
|
|||
|
||||
def setup(hass, config):
|
||||
"""Setup input select."""
|
||||
if not isinstance(config.get(DOMAIN), dict):
|
||||
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||
return False
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
entities = []
|
||||
|
||||
for object_id, cfg in config[DOMAIN].items():
|
||||
if object_id != slugify(object_id):
|
||||
_LOGGER.warning("Found invalid key for boolean input: %s. "
|
||||
"Use %s instead", object_id, slugify(object_id))
|
||||
continue
|
||||
if not cfg:
|
||||
_LOGGER.warning("No configuration specified for %s", object_id)
|
||||
continue
|
||||
|
||||
name = cfg.get(CONF_NAME)
|
||||
options = cfg.get(CONF_OPTIONS)
|
||||
|
||||
if not isinstance(options, list) or len(options) == 0:
|
||||
_LOGGER.warning('Key %s should be a list of options', CONF_OPTIONS)
|
||||
continue
|
||||
|
||||
options = [str(val) for val in options]
|
||||
|
||||
state = cfg.get(CONF_INITIAL)
|
||||
|
||||
if state not in options:
|
||||
state = options[0]
|
||||
|
||||
state = cfg.get(CONF_INITIAL, options[0])
|
||||
icon = cfg.get(CONF_ICON)
|
||||
|
||||
entities.append(InputSelect(object_id, name, state, options, icon))
|
||||
|
||||
if not entities:
|
||||
|
|
|
@ -8,21 +8,19 @@ import logging
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, CONF_ICON, CONF_NAME)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.util import slugify
|
||||
|
||||
DOMAIN = 'input_slider'
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_NAME = 'name'
|
||||
CONF_INITIAL = 'initial'
|
||||
CONF_MIN = 'min'
|
||||
CONF_MAX = 'max'
|
||||
CONF_ICON = 'icon'
|
||||
CONF_STEP = 'step'
|
||||
|
||||
ATTR_VALUE = 'value'
|
||||
|
@ -38,6 +36,33 @@ SERVICE_SELECT_VALUE_SCHEMA = vol.Schema({
|
|||
})
|
||||
|
||||
|
||||
def _cv_input_slider(cfg):
|
||||
"""Config validation helper for input slider (Voluptuous)."""
|
||||
minimum = cfg.get(CONF_MIN)
|
||||
maximum = cfg.get(CONF_MAX)
|
||||
if minimum >= maximum:
|
||||
raise vol.Invalid('Maximum ({}) is not greater than minimum ({})'
|
||||
.format(minimum, maximum))
|
||||
state = cfg.get(CONF_INITIAL, minimum)
|
||||
if state < minimum or state > maximum:
|
||||
raise vol.Invalid('Initial value {} not in range {}-{}'
|
||||
.format(state, minimum, maximum))
|
||||
cfg[CONF_INITIAL] = state
|
||||
return cfg
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({DOMAIN: {
|
||||
cv.slug: vol.All({
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_MIN): vol.Coerce(float),
|
||||
vol.Required(CONF_MAX): vol.Coerce(float),
|
||||
vol.Optional(CONF_INITIAL): vol.Coerce(float),
|
||||
vol.Optional(CONF_STEP, default=1): vol.All(vol.Coerce(float),
|
||||
vol.Range(min=1e-3)),
|
||||
vol.Optional(CONF_ICON): cv.icon,
|
||||
vol.Optional(ATTR_UNIT_OF_MEASUREMENT): cv.string
|
||||
}, _cv_input_slider)}}, required=True, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
def select_value(hass, entity_id, value):
|
||||
"""Set input_slider to value."""
|
||||
hass.services.call(DOMAIN, SERVICE_SELECT_VALUE, {
|
||||
|
@ -48,36 +73,19 @@ def select_value(hass, entity_id, value):
|
|||
|
||||
def setup(hass, config):
|
||||
"""Set up input slider."""
|
||||
if not isinstance(config.get(DOMAIN), dict):
|
||||
_LOGGER.error('Expected %s config to be a dictionary', DOMAIN)
|
||||
return False
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
entities = []
|
||||
|
||||
for object_id, cfg in config[DOMAIN].items():
|
||||
if object_id != slugify(object_id):
|
||||
_LOGGER.warning("Found invalid key for boolean input: %s. "
|
||||
"Use %s instead", object_id, slugify(object_id))
|
||||
continue
|
||||
if not cfg:
|
||||
_LOGGER.warning("No configuration specified for %s", object_id)
|
||||
continue
|
||||
|
||||
name = cfg.get(CONF_NAME)
|
||||
minimum = cfg.get(CONF_MIN)
|
||||
maximum = cfg.get(CONF_MAX)
|
||||
state = cfg.get(CONF_INITIAL, minimum)
|
||||
step = cfg.get(CONF_STEP, 1)
|
||||
step = cfg.get(CONF_STEP)
|
||||
icon = cfg.get(CONF_ICON)
|
||||
unit = cfg.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
|
||||
if state < minimum:
|
||||
state = minimum
|
||||
if state > maximum:
|
||||
state = maximum
|
||||
|
||||
entities.append(InputSlider(object_id, name, state, minimum, maximum,
|
||||
step, icon, unit))
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""Helper methods for components within Home Assistant."""
|
||||
import re
|
||||
|
||||
from typing import Any, Iterable, Tuple, List, Dict
|
||||
from typing import Any, Iterable, Tuple, Sequence, Dict
|
||||
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
|
||||
# Typing Imports and TypeAlias
|
||||
# pylint: disable=using-constant-test,unused-import
|
||||
# pylint: disable=using-constant-test,unused-import,wrong-import-order
|
||||
if False:
|
||||
from logging import Logger # NOQA
|
||||
|
||||
|
@ -34,7 +34,7 @@ def config_per_platform(config: ConfigType,
|
|||
yield platform, item
|
||||
|
||||
|
||||
def extract_domain_configs(config: ConfigType, domain: str) -> List[str]:
|
||||
def extract_domain_configs(config: ConfigType, domain: str) -> Sequence[str]:
|
||||
"""Extract keys from config for given domain name."""
|
||||
pattern = re.compile(r'^{}(| .+)$'.format(domain))
|
||||
return [key for key in config.keys() if pattern.match(key)]
|
||||
|
|
|
@ -4,7 +4,7 @@ from datetime import timedelta
|
|||
import os
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from typing import Any, Union, TypeVar, Callable, Sequence, List, Dict
|
||||
from typing import Any, Union, TypeVar, Callable, Sequence, Dict
|
||||
|
||||
import jinja2
|
||||
import voluptuous as vol
|
||||
|
@ -80,7 +80,7 @@ def isfile(value: Any) -> str:
|
|||
return file_in
|
||||
|
||||
|
||||
def ensure_list(value: Union[T, Sequence[T]]) -> List[T]:
|
||||
def ensure_list(value: Union[T, Sequence[T]]) -> Sequence[T]:
|
||||
"""Wrap value in list if it is not one."""
|
||||
return value if isinstance(value, list) else [value]
|
||||
|
||||
|
@ -93,7 +93,7 @@ def entity_id(value: Any) -> str:
|
|||
raise vol.Invalid('Entity ID {} is an invalid entity id'.format(value))
|
||||
|
||||
|
||||
def entity_ids(value: Union[str, Sequence]) -> List[str]:
|
||||
def entity_ids(value: Union[str, Sequence]) -> Sequence[str]:
|
||||
"""Validate Entity IDs."""
|
||||
if value is None:
|
||||
raise vol.Invalid('Entity IDs can not be None')
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
"""The tests for the input_boolean component."""
|
||||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
from homeassistant.components import input_boolean
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components.input_boolean import (
|
||||
DOMAIN, is_on, toggle, turn_off, turn_on)
|
||||
from homeassistant.const import (
|
||||
STATE_ON, STATE_OFF, ATTR_ICON, ATTR_FRIENDLY_NAME)
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestInputBoolean(unittest.TestCase):
|
||||
|
@ -22,68 +27,63 @@ class TestInputBoolean(unittest.TestCase):
|
|||
|
||||
def test_config(self):
|
||||
"""Test config."""
|
||||
self.assertFalse(input_boolean.setup(self.hass, {
|
||||
'input_boolean': None
|
||||
}))
|
||||
invalid_configs = [
|
||||
None,
|
||||
1,
|
||||
{},
|
||||
{'name with space': None},
|
||||
]
|
||||
|
||||
self.assertFalse(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
'name with space': None
|
||||
}
|
||||
}))
|
||||
for cfg in invalid_configs:
|
||||
self.assertFalse(
|
||||
setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
|
||||
|
||||
def test_methods(self):
|
||||
"""Test is_on, turn_on, turn_off methods."""
|
||||
self.assertTrue(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
|
||||
'test_1': None,
|
||||
}
|
||||
}))
|
||||
}}))
|
||||
entity_id = 'input_boolean.test_1'
|
||||
|
||||
self.assertFalse(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
is_on(self.hass, entity_id))
|
||||
|
||||
input_boolean.turn_on(self.hass, entity_id)
|
||||
turn_on(self.hass, entity_id)
|
||||
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertTrue(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
is_on(self.hass, entity_id))
|
||||
|
||||
input_boolean.turn_off(self.hass, entity_id)
|
||||
turn_off(self.hass, entity_id)
|
||||
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertFalse(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
is_on(self.hass, entity_id))
|
||||
|
||||
input_boolean.toggle(self.hass, entity_id)
|
||||
toggle(self.hass, entity_id)
|
||||
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertTrue(
|
||||
input_boolean.is_on(self.hass, entity_id))
|
||||
self.assertTrue(is_on(self.hass, entity_id))
|
||||
|
||||
def test_config_options(self):
|
||||
"""Test configuration options."""
|
||||
count_start = len(self.hass.states.entity_ids())
|
||||
|
||||
self.assertTrue(input_boolean.setup(self.hass, {
|
||||
'input_boolean': {
|
||||
_LOGGER.debug('ENTITIES @ start: %s', self.hass.states.entity_ids())
|
||||
|
||||
self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
|
||||
'test_1': None,
|
||||
'test_2': {
|
||||
'name': 'Hello World',
|
||||
'icon': 'work',
|
||||
'icon': 'mdi:work',
|
||||
'initial': True,
|
||||
},
|
||||
},
|
||||
}))
|
||||
}}))
|
||||
|
||||
_LOGGER.debug('ENTITIES: %s', self.hass.states.entity_ids())
|
||||
|
||||
self.assertEqual(count_start + 2, len(self.hass.states.entity_ids()))
|
||||
|
||||
|
@ -100,4 +100,4 @@ class TestInputBoolean(unittest.TestCase):
|
|||
self.assertEqual(STATE_ON, state_2.state)
|
||||
self.assertEqual('Hello World',
|
||||
state_2.attributes.get(ATTR_FRIENDLY_NAME))
|
||||
self.assertEqual('work', state_2.attributes.get(ATTR_ICON))
|
||||
self.assertEqual('mdi:work', state_2.attributes.get(ATTR_ICON))
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import unittest
|
||||
|
||||
from homeassistant.components import input_select
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components.input_select import (
|
||||
ATTR_OPTIONS, DOMAIN, select_option)
|
||||
from homeassistant.const import (
|
||||
ATTR_ICON, ATTR_FRIENDLY_NAME)
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class TestInputSelect(unittest.TestCase):
|
||||
"""Test the input select component."""
|
||||
|
@ -22,59 +24,44 @@ class TestInputSelect(unittest.TestCase):
|
|||
|
||||
def test_config(self):
|
||||
"""Test config."""
|
||||
self.assertFalse(input_select.setup(self.hass, {
|
||||
'input_select': None
|
||||
}))
|
||||
invalid_configs = [
|
||||
None,
|
||||
{},
|
||||
{'name with space': None},
|
||||
# {'bad_options': {'options': None}},
|
||||
{'bad_initial': {
|
||||
'options': [1, 2],
|
||||
'initial': 3,
|
||||
}},
|
||||
]
|
||||
|
||||
self.assertFalse(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
'name with space': None
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
'hello': {
|
||||
'options': None
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
'hello': None
|
||||
}
|
||||
}))
|
||||
for cfg in invalid_configs:
|
||||
self.assertFalse(
|
||||
setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
|
||||
|
||||
def test_select_option(self):
|
||||
"""Test select_option methods."""
|
||||
self.assertTrue(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
self.assertTrue(
|
||||
setup_component(self.hass, DOMAIN, {DOMAIN: {
|
||||
'test_1': {
|
||||
'options': [
|
||||
'some option',
|
||||
'another option',
|
||||
],
|
||||
},
|
||||
}
|
||||
}))
|
||||
}}))
|
||||
entity_id = 'input_select.test_1'
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual('some option', state.state)
|
||||
|
||||
input_select.select_option(self.hass, entity_id, 'another option')
|
||||
select_option(self.hass, entity_id, 'another option')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual('another option', state.state)
|
||||
|
||||
input_select.select_option(self.hass, entity_id, 'non existing option')
|
||||
select_option(self.hass, entity_id, 'non existing option')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
|
@ -90,8 +77,8 @@ class TestInputSelect(unittest.TestCase):
|
|||
'Best Option',
|
||||
]
|
||||
|
||||
self.assertTrue(input_select.setup(self.hass, {
|
||||
'input_select': {
|
||||
self.assertTrue(setup_component(self.hass, DOMAIN, {
|
||||
DOMAIN: {
|
||||
'test_1': {
|
||||
'options': [
|
||||
1,
|
||||
|
@ -100,11 +87,11 @@ class TestInputSelect(unittest.TestCase):
|
|||
},
|
||||
'test_2': {
|
||||
'name': 'Hello World',
|
||||
'icon': 'work',
|
||||
'icon': 'mdi:work',
|
||||
'options': test_2_options,
|
||||
'initial': 'Better Option',
|
||||
},
|
||||
},
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertEqual(count_start + 2, len(self.hass.states.entity_ids()))
|
||||
|
@ -117,13 +104,12 @@ class TestInputSelect(unittest.TestCase):
|
|||
|
||||
self.assertEqual('1', state_1.state)
|
||||
self.assertEqual(['1', '2'],
|
||||
state_1.attributes.get(input_select.ATTR_OPTIONS))
|
||||
state_1.attributes.get(ATTR_OPTIONS))
|
||||
self.assertNotIn(ATTR_ICON, state_1.attributes)
|
||||
self.assertNotIn(ATTR_FRIENDLY_NAME, state_1.attributes)
|
||||
|
||||
self.assertEqual('Better Option', state_2.state)
|
||||
self.assertEqual(test_2_options,
|
||||
state_2.attributes.get(input_select.ATTR_OPTIONS))
|
||||
state_2.attributes.get(ATTR_OPTIONS))
|
||||
self.assertEqual('Hello World',
|
||||
state_2.attributes.get(ATTR_FRIENDLY_NAME))
|
||||
self.assertEqual('work', state_2.attributes.get(ATTR_ICON))
|
||||
self.assertEqual('mdi:work', state_2.attributes.get(ATTR_ICON))
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import unittest
|
||||
|
||||
from homeassistant.components import input_slider
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components.input_slider import (DOMAIN, select_value)
|
||||
|
||||
|
||||
class TestInputSlider(unittest.TestCase):
|
||||
"""Test the input slider component."""
|
||||
|
@ -20,50 +21,46 @@ class TestInputSlider(unittest.TestCase):
|
|||
|
||||
def test_config(self):
|
||||
"""Test config."""
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': None
|
||||
}))
|
||||
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
}
|
||||
}))
|
||||
|
||||
self.assertFalse(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
'name with space': None
|
||||
}
|
||||
}))
|
||||
invalid_configs = [
|
||||
None,
|
||||
{},
|
||||
{'name with space': None},
|
||||
{'test_1': {
|
||||
'min': 50,
|
||||
'max': 50,
|
||||
}},
|
||||
]
|
||||
for cfg in invalid_configs:
|
||||
self.assertFalse(
|
||||
setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
|
||||
|
||||
def test_select_value(self):
|
||||
"""Test select_value method."""
|
||||
self.assertTrue(input_slider.setup(self.hass, {
|
||||
'input_slider': {
|
||||
self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
|
||||
'test_1': {
|
||||
'initial': 50,
|
||||
'min': 0,
|
||||
'max': 100,
|
||||
},
|
||||
}
|
||||
}))
|
||||
}}))
|
||||
entity_id = 'input_slider.test_1'
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual(50, float(state.state))
|
||||
|
||||
input_slider.select_value(self.hass, entity_id, '30.4')
|
||||
select_value(self.hass, entity_id, '30.4')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual(30.4, float(state.state))
|
||||
|
||||
input_slider.select_value(self.hass, entity_id, '70')
|
||||
select_value(self.hass, entity_id, '70')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
self.assertEqual(70, float(state.state))
|
||||
|
||||
input_slider.select_value(self.hass, entity_id, '110')
|
||||
select_value(self.hass, entity_id, '110')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get(entity_id)
|
||||
|
|
Loading…
Reference in New Issue