mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 22:07:10 +00:00
Enforce async_load_fixture in async test functions (#145709)
This commit is contained in:
parent
179e1c2b00
commit
e642cd45ae
80
pylint/plugins/hass_async_load_fixtures.py
Normal file
80
pylint/plugins/hass_async_load_fixtures.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
"""Plugin for logger invocations."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from astroid import nodes
|
||||||
|
from pylint.checkers import BaseChecker
|
||||||
|
from pylint.lint import PyLinter
|
||||||
|
|
||||||
|
FUNCTION_NAMES = (
|
||||||
|
"load_fixture",
|
||||||
|
"load_json_array_fixture",
|
||||||
|
"load_json_object_fixture",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HassLoadFixturesChecker(BaseChecker):
|
||||||
|
"""Checker for I/O load fixtures."""
|
||||||
|
|
||||||
|
name = "hass_async_load_fixtures"
|
||||||
|
priority = -1
|
||||||
|
msgs = {
|
||||||
|
"W7481": (
|
||||||
|
"Test fixture files should be loaded asynchronously",
|
||||||
|
"hass-async-load-fixtures",
|
||||||
|
"Used when a test fixture file is loaded synchronously",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
options = ()
|
||||||
|
|
||||||
|
_decorators_queue: list[nodes.Decorators]
|
||||||
|
_function_queue: list[nodes.FunctionDef | nodes.AsyncFunctionDef]
|
||||||
|
_in_test_module: bool
|
||||||
|
|
||||||
|
def visit_module(self, node: nodes.Module) -> None:
|
||||||
|
"""Visit a module definition."""
|
||||||
|
self._in_test_module = node.name.startswith("tests.")
|
||||||
|
self._decorators_queue = []
|
||||||
|
self._function_queue = []
|
||||||
|
|
||||||
|
def visit_decorators(self, node: nodes.Decorators) -> None:
|
||||||
|
"""Visit a function definition."""
|
||||||
|
self._decorators_queue.append(node)
|
||||||
|
|
||||||
|
def leave_decorators(self, node: nodes.Decorators) -> None:
|
||||||
|
"""Leave a function definition."""
|
||||||
|
self._decorators_queue.pop()
|
||||||
|
|
||||||
|
def visit_functiondef(self, node: nodes.FunctionDef) -> None:
|
||||||
|
"""Visit a function definition."""
|
||||||
|
self._function_queue.append(node)
|
||||||
|
|
||||||
|
def leave_functiondef(self, node: nodes.FunctionDef) -> None:
|
||||||
|
"""Leave a function definition."""
|
||||||
|
self._function_queue.pop()
|
||||||
|
|
||||||
|
visit_asyncfunctiondef = visit_functiondef
|
||||||
|
leave_asyncfunctiondef = leave_functiondef
|
||||||
|
|
||||||
|
def visit_call(self, node: nodes.Call) -> None:
|
||||||
|
"""Check for sync I/O in load_fixture."""
|
||||||
|
if (
|
||||||
|
# Ensure we are in a test module
|
||||||
|
not self._in_test_module
|
||||||
|
# Ensure we are in an async function context
|
||||||
|
or not self._function_queue
|
||||||
|
or not isinstance(self._function_queue[-1], nodes.AsyncFunctionDef)
|
||||||
|
# Ensure we are not in the decorators
|
||||||
|
or self._decorators_queue
|
||||||
|
# Check function name
|
||||||
|
or not isinstance(node.func, nodes.Name)
|
||||||
|
or node.func.name not in FUNCTION_NAMES
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.add_message("hass-async-load-fixtures", node=node)
|
||||||
|
|
||||||
|
|
||||||
|
def register(linter: PyLinter) -> None:
|
||||||
|
"""Register the checker."""
|
||||||
|
linter.register_checker(HassLoadFixturesChecker(linter))
|
@ -118,6 +118,7 @@ init-hook = """\
|
|||||||
load-plugins = [
|
load-plugins = [
|
||||||
"pylint.extensions.code_style",
|
"pylint.extensions.code_style",
|
||||||
"pylint.extensions.typing",
|
"pylint.extensions.typing",
|
||||||
|
"hass_async_load_fixtures",
|
||||||
"hass_decorator",
|
"hass_decorator",
|
||||||
"hass_enforce_class_module",
|
"hass_enforce_class_module",
|
||||||
"hass_enforce_sorted_platforms",
|
"hass_enforce_sorted_platforms",
|
||||||
|
@ -9,7 +9,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.util import location as location_util
|
from homeassistant.util import location as location_util
|
||||||
|
|
||||||
from tests.common import load_fixture
|
from tests.common import async_load_fixture
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
# Paris
|
# Paris
|
||||||
@ -77,10 +77,14 @@ def test_get_miles() -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_detect_location_info_whoami(
|
async def test_detect_location_info_whoami(
|
||||||
aioclient_mock: AiohttpClientMocker, session: aiohttp.ClientSession
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
session: aiohttp.ClientSession,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test detect location info using services.home-assistant.io/whoami."""
|
"""Test detect location info using services.home-assistant.io/whoami."""
|
||||||
aioclient_mock.get(location_util.WHOAMI_URL, text=load_fixture("whoami.json"))
|
aioclient_mock.get(
|
||||||
|
location_util.WHOAMI_URL, text=await async_load_fixture(hass, "whoami.json")
|
||||||
|
)
|
||||||
|
|
||||||
with patch("homeassistant.util.location.HA_VERSION", "1.0"):
|
with patch("homeassistant.util.location.HA_VERSION", "1.0"):
|
||||||
info = await location_util.async_detect_location_info(session, _test_real=True)
|
info = await location_util.async_detect_location_info(session, _test_real=True)
|
||||||
@ -101,10 +105,14 @@ async def test_detect_location_info_whoami(
|
|||||||
|
|
||||||
|
|
||||||
async def test_dev_url(
|
async def test_dev_url(
|
||||||
aioclient_mock: AiohttpClientMocker, session: aiohttp.ClientSession
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
session: aiohttp.ClientSession,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test usage of dev URL."""
|
"""Test usage of dev URL."""
|
||||||
aioclient_mock.get(location_util.WHOAMI_URL_DEV, text=load_fixture("whoami.json"))
|
aioclient_mock.get(
|
||||||
|
location_util.WHOAMI_URL_DEV, text=await async_load_fixture(hass, "whoami.json")
|
||||||
|
)
|
||||||
with patch("homeassistant.util.location.HA_VERSION", "1.0.dev0"):
|
with patch("homeassistant.util.location.HA_VERSION", "1.0.dev0"):
|
||||||
info = await location_util.async_detect_location_info(session, _test_real=True)
|
info = await location_util.async_detect_location_info(session, _test_real=True)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user