Repository: MatthewFlamm/pytest-homeassistant-custom-component (language: python)

Issue:
Fix load fixture
Fixes #41 

Instead of using `__file__` which gives a path to where this library is installed, use `traceback.extract_stack` to find the path where `load_fixture` is called from.

files must be placed in `path_of_test/fixtures`


Discussion / hints:

Fix patch:
diff --git a/requirements_dev.txt b/requirements_dev.txt
index b01432a..896e6ef 100644
--- a/requirements_dev.txt
+++ b/requirements_dev.txt
@@ -1,6 +1,6 @@
 # This file is originally from homeassistant/core and modified by pytest-homeassistant-custom-component.
 codecov==2.1.10
 mypy==0.800
-pre-commit==2.10.0
+pre-commit==2.10.1
 pylint==2.6.0
 astroid==2.4.2


Test patch:
diff --git a/pytest_homeassistant_custom_component/common.py b/pytest_homeassistant_custom_component/common.py
index 8edba41..e769198 100644
--- a/pytest_homeassistant_custom_component/common.py
+++ b/pytest_homeassistant_custom_component/common.py
@@ -16,6 +16,9 @@
 import pathlib
 import threading
 import time
+from time import monotonic
+import types
+from typing import Any, Awaitable, Collection, Optional
 from unittest.mock import AsyncMock, Mock, patch
 import uuid
 
@@ -47,7 +50,7 @@
     STATE_OFF,
     STATE_ON,
 )
-from homeassistant.core import State
+from homeassistant.core import BLOCK_LOG_TIMEOUT, State
 from homeassistant.helpers import (
     area_registry,
     device_registry,
@@ -194,9 +197,76 @@ def async_create_task(coroutine):
 
         return orig_async_create_task(coroutine)
 
+    async def async_wait_for_task_count(self, max_remaining_tasks: int = 0) -> None:
+        """Block until at most max_remaining_tasks remain.
+
+        Based on HomeAssistant.async_block_till_done
+        """
+        # To flush out any call_soon_threadsafe
+        await asyncio.sleep(0)
+        start_time: Optional[float] = None
+
+        while len(self._pending_tasks) > max_remaining_tasks:
+            pending = [
+                task for task in self._pending_tasks if not task.done()
+            ]  # type: Collection[Awaitable[Any]]
+            self._pending_tasks.clear()
+            if len(pending) > max_remaining_tasks:
+                remaining_pending = await self._await_count_and_log_pending(
+                    pending, max_remaining_tasks=max_remaining_tasks
+                )
+                self._pending_tasks.extend(remaining_pending)
+
+                if start_time is None:
+                    # Avoid calling monotonic() until we know
+                    # we may need to start logging blocked tasks.
+                    start_time = 0
+                elif start_time == 0:
+                    # If we have waited twice then we set the start
+                    # time
+                    start_time = monotonic()
+                elif monotonic() - start_time > BLOCK_LOG_TIMEOUT:
+                    # We have waited at least three loops and new tasks
+                    # continue to block. At this point we start
+                    # logging all waiting tasks.
+                    for task in pending:
+                        _LOGGER.debug("Waiting for task: %s", task)
+            else:
+                self._pending_tasks.extend(pending)
+                await asyncio.sleep(0)
+
+    async def _await_count_and_log_pending(
+        self, pending: Collection[Awaitable[Any]], max_remaining_tasks: int = 0
+    ) -> Collection[Awaitable[Any]]:
+        """Block at most max_remaining_tasks remain and log tasks that take a long time.
+
+        Based on HomeAssistant._await_and_log_pending
+        """
+        wait_time = 0
+
+        return_when = asyncio.ALL_COMPLETED
+        if max_remaining_tasks:
+            return_when = asyncio.FIRST_COMPLETED
+
+        while len(pending) > max_remaining_tasks:
+            _, pending = await asyncio.wait(
+                pending, timeout=BLOCK_LOG_TIMEOUT, return_when=return_when
+            )
+            if not pending or max_remaining_tasks:
+                return pending
+            wait_time += BLOCK_LOG_TIMEOUT
+            for task in pending:
+                _LOGGER.debug("Waited %s seconds for task: %s", wait_time, task)
+
+        return []
+
     hass.async_add_job = async_add_job
     hass.async_add_executor_job = async_add_executor_job
     hass.async_create_task = async_create_task
+    hass.async_wait_for_task_count = types.MethodType(async_wait_for_task_count, hass)
+    hass._await_count_and_log_pending = types.MethodType(
+        _await_count_and_log_pending, hass
+    )
 
     hass.data[loader.DATA_CUSTOM_COMPONENTS] = {}
 
diff --git a/requirements_test.txt b/requirements_test.txt
index 567c0d7..00a32af 100644
--- a/requirements_test.txt
+++ b/requirements_test.txt
@@ -9,7 +9,6 @@ coverage==5.4
 jsonpickle==1.4.1
 mock-open==1.4.0
 pipdeptree==1.0.0
-awesomeversion==21.1.6
 pylint-strict-informational==0.1
 pytest-aiohttp==0.3.0
 pytest-cov==2.10.1