core/tests/test_const.py

190 lines
5.4 KiB
Python

"""Test const module."""
from enum import Enum
import logging
import sys
from unittest.mock import Mock, patch
import pytest
from homeassistant import const
from homeassistant.components import alarm_control_panel, lock
from .common import (
extract_stack_to_frame,
help_test_all,
import_and_test_deprecated_constant,
import_and_test_deprecated_constant_enum,
)
def _create_tuples(
value: type[Enum] | list[Enum], constant_prefix: str
) -> list[tuple[Enum, str]]:
return [(enum, constant_prefix) for enum in value]
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(const)
@pytest.mark.parametrize(
("replacement", "constant_name", "breaks_in_version"),
[
(const.UnitOfArea.SQUARE_METERS, "AREA_SQUARE_METERS", "2025.12"),
],
)
def test_deprecated_constant_name_changes(
caplog: pytest.LogCaptureFixture,
replacement: Enum,
constant_name: str,
breaks_in_version: str,
) -> None:
"""Test deprecated constants, where the name is not the same as the enum value."""
import_and_test_deprecated_constant(
caplog,
const,
constant_name,
f"{replacement.__class__.__name__}.{replacement.name}",
replacement,
breaks_in_version,
)
def _create_tuples_lock_states(
enum: type[Enum], constant_prefix: str, remove_in_version: str
) -> list[tuple[Enum, str]]:
return [
(enum_field, constant_prefix, remove_in_version)
for enum_field in enum
if enum_field
not in [
lock.LockState.OPEN,
lock.LockState.OPENING,
]
]
@pytest.mark.parametrize(
("enum", "constant_prefix", "remove_in_version"),
_create_tuples_lock_states(lock.LockState, "STATE_", "2025.10"),
)
def test_deprecated_constants_lock(
caplog: pytest.LogCaptureFixture,
enum: Enum,
constant_prefix: str,
remove_in_version: str,
) -> None:
"""Test deprecated constants."""
import_and_test_deprecated_constant_enum(
caplog, const, enum, constant_prefix, remove_in_version
)
def _create_tuples_alarm_states(
enum: type[Enum], constant_prefix: str, remove_in_version: str
) -> list[tuple[Enum, str]]:
return [
(enum_field, constant_prefix, remove_in_version)
for enum_field in enum
if enum_field
not in [
lock.LockState.OPEN,
lock.LockState.OPENING,
]
]
@pytest.mark.parametrize(
("enum", "constant_prefix", "remove_in_version"),
_create_tuples_lock_states(
alarm_control_panel.AlarmControlPanelState, "STATE_ALARM_", "2025.11"
),
)
def test_deprecated_constants_alarm(
caplog: pytest.LogCaptureFixture,
enum: Enum,
constant_prefix: str,
remove_in_version: str,
) -> None:
"""Test deprecated constants."""
import_and_test_deprecated_constant_enum(
caplog, const, enum, constant_prefix, remove_in_version
)
def test_deprecated_unit_of_conductivity_alias() -> None:
"""Test UnitOfConductivity deprecation."""
# Test the deprecated members are aliases
assert set(const.UnitOfConductivity) == {"S/cm", "µS/cm", "mS/cm"}
def test_deprecated_unit_of_conductivity_members(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test UnitOfConductivity deprecation."""
module_name = "config.custom_components.hue.light"
filename = f"/home/paulus/{module_name.replace('.', '/')}.py"
with (
patch.dict(sys.modules, {module_name: Mock(__file__=filename)}),
patch(
"homeassistant.helpers.frame.linecache.getline",
return_value="await session.close()",
),
patch(
"homeassistant.helpers.frame.get_current_frame",
return_value=extract_stack_to_frame(
[
Mock(
filename="/home/paulus/homeassistant/core.py",
lineno="23",
line="do_something()",
),
Mock(
filename=filename,
lineno="23",
line="await session.close()",
),
Mock(
filename="/home/paulus/aiohue/lights.py",
lineno="2",
line="something()",
),
]
),
),
):
const.UnitOfConductivity.SIEMENS # noqa: B018
const.UnitOfConductivity.MICROSIEMENS # noqa: B018
const.UnitOfConductivity.MILLISIEMENS # noqa: B018
assert len(caplog.record_tuples) == 3
def deprecation_message(member: str, replacement: str) -> str:
return (
f"UnitOfConductivity.{member} was used from hue, this is a deprecated enum "
"member which will be removed in HA Core 2025.11.0. Use UnitOfConductivity."
f"{replacement} instead, please report it to the author of the 'hue' custom"
" integration"
)
assert (
const.__name__,
logging.WARNING,
deprecation_message("SIEMENS", "SIEMENS_PER_CM"),
) in caplog.record_tuples
assert (
const.__name__,
logging.WARNING,
deprecation_message("MICROSIEMENS", "MICROSIEMENS_PER_CM"),
) in caplog.record_tuples
assert (
const.__name__,
logging.WARNING,
deprecation_message("MILLISIEMENS", "MILLISIEMENS_PER_CM"),
) in caplog.record_tuples