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 behaviour
pull/3492/head
Johann Kellerman 2016-09-23 09:12:11 +02:00 committed by Paulus Schoutsen
parent de51cfbc07
commit 9631179126
9 changed files with 166 additions and 185 deletions

View File

@ -145,7 +145,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
if hasattr(component, 'CONFIG_SCHEMA'): if hasattr(component, 'CONFIG_SCHEMA'):
try: try:
config = component.CONFIG_SCHEMA(config) config = component.CONFIG_SCHEMA(config)
except vol.MultipleInvalid as ex: except vol.Invalid as ex:
log_exception(ex, domain, config) log_exception(ex, domain, config)
return None return None
@ -155,8 +155,8 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
# Validate component specific platform schema # Validate component specific platform schema
try: try:
p_validated = component.PLATFORM_SCHEMA(p_config) p_validated = component.PLATFORM_SCHEMA(p_config)
except vol.MultipleInvalid as ex: except vol.Invalid as ex:
log_exception(ex, domain, p_config) log_exception(ex, domain, config)
return None return None
# Not all platform components follow same pattern for platforms # 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'): if hasattr(platform, 'PLATFORM_SCHEMA'):
try: try:
p_validated = platform.PLATFORM_SCHEMA(p_validated) p_validated = platform.PLATFORM_SCHEMA(p_validated)
except vol.MultipleInvalid as ex: except vol.Invalid as ex:
log_exception(ex, '{}.{}'.format(domain, p_name), log_exception(ex, '{}.{}'.format(domain, p_name),
p_validated) p_validated)
return None return None

View File

@ -9,12 +9,11 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_TOGGLE, ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON,
STATE_ON) SERVICE_TOGGLE, STATE_ON)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.util import slugify
DOMAIN = 'input_boolean' DOMAIN = 'input_boolean'
@ -22,14 +21,19 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_NAME = "name" CONF_INITIAL = 'initial'
CONF_INITIAL = "initial"
CONF_ICON = "icon"
SERVICE_SCHEMA = vol.Schema({ SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, 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): def is_on(hass, entity_id):
"""Test if input_boolean is True.""" """Test if input_boolean is True."""
@ -53,19 +57,11 @@ def toggle(hass, entity_id):
def setup(hass, config): def setup(hass, config):
"""Set up input boolean.""" """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) component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = [] entities = []
for object_id, cfg in config[DOMAIN].items(): 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: if not cfg:
cfg = {} cfg = {}

View File

@ -8,19 +8,17 @@ import logging
import voluptuous as vol 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 import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.util import slugify
DOMAIN = 'input_select' DOMAIN = 'input_select'
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_NAME = 'name'
CONF_INITIAL = 'initial' CONF_INITIAL = 'initial'
CONF_ICON = 'icon'
CONF_OPTIONS = 'options' CONF_OPTIONS = 'options'
ATTR_OPTION = 'option' 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): def select_option(hass, entity_id, option):
"""Set input_select to False.""" """Set input_select to False."""
hass.services.call(DOMAIN, SERVICE_SELECT_OPTION, { hass.services.call(DOMAIN, SERVICE_SELECT_OPTION, {
@ -44,39 +62,15 @@ def select_option(hass, entity_id, option):
def setup(hass, config): def setup(hass, config):
"""Setup input select.""" """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) component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = [] entities = []
for object_id, cfg in config[DOMAIN].items(): 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) name = cfg.get(CONF_NAME)
options = cfg.get(CONF_OPTIONS) options = cfg.get(CONF_OPTIONS)
state = cfg.get(CONF_INITIAL, options[0])
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]
icon = cfg.get(CONF_ICON) icon = cfg.get(CONF_ICON)
entities.append(InputSelect(object_id, name, state, options, icon)) entities.append(InputSelect(object_id, name, state, options, icon))
if not entities: if not entities:

View File

