mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Load requirements and dependencies from manifests. Fallback to current REQUIREMENTS
and DEPENDENCIES
(#22717)
* Load dependencies from manifests. Fallback to current DEPENDENCIES * Fix typing * Ignore typing correctly * Split out dependency processing to a new method * Fix tests * Only pull from manifest if dependencies is non empty * Inline temporary function * Fix light tests [skip ci] * Fix tests/common * Fix some mqtt tests [skip ci] * Fix tests and component manifests which have only one platform * Fix rflink tests * Fix more tests and manifests * Readability over shorthand format * Fix demo/notify tests * Load dependencies from manifests. Fallback to current DEPENDENCIES * Load requirements from manifests. Fallback to current REQUIREMENTS * Fix typing * Ignore typing correctly * Split out dependency processing to a new method * Only pull from manifest if dependencies is non empty * Inline temporary function * Fix tests and component manifests which have only one platform * Fix rflink tests * Readability over shorthand format * Clean up requirements * Use integration to resolve deps/reqs * Lint * Lint * revert a change * Revert a test change * Fix types * Fix types * Add back cache for load component * Fix test_component_not_found * Move light.test and device_tracker.test into test package instead with manifest to fix tests * Fix broken device_tracker tests * Add docstrings to __init__ * Fix all of the light tests that I broke earlier * Embed the test.switch platform to fix other tests * Embed and fix the test.imagimage_processing platform * Fix tests for nx584 * Add dependencies from platform file's DEPENDENCIES * Try to setup component when entity_platform is setting up Fix tests in helpers folder * Rewrite test_setup * Simplify * Lint * Disable demo component if running in test Temp workaround to unblock CI tests * Skip demo tests * Fix config entry test * Fix repeat test * Clarify doc * One extra guard * Fix import * Lint * Workaround google tts
This commit is contained in:
parent
8a81286abb
commit
6ba9ccf052
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"pyarlo==0.2.3"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Arwn",
|
||||
"documentation": "https://www.home-assistant.io/components/arwn",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"mqtt"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Asterisk cdr",
|
||||
"documentation": "https://www.home-assistant.io/components/asterisk_cdr",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"asterisk_mbox"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
"requirements": [
|
||||
"aioautomatic==0.6.5"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": [
|
||||
"@armills"
|
||||
]
|
||||
|
@ -4,7 +4,8 @@
|
||||
"documentation": "https://www.home-assistant.io/components/automation",
|
||||
"requirements": [],
|
||||
"dependencies": [
|
||||
"group"
|
||||
"group",
|
||||
"webhook"
|
||||
],
|
||||
"codeowners": [
|
||||
"@home-assistant/core"
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"py-canary==0.5.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Set up the demo environment that mimics interaction with devices."""
|
||||
import asyncio
|
||||
import time
|
||||
import sys
|
||||
|
||||
from homeassistant import bootstrap
|
||||
import homeassistant.core as ha
|
||||
@ -31,7 +32,7 @@ COMPONENTS_WITH_DEMO_PLATFORM = [
|
||||
]
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
async def _async_setup(hass, config):
|
||||
"""Set up the demo environment."""
|
||||
group = hass.components.group
|
||||
configurator = hass.components.configurator
|
||||
@ -224,3 +225,7 @@ async def async_setup(hass, config):
|
||||
hass.async_add_job(setup_configurator)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if 'pytest' not in sys.modules:
|
||||
async_setup = _async_setup # pylint: disable=invalid-name
|
||||
|
@ -5,7 +5,9 @@
|
||||
"requirements": [
|
||||
"fitbit==0.3.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": [
|
||||
"@robbiet480"
|
||||
]
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"pyflexit==0.3"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"modbus"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Flux",
|
||||
"documentation": "https://www.home-assistant.io/components/flux",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"light"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
"name": "Generic thermostat",
|
||||
"documentation": "https://www.home-assistant.io/components/generic_thermostat",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"sensor",
|
||||
"switch"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -153,6 +153,9 @@ def setup(hass, config):
|
||||
hass.data[DATA_INDEX] = {}
|
||||
|
||||
conf = config.get(DOMAIN, {})
|
||||
if not conf:
|
||||
# component is set up by tts platform
|
||||
return True
|
||||
|
||||
token_file = hass.config.path(TOKEN_FILE)
|
||||
if not os.path.isfile(token_file):
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "History stats",
|
||||
"documentation": "https://www.home-assistant.io/components/history_stats",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"history"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Manual mqtt",
|
||||
"documentation": "https://www.home-assistant.io/components/manual_mqtt",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"mqtt"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
"hbmqtt==0.9.4",
|
||||
"paho-mqtt==1.4.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": [
|
||||
"@home-assistant/core"
|
||||
]
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Mqtt json",
|
||||
"documentation": "https://www.home-assistant.io/components/mqtt_json",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"mqtt"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Mqtt room",
|
||||
"documentation": "https://www.home-assistant.io/components/mqtt_room",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"mqtt"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
"requirements": [
|
||||
"python-mystrom==0.5.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": [
|
||||
"@fabaff"
|
||||
]
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Netatmo public",
|
||||
"documentation": "https://www.home-assistant.io/components/netatmo_public",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"netatmo"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"pynetio==0.1.9.1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
"suds-passworddigest-homeassistant==0.1.2a0.dev0",
|
||||
"suds-py3==1.3.3.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"ring_doorbell==0.2.3"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"spotipy-homeassistant==2.4.4.dev1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Telegram",
|
||||
"documentation": "https://www.home-assistant.io/components/telegram",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"telegram_bot"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
"requirements": [
|
||||
"VL53L1X2==0.1.5"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"rpi_gpio"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Torque",
|
||||
"documentation": "https://www.home-assistant.io/components/torque",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"http"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -3,7 +3,9 @@
|
||||
"name": "Twilio call",
|
||||
"documentation": "https://www.home-assistant.io/components/twilio_call",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"twilio"
|
||||
],
|
||||
"codeowners": [
|
||||
"@robbiet480"
|
||||
]
|
||||
|
@ -3,7 +3,9 @@
|
||||
"name": "Twilio sms",
|
||||
"documentation": "https://www.home-assistant.io/components/twilio_sms",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"twilio"
|
||||
],
|
||||
"codeowners": [
|
||||
"@robbiet480"
|
||||
]
|
||||
|
@ -3,6 +3,8 @@
|
||||
"name": "Xiaomi",
|
||||
"documentation": "https://www.home-assistant.io/components/xiaomi",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": []
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
"requirements": [
|
||||
"aioftp==0.12.0"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"ffmpeg"
|
||||
],
|
||||
"codeowners": [
|
||||
"@bachya"
|
||||
]
|
||||
|
@ -126,7 +126,7 @@ import uuid
|
||||
from typing import Callable, Dict, List, Optional, Set # noqa pylint: disable=unused-import
|
||||
import weakref
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant import data_entry_flow, loader
|
||||
from homeassistant.core import callback, HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ConfigEntryNotReady
|
||||
from homeassistant.setup import async_setup_component, async_process_deps_reqs
|
||||
@ -688,7 +688,12 @@ class ConfigEntries:
|
||||
|
||||
Handler key is the domain of the component that we want to set up.
|
||||
"""
|
||||
component = getattr(self.hass.components, handler_key)
|
||||
integration = await loader.async_get_integration(
|
||||
self.hass, handler_key)
|
||||
|
||||
if integration is None:
|
||||
raise data_entry_flow.UnknownHandler
|
||||
|
||||
handler = HANDLERS.get(handler_key)
|
||||
|
||||
if handler is None:
|
||||
@ -698,7 +703,7 @@ class ConfigEntries:
|
||||
|
||||
# Make sure requirements and dependencies of component are resolved
|
||||
await async_process_deps_reqs(
|
||||
self.hass, self._hass_config, handler, component)
|
||||
self.hass, self._hass_config, integration)
|
||||
|
||||
# Create notification.
|
||||
if source in DISCOVERY_SOURCES:
|
||||
|
@ -52,11 +52,11 @@ LOOKUP_PATHS = [PACKAGE_CUSTOM_COMPONENTS, PACKAGE_BUILTIN]
|
||||
_UNDEF = object()
|
||||
|
||||
|
||||
def manifest_from_legacy_module(module: Any) -> Dict:
|
||||
def manifest_from_legacy_module(module: ModuleType) -> Dict:
|
||||
"""Generate a manifest from a legacy module."""
|
||||
return {
|
||||
'domain': module.DOMAIN,
|
||||
'name': module.DOMAIN,
|
||||
'domain': module.DOMAIN, # type: ignore
|
||||
'name': module.DOMAIN, # type: ignore
|
||||
'documentation': None,
|
||||
'requirements': getattr(module, 'REQUIREMENTS', []),
|
||||
'dependencies': getattr(module, 'DEPENDENCIES', []),
|
||||
@ -68,10 +68,10 @@ class Integration:
|
||||
"""An integration in Home Assistant."""
|
||||
|
||||
@classmethod
|
||||
def resolve_from_root(cls, hass: 'HomeAssistant', root_module: Any,
|
||||
def resolve_from_root(cls, hass: 'HomeAssistant', root_module: ModuleType,
|
||||
domain: str) -> 'Optional[Integration]':
|
||||
"""Resolve an integration from a root module."""
|
||||
for base in root_module.__path__:
|
||||
for base in root_module.__path__: # type: ignore
|
||||
manifest_path = (
|
||||
pathlib.Path(base) / domain / 'manifest.json'
|
||||
)
|
||||
@ -117,15 +117,22 @@ class Integration:
|
||||
self.dependencies = manifest['dependencies'] # type: List[str]
|
||||
self.requirements = manifest['requirements'] # type: List[str]
|
||||
|
||||
def get_component(self) -> Any:
|
||||
def get_component(self) -> ModuleType:
|
||||
"""Return the component."""
|
||||
return importlib.import_module(self.pkg_path)
|
||||
cache = self.hass.data.setdefault(DATA_KEY, {})
|
||||
if self.domain not in cache:
|
||||
cache[self.domain] = importlib.import_module(self.pkg_path)
|
||||
return cache[self.domain] # type: ignore
|
||||
|
||||
def get_platform(self, platform_name: str) -> Any:
|
||||
def get_platform(self, platform_name: str) -> ModuleType:
|
||||
"""Return a platform for an integration."""
|
||||
return importlib.import_module(
|
||||
"{}.{}".format(self.pkg_path, platform_name)
|
||||
)
|
||||
cache = self.hass.data.setdefault(DATA_KEY, {})
|
||||
full_name = "{}.{}".format(self.domain, platform_name)
|
||||
if full_name not in cache:
|
||||
cache[full_name] = importlib.import_module(
|
||||
"{}.{}".format(self.pkg_path, platform_name)
|
||||
)
|
||||
return cache[full_name] # type: ignore
|
||||
|
||||
|
||||
async def async_get_integration(hass: 'HomeAssistant', domain: str)\
|
||||
|
@ -100,10 +100,16 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
_LOGGER.error("Setup failed for %s: %s", domain, msg)
|
||||
async_notify_setup_error(hass, domain, link)
|
||||
|
||||
component = loader.get_component(hass, domain)
|
||||
try:
|
||||
integration = await loader.async_get_integration(hass, domain)
|
||||
except loader.IntegrationNotFound:
|
||||
log_error("Integration not found.", False)
|
||||
return False
|
||||
|
||||
if not component:
|
||||
log_error("Component not found.", False)
|
||||
try:
|
||||
component = integration.get_component()
|
||||
except ImportError:
|
||||
log_error("Unable to import component", False)
|
||||
return False
|
||||
|
||||
# Validate all dependencies exist and there are no circular dependencies
|
||||
@ -128,7 +134,7 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
return False
|
||||
|
||||
try:
|
||||
await async_process_deps_reqs(hass, config, domain, component)
|
||||
await async_process_deps_reqs(hass, config, integration)
|
||||
except HomeAssistantError as err:
|
||||
log_error(str(err))
|
||||
return False
|
||||
@ -183,13 +189,14 @@ async def _async_setup_component(hass: core.HomeAssistant,
|
||||
|
||||
hass.bus.async_fire(
|
||||
EVENT_COMPONENT_LOADED,
|
||||
{ATTR_COMPONENT: component.DOMAIN} # type: ignore
|
||||
{ATTR_COMPONENT: component.DOMAIN} # type: ignore
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_prepare_setup_platform(hass: core.HomeAssistant, config: Dict,
|
||||
async def async_prepare_setup_platform(hass: core.HomeAssistant,
|
||||
hass_config: Dict,
|
||||
domain: str, platform_name: str) \
|
||||
-> Optional[ModuleType]:
|
||||
"""Load a platform and makes sure dependencies are setup.
|
||||
@ -202,13 +209,18 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant, config: Dict,
|
||||
def log_error(msg: str) -> None:
|
||||
"""Log helper."""
|
||||
_LOGGER.error("Unable to prepare setup for platform %s: %s",
|
||||
platform_path, msg)
|
||||
platform_name, msg)
|
||||
async_notify_setup_error(hass, platform_path)
|
||||
|
||||
platform = loader.get_platform(hass, domain, platform_name)
|
||||
try:
|
||||
integration = await loader.async_get_integration(hass, platform_name)
|
||||
except loader.IntegrationNotFound:
|
||||
log_error("Integration not found")
|
||||
return None
|
||||
|
||||
# Not found
|
||||
if platform is None:
|
||||
try:
|
||||
platform = integration.get_platform(domain)
|
||||
except ImportError:
|
||||
log_error("Platform not found.")
|
||||
return None
|
||||
|
||||
@ -216,9 +228,25 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant, config: Dict,
|
||||
if platform_path in hass.config.components:
|
||||
return platform
|
||||
|
||||
# Platforms cannot exist on their own, they are part of their integration.
|
||||
# If the integration is not set up yet, and can be set up, set it up.
|
||||
if integration.domain not in hass.config.components:
|
||||
try:
|
||||
component = integration.get_component()
|
||||
except ImportError:
|
||||
log_error("Unable to import the component")
|
||||
return None
|
||||
|
||||
if (hasattr(component, 'setup')
|
||||
or hasattr(component, 'async_setup')):
|
||||
if not await async_setup_component(
|
||||
hass, integration.domain, hass_config
|
||||
):
|
||||
log_error("Unable to set up component.")
|
||||
return None
|
||||
|
||||
try:
|
||||
await async_process_deps_reqs(
|
||||
hass, config, platform_path, platform)
|
||||
await async_process_deps_reqs(hass, hass_config, integration)
|
||||
except HomeAssistantError as err:
|
||||
log_error(str(err))
|
||||
return None
|
||||
@ -227,8 +255,8 @@ async def async_prepare_setup_platform(hass: core.HomeAssistant, config: Dict,
|
||||
|
||||
|
||||
async def async_process_deps_reqs(
|
||||
hass: core.HomeAssistant, config: Dict, name: str,
|
||||
module: ModuleType) -> None:
|
||||
hass: core.HomeAssistant, config: Dict,
|
||||
integration: loader.Integration) -> None:
|
||||
"""Process all dependencies and requirements for a module.
|
||||
|
||||
Module is a Python module of either a component or platform.
|
||||
@ -237,24 +265,23 @@ async def async_process_deps_reqs(
|
||||
|
||||
if processed is None:
|
||||
processed = hass.data[DATA_DEPS_REQS] = set()
|
||||
elif name in processed:
|
||||
elif integration.domain in processed:
|
||||
return
|
||||
|
||||
if hasattr(module, 'DEPENDENCIES'):
|
||||
dep_success = await _async_process_dependencies(
|
||||
hass, config, name, module.DEPENDENCIES) # type: ignore
|
||||
if integration.dependencies and not await _async_process_dependencies(
|
||||
hass,
|
||||
config,
|
||||
integration.domain,
|
||||
integration.dependencies
|
||||
):
|
||||
raise HomeAssistantError("Could not set up all dependencies.")
|
||||
|
||||
if not dep_success:
|
||||
raise HomeAssistantError("Could not set up all dependencies.")
|
||||
if (not hass.config.skip_pip and integration.requirements and
|
||||
not await requirements.async_process_requirements(
|
||||
hass, integration.domain, integration.requirements)):
|
||||
raise HomeAssistantError("Could not install all requirements.")
|
||||
|
||||
if not hass.config.skip_pip and hasattr(module, 'REQUIREMENTS'):
|
||||
req_success = await requirements.async_process_requirements(
|
||||
hass, name, module.REQUIREMENTS) # type: ignore
|
||||
|
||||
if not req_success:
|
||||
raise HomeAssistantError("Could not install all requirements.")
|
||||
|
||||
processed.add(name)
|
||||
processed.add(integration.domain)
|
||||
|
||||
|
||||
@core.callback
|
||||
|
@ -111,6 +111,9 @@ geojson_client==0.3
|
||||
# homeassistant.components.geo_rss_events
|
||||
georss_generic_client==0.2
|
||||
|
||||
# homeassistant.components.google
|
||||
google-api-python-client==1.6.4
|
||||
|
||||
# homeassistant.components.ffmpeg
|
||||
ha-ffmpeg==2.0
|
||||
|
||||
@ -138,6 +141,10 @@ homekit[IP]==0.13.0
|
||||
# homeassistant.components.homematicip_cloud
|
||||
homematicip==0.10.6
|
||||
|
||||
# homeassistant.components.google
|
||||
# homeassistant.components.remember_the_milk
|
||||
httplib2==0.10.3
|
||||
|
||||
# homeassistant.components.influxdb
|
||||
influxdb==5.2.0
|
||||
|
||||
@ -165,6 +172,9 @@ mficlient==0.3.0
|
||||
# homeassistant.components.trend
|
||||
numpy==1.16.2
|
||||
|
||||
# homeassistant.components.google
|
||||
oauth2client==4.0.0
|
||||
|
||||
# homeassistant.components.mqtt
|
||||
# homeassistant.components.shiftr
|
||||
paho-mqtt==1.4.0
|
||||
|
@ -62,6 +62,7 @@ TEST_REQUIREMENTS = (
|
||||
'foobot_async',
|
||||
'geojson_client',
|
||||
'georss_generic_client',
|
||||
'google-api-python-client',
|
||||
'gTTS-token',
|
||||
'ha-ffmpeg',
|
||||
'hangups',
|
||||
@ -74,6 +75,7 @@ TEST_REQUIREMENTS = (
|
||||
'home-assistant-frontend',
|
||||
'homekit[IP]',
|
||||
'homematicip',
|
||||
'httplib2',
|
||||
'influxdb',
|
||||
'jsonpath',
|
||||
'libpurecool',
|
||||
@ -82,6 +84,7 @@ TEST_REQUIREMENTS = (
|
||||
'mbddns',
|
||||
'mficlient',
|
||||
'numpy',
|
||||
'oauth2client',
|
||||
'paho-mqtt',
|
||||
'pexpect',
|
||||
'pilight',
|
||||
|
@ -906,11 +906,26 @@ def mock_integration(hass, module):
|
||||
integration = loader.Integration(
|
||||
hass, 'homeassisant.components.{}'.format(module.DOMAIN),
|
||||
loader.manifest_from_legacy_module(module))
|
||||
integration.get_component = lambda: module
|
||||
|
||||
# Backwards compat
|
||||
loader.set_component(hass, module.DOMAIN, module)
|
||||
|
||||
_LOGGER.info("Adding mock integration: %s", module.DOMAIN)
|
||||
hass.data.setdefault(
|
||||
loader.DATA_INTEGRATIONS, {}
|
||||
)[module.DOMAIN] = integration
|
||||
hass.data.setdefault(loader.DATA_KEY, {})[module.DOMAIN] = module
|
||||
|
||||
|
||||
def mock_entity_platform(hass, platform_path, module):
|
||||
"""Mock a entity platform.
|
||||
|
||||
platform_path is in form light.hue. Will create platform
|
||||
hue.light.
|
||||
"""
|
||||
domain, platform_name = platform_path.split('.')
|
||||
integration_cache = hass.data.setdefault(loader.DATA_KEY, {})
|
||||
module_cache = hass.data.setdefault(loader.DATA_KEY, {})
|
||||
|
||||
if platform_name not in integration_cache:
|
||||
mock_integration(hass, MockModule(platform_name))
|
||||
|
||||
_LOGGER.info("Adding mock integration platform: %s", platform_path)
|
||||
module_cache["{}.{}".format(platform_name, domain)] = module
|
||||
|
@ -40,14 +40,13 @@ class TestDemoPlatform(unittest.TestCase):
|
||||
assert setup_component(self.hass, geo_location.DOMAIN, CONFIG)
|
||||
self.hass.block_till_done()
|
||||
|
||||
# In this test, five geolocation entities have been
|
||||
# In this test, one zone and geolocation entities have been
|
||||
# generated.
|
||||
all_states = self.hass.states.all()
|
||||
print(all_states)
|
||||
assert len(all_states) == NUMBER_OF_DEMO_DEVICES
|
||||
assert len(all_states) == NUMBER_OF_DEMO_DEVICES + 1
|
||||
|
||||
# Check a single device's attributes.
|
||||
state_first_entry = all_states[0]
|
||||
state_first_entry = all_states[1] # 0 is zone
|
||||
assert abs(
|
||||
state_first_entry.attributes['latitude'] -
|
||||
self.hass.config.latitude
|
||||
@ -64,5 +63,5 @@ class TestDemoPlatform(unittest.TestCase):
|
||||
# Get all states again, ensure that the number of states is still
|
||||
# the same, but the lists are different.
|
||||
all_states_updated = self.hass.states.all()
|
||||
assert len(all_states_updated) == NUMBER_OF_DEMO_DEVICES
|
||||
assert len(all_states_updated) == NUMBER_OF_DEMO_DEVICES + 1
|
||||
assert all_states != all_states_updated
|
||||
|
@ -38,6 +38,7 @@ def demo_cleanup(hass):
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@asyncio.coroutine
|
||||
def test_if_demo_state_shows_by_default(hass, minimize_demo_platforms):
|
||||
"""Test if demo state shows if we give no configuration."""
|
||||
@ -46,6 +47,7 @@ def test_if_demo_state_shows_by_default(hass, minimize_demo_platforms):
|
||||
assert hass.states.get('a.Demo_Mode') is not None
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@asyncio.coroutine
|
||||
def test_hiding_demo_state(hass, minimize_demo_platforms):
|
||||
"""Test if you can hide the demo card."""
|
||||
@ -55,6 +57,7 @@ def test_hiding_demo_state(hass, minimize_demo_platforms):
|
||||
assert hass.states.get('a.Demo_Mode') is None
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@asyncio.coroutine
|
||||
def test_all_entities_can_be_loaded_over_json(hass):
|
||||
"""Test if you can hide the demo card."""
|
||||
|
@ -19,12 +19,12 @@ from tests.components.light import common as common_light
|
||||
def scanner(hass):
|
||||
"""Initialize components."""
|
||||
scanner = loader.get_component(
|
||||
hass, 'device_tracker.test').get_scanner(None, None)
|
||||
hass, 'test.device_tracker').get_scanner(None, None)
|
||||
|
||||
scanner.reset()
|
||||
scanner.come_home('DEV1')
|
||||
|
||||
loader.get_component(hass, 'light.test').init()
|
||||
loader.get_component(hass, 'test.light').init()
|
||||
|
||||
with patch(
|
||||
'homeassistant.components.device_tracker.load_yaml_config_file',
|
||||
|
@ -192,7 +192,7 @@ async def test_discover_platform(mock_demo_setup_scanner, mock_see, hass):
|
||||
|
||||
async def test_update_stale(hass):
|
||||
"""Test stalled update."""
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'test.device_tracker').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('DEV1')
|
||||
|
||||
@ -256,7 +256,7 @@ async def test_device_hidden(hass, yaml_devices):
|
||||
hide_if_away=True)
|
||||
device_tracker.update_config(yaml_devices, dev_id, device)
|
||||
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'test.device_tracker').SCANNER
|
||||
scanner.reset()
|
||||
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
@ -275,7 +275,7 @@ async def test_group_all_devices(hass, yaml_devices):
|
||||
hide_if_away=True)
|
||||
device_tracker.update_config(yaml_devices, dev_id, device)
|
||||
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'test.device_tracker').SCANNER
|
||||
scanner.reset()
|
||||
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
@ -441,7 +441,7 @@ async def test_see_passive_zone_state(hass):
|
||||
'zone': zone_info
|
||||
})
|
||||
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'test.device_tracker').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('dev1')
|
||||
|
||||
@ -557,7 +557,7 @@ def test_bad_platform(hass):
|
||||
|
||||
async def test_adding_unknown_device_to_config(mock_device_tracker_conf, hass):
|
||||
"""Test the adding of unknown devices to configuration file."""
|
||||
scanner = get_component(hass, 'device_tracker.test').SCANNER
|
||||
scanner = get_component(hass, 'test.device_tracker').SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home('DEV1')
|
||||
|
||||
|
@ -74,7 +74,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_when_switch_is_off(self):
|
||||
"""Test the flux switch when it is off."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -114,7 +114,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_before_sunrise(self):
|
||||
"""Test the flux switch before sunrise."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -159,7 +159,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_sunrise_before_sunset(self):
|
||||
"""Test the flux switch after sunrise and before sunset."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -205,7 +205,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_sunset_before_stop(self):
|
||||
"""Test the flux switch after sunset and before stop."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -252,7 +252,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_after_stop_before_sunrise(self):
|
||||
"""Test the flux switch after stop and before sunrise."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -297,7 +297,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_start_stop_times(self):
|
||||
"""Test the flux with custom start and stop times."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -347,7 +347,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -398,7 +398,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -448,7 +448,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -497,7 +497,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -547,7 +547,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
This test has the stop_time on the next day (after midnight).
|
||||
"""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -594,7 +594,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_colortemps(self):
|
||||
"""Test the flux with custom start and stop colortemps."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -643,7 +643,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
# pylint: disable=invalid-name
|
||||
def test_flux_with_custom_brightness(self):
|
||||
"""Test the flux with custom start and stop colortemps."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -690,7 +690,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_multiple_lights(self):
|
||||
"""Test the flux switch with multiple light entities."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -758,7 +758,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_mired(self):
|
||||
"""Test the flux switch´s mode mired."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
@ -802,7 +802,7 @@ class TestSwitchFlux(unittest.TestCase):
|
||||
|
||||
def test_flux_with_rgb(self):
|
||||
"""Test the flux switch´s mode rgb."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
{light.DOMAIN: {CONF_PLATFORM: 'test'}})
|
||||
|
@ -78,9 +78,9 @@ def test_frontend_and_static(mock_http_client, mock_onboarded):
|
||||
|
||||
# Test we can retrieve frontend.js
|
||||
frontendjs = re.search(
|
||||
r'(?P<app>\/frontend_es5\/app-[A-Za-z0-9]{8}.js)', text)
|
||||
r'(?P<app>\/frontend_es5\/app.[A-Za-z0-9]{8}.js)', text)
|
||||
|
||||
assert frontendjs is not None
|
||||
assert frontendjs is not None, text
|
||||
resp = yield from mock_http_client.get(frontendjs.groups(0)[0])
|
||||
assert resp.status == 200
|
||||
assert 'public' in resp.headers.get('cache-control')
|
||||
|
@ -98,7 +98,7 @@ async def test_heater_input_boolean(hass, setup_comp_1):
|
||||
|
||||
async def test_heater_switch(hass, setup_comp_1):
|
||||
"""Test heater switching test switch."""
|
||||
platform = loader.get_component(hass, 'switch.test')
|
||||
platform = loader.get_component(hass, 'test.switch')
|
||||
platform.init()
|
||||
switch_1 = platform.DEVICES[1]
|
||||
assert await async_setup_component(hass, switch.DOMAIN, {'switch': {
|
||||
@ -112,6 +112,7 @@ async def test_heater_switch(hass, setup_comp_1):
|
||||
'target_sensor': ENT_SENSOR
|
||||
}})
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert STATE_OFF == \
|
||||
hass.states.get(heater_switch).state
|
||||
|
||||
|
@ -121,7 +121,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_services(self):
|
||||
"""Test the provided services."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
|
||||
platform.init()
|
||||
assert setup_component(self.hass, light.DOMAIN,
|
||||
@ -308,7 +308,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_broken_light_profiles(self):
|
||||
"""Test light profiles."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
@ -323,7 +323,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_light_profiles(self):
|
||||
"""Test light profiles."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
@ -362,7 +362,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_default_profiles_group(self):
|
||||
"""Test default turn-on light profile for all lights."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
@ -400,7 +400,7 @@ class TestLight(unittest.TestCase):
|
||||
|
||||
def test_default_profiles_light(self):
|
||||
"""Test default turn-on light profile for a specific light."""
|
||||
platform = loader.get_component(self.hass, 'light.test')
|
||||
platform = loader.get_component(self.hass, 'test.light')
|
||||
platform.init()
|
||||
|
||||
user_light_file = self.hass.config.path(light.LIGHT_PROFILES_FILE)
|
||||
|
@ -85,7 +85,7 @@ class TestNX584SensorSetup(unittest.TestCase):
|
||||
def _test_assert_graceful_fail(self, config):
|
||||
"""Test the failing."""
|
||||
assert not setup_component(
|
||||
self.hass, 'binary_sensor.nx584', config)
|
||||
self.hass, 'nx584', config)
|
||||
|
||||
def test_setup_bad_config(self):
|
||||
"""Test the setup with bad configuration."""
|
||||
|
@ -18,7 +18,7 @@ class TestScene(unittest.TestCase):
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
test_light = loader.get_component(self.hass, 'light.test')
|
||||
test_light = loader.get_component(self.hass, 'test.light')
|
||||
test_light.init()
|
||||
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
|
@ -18,7 +18,7 @@ class TestSwitch(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
platform = loader.get_component(self.hass, 'switch.test')
|
||||
platform = loader.get_component(self.hass, 'test.switch')
|
||||
platform.init()
|
||||
# Switch 1 is ON, switch 2 is OFF
|
||||
self.switch_1, self.switch_2, self.switch_3 = \
|
||||
@ -77,7 +77,7 @@ class TestSwitch(unittest.TestCase):
|
||||
def test_setup_two_platforms(self):
|
||||
"""Test with bad configuration."""
|
||||
# Test if switch component returns 0 switches
|
||||
test_platform = loader.get_component(self.hass, 'switch.test')
|
||||
test_platform = loader.get_component(self.hass, 'test.switch')
|
||||
test_platform.init(True)
|
||||
|
||||
loader.set_component(self.hass, 'switch.test2', test_platform)
|
||||
@ -99,6 +99,8 @@ async def test_switch_context(hass, hass_admin_user):
|
||||
}
|
||||
})
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get('switch.ac')
|
||||
assert state is not None
|
||||
|
||||
|
@ -132,10 +132,14 @@ class TestHelpersDiscovery:
|
||||
self.hass, 'test_component',
|
||||
MockModule('test_component', setup=component_setup))
|
||||
|
||||
# dependencies are only set in component level
|
||||
# since we are using manifest to hold them
|
||||
loader.set_component(
|
||||
self.hass, 'switch.test_circular',
|
||||
MockPlatform(setup_platform,
|
||||
dependencies=['test_component']))
|
||||
self.hass, 'test_circular',
|
||||
MockModule('test_circular', dependencies=['test_component']))
|
||||
loader.set_component(
|
||||
self.hass, 'test_circular.switch',
|
||||
MockPlatform(setup_platform))
|
||||
|
||||
setup.setup_component(self.hass, 'test_component', {
|
||||
'test_component': None,
|
||||
|
@ -21,7 +21,8 @@ import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import (
|
||||
get_test_home_assistant, MockPlatform, MockModule, mock_coro,
|
||||
async_fire_time_changed, MockEntity, MockConfigEntry)
|
||||
async_fire_time_changed, MockEntity, MockConfigEntry,
|
||||
mock_entity_platform, mock_integration)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
DOMAIN = "test_domain"
|
||||
@ -74,11 +75,14 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
"""Test the loading of the platforms."""
|
||||
component_setup = Mock(return_value=True)
|
||||
platform_setup = Mock(return_value=None)
|
||||
loader.set_component(
|
||||
self.hass, 'test_component',
|
||||
MockModule('test_component', setup=component_setup))
|
||||
loader.set_component(self.hass, 'test_domain.mod2',
|
||||
MockPlatform(platform_setup, ['test_component']))
|
||||
|
||||
mock_integration(self.hass,
|
||||
MockModule('test_component', setup=component_setup))
|
||||
# mock the dependencies
|
||||
mock_integration(self.hass,
|
||||
MockModule('mod2', dependencies=['test_component']))
|
||||
mock_entity_platform(self.hass, 'test_domain.mod2',
|
||||
MockPlatform(platform_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -100,9 +104,9 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
platform1_setup = Mock(side_effect=Exception('Broken'))
|
||||
platform2_setup = Mock(return_value=None)
|
||||
|
||||
loader.set_component(self.hass, 'test_domain.mod1',
|
||||
mock_entity_platform(self.hass, 'test_domain.mod1',
|
||||
MockPlatform(platform1_setup))
|
||||
loader.set_component(self.hass, 'test_domain.mod2',
|
||||
mock_entity_platform(self.hass, 'test_domain.mod2',
|
||||
MockPlatform(platform2_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
@ -147,7 +151,7 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
"""Test the platform setup."""
|
||||
add_entities([MockEntity(should_poll=True)])
|
||||
|
||||
loader.set_component(self.hass, 'test_domain.platform',
|
||||
mock_entity_platform(self.hass, 'test_domain.platform',
|
||||
MockPlatform(platform_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
@ -174,7 +178,7 @@ class TestHelpersEntityComponent(unittest.TestCase):
|
||||
|
||||
platform = MockPlatform(platform_setup)
|
||||
|
||||
loader.set_component(self.hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(self.hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -222,7 +226,9 @@ def test_platform_not_ready(hass):
|
||||
"""Test that we retry when platform not ready."""
|
||||
platform1_setup = Mock(side_effect=[PlatformNotReady, PlatformNotReady,
|
||||
None])
|
||||
loader.set_component(hass, 'test_domain.mod1',
|
||||
loader.set_component(hass, 'mod1',
|
||||
MockModule('mod1'))
|
||||
loader.set_component(hass, 'mod1.test_domain',
|
||||
MockPlatform(platform1_setup))
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
@ -320,17 +326,15 @@ def test_setup_dependencies_platform(hass):
|
||||
We're explictely testing that we process dependencies even if a component
|
||||
with the same name has already been loaded.
|
||||
"""
|
||||
loader.set_component(hass, 'test_component', MockModule('test_component'))
|
||||
loader.set_component(hass, 'test_component',
|
||||
MockModule('test_component',
|
||||
dependencies=['test_component2']))
|
||||
loader.set_component(hass, 'test_component2',
|
||||
MockModule('test_component2'))
|
||||
loader.set_component(
|
||||
hass, 'test_component.test_domain',
|
||||
MockPlatform(dependencies=['test_component', 'test_component2']))
|
||||
loader.set_component(hass, 'test_component.test_domain', MockPlatform())
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
yield from async_setup_component(hass, 'test_component', {})
|
||||
|
||||
yield from component.async_setup({
|
||||
DOMAIN: {
|
||||
'platform': 'test_component',
|
||||
@ -345,7 +349,7 @@ def test_setup_dependencies_platform(hass):
|
||||
async def test_setup_entry(hass):
|
||||
"""Test setup entry calls async_setup_entry on platform."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry,
|
||||
scan_interval=timedelta(seconds=5)))
|
||||
@ -374,7 +378,7 @@ async def test_setup_entry_platform_not_exist(hass):
|
||||
async def test_setup_entry_fails_duplicate(hass):
|
||||
"""Test we don't allow setting up a config entry twice."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry))
|
||||
|
||||
@ -390,7 +394,7 @@ async def test_setup_entry_fails_duplicate(hass):
|
||||
async def test_unload_entry_resets_platform(hass):
|
||||
"""Test unloading an entry removes all entities."""
|
||||
mock_setup_entry = Mock(return_value=mock_coro(True))
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
hass, 'test_domain.entry_domain',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry))
|
||||
|
||||
|
@ -8,7 +8,6 @@ from datetime import timedelta
|
||||
import pytest
|
||||
|
||||
from homeassistant.exceptions import PlatformNotReady
|
||||
import homeassistant.loader as loader
|
||||
from homeassistant.helpers.entity import generate_entity_id
|
||||
from homeassistant.helpers.entity_component import (
|
||||
EntityComponent, DEFAULT_SCAN_INTERVAL)
|
||||
@ -18,7 +17,7 @@ import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import (
|
||||
get_test_home_assistant, MockPlatform, fire_time_changed, mock_registry,
|
||||
MockEntity, MockEntityPlatform, MockConfigEntry)
|
||||
MockEntity, MockEntityPlatform, MockConfigEntry, mock_entity_platform)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
DOMAIN = "test_domain"
|
||||
@ -149,7 +148,7 @@ class TestHelpersEntityPlatform(unittest.TestCase):
|
||||
platform = MockPlatform(platform_setup)
|
||||
platform.SCAN_INTERVAL = timedelta(seconds=30)
|
||||
|
||||
loader.set_component(self.hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(self.hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, self.hass)
|
||||
|
||||
@ -186,7 +185,7 @@ def test_platform_warn_slow_setup(hass):
|
||||
"""Warn we log when platform setup takes a long time."""
|
||||
platform = MockPlatform()
|
||||
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
|
||||
@ -199,7 +198,9 @@ def test_platform_warn_slow_setup(hass):
|
||||
})
|
||||
assert mock_call.called
|
||||
|
||||
timeout, logger_method = mock_call.mock_calls[0][1][:2]
|
||||
# mock_calls[0] is the warning message for component setup
|
||||
# mock_calls[3] is the warning message for platform setup
|
||||
timeout, logger_method = mock_call.mock_calls[3][1][:2]
|
||||
|
||||
assert timeout == entity_platform.SLOW_SETUP_WARNING
|
||||
assert logger_method == _LOGGER.warning
|
||||
@ -220,7 +221,7 @@ def test_platform_error_slow_setup(hass, caplog):
|
||||
|
||||
platform = MockPlatform(async_setup_platform=setup_platform)
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
loader.set_component(hass, 'test_domain.test_platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.test_platform', platform)
|
||||
yield from component.async_setup({
|
||||
DOMAIN: {
|
||||
'platform': 'test_platform',
|
||||
@ -255,7 +256,7 @@ async def test_parallel_updates_async_platform(hass):
|
||||
"""Test async platform does not have parallel_updates limit by default."""
|
||||
platform = MockPlatform()
|
||||
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
@ -285,7 +286,7 @@ async def test_parallel_updates_async_platform_with_constant(hass):
|
||||
platform = MockPlatform()
|
||||
platform.PARALLEL_UPDATES = 2
|
||||
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
@ -316,7 +317,7 @@ async def test_parallel_updates_sync_platform(hass):
|
||||
"""Test sync platform parallel_updates default set to 1."""
|
||||
platform = MockPlatform()
|
||||
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
@ -347,7 +348,7 @@ async def test_parallel_updates_sync_platform_with_constant(hass):
|
||||
platform = MockPlatform()
|
||||
platform.PARALLEL_UPDATES = 2
|
||||
|
||||
loader.set_component(hass, 'test_domain.platform', platform)
|
||||
mock_entity_platform(hass, 'test_domain.platform', platform)
|
||||
|
||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||
component._platforms = {}
|
||||
|
@ -54,7 +54,7 @@ async def test_component_translation_file(hass):
|
||||
|
||||
assert path.normpath(translation.component_translation_file(
|
||||
hass, 'switch.test', 'en')) == path.normpath(hass.config.path(
|
||||
'custom_components', 'switch', '.translations', 'test.en.json'))
|
||||
'custom_components', 'test', '.translations', 'switch.en.json'))
|
||||
|
||||
assert path.normpath(translation.component_translation_file(
|
||||
hass, 'switch.test_embedded', 'en')) == path.normpath(hass.config.path(
|
||||
@ -74,9 +74,9 @@ def test_load_translations_files(hass):
|
||||
"""Test the load translation files function."""
|
||||
# Test one valid and one invalid file
|
||||
file1 = hass.config.path(
|
||||
'custom_components', 'switch', '.translations', 'test.en.json')
|
||||
'custom_components', 'test', '.translations', 'switch.en.json')
|
||||
file2 = hass.config.path(
|
||||
'custom_components', 'switch', '.translations', 'invalid.json')
|
||||
'custom_components', 'test', '.translations', 'invalid.json')
|
||||
assert translation.load_translations_files({
|
||||
'switch.test': file1,
|
||||
'invalid': file2
|
||||
|
@ -13,15 +13,22 @@ from homeassistant.util import dt
|
||||
|
||||
from tests.common import (
|
||||
MockModule, mock_coro, MockConfigEntry, async_fire_time_changed,
|
||||
MockPlatform, MockEntity)
|
||||
MockPlatform, MockEntity, mock_integration, mock_entity_platform)
|
||||
|
||||
|
||||
@config_entries.HANDLERS.register('test')
|
||||
@config_entries.HANDLERS.register('comp')
|
||||
class MockFlowHandler(config_entries.ConfigFlow):
|
||||
"""Define a mock flow handler."""
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_handlers():
|
||||
"""Mock config flows."""
|
||||
class MockFlowHandler(config_entries.ConfigFlow):
|
||||
"""Define a mock flow handler."""
|
||||
|
||||
VERSION = 1
|
||||
VERSION = 1
|
||||
|
||||
with patch.dict(config_entries.HANDLERS, {
|
||||
'comp': MockFlowHandler,
|
||||
'test': MockFlowHandler,
|
||||
}):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -185,23 +192,27 @@ async def test_remove_entry(hass, manager):
|
||||
"""Mock setting up platform."""
|
||||
async_add_entities([entity])
|
||||
|
||||
loader.set_component(hass, 'test', MockModule(
|
||||
mock_integration(hass, MockModule(
|
||||
'test',
|
||||
async_setup_entry=mock_setup_entry,
|
||||
async_unload_entry=mock_unload_entry,
|
||||
async_remove_entry=mock_remove_entry
|
||||
))
|
||||
loader.set_component(
|
||||
hass, 'test.light',
|
||||
mock_entity_platform(
|
||||
hass, 'light.test',
|
||||
MockPlatform(async_setup_entry=mock_setup_entry_platform))
|
||||
|
||||
MockConfigEntry(domain='test', entry_id='test1').add_to_manager(manager)
|
||||
MockConfigEntry(
|
||||
domain='test_other', entry_id='test1'
|
||||
).add_to_manager(manager)
|
||||
entry = MockConfigEntry(
|
||||
domain='test',
|
||||
entry_id='test2',
|
||||
)
|
||||
entry.add_to_manager(manager)
|
||||
MockConfigEntry(domain='test', entry_id='test3').add_to_manager(manager)
|
||||
MockConfigEntry(
|
||||
domain='test_other', entry_id='test3'
|
||||
).add_to_manager(manager)
|
||||
|
||||
# Check all config entries exist
|
||||
assert [item.entry_id for item in manager.async_entries()] == \
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Test to verify that we can load components."""
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
import homeassistant.loader as loader
|
||||
@ -63,20 +61,18 @@ def test_component_loader_non_existing(hass):
|
||||
components.non_existing
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_component_wrapper(hass):
|
||||
async def test_component_wrapper(hass):
|
||||
"""Test component wrapper."""
|
||||
calls = async_mock_service(hass, 'persistent_notification', 'create')
|
||||
|
||||
components = loader.Components(hass)
|
||||
components.persistent_notification.async_create('message')
|
||||
yield from hass.async_block_till_done()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_helpers_wrapper(hass):
|
||||
async def test_helpers_wrapper(hass):
|
||||
"""Test helpers wrapper."""
|
||||
helpers = loader.Helpers(hass)
|
||||
|
||||
@ -88,8 +84,8 @@ def test_helpers_wrapper(hass):
|
||||
|
||||
helpers.discovery.async_listen('service_name', discovery_callback)
|
||||
|
||||
yield from helpers.discovery.async_discover('service_name', 'hello')
|
||||
yield from hass.async_block_till_done()
|
||||
await helpers.discovery.async_discover('service_name', 'hello')
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result == ['hello']
|
||||
|
||||
@ -104,9 +100,9 @@ async def test_custom_component_name(hass):
|
||||
assert comp.__name__ == 'custom_components.test_package'
|
||||
assert comp.__package__ == 'custom_components.test_package'
|
||||
|
||||
comp = loader.get_component(hass, 'light.test')
|
||||
assert comp.__name__ == 'custom_components.light.test'
|
||||
assert comp.__package__ == 'custom_components.light'
|
||||
comp = loader.get_component(hass, 'test.light')
|
||||
assert comp.__name__ == 'custom_components.test.light'
|
||||
assert comp.__package__ == 'custom_components.test'
|
||||
|
||||
# Test custom components is mounted
|
||||
from custom_components.test_package import TEST
|
||||
@ -119,8 +115,8 @@ async def test_log_warning_custom_component(hass, caplog):
|
||||
assert \
|
||||
'You are using a custom component for test_standalone' in caplog.text
|
||||
|
||||
loader.get_component(hass, 'light.test')
|
||||
assert 'You are using a custom component for light.test' in caplog.text
|
||||
loader.get_component(hass, 'test.light')
|
||||
assert 'You are using a custom component for test.light' in caplog.text
|
||||
|
||||
|
||||
async def test_get_platform(hass, caplog):
|
||||
@ -132,8 +128,8 @@ async def test_get_platform(hass, caplog):
|
||||
|
||||
caplog.clear()
|
||||
|
||||
legacy_platform = loader.get_platform(hass, 'switch', 'test')
|
||||
assert legacy_platform.__name__ == 'custom_components.switch.test'
|
||||
legacy_platform = loader.get_platform(hass, 'switch', 'test_legacy')
|
||||
assert legacy_platform.__name__ == 'custom_components.switch.test_legacy'
|
||||
assert 'Integrations need to be in their own folder.' in caplog.text
|
||||
|
||||
|
||||
|
@ -20,7 +20,8 @@ from homeassistant.helpers import discovery
|
||||
|
||||
from tests.common import \
|
||||
get_test_home_assistant, MockModule, MockPlatform, \
|
||||
assert_setup_component, get_test_config_dir, mock_integration
|
||||
assert_setup_component, get_test_config_dir, mock_integration, \
|
||||
mock_entity_platform
|
||||
|
||||
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
|
||||
VERSION_PATH = os.path.join(get_test_config_dir(), config_util.VERSION_FILE)
|
||||
@ -50,9 +51,9 @@ class TestSetup:
|
||||
'hello': str
|
||||
}
|
||||
}, required=True)
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'comp_conf', MockModule('comp_conf', config_schema=config_schema))
|
||||
MockModule('comp_conf', config_schema=config_schema))
|
||||
|
||||
with assert_setup_component(0):
|
||||
assert not setup.setup_component(self.hass, 'comp_conf', {})
|
||||
@ -97,17 +98,15 @@ class TestSetup:
|
||||
})
|
||||
platform_schema_base = PLATFORM_SCHEMA_BASE.extend({
|
||||
})
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'platform_conf',
|
||||
MockModule('platform_conf',
|
||||
platform_schema_base=platform_schema_base))
|
||||
|
||||
loader.set_component(
|
||||
platform_schema_base=platform_schema_base),
|
||||
)
|
||||
mock_entity_platform(
|
||||
self.hass,
|
||||
'platform_conf.whatever',
|
||||
MockPlatform('whatever',
|
||||
platform_schema=platform_schema))
|
||||
MockPlatform(platform_schema=platform_schema))
|
||||
|
||||
with assert_setup_component(1):
|
||||
assert setup.setup_component(self.hass, 'platform_conf', {
|
||||
@ -195,14 +194,13 @@ class TestSetup:
|
||||
platform_schema_base = PLATFORM_SCHEMA_BASE.extend({
|
||||
'hello': 'world',
|
||||
})
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'platform_conf',
|
||||
MockModule('platform_conf',
|
||||
platform_schema=platform_schema,
|
||||
platform_schema_base=platform_schema_base))
|
||||
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
self.hass,
|
||||
'platform_conf.whatever',
|
||||
MockPlatform('whatever',
|
||||
@ -249,13 +247,12 @@ class TestSetup:
|
||||
'cheers': str,
|
||||
'hello': 'world',
|
||||
})
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'platform_conf',
|
||||
MockModule('platform_conf',
|
||||
platform_schema=component_schema))
|
||||
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
self.hass,
|
||||
'platform_conf.whatever',
|
||||
MockPlatform('whatever',
|
||||
@ -296,17 +293,15 @@ class TestSetup:
|
||||
"""Test entity_namespace in PLATFORM_SCHEMA."""
|
||||
component_schema = PLATFORM_SCHEMA_BASE
|
||||
platform_schema = PLATFORM_SCHEMA
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'platform_conf',
|
||||
MockModule('platform_conf',
|
||||
platform_schema_base=component_schema))
|
||||
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
self.hass,
|
||||
'platform_conf.whatever',
|
||||
MockPlatform('whatever',
|
||||
platform_schema=platform_schema))
|
||||
MockPlatform(platform_schema=platform_schema))
|
||||
|
||||
with assert_setup_component(1):
|
||||
assert setup.setup_component(self.hass, 'platform_conf', {
|
||||
@ -322,14 +317,15 @@ class TestSetup:
|
||||
|
||||
def test_component_not_found(self):
|
||||
"""setup_component should not crash if component doesn't exist."""
|
||||
assert not setup.setup_component(self.hass, 'non_existing')
|
||||
assert setup.setup_component(self.hass, 'non_existing') is False
|
||||
|
||||
def test_component_not_double_initialized(self):
|
||||
"""Test we do not set up a component twice."""
|
||||
mock_setup = mock.MagicMock(return_value=True)
|
||||
|
||||
loader.set_component(
|
||||
self.hass, 'comp', MockModule('comp', setup=mock_setup))
|
||||
mock_integration(
|
||||
self.hass,
|
||||
MockModule('comp', setup=mock_setup))
|
||||
|
||||
assert setup.setup_component(self.hass, 'comp')
|
||||
assert mock_setup.called
|
||||
@ -344,9 +340,9 @@ class TestSetup:
|
||||
def test_component_not_installed_if_requirement_fails(self, mock_install):
|
||||
"""Component setup should fail if requirement can't install."""
|
||||
self.hass.config.skip_pip = False
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'comp', MockModule('comp', requirements=['package==0.0.1']))
|
||||
MockModule('comp', requirements=['package==0.0.1']))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp')
|
||||
assert 'comp' not in self.hass.config.components
|
||||
@ -360,9 +356,9 @@ class TestSetup:
|
||||
"""Tracking Setup."""
|
||||
result.append(1)
|
||||
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'comp', MockModule('comp', async_setup=async_setup))
|
||||
MockModule('comp', async_setup=async_setup))
|
||||
|
||||
def setup_component():
|
||||
"""Set up the component."""
|
||||
@ -393,8 +389,8 @@ class TestSetup:
|
||||
|
||||
def test_component_failing_setup(self):
|
||||
"""Test component that fails setup."""
|
||||
loader.set_component(
|
||||
self.hass, 'comp',
|
||||
mock_integration(
|
||||
self.hass,
|
||||
MockModule('comp', setup=lambda hass, config: False))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp', {})
|
||||
@ -406,8 +402,8 @@ class TestSetup:
|
||||
"""Raise exception."""
|
||||
raise Exception('fail!')
|
||||
|
||||
loader.set_component(
|
||||
self.hass, 'comp', MockModule('comp', setup=exception_setup))
|
||||
mock_integration(self.hass,
|
||||
MockModule('comp', setup=exception_setup))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'comp', {})
|
||||
assert 'comp' not in self.hass.config.components
|
||||
@ -420,12 +416,18 @@ class TestSetup:
|
||||
return True
|
||||
raise Exception('Config not passed in: {}'.format(config))
|
||||
|
||||
loader.set_component(
|
||||
self.hass, 'comp_a',
|
||||
MockModule('comp_a', setup=config_check_setup))
|
||||
platform = MockPlatform()
|
||||
|
||||
loader.set_component(
|
||||
self.hass, 'switch.platform_a', MockPlatform('comp_b', ['comp_a']))
|
||||
mock_integration(self.hass,
|
||||
MockModule('comp_a', setup=config_check_setup))
|
||||
mock_integration(
|
||||
self.hass,
|
||||
MockModule('platform_a',
|
||||
setup=config_check_setup,
|
||||
dependencies=['comp_a']),
|
||||
)
|
||||
|
||||
mock_entity_platform(self.hass, 'switch.platform_a', platform)
|
||||
|
||||
setup.setup_component(self.hass, 'switch', {
|
||||
'comp_a': {
|
||||
@ -445,7 +447,7 @@ class TestSetup:
|
||||
|
||||
mock_setup = mock.MagicMock(spec_set=True)
|
||||
|
||||
loader.set_component(
|
||||
mock_entity_platform(
|
||||
self.hass,
|
||||
'switch.platform_a',
|
||||
MockPlatform(platform_schema=platform_schema,
|
||||
@ -476,7 +478,7 @@ class TestSetup:
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
self.hass.config.components.remove('switch')
|
||||
|
||||
with assert_setup_component(1):
|
||||
with assert_setup_component(1, 'switch'):
|
||||
assert setup.setup_component(self.hass, 'switch', {
|
||||
'switch': {
|
||||
'platform': 'platform_a',
|
||||
@ -487,9 +489,8 @@ class TestSetup:
|
||||
|
||||
def test_disable_component_if_invalid_return(self):
|
||||
"""Test disabling component if invalid return."""
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: None))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'disabled_component')
|
||||
@ -497,9 +498,8 @@ class TestSetup:
|
||||
assert 'disabled_component' not in self.hass.config.components
|
||||
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: False))
|
||||
|
||||
assert not setup.setup_component(self.hass, 'disabled_component')
|
||||
@ -508,9 +508,8 @@ class TestSetup:
|
||||
assert 'disabled_component' not in self.hass.config.components
|
||||
|
||||
self.hass.data.pop(setup.DATA_SETUP)
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'disabled_component',
|
||||
MockModule('disabled_component', setup=lambda hass, config: True))
|
||||
|
||||
assert setup.setup_component(self.hass, 'disabled_component')
|
||||
@ -535,19 +534,16 @@ class TestSetup:
|
||||
call_order.append(1)
|
||||
return True
|
||||
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'test_component1',
|
||||
MockModule('test_component1', setup=component1_setup))
|
||||
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'test_component2',
|
||||
MockModule('test_component2', setup=component_track_setup))
|
||||
|
||||
loader.set_component(
|
||||
mock_integration(
|
||||
self.hass,
|
||||
'test_component3',
|
||||
MockModule('test_component3', setup=component_track_setup))
|
||||
|
||||
@callback
|
||||
@ -575,8 +571,7 @@ def test_component_cannot_depend_config(hass):
|
||||
@asyncio.coroutine
|
||||
def test_component_warn_slow_setup(hass):
|
||||
"""Warn we log when a component setup takes a long time."""
|
||||
loader.set_component(
|
||||
hass, 'test_component1', MockModule('test_component1'))
|
||||
mock_integration(hass, MockModule('test_component1'))
|
||||
with mock.patch.object(hass.loop, 'call_later', mock.MagicMock()) \
|
||||
as mock_call:
|
||||
result = yield from setup.async_setup_component(
|
||||
@ -596,8 +591,8 @@ def test_component_warn_slow_setup(hass):
|
||||
@asyncio.coroutine
|
||||
def test_platform_no_warn_slow(hass):
|
||||
"""Do not warn for long entity setup time."""
|
||||
loader.set_component(
|
||||
hass, 'test_component1',
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule('test_component1', platform_schema=PLATFORM_SCHEMA))
|
||||
with mock.patch.object(hass.loop, 'call_later', mock.MagicMock()) \
|
||||
as mock_call:
|
||||
|
1
tests/testing_config/__init__.py
Normal file
1
tests/testing_config/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""Configuration that's used when running tests."""
|
1
tests/testing_config/custom_components/__init__.py
Normal file
1
tests/testing_config/custom_components/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""A collection of custom integrations used when running tests."""
|
1
tests/testing_config/custom_components/test/__init__.py
Normal file
1
tests/testing_config/custom_components/test/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
"""An integration with several platforms used with unit tests."""
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"domain": "test",
|
||||
"name": "Test Components",
|
||||
"documentation": "http://example.com",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"codeowners": []
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user