2017-05-06 17:10:48 +00:00
|
|
|
"""Test deprecation helpers."""
|
2023-10-03 17:21:27 +00:00
|
|
|
from unittest.mock import MagicMock, Mock, patch
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-02-20 10:42:56 +00:00
|
|
|
import pytest
|
|
|
|
|
2021-01-26 14:53:21 +00:00
|
|
|
from homeassistant.helpers.deprecation import (
|
2023-10-03 18:57:24 +00:00
|
|
|
deprecated_class,
|
2021-01-26 14:53:21 +00:00
|
|
|
deprecated_function,
|
|
|
|
deprecated_substitute,
|
|
|
|
get_deprecated,
|
|
|
|
)
|
2020-05-03 18:27:19 +00:00
|
|
|
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
class MockBaseClassDeprecatedProperty:
|
2017-05-06 17:10:48 +00:00
|
|
|
"""Mock base class for deprecated testing."""
|
|
|
|
|
|
|
|
@property
|
2019-07-31 19:25:30 +00:00
|
|
|
@deprecated_substitute("old_property")
|
2017-05-06 17:10:48 +00:00
|
|
|
def new_property(self):
|
|
|
|
"""Test property to fetch."""
|
2023-10-03 18:57:24 +00:00
|
|
|
return "default_new"
|
2017-05-06 17:10:48 +00:00
|
|
|
|
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
@patch("logging.getLogger")
|
|
|
|
def test_deprecated_substitute_old_class(mock_get_logger) -> None:
|
|
|
|
"""Test deprecated class object."""
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
class MockDeprecatedClass(MockBaseClassDeprecatedProperty):
|
|
|
|
"""Mock deprecated class object."""
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
@property
|
|
|
|
def old_property(self):
|
|
|
|
"""Test property to fetch."""
|
|
|
|
return "old"
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
2017-05-06 17:10:48 +00:00
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
mock_object = MockDeprecatedClass()
|
|
|
|
assert mock_object.new_property == "old"
|
|
|
|
assert mock_logger.warning.called
|
|
|
|
assert len(mock_logger.warning.mock_calls) == 1
|
2017-05-06 17:10:48 +00:00
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("logging.getLogger")
|
2023-10-03 18:57:24 +00:00
|
|
|
def test_deprecated_substitute_default_class(mock_get_logger) -> None:
|
2017-05-06 17:10:48 +00:00
|
|
|
"""Test deprecated class object."""
|
2023-10-03 18:57:24 +00:00
|
|
|
|
|
|
|
class MockDefaultClass(MockBaseClassDeprecatedProperty):
|
|
|
|
"""Mock updated class object."""
|
|
|
|
|
2017-05-06 17:10:48 +00:00
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
mock_object = MockDefaultClass()
|
|
|
|
assert mock_object.new_property == "default_new"
|
|
|
|
assert not mock_logger.warning.called
|
2017-05-06 17:10:48 +00:00
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("logging.getLogger")
|
2023-02-20 10:42:56 +00:00
|
|
|
def test_deprecated_substitute_new_class(mock_get_logger) -> None:
|
2017-05-06 17:10:48 +00:00
|
|
|
"""Test deprecated class object."""
|
2023-10-03 18:57:24 +00:00
|
|
|
|
|
|
|
class MockUpdatedClass(MockBaseClassDeprecatedProperty):
|
|
|
|
"""Mock updated class object."""
|
|
|
|
|
|
|
|
@property
|
|
|
|
def new_property(self):
|
|
|
|
"""Test property to fetch."""
|
|
|
|
return "new"
|
|
|
|
|
2017-05-06 17:10:48 +00:00
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
|
|
|
|
|
|
|
mock_object = MockUpdatedClass()
|
2023-10-03 18:57:24 +00:00
|
|
|
assert mock_object.new_property == "new"
|
2017-05-06 17:10:48 +00:00
|
|
|
assert not mock_logger.warning.called
|
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("logging.getLogger")
|
2023-02-20 10:42:56 +00:00
|
|
|
def test_config_get_deprecated_old(mock_get_logger) -> None:
|
2023-10-03 18:57:24 +00:00
|
|
|
"""Test deprecated config."""
|
2017-05-06 17:10:48 +00:00
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
config = {"old_name": True}
|
|
|
|
assert get_deprecated(config, "new_name", "old_name") is True
|
2017-05-06 17:10:48 +00:00
|
|
|
assert mock_logger.warning.called
|
|
|
|
assert len(mock_logger.warning.mock_calls) == 1
|
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("logging.getLogger")
|
2023-02-20 10:42:56 +00:00
|
|
|
def test_config_get_deprecated_new(mock_get_logger) -> None:
|
2023-10-03 18:57:24 +00:00
|
|
|
"""Test deprecated config."""
|
2017-05-06 17:10:48 +00:00
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
config = {"new_name": True}
|
|
|
|
assert get_deprecated(config, "new_name", "old_name") is True
|
2017-05-06 17:10:48 +00:00
|
|
|
assert not mock_logger.warning.called
|
2021-01-26 14:53:21 +00:00
|
|
|
|
|
|
|
|
2023-10-03 18:57:24 +00:00
|
|
|
@deprecated_class("homeassistant.blah.NewClass")
|
|
|
|
class MockDeprecatedClass:
|
|
|
|
"""Mock class for deprecated testing."""
|
|
|
|
|
|
|
|
|
|
|
|
@patch("logging.getLogger")
|
|
|
|
def test_deprecated_class(mock_get_logger) -> None:
|
|
|
|
"""Test deprecated class."""
|
|
|
|
mock_logger = MagicMock()
|
|
|
|
mock_get_logger.return_value = mock_logger
|
|
|
|
|
|
|
|
MockDeprecatedClass()
|
|
|
|
assert mock_logger.warning.called
|
|
|
|
assert len(mock_logger.warning.mock_calls) == 1
|
|
|
|
|
|
|
|
|
2023-02-20 10:42:56 +00:00
|
|
|
def test_deprecated_function(caplog: pytest.LogCaptureFixture) -> None:
|
2023-10-03 17:21:27 +00:00
|
|
|
"""Test deprecated_function decorator.
|
|
|
|
|
|
|
|
This tests the behavior when the calling integration is not known.
|
|
|
|
"""
|
2021-01-26 14:53:21 +00:00
|
|
|
|
|
|
|
@deprecated_function("new_function")
|
|
|
|
def mock_deprecated_function():
|
|
|
|
pass
|
|
|
|
|
|
|
|
mock_deprecated_function()
|
|
|
|
assert (
|
|
|
|
"mock_deprecated_function is a deprecated function. Use new_function instead"
|
|
|
|
in caplog.text
|
|
|
|
)
|
2023-10-03 17:21:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_deprecated_function_called_from_built_in_integration(
|
|
|
|
caplog: pytest.LogCaptureFixture,
|
|
|
|
) -> None:
|
|
|
|
"""Test deprecated_function decorator.
|
|
|
|
|
|
|
|
This tests the behavior when the calling integration is built-in.
|
|
|
|
"""
|
|
|
|
|
|
|
|
@deprecated_function("new_function")
|
|
|
|
def mock_deprecated_function():
|
|
|
|
pass
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.frame.extract_stack",
|
|
|
|
return_value=[
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/homeassistant/core.py",
|
|
|
|
lineno="23",
|
|
|
|
line="do_something()",
|
|
|
|
),
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/homeassistant/components/hue/light.py",
|
|
|
|
lineno="23",
|
|
|
|
line="await session.close()",
|
|
|
|
),
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/aiohue/lights.py",
|
|
|
|
lineno="2",
|
|
|
|
line="something()",
|
|
|
|
),
|
|
|
|
],
|
|
|
|
):
|
|
|
|
mock_deprecated_function()
|
|
|
|
assert (
|
|
|
|
"mock_deprecated_function was called from hue, this is a deprecated function. "
|
|
|
|
"Use new_function instead" in caplog.text
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def test_deprecated_function_called_from_custom_integration(
|
|
|
|
caplog: pytest.LogCaptureFixture,
|
|
|
|
) -> None:
|
|
|
|
"""Test deprecated_function decorator.
|
|
|
|
|
|
|
|
This tests the behavior when the calling integration is custom.
|
|
|
|
"""
|
|
|
|
|
|
|
|
@deprecated_function("new_function")
|
|
|
|
def mock_deprecated_function():
|
|
|
|
pass
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.frame.extract_stack",
|
|
|
|
return_value=[
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/homeassistant/core.py",
|
|
|
|
lineno="23",
|
|
|
|
line="do_something()",
|
|
|
|
),
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/config/custom_components/hue/light.py",
|
|
|
|
lineno="23",
|
|
|
|
line="await session.close()",
|
|
|
|
),
|
|
|
|
Mock(
|
|
|
|
filename="/home/paulus/aiohue/lights.py",
|
|
|
|
lineno="2",
|
|
|
|
line="something()",
|
|
|
|
),
|
|
|
|
],
|
|
|
|
):
|
|
|
|
mock_deprecated_function()
|
|
|
|
assert (
|
|
|
|
"mock_deprecated_function was called from hue, this is a deprecated function. "
|
|
|
|
"Use new_function instead, please report this to the maintainer of hue"
|
|
|
|
in caplog.text
|
|
|
|
)
|