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