@ -8,21 +8,19 @@ import logging
import voluptuous as vol 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 import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.util import slugify
DOMAIN = 'input_slider' DOMAIN = 'input_slider'
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_NAME = 'name'
CONF_INITIAL = 'initial' CONF_INITIAL = 'initial'
CONF_MIN = 'min' CONF_MIN = 'min'
CONF_MAX = 'max' CONF_MAX = 'max'
CONF_ICON = 'icon'
CONF_STEP = 'step' CONF_STEP = 'step'
ATTR_VALUE = 'value' 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): def select_value(hass, entity_id, value):
"""Set input_slider to value.""" """Set input_slider to value."""
hass.services.call(DOMAIN, SERVICE_SELECT_VALUE, { hass.services.call(DOMAIN, SERVICE_SELECT_VALUE, {
@ -48,36 +73,19 @@ def select_value(hass, entity_id, value):
def setup(hass, config): def setup(hass, config):
"""Set up input slider.""" """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) component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = [] entities = []
for object_id, cfg in config[DOMAIN].items(): 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) name = cfg.get(CONF_NAME)
minimum = cfg.get(CONF_MIN) minimum = cfg.get(CONF_MIN)
maximum = cfg.get(CONF_MAX) maximum = cfg.get(CONF_MAX)
state = cfg.get(CONF_INITIAL, minimum) state = cfg.get(CONF_INITIAL, minimum)
step = cfg.get(CONF_STEP, 1) step = cfg.get(CONF_STEP)
icon = cfg.get(CONF_ICON) icon = cfg.get(CONF_ICON)
unit = cfg.get(ATTR_UNIT_OF_MEASUREMENT) 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, entities.append(InputSlider(object_id, name, state, minimum, maximum,
step, icon, unit)) step, icon, unit))

View File

@ -1,12 +1,12 @@
"""Helper methods for components within Home Assistant.""" """Helper methods for components within Home Assistant."""
import re import re
from typing import Any, Iterable, Tuple, List, Dict from typing import Any, Iterable, Tuple, Sequence, Dict
from homeassistant.const import CONF_PLATFORM from homeassistant.const import CONF_PLATFORM
# Typing Imports and TypeAlias # Typing Imports and TypeAlias
# pylint: disable=using-constant-test,unused-import # pylint: disable=using-constant-test,unused-import,wrong-import-order
if False: if False:
from logging import Logger # NOQA from logging import Logger # NOQA
@ -34,7 +34,7 @@ def config_per_platform(config: ConfigType,
yield platform, item 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.""" """Extract keys from config for given domain name."""
pattern = re.compile(r'^{}(| .+)$'.format(domain)) pattern = re.compile(r'^{}(| .+)$'.format(domain))
return [key for key in config.keys() if pattern.match(key)] return [key for key in config.keys() if pattern.match(key)]

View File

@ -4,7 +4,7 @@ from datetime import timedelta
import os import os
from urllib.parse import urlparse 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 jinja2
import voluptuous as vol import voluptuous as vol
@ -80,7 +80,7 @@ def isfile(value: Any) -> str:
return file_in 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.""" """Wrap value in list if it is not one."""
return value if isinstance(value, list) else [value] 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)) 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.""" """Validate Entity IDs."""
if value is None: if value is None:
raise vol.Invalid('Entity IDs can not be None') raise vol.Invalid('Entity IDs can not be None')

View File

@ -1,12 +1,17 @@
"""The tests for the input_boolean component.""" """The tests for the input_boolean component."""
# pylint: disable=too-many-public-methods,protected-access # pylint: disable=too-many-public-methods,protected-access
import unittest 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 ( from homeassistant.const import (
STATE_ON, STATE_OFF, ATTR_ICON, ATTR_FRIENDLY_NAME) 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): class TestInputBoolean(unittest.TestCase):
@ -22,68 +27,63 @@ class TestInputBoolean(unittest.TestCase):
def test_config(self): def test_config(self):
"""Test config.""" """Test config."""
self.assertFalse(input_boolean.setup(self.hass, { invalid_configs = [
'input_boolean': None None,
})) 1,
{},
{'name with space': None},
]
self.assertFalse(input_boolean.setup(self.hass, { for cfg in invalid_configs:
'input_boolean': { self.assertFalse(
} setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
}))
self.assertFalse(input_boolean.setup(self.hass, {
'input_boolean': {
'name with space': None
}
}))
def test_methods(self): def test_methods(self):
"""Test is_on, turn_on, turn_off methods.""" """Test is_on, turn_on, turn_off methods."""
self.assertTrue(input_boolean.setup(self.hass, { self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
'input_boolean': { 'test_1': None,
'test_1': None, }}))
}
}))
entity_id = 'input_boolean.test_1' entity_id = 'input_boolean.test_1'
self.assertFalse( 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.hass.block_till_done()
self.assertTrue( 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.hass.block_till_done()
self.assertFalse( 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.hass.block_till_done()
self.assertTrue( self.assertTrue(is_on(self.hass, entity_id))
input_boolean.is_on(self.hass, entity_id))
def test_config_options(self): def test_config_options(self):
"""Test configuration options.""" """Test configuration options."""
count_start = len(self.hass.states.entity_ids()) count_start = len(self.hass.states.entity_ids())
self.assertTrue(input_boolean.setup(self.hass, { _LOGGER.debug('ENTITIES @ start: %s', self.hass.states.entity_ids())
'input_boolean': {
'test_1': None, self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
'test_2': { 'test_1': None,
'name': 'Hello World', 'test_2': {
'icon': 'work', 'name': 'Hello World',
'initial': True, '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())) 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(STATE_ON, state_2.state)
self.assertEqual('Hello World', self.assertEqual('Hello World',
state_2.attributes.get(ATTR_FRIENDLY_NAME)) 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))

View File

@ -2,12 +2,14 @@
# pylint: disable=too-many-public-methods,protected-access # pylint: disable=too-many-public-methods,protected-access
import unittest 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 ( from homeassistant.const import (
ATTR_ICON, ATTR_FRIENDLY_NAME) ATTR_ICON, ATTR_FRIENDLY_NAME)
from tests.common import get_test_home_assistant
class TestInputSelect(unittest.TestCase): class TestInputSelect(unittest.TestCase):
"""Test the input select component.""" """Test the input select component."""
@ -22,59 +24,44 @@ class TestInputSelect(unittest.TestCase):
def test_config(self): def test_config(self):
"""Test config.""" """Test config."""
self.assertFalse(input_select.setup(self.hass, { invalid_configs = [
'input_select': None None,
})) {},
{'name with space': None},
# {'bad_options': {'options': None}},
{'bad_initial': {
'options': [1, 2],
'initial': 3,
}},
]
self.assertFalse(input_select.setup(self.hass, { for cfg in invalid_configs:
'input_select': { self.assertFalse(
} setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
}))
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
}
}))
def test_select_option(self): def test_select_option(self):
"""Test select_option methods.""" """Test select_option methods."""
self.assertTrue(input_select.setup(self.hass, { self.assertTrue(
'input_select': { setup_component(self.hass, DOMAIN, {DOMAIN: {
'test_1': { 'test_1': {
'options': [ 'options': [
'some option', 'some option',
'another option', 'another option',
], ],
}, },
} }}))
}))
entity_id = 'input_select.test_1' entity_id = 'input_select.test_1'
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
self.assertEqual('some option', state.state) 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() self.hass.block_till_done()
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
self.assertEqual('another option', state.state) 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() self.hass.block_till_done()
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
@ -90,8 +77,8 @@ class TestInputSelect(unittest.TestCase):
'Best Option', 'Best Option',
] ]
self.assertTrue(input_select.setup(self.hass, { self.assertTrue(setup_component(self.hass, DOMAIN, {
'input_select': { DOMAIN: {
'test_1': { 'test_1': {
'options': [ 'options': [
1, 1,
@ -100,11 +87,11 @@ class TestInputSelect(unittest.TestCase):
}, },
'test_2': { 'test_2': {
'name': 'Hello World', 'name': 'Hello World',
'icon': 'work', 'icon': 'mdi:work',
'options': test_2_options, 'options': test_2_options,
'initial': 'Better Option', 'initial': 'Better Option',
}, },
}, }
})) }))
self.assertEqual(count_start + 2, len(self.hass.states.entity_ids())) 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', state_1.state)
self.assertEqual(['1', '2'], 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_ICON, state_1.attributes)
self.assertNotIn(ATTR_FRIENDLY_NAME, state_1.attributes)
self.assertEqual('Better Option', state_2.state) self.assertEqual('Better Option', state_2.state)
self.assertEqual(test_2_options, self.assertEqual(test_2_options,
state_2.attributes.get(input_select.ATTR_OPTIONS)) state_2.attributes.get(ATTR_OPTIONS))
self.assertEqual('Hello World', self.assertEqual('Hello World',
state_2.attributes.get(ATTR_FRIENDLY_NAME)) 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))

View File

@ -2,10 +2,11 @@
# pylint: disable=too-many-public-methods,protected-access # pylint: disable=too-many-public-methods,protected-access
import unittest import unittest
from homeassistant.components import input_slider
from tests.common import get_test_home_assistant 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): class TestInputSlider(unittest.TestCase):
"""Test the input slider component.""" """Test the input slider component."""
@ -20,50 +21,46 @@ class TestInputSlider(unittest.TestCase):
def test_config(self): def test_config(self):
"""Test config.""" """Test config."""
self.assertFalse(input_slider.setup(self.hass, { invalid_configs = [
'input_slider': None None,
})) {},
{'name with space': None},
self.assertFalse(input_slider.setup(self.hass, { {'test_1': {
'input_slider': { 'min': 50,
} 'max': 50,
})) }},
]
self.assertFalse(input_slider.setup(self.hass, { for cfg in invalid_configs:
'input_slider': { self.assertFalse(
'name with space': None setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))
}
}))
def test_select_value(self): def test_select_value(self):
"""Test select_value method.""" """Test select_value method."""
self.assertTrue(input_slider.setup(self.hass, { self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: {
'input_slider': { 'test_1': {
'test_1': { 'initial': 50,
'initial': 50, 'min': 0,
'min': 0, 'max': 100,
'max': 100, },
}, }}))
}
}))
entity_id = 'input_slider.test_1' entity_id = 'input_slider.test_1'
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
self.assertEqual(50, float(state.state)) 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() self.hass.block_till_done()
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
self.assertEqual(30.4, float(state.state)) 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() self.hass.block_till_done()
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
self.assertEqual(70, float(state.state)) 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() self.hass.block_till_done()
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)