From 0631f5c59df0ee7ffdb627832022cbbcf6b46bee Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 06:44:22 -0500 Subject: [PATCH 01/17] Added tests for package utilities --- tests/util/test_package.py | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/util/test_package.py diff --git a/tests/util/test_package.py b/tests/util/test_package.py new file mode 100644 index 00000000000..1ffd66e1bb4 --- /dev/null +++ b/tests/util/test_package.py @@ -0,0 +1,58 @@ +""" +Tests Home Assistant package util methods. +""" +import unittest +import sys +import tempfile +import homeassistant.util.package as package + +TEST_EXIST_REQ = "pip>=7.0.0" +TEST_NEW_REQ = "pyhelloworld3==1.0.0" +TEST_ZIP_REQ = \ + "https://github.com/rmkraus/pyhelloworld3/archive/" \ + "5ba878316d68ea164e2cf5bd085d0cf1fd76bd15.zip#pyhelloworld3==1.0.0" + + +class TestPackageUtil(unittest.TestCase): + """ Tests for homeassistant.util.package module """ + + def setUp(self): + """ Create local library for testing """ + self.lib_dir = tempfile.TemporaryDirectory() + + def tearDown(self): + """ Remove local library """ + del self.lib_dir + + def test_install_existing_package(self): + """ Test an install attempt on an existing package """ + self.assertTrue(package.check_package_exists( + TEST_EXIST_REQ, self.lib_dir.name)) + + self.assertTrue(package.install_package(TEST_EXIST_REQ)) + + def test_install_package_locally(self): + """ Test an install attempt to the local library """ + self.assertFalse(package.check_package_exists( + TEST_NEW_REQ, self.lib_dir.name)) + + self.assertTrue(package.install_package( + TEST_NEW_REQ, True, self.lib_dir.name)) + + sys.path.insert(0, self.lib_dir.name) + import pyhelloworld3 + + self.assertEqual(pyhelloworld3.__version__, '1.0.0') + + def test_install_package_zip(self): + """ Test an install attempt from a zip path """ + self.assertFalse(package.check_package_exists( + TEST_ZIP_REQ, self.lib_dir.name)) + + self.assertTrue(package.install_package( + TEST_ZIP_REQ, True, self.lib_dir.name)) + + sys.path.insert(0, self.lib_dir.name) + import pyhelloworld3 + + self.assertEqual(pyhelloworld3.__version__, '1.0.0') From c396dbb570d55b9f3c653f1bebdf5110559b724e Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 07:18:37 -0500 Subject: [PATCH 02/17] Added tests to check setup and config of universal media player. --- .../components/media_player/test_universal.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/components/media_player/test_universal.py b/tests/components/media_player/test_universal.py index eca863b935e..26e8b517936 100644 --- a/tests/components/media_player/test_universal.py +++ b/tests/components/media_player/test_universal.py @@ -135,6 +135,65 @@ class TestMediaPlayer(unittest.TestCase): self.assertTrue(response) self.assertEqual(config_start, self.config_children_and_attr) + def test_check_config_no_name(self): + """ Check config with no Name entry """ + response = universal.validate_config({'platform': 'universal'}) + + self.assertFalse(response) + + def test_check_config_bad_children(self): + """ Check config with bad children entry """ + config_no_children = {'name': 'test', 'platform': 'universal'} + config_bad_children = {'name': 'test', 'children': {}, + 'platform': 'universal'} + + response = universal.validate_config(config_no_children) + self.assertTrue(response) + self.assertEqual(config_no_children['children'], []) + + response = universal.validate_config(config_bad_children) + self.assertTrue(response) + self.assertEqual(config_bad_children['children'], []) + + def test_check_config_bad_commands(self): + """ Check config with bad commands entry """ + config = {'name': 'test', 'commands': [], 'platform': 'universal'} + + response = universal.validate_config(config) + self.assertTrue(response) + self.assertEqual(config['commands'], {}) + + def test_check_config_bad_attributes(self): + """ Check config with bad attributes """ + config = {'name': 'test', 'atttributes': [], 'platform': 'universal'} + + response = universal.validate_config(config) + self.assertTrue(response) + self.assertEqual(config['attributes'], {}) + + def test_check_config_bad_key(self): + """ check config with bad key """ + config = {'name': 'test', 'asdf': 5, 'platform': 'universal'} + + response = universal.validate_config(config) + self.assertTrue(response) + self.assertFalse('asdf' in config) + + def test_platform_setup(self): + """ test platform setup """ + config = {'name': 'test', 'platform': 'universal'} + entities = [] + + def add_devices(new_entities): + """ add devices to list """ + for dev in new_entities: + entities.append(dev) + + universal.setup_platform(self.hass, config, add_devices) + + self.assertEqual(len(entities), 1) + self.assertEqual(entities[0].name, 'test') + def test_master_state(self): """ test master state property """ config = self.config_children_only From c1d057407b20496b09ed3903e65210030db792bd Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 11:53:15 -0500 Subject: [PATCH 03/17] Fixed typo in universal media player test. --- tests/components/media_player/test_universal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/media_player/test_universal.py b/tests/components/media_player/test_universal.py index 26e8b517936..6600f9091ed 100644 --- a/tests/components/media_player/test_universal.py +++ b/tests/components/media_player/test_universal.py @@ -165,7 +165,7 @@ class TestMediaPlayer(unittest.TestCase): def test_check_config_bad_attributes(self): """ Check config with bad attributes """ - config = {'name': 'test', 'atttributes': [], 'platform': 'universal'} + config = {'name': 'test', 'attributes': [], 'platform': 'universal'} response = universal.validate_config(config) self.assertTrue(response) From 6a75b524cb66ca6064d7765cb6879afb2dc9abc4 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 11:57:46 -0500 Subject: [PATCH 04/17] Removed unused private method from universal media player MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The universal media player contained a private method that was replaced by the update method. It was meant to be removed and wasn’t. This commit removed that method. --- homeassistant/components/media_player/universal.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/homeassistant/components/media_player/universal.py b/homeassistant/components/media_player/universal.py index 09bb12ec332..359249f15e2 100644 --- a/homeassistant/components/media_player/universal.py +++ b/homeassistant/components/media_player/universal.py @@ -215,15 +215,6 @@ class UniversalMediaPlayer(MediaPlayerDevice): else: return None - def _cache_active_child_state(self): - """ The state of the active child or None """ - for child_name in self._children: - child_state = self.hass.states.get(child_name) - if child_state and child_state.state not in OFF_STATES: - self._child_state = child_state - return - self._child_state = None - @property def name(self): """ name of universal player """ From 8ac763c6f6f9b9fae2c9a849bd07cd2835d912de Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 12:26:28 -0500 Subject: [PATCH 05/17] Added test for universal mp service routing. Added tests to ensure that the Universal Media Player is routing service calls correctly. --- .../components/media_player/test_universal.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/components/media_player/test_universal.py b/tests/components/media_player/test_universal.py index 6600f9091ed..9ed0193959e 100644 --- a/tests/components/media_player/test_universal.py +++ b/tests/components/media_player/test_universal.py @@ -14,6 +14,8 @@ import homeassistant.components.switch as switch import homeassistant.components.media_player as media_player import homeassistant.components.media_player.universal as universal +from tests.common import mock_service + class MockMediaPlayer(media_player.MediaPlayerDevice): """ Mock media player for testing """ @@ -28,6 +30,9 @@ class MockMediaPlayer(media_player.MediaPlayerDevice): self._media_title = None self._supported_media_commands = 0 + self.turn_off_service_calls = mock_service( + hass, media_player.DOMAIN, media_player.SERVICE_TURN_OFF) + @property def name(self): """ name of player """ @@ -399,3 +404,38 @@ class TestMediaPlayer(unittest.TestCase): | universal.SUPPORT_VOLUME_STEP | universal.SUPPORT_VOLUME_MUTE self.assertEqual(check_flags, ump.supported_media_commands) + + def test_service_call_to_child(self): + """ test a service call that should be routed to a child """ + config = self.config_children_only + universal.validate_config(config) + + ump = universal.UniversalMediaPlayer(self.hass, **config) + ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) + ump.update() + + self.mock_mp_2._state = STATE_PLAYING + self.mock_mp_2.update_ha_state() + ump.update() + + ump.turn_off() + self.assertEqual(len(self.mock_mp_2.turn_off_service_calls), 1) + + def test_service_call_to_command(self): + config = self.config_children_only + config['commands'] = \ + {'turn_off': {'service': 'test.turn_off', 'data': {}}} + universal.validate_config(config) + + service = mock_service(self.hass, 'test', 'turn_off') + + ump = universal.UniversalMediaPlayer(self.hass, **config) + ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) + ump.update() + + self.mock_mp_2._state = STATE_PLAYING + self.mock_mp_2.update_ha_state() + ump.update() + + ump.turn_off() + self.assertEqual(len(service), 1) From 4cc9606bcc11f579437228ba25a9d90c073ebfbb Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 13:03:46 -0500 Subject: [PATCH 06/17] Added test for logger component. --- tests/components/test_logger.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/components/test_logger.py diff --git a/tests/components/test_logger.py b/tests/components/test_logger.py new file mode 100644 index 00000000000..96aecc73a0e --- /dev/null +++ b/tests/components/test_logger.py @@ -0,0 +1,31 @@ +""" +tests.test_logger +~~~~~~~~~~~~~~~~~~ + +Tests logger component. +""" +import logging +import unittest + +from homeassistant.components import logger + + +class TestUpdater(unittest.TestCase): + """ Test logger component. """ + + def test_logger(self): + """ Uses logger to create a logging filter """ + config = {'logger': + {'default': 'warning', + 'logs': {'test': 'info'}}} + + logger.setup(None, config) + + self.assertTrue(len(logging.root.handlers) > 0) + handler = logging.root.handlers[-1] + + self.assertEqual(len(handler.filters), 1) + log_filter = handler.filters[0].logfilter + + self.assertEqual(log_filter['default'], logging.WARNING) + self.assertEqual(log_filter['logs']['test'], logging.INFO) From de61bcb80ec4a930b34312f68e35fcba321754f4 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 13:23:35 -0500 Subject: [PATCH 07/17] Additional testing for logger component Added an additional test for the logger component the validates the filtering logic of the filters that were created during setup. --- tests/components/test_logger.py | 42 ++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/tests/components/test_logger.py b/tests/components/test_logger.py index 96aecc73a0e..5e3aeda88d3 100644 --- a/tests/components/test_logger.py +++ b/tests/components/test_logger.py @@ -4,22 +4,30 @@ tests.test_logger Tests logger component. """ +from collections import namedtuple import logging import unittest from homeassistant.components import logger +RECORD = namedtuple('record', ('name', 'levelno')) + class TestUpdater(unittest.TestCase): """ Test logger component. """ - def test_logger(self): - """ Uses logger to create a logging filter """ - config = {'logger': - {'default': 'warning', - 'logs': {'test': 'info'}}} + def setUp(self): + """ Create default config """ + self.log_config = {'logger': + {'default': 'warning', 'logs': {'test': 'info'}}} - logger.setup(None, config) + def tearDown(self): + """ Reset logs """ + del logging.root.handlers[-1] + + def test_logger_setup(self): + """ Uses logger to create a logging filter """ + logger.setup(None, self.log_config) self.assertTrue(len(logging.root.handlers) > 0) handler = logging.root.handlers[-1] @@ -29,3 +37,25 @@ class TestUpdater(unittest.TestCase): self.assertEqual(log_filter['default'], logging.WARNING) self.assertEqual(log_filter['logs']['test'], logging.INFO) + + def test_logger_test_filters(self): + """ Tests resulting filter operation """ + logger.setup(None, self.log_config) + + log_filter = logging.root.handlers[-1].filters[0] + + # blocked default record + record = RECORD('asdf', logging.DEBUG) + self.assertFalse(log_filter.filter(record)) + + # allowed default record + record = RECORD('asdf', logging.WARNING) + self.assertTrue(log_filter.filter(record)) + + # blocked named record + record = RECORD('test', logging.DEBUG) + self.assertFalse(log_filter.filter(record)) + + # allowed named record + record = RECORD('test', logging.INFO) + self.assertTrue(log_filter.filter(record)) From 4a8f55e63043369fba32375fe53f0878e7da8b36 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 14:08:32 -0500 Subject: [PATCH 08/17] Revised package util tests The package util tests were revised to pull the external library pyhelloworld3 from an internal source rather than external. This speeds up tests, makes tests more reliable, and removes dependency on internet connection. --- tests/resources/pyhelloworld3.zip | Bin 0 -> 2100 bytes tests/util/test_package.py | 53 ++++++++++++++++-------------- 2 files changed, 28 insertions(+), 25 deletions(-) create mode 100644 tests/resources/pyhelloworld3.zip diff --git a/tests/resources/pyhelloworld3.zip b/tests/resources/pyhelloworld3.zip new file mode 100644 index 0000000000000000000000000000000000000000..f2a419e9f340dd870e1c729d06cbc9d622ef0e0f GIT binary patch literal 2100 zcmWIWW@h1H0D&)3b{=2`ln`a$WGJZ2NX^N~FV8Q^Nio*VO)M@+Ez%DSVP#;nox3J1 z07Y-^l&d{@K)oO=k4vv!dS*#xdR~4}D%_N$(#)I`E@YeZQq$9QGxO5&xwP~ODwDb5 zS0-R`&L7FK63T&IeYX+c)sMV4+h?48qcYTCxBZFlzdalcimxb*wiF^Ln$oz86Xe)y8B zpnu-XRY~8@PoK~E()TEnjaF-~p@(DcYtyqY%%{GXy6k@LmzBL9p8MUnSH)U7^Tqmg z@0i4T*{->m_j>50;)=r$liaQO7#4cC{LXL9J`*HjT_}5y9TrLuzkTxjvM&wjuL>YG zATE>;=^NR1!C@D!UJCU%=YR5y_x7L*3ln2skhGcd^Fa(r=WNofJHOKT_jX5TRoXnX%pG)X^i zVJH9F%!3znIZIw{<1F>!Q=Ac5ozwk-yEf;;{`VeX!ModEC7FCaWBtCzG(vZ#vwY9> zD2roDFJ9B1s1$$3W}(2Z(CCZxI$cw$!wsysRIWW$i?8#T$sKik>nih|ueY83xGi== zf@`ebJ?ZW1S55q_IcL4KuC{i(4oi6Msnu(AE80&5K5lNzbGr88;Ql7pvM3?R<_GGz zuRlHK>8kB6n(fjpWKp_&_Ow0R?>)V*RWkSKvE!Df)?Z}zcKdhZLRQZ8GwUWQ zuvp!aDA6}ia+WHe{@|{DyR$&fg=v*eJES6C@yPu)k84`g@A9*UR?Nb#b3! zN|nCcNL%;zp!44Z=4VBW^Q^qwlUG^(e#c^QoZYW}QJvSsic{6A-MNF@($xc!JKDZg zm)T$57P8Lw32(3JmQJ(C#|PQPcly8Ss&(Yg{=}}T+tGV(trTndWvShv;(1%Wnp|ui z&0Oo0{b_~Gs(EH*9JcOPRgb=De-^p;r=iP(b(Wi&4a4GBOnUdf-hAb+z9$NQm!_4; zJykl~cjb-?dvrAatq*!i`IBDD2L3s6UQEaRd->uwyWcVIoi_Dc@yC5Xcmuo{nSg~D zFx6t_c2F@40Rm7OC39jalu^w>FP1@u08<$d*Z?tBv#=D>2p3{6ctPetOx=LXRLo)+ zVJN1zL4_OyfV@2uXf{@-q6i`vd9XmhUg&{LhB)^zaVBFc0uj!~Uiu&`*$<3e6qmwc z4Mk8Nds&2T4SG3&u%-rBa-f(9vj(Ho2=HcQ1L Date: Sat, 30 Jan 2016 14:38:27 -0500 Subject: [PATCH 09/17] Cleaned up universal MP tests Changed all assertEquals in universal media player tests to have assumed value first. --- .../components/media_player/test_universal.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/components/media_player/test_universal.py b/tests/components/media_player/test_universal.py index 9ed0193959e..e359700f2fa 100644 --- a/tests/components/media_player/test_universal.py +++ b/tests/components/media_player/test_universal.py @@ -154,11 +154,11 @@ class TestMediaPlayer(unittest.TestCase): response = universal.validate_config(config_no_children) self.assertTrue(response) - self.assertEqual(config_no_children['children'], []) + self.assertEqual([], config_no_children['children']) response = universal.validate_config(config_bad_children) self.assertTrue(response) - self.assertEqual(config_bad_children['children'], []) + self.assertEqual([], config_bad_children['children']) def test_check_config_bad_commands(self): """ Check config with bad commands entry """ @@ -166,7 +166,7 @@ class TestMediaPlayer(unittest.TestCase): response = universal.validate_config(config) self.assertTrue(response) - self.assertEqual(config['commands'], {}) + self.assertEqual({}, config['commands']) def test_check_config_bad_attributes(self): """ Check config with bad attributes """ @@ -174,7 +174,7 @@ class TestMediaPlayer(unittest.TestCase): response = universal.validate_config(config) self.assertTrue(response) - self.assertEqual(config['attributes'], {}) + self.assertEqual({}, config['attributes']) def test_check_config_bad_key(self): """ check config with bad key """ @@ -196,8 +196,8 @@ class TestMediaPlayer(unittest.TestCase): universal.setup_platform(self.hass, config, add_devices) - self.assertEqual(len(entities), 1) - self.assertEqual(entities[0].name, 'test') + self.assertEqual(1, len(entities)) + self.assertEqual('test', entities[0].name) def test_master_state(self): """ test master state property """ @@ -294,20 +294,20 @@ class TestMediaPlayer(unittest.TestCase): ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name']) ump.update() - self.assertEqual(ump.state, STATE_OFF) + self.assertEqual(STATE_OFF, ump.state) self.hass.states.set(self.mock_state_switch_id, STATE_ON) ump.update() - self.assertEqual(ump.state, STATE_ON) + self.assertEqual(STATE_ON, ump.state) self.mock_mp_1._state = STATE_PLAYING self.mock_mp_1.update_ha_state() ump.update() - self.assertEqual(ump.state, STATE_PLAYING) + self.assertEqual(STATE_PLAYING, ump.state) self.hass.states.set(self.mock_state_switch_id, STATE_OFF) ump.update() - self.assertEqual(ump.state, STATE_OFF) + self.assertEqual(STATE_OFF, ump.state) def test_volume_level(self): """ test volume level property """ @@ -419,7 +419,7 @@ class TestMediaPlayer(unittest.TestCase): ump.update() ump.turn_off() - self.assertEqual(len(self.mock_mp_2.turn_off_service_calls), 1) + self.assertEqual(1, len(self.mock_mp_2.turn_off_service_calls)) def test_service_call_to_command(self): config = self.config_children_only @@ -438,4 +438,4 @@ class TestMediaPlayer(unittest.TestCase): ump.update() ump.turn_off() - self.assertEqual(len(service), 1) + self.assertEqual(1, len(service)) From 56ac4281c75bc450bc7ff182068b914d69d9202b Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 14:39:17 -0500 Subject: [PATCH 10/17] Better tear down of util/package tests Explicitly removed temp directory at the end of util/package unit tests. --- tests/util/test_package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/test_package.py b/tests/util/test_package.py index 7c10134c60a..db5a8a88e94 100644 --- a/tests/util/test_package.py +++ b/tests/util/test_package.py @@ -27,7 +27,7 @@ class TestPackageUtil(unittest.TestCase): def tearDown(self): """ Remove local library """ - del self.tmp_dir + self.tmp_dir.cleanup() def test_install_existing_package(self): """ Test an install attempt on an existing package """ From 265102146123a0495989c165475a7dc7fc340b6b Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 21:27:00 -0500 Subject: [PATCH 11/17] Added test for entity customization Added test for entity customization from configuration. Processes a sample configuration to hide an entity, creates the entity, updates ha state, and then verifies customization made it through. --- tests/test_bootstrap.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index a0c4da894f0..688e5fb0b41 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -11,8 +11,10 @@ import unittest from unittest import mock from homeassistant import core, bootstrap -from homeassistant.const import __version__ +from homeassistant.const import (__version__, CONF_LATITUDE, CONF_LONGITUDE, + CONF_NAME, CONF_CUSTOMIZE) import homeassistant.util.dt as dt_util +from homeassistant.helpers.entity import Entity from tests.common import mock_detect_location_info @@ -83,3 +85,23 @@ class TestBootstrap(unittest.TestCase): bootstrap.process_ha_config_upgrade(hass) self.assertTrue(os.path.isfile(check_file)) + + def test_entity_customization(self): + """ Test entity customization through config """ + config = {CONF_LATITUDE: 50, + CONF_LONGITUDE: 50, + CONF_NAME: 'Test', + CONF_CUSTOMIZE: {'test.test': {'hidden': True}}} + + hass = core.HomeAssistant() + + bootstrap.process_ha_core_config(hass, config) + + entity = Entity() + entity.entity_id = 'test.test' + entity.hass = hass + entity.update_ha_state() + + state = hass.states.get('test.test') + + self.assertTrue(state.attributes['hidden']) From 97e867052d2b88dc487e473ac681aaef27303247 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:01:10 -0500 Subject: [PATCH 12/17] Added tests for command sensor Added tests to create and check basic functionality of command sensor. --- .../components/sensor/test_command_sensor.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/components/sensor/test_command_sensor.py diff --git a/tests/components/sensor/test_command_sensor.py b/tests/components/sensor/test_command_sensor.py new file mode 100644 index 00000000000..7059e715ffb --- /dev/null +++ b/tests/components/sensor/test_command_sensor.py @@ -0,0 +1,45 @@ +""" +tests.components.sensor.command_sensor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tests command sensor. +""" + +import unittest + +import homeassistant.core as ha +from homeassistant.components.sensor import command_sensor + + +class TestCommandSensorSensor(unittest.TestCase): + """ Test the Template sensor. """ + + def setUp(self): + self.hass = ha.HomeAssistant() + + self.config = {'name': 'Test', + 'unit_of_measurement': 'in', + 'command': 'echo 5', + 'value_template': '{{ value }}'} + + def tearDown(self): + """ Stop down stuff we started. """ + self.hass.stop() + + def test_setup(self): + """ Test sensor setup """ + devices = [] + + def add_dev_callback(devs): + """ callback to add device """ + for dev in devs: + devices.append(dev) + + command_sensor.setup_platform( + self.hass, self.config, add_dev_callback) + + self.assertEqual(1, len(devices)) + entity = devices[0] + self.assertEqual('Test', entity.name) + self.assertEqual('in', entity.unit_of_measurement) + self.assertEqual('5', entity.state) From 6a08f1412048ad2578e71a60bc284b671de9eab4 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:13:42 -0500 Subject: [PATCH 13/17] Additional tests for Command Sensor. 1. Moved template testing out of main test. 2. Added test for bad command. --- .../components/sensor/test_command_sensor.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/components/sensor/test_command_sensor.py b/tests/components/sensor/test_command_sensor.py index 7059e715ffb..21cd10a5e46 100644 --- a/tests/components/sensor/test_command_sensor.py +++ b/tests/components/sensor/test_command_sensor.py @@ -17,17 +17,15 @@ class TestCommandSensorSensor(unittest.TestCase): def setUp(self): self.hass = ha.HomeAssistant() - self.config = {'name': 'Test', - 'unit_of_measurement': 'in', - 'command': 'echo 5', - 'value_template': '{{ value }}'} - def tearDown(self): """ Stop down stuff we started. """ self.hass.stop() def test_setup(self): """ Test sensor setup """ + config = {'name': 'Test', + 'unit_of_measurement': 'in', + 'command': 'echo 5'} devices = [] def add_dev_callback(devs): @@ -36,10 +34,26 @@ class TestCommandSensorSensor(unittest.TestCase): devices.append(dev) command_sensor.setup_platform( - self.hass, self.config, add_dev_callback) + self.hass, config, add_dev_callback) self.assertEqual(1, len(devices)) entity = devices[0] self.assertEqual('Test', entity.name) self.assertEqual('in', entity.unit_of_measurement) self.assertEqual('5', entity.state) + + def test_template(self): + """ Test command sensor with template """ + data = command_sensor.CommandSensorData('echo 50') + + entity = command_sensor.CommandSensor( + self.hass, data, 'test', 'in', '{{ value | multiply(0.1) }}') + + self.assertEqual(5, float(entity.state)) + + def test_bad_command(self): + """ Test bad command """ + data = command_sensor.CommandSensorData('asdfasdf') + data.update() + + self.assertEqual(None, data.value) From 2d0004f46aa6844b1de7690c20b5da72fa98d760 Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:16:22 -0500 Subject: [PATCH 14/17] Another test for for command sensor Added a test for command sensors with bad configurations. --- tests/components/sensor/test_command_sensor.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/components/sensor/test_command_sensor.py b/tests/components/sensor/test_command_sensor.py index 21cd10a5e46..ae6c9452d3f 100644 --- a/tests/components/sensor/test_command_sensor.py +++ b/tests/components/sensor/test_command_sensor.py @@ -42,6 +42,22 @@ class TestCommandSensorSensor(unittest.TestCase): self.assertEqual('in', entity.unit_of_measurement) self.assertEqual('5', entity.state) + def test_setup_bad_config(self): + """ Test setup with a bad config """ + config = {} + + devices = [] + + def add_dev_callback(devs): + """ callback to add device """ + for dev in devs: + devices.append(dev) + + self.assertFalse(command_sensor.setup_platform( + self.hass, config, add_dev_callback)) + + self.assertEqual(0, len(devices)) + def test_template(self): """ Test command sensor with template """ data = command_sensor.CommandSensorData('echo 50') From 283d621e90f2806487f50d01d094b0dc090d2dae Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:32:25 -0500 Subject: [PATCH 15/17] Added tests for Binary Command Sensor --- .../binary_sensor/test_command_sensor.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/components/binary_sensor/test_command_sensor.py diff --git a/tests/components/binary_sensor/test_command_sensor.py b/tests/components/binary_sensor/test_command_sensor.py new file mode 100644 index 00000000000..011946b1279 --- /dev/null +++ b/tests/components/binary_sensor/test_command_sensor.py @@ -0,0 +1,68 @@ +""" +tests.components.binary_sensor.command_sensor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tests command binary sensor. +""" + +import unittest + +import homeassistant.core as ha +from homeassistant.components.binary_sensor import command_sensor + + +class TestCommandSensorBinarySensor(unittest.TestCase): + """ Test the Template sensor. """ + + def setUp(self): + self.hass = ha.HomeAssistant() + + def tearDown(self): + """ Stop down stuff we started. """ + self.hass.stop() + + def test_setup(self): + """ Test sensor setup """ + config = {'name': 'Test', + 'command': 'echo 1', + 'payload_on': '1', + 'payload_off': '0'} + devices = [] + + def add_dev_callback(devs): + """ callback to add device """ + for dev in devs: + devices.append(dev) + + command_sensor.setup_platform( + self.hass, config, add_dev_callback) + + self.assertEqual(1, len(devices)) + entity = devices[0] + self.assertEqual('Test', entity.name) + self.assertTrue(entity.state) + + def test_setup_bad_config(self): + """ Test setup with a bad config """ + config = {} + + devices = [] + + def add_dev_callback(devs): + """ callback to add device """ + for dev in devs: + devices.append(dev) + + self.assertFalse(command_sensor.setup_platform( + self.hass, config, add_dev_callback)) + + self.assertEqual(0, len(devices)) + + def test_template(self): + """ Test command sensor with template """ + data = command_sensor.CommandSensorData('echo 10') + + entity = command_sensor.CommandBinarySensor( + self.hass, data, 'test', '1.0', '0', '{{ value | multiply(0.1) }}') + + self.assertTrue(entity.state) From 5fdbe5fd9ac8d99af306d6ac53342af41ee4170c Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:41:29 -0500 Subject: [PATCH 16/17] More tests for Binary Command Sensor 1. Added a test for detecting STATE_OFF 2. Fixed tests for detecting STATE_ON --- .../binary_sensor/test_command_sensor.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/components/binary_sensor/test_command_sensor.py b/tests/components/binary_sensor/test_command_sensor.py index 011946b1279..aa6a87c2061 100644 --- a/tests/components/binary_sensor/test_command_sensor.py +++ b/tests/components/binary_sensor/test_command_sensor.py @@ -8,6 +8,7 @@ Tests command binary sensor. import unittest import homeassistant.core as ha +from homeassistant.const import (STATE_ON, STATE_OFF) from homeassistant.components.binary_sensor import command_sensor @@ -40,7 +41,7 @@ class TestCommandSensorBinarySensor(unittest.TestCase): self.assertEqual(1, len(devices)) entity = devices[0] self.assertEqual('Test', entity.name) - self.assertTrue(entity.state) + self.assertEqual(STATE_ON, entity.state) def test_setup_bad_config(self): """ Test setup with a bad config """ @@ -65,4 +66,13 @@ class TestCommandSensorBinarySensor(unittest.TestCase): entity = command_sensor.CommandBinarySensor( self.hass, data, 'test', '1.0', '0', '{{ value | multiply(0.1) }}') - self.assertTrue(entity.state) + self.assertEqual(STATE_ON, entity.state) + + def test_sensor_off(self): + """ Test command sensor with template """ + data = command_sensor.CommandSensorData('echo 0') + + entity = command_sensor.CommandBinarySensor( + self.hass, data, 'test', '1', '0', None) + + self.assertEqual(STATE_OFF, entity.state) From a230d00ed02ac3044b5bd8c840b8ff8edd167ffc Mon Sep 17 00:00:00 2001 From: Ryan Kraus Date: Sat, 30 Jan 2016 22:50:56 -0500 Subject: [PATCH 17/17] Added test for Introduction component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test may seem useless, but it is good to ensure that default components don’t ever crash HASS. --- tests/components/test_introduction.py | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/components/test_introduction.py diff --git a/tests/components/test_introduction.py b/tests/components/test_introduction.py new file mode 100644 index 00000000000..42c16081d1e --- /dev/null +++ b/tests/components/test_introduction.py @@ -0,0 +1,28 @@ +""" +tests.components.introduction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Test introduction. + +This test is primarily to ensure that default components don't crash HASS. +""" + +import unittest + +import homeassistant.core as ha +from homeassistant.components import introduction + + +class TestIntroduction(unittest.TestCase): + """ Test Introduction. """ + + def setUp(self): + self.hass = ha.HomeAssistant() + + def tearDown(self): + """ Stop down stuff we started. """ + self.hass.stop() + + def test_setup(self): + """ Test Introduction setup """ + self.assertTrue(introduction.setup(self.hass, {}))