diff --git a/homeassistant/components/recorder/models.py b/homeassistant/components/recorder/models.py index 3bbd9f173a3..4d92ec30986 100644 --- a/homeassistant/components/recorder/models.py +++ b/homeassistant/components/recorder/models.py @@ -233,15 +233,6 @@ class LazyStatePreSchema31(State): "last_updated": last_updated_isoformat, } - def __eq__(self, other: Any) -> bool: - """Return the comparison.""" - return ( - other.__class__ in [self.__class__, State] - and self.entity_id == other.entity_id - and self.state == other.state - and self.attributes == other.attributes - ) - class LazyState(State): """A lazy version of core State after schema 31.""" @@ -341,15 +332,6 @@ class LazyState(State): "last_updated": last_updated_isoformat, } - def __eq__(self, other: Any) -> bool: - """Return the comparison.""" - return ( - other.__class__ in [self.__class__, State] - and self.entity_id == other.entity_id - and self.state == other.state - and self.attributes == other.attributes - ) - def decode_attributes_from_row( row: Row, attr_cache: dict[str, dict[str, Any]] diff --git a/homeassistant/core.py b/homeassistant/core.py index 97ffd3e7fe0..57b37af3904 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -813,11 +813,6 @@ class Event: id=ulid_util.ulid(dt_util.utc_to_timestamp(self.time_fired)) ) - def __hash__(self) -> int: - """Make hashable.""" - # The only event type that shares context are the TIME_CHANGED - return hash((self.event_type, self.context.id, self.time_fired)) - def as_dict(self) -> dict[str, Any]: """Create a dict representation of this Event. @@ -841,17 +836,6 @@ class Event: return f"" - def __eq__(self, other: Any) -> bool: - """Return the comparison.""" - return ( # type: ignore[no-any-return] - self.__class__ == other.__class__ - and self.event_type == other.event_type - and self.data == other.data - and self.origin == other.origin - and self.time_fired == other.time_fired - and self.context == other.context - ) - class _FilterableJob(NamedTuple): """Event listener job to be executed with optional filter.""" @@ -1156,13 +1140,6 @@ class State: self._as_dict: ReadOnlyDict[str, Collection[Any]] | None = None self._as_compressed_state: dict[str, Any] | None = None - def __hash__(self) -> int: - """Make the state hashable. - - State objects are effectively immutable. - """ - return hash((id(self), self.last_updated)) - @property def name(self) -> str: """Name of this state.""" @@ -1274,16 +1251,6 @@ class State: self.context.user_id, self.context.parent_id, self.context.id ) - def __eq__(self, other: Any) -> bool: - """Return the comparison of the state.""" - return ( # type: ignore[no-any-return] - self.__class__ == other.__class__ - and self.entity_id == other.entity_id - and self.state == other.state - and self.attributes == other.attributes - and self.context == other.context - ) - def __repr__(self) -> str: """Return the representation of the states.""" attrs = f"; {util.repr_helper(self.attributes)}" if self.attributes else "" diff --git a/tests/components/api/test_init.py b/tests/components/api/test_init.py index f1df9d1eded..1d90e7cc7e1 100644 --- a/tests/components/api/test_init.py +++ b/tests/components/api/test_init.py @@ -30,8 +30,9 @@ async def test_api_list_state_entities(hass, mock_api_client): assert resp.status == HTTPStatus.OK json = await resp.json() - remote_data = [ha.State.from_dict(item) for item in json] - assert remote_data == hass.states.async_all() + remote_data = [ha.State.from_dict(item).as_dict() for item in json] + local_data = [state.as_dict() for state in hass.states.async_all()] + assert remote_data == local_data async def test_api_get_state(hass, mock_api_client): diff --git a/tests/components/group/test_reproduce_state.py b/tests/components/group/test_reproduce_state.py index 58bbc94876e..bee3883aad2 100644 --- a/tests/components/group/test_reproduce_state.py +++ b/tests/components/group/test_reproduce_state.py @@ -1,7 +1,7 @@ """The tests for reproduction of state.""" from asyncio import Future -from unittest.mock import patch +from unittest.mock import ANY, patch from homeassistant.components.group.reproduce_state import async_reproduce_states from homeassistant.core import Context, State @@ -43,11 +43,12 @@ async def test_reproduce_group(hass): fun.assert_called_once_with( hass, - [ - clone_state(state, "light.test1"), - clone_state(state, "light.test2"), - clone_state(state, "switch.test1"), - ], + ANY, context=context, reproduce_options=None, ) + entities = fun.call_args[0][1] + + assert entities[0].entity_id == "light.test1" + assert entities[1].entity_id == "light.test2" + assert entities[2].entity_id == "switch.test1" diff --git a/tests/components/history/__init__.py b/tests/components/history/__init__.py index 662e70a7bff..ff4af92d985 100644 --- a/tests/components/history/__init__.py +++ b/tests/components/history/__init__.py @@ -1 +1,5 @@ """Tests for the history component.""" + +import pytest + +pytest.register_assert_rewrite("tests.components.recorder.common") diff --git a/tests/components/history/test_init.py b/tests/components/history/test_init.py index 39d11f69b2e..a3fc5363ee1 100644 --- a/tests/components/history/test_init.py +++ b/tests/components/history/test_init.py @@ -23,6 +23,10 @@ from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util from tests.components.recorder.common import ( + assert_dict_of_states_equal_without_context_and_last_changed, + assert_multiple_states_equal_without_context, + assert_multiple_states_equal_without_context_and_last_changed, + assert_states_equal_without_context, async_wait_recording_done, wait_recording_done, ) @@ -53,7 +57,7 @@ def test_get_significant_states(hass_history): hass = hass_history zero, four, states = record_states(hass) hist = get_significant_states(hass, zero, four, filters=history.Filters()) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_minimal_response(hass_history): @@ -95,7 +99,30 @@ def test_get_significant_states_minimal_response(hass_history): "last_changed": orig_last_changed, "state": orig_state, } - assert states == hist + assert len(hist) == len(states) + assert_states_equal_without_context( + states["media_player.test"][0], hist["media_player.test"][0] + ) + assert states["media_player.test"][1] == hist["media_player.test"][1] + assert states["media_player.test"][2] == hist["media_player.test"][2] + + assert_multiple_states_equal_without_context( + states["media_player.test2"], hist["media_player.test2"] + ) + assert_states_equal_without_context( + states["media_player.test3"][0], hist["media_player.test3"][0] + ) + assert states["media_player.test3"][1] == hist["media_player.test3"][1] + + assert_multiple_states_equal_without_context( + states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test2"], hist["thermostat.test2"] + ) def test_get_significant_states_with_initial(hass_history): @@ -123,7 +150,7 @@ def test_get_significant_states_with_initial(hass_history): filters=history.Filters(), include_start_time_state=True, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_without_initial(hass_history): @@ -150,7 +177,7 @@ def test_get_significant_states_without_initial(hass_history): filters=history.Filters(), include_start_time_state=False, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_entity_id(hass_history): @@ -166,7 +193,7 @@ def test_get_significant_states_entity_id(hass_history): hist = get_significant_states( hass, zero, four, ["media_player.test"], filters=history.Filters() ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_multiple_entity_ids(hass_history): @@ -185,7 +212,7 @@ def test_get_significant_states_multiple_entity_ids(hass_history): ["media_player.test", "thermostat.test"], filters=history.Filters(), ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_exclude_domain(hass_history): @@ -490,14 +517,22 @@ def test_get_significant_states_only(hass_history): hist = get_significant_states(hass, start, significant_changes_only=True) assert len(hist[entity_id]) == 2 - assert states[0] not in hist[entity_id] - assert states[1] in hist[entity_id] - assert states[2] in hist[entity_id] + assert not any( + state.last_updated == states[0].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[1].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[2].last_updated for state in hist[entity_id] + ) hist = get_significant_states(hass, start, significant_changes_only=False) assert len(hist[entity_id]) == 3 - assert states == hist[entity_id] + assert_multiple_states_equal_without_context_and_last_changed( + states, hist[entity_id] + ) def check_significant_states(hass, zero, four, states, config): @@ -513,7 +548,7 @@ def check_significant_states(hass, zero, four, states, config): filters.included_domains = include.get(CONF_DOMAINS, []) hist = get_significant_states(hass, zero, four, filters=filters) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def record_states(hass): diff --git a/tests/components/history/test_init_db_schema_30.py b/tests/components/history/test_init_db_schema_30.py index 7d1659d94f9..0aca4140f10 100644 --- a/tests/components/history/test_init_db_schema_30.py +++ b/tests/components/history/test_init_db_schema_30.py @@ -24,6 +24,10 @@ from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util from tests.components.recorder.common import ( + assert_dict_of_states_equal_without_context_and_last_changed, + assert_multiple_states_equal_without_context, + assert_multiple_states_equal_without_context_and_last_changed, + assert_states_equal_without_context, async_recorder_block_till_done, async_wait_recording_done, wait_recording_done, @@ -91,7 +95,7 @@ def test_get_significant_states(hass_history): hass = hass_history zero, four, states = record_states(hass) hist = get_significant_states(hass, zero, four, filters=history.Filters()) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_minimal_response(hass_history): @@ -133,7 +137,31 @@ def test_get_significant_states_minimal_response(hass_history): "last_changed": orig_last_changed, "state": orig_state, } - assert states == hist + + assert len(hist) == len(states) + assert_states_equal_without_context( + states["media_player.test"][0], hist["media_player.test"][0] + ) + assert states["media_player.test"][1] == hist["media_player.test"][1] + assert states["media_player.test"][2] == hist["media_player.test"][2] + + assert_multiple_states_equal_without_context( + states["media_player.test2"], hist["media_player.test2"] + ) + assert_states_equal_without_context( + states["media_player.test3"][0], hist["media_player.test3"][0] + ) + assert states["media_player.test3"][1] == hist["media_player.test3"][1] + + assert_multiple_states_equal_without_context( + states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test2"], hist["thermostat.test2"] + ) def test_get_significant_states_with_initial(hass_history): @@ -153,6 +181,7 @@ def test_get_significant_states_with_initial(hass_history): for state in states[entity_id]: if state.last_changed == one: state.last_changed = one_and_half + state.last_updated = one_and_half hist = get_significant_states( hass, @@ -161,7 +190,7 @@ def test_get_significant_states_with_initial(hass_history): filters=history.Filters(), include_start_time_state=True, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_without_initial(hass_history): @@ -188,7 +217,7 @@ def test_get_significant_states_without_initial(hass_history): filters=history.Filters(), include_start_time_state=False, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_entity_id(hass_history): @@ -204,7 +233,7 @@ def test_get_significant_states_entity_id(hass_history): hist = get_significant_states( hass, zero, four, ["media_player.test"], filters=history.Filters() ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_multiple_entity_ids(hass_history): @@ -223,7 +252,7 @@ def test_get_significant_states_multiple_entity_ids(hass_history): ["media_player.test", "thermostat.test"], filters=history.Filters(), ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_exclude_domain(hass_history): @@ -528,14 +557,22 @@ def test_get_significant_states_only(hass_history): hist = get_significant_states(hass, start, significant_changes_only=True) assert len(hist[entity_id]) == 2 - assert states[0] not in hist[entity_id] - assert states[1] in hist[entity_id] - assert states[2] in hist[entity_id] + assert not any( + state.last_updated == states[0].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[1].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[2].last_updated for state in hist[entity_id] + ) hist = get_significant_states(hass, start, significant_changes_only=False) assert len(hist[entity_id]) == 3 - assert states == hist[entity_id] + assert_multiple_states_equal_without_context_and_last_changed( + states, hist[entity_id] + ) def check_significant_states(hass, zero, four, states, config): @@ -551,7 +588,7 @@ def check_significant_states(hass, zero, four, states, config): filters.included_domains = include.get(CONF_DOMAINS, []) hist = get_significant_states(hass, zero, four, filters=filters) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def record_states(hass): diff --git a/tests/components/recorder/__init__.py b/tests/components/recorder/__init__.py index fca6a655ba4..6e98d881ea9 100644 --- a/tests/components/recorder/__init__.py +++ b/tests/components/recorder/__init__.py @@ -1 +1,5 @@ """Tests for Recorder component.""" + +import pytest + +pytest.register_assert_rewrite("tests.components.recorder.common") diff --git a/tests/components/recorder/common.py b/tests/components/recorder/common.py index ce9ed30797b..aec5bf81349 100644 --- a/tests/components/recorder/common.py +++ b/tests/components/recorder/common.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio +from collections.abc import Iterable from dataclasses import dataclass from datetime import datetime import time @@ -16,7 +17,7 @@ from homeassistant.components.recorder import get_instance, statistics from homeassistant.components.recorder.core import Recorder from homeassistant.components.recorder.db_schema import RecorderRuns from homeassistant.components.recorder.tasks import RecorderTask, StatisticsTask -from homeassistant.core import HomeAssistant +from homeassistant.core import Event, HomeAssistant, State from homeassistant.util import dt as dt_util from . import db_schema_0 @@ -155,3 +156,68 @@ def statistics_during_period( return statistics.statistics_during_period( hass, start_time, end_time, statistic_ids, period, units, types ) + + +def assert_states_equal_without_context(state: State, other: State) -> None: + """Assert that two states are equal, ignoring context.""" + assert_states_equal_without_context_and_last_changed(state, other) + assert state.last_changed == other.last_changed + + +def assert_states_equal_without_context_and_last_changed( + state: State, other: State +) -> None: + """Assert that two states are equal, ignoring context and last_changed.""" + assert state.state == other.state + assert state.attributes == other.attributes + assert state.last_updated == other.last_updated + + +def assert_multiple_states_equal_without_context_and_last_changed( + states: Iterable[State], others: Iterable[State] +) -> None: + """Assert that multiple states are equal, ignoring context and last_changed.""" + states_list = list(states) + others_list = list(others) + assert len(states_list) == len(others_list) + for i, state in enumerate(states_list): + assert_states_equal_without_context_and_last_changed(state, others_list[i]) + + +def assert_multiple_states_equal_without_context( + states: Iterable[State], others: Iterable[State] +) -> None: + """Assert that multiple states are equal, ignoring context.""" + states_list = list(states) + others_list = list(others) + assert len(states_list) == len(others_list) + for i, state in enumerate(states_list): + assert_states_equal_without_context(state, others_list[i]) + + +def assert_events_equal_without_context(event: Event, other: Event) -> None: + """Assert that two events are equal, ignoring context.""" + assert event.data == other.data + assert event.event_type == other.event_type + assert event.origin == other.origin + assert event.time_fired == other.time_fired + + +def assert_dict_of_states_equal_without_context( + states: dict[str, list[State]], others: dict[str, list[State]] +) -> None: + """Assert that two dicts of states are equal, ignoring context.""" + assert len(states) == len(others) + for entity_id, state in states.items(): + assert_multiple_states_equal_without_context(state, others[entity_id]) + + +def assert_dict_of_states_equal_without_context_and_last_changed( + states: dict[str, list[State]], others: dict[str, list[State]] +) -> None: + """Assert that two dicts of states are equal, ignoring context and last_changed.""" + assert len(states) == len(others) + for entity_id, state in states.items(): + assert_multiple_states_equal_without_context_and_last_changed( + state, others[entity_id] + ) diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index c35f0075844..83d55f978af 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -30,6 +30,10 @@ from homeassistant.helpers.json import JSONEncoder import homeassistant.util.dt as dt_util from .common import ( + assert_dict_of_states_equal_without_context_and_last_changed, + assert_multiple_states_equal_without_context, + assert_multiple_states_equal_without_context_and_last_changed, + assert_states_equal_without_context, async_recorder_block_till_done, async_wait_recording_done, wait_recording_done, @@ -250,7 +254,7 @@ def test_state_changes_during_period(hass_recorder, attributes, no_attributes, l hass, start, end, entity_id, no_attributes, limit=limit ) - assert states[:limit] == hist[entity_id] + assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) def test_state_changes_during_period_descending(hass_recorder): @@ -303,12 +307,14 @@ def test_state_changes_during_period_descending(hass_recorder): hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False ) - assert states == hist[entity_id] + assert_multiple_states_equal_without_context(states, hist[entity_id]) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=True ) - assert states == list(reversed(list(hist[entity_id]))) + assert_multiple_states_equal_without_context( + states, list(reversed(list(hist[entity_id]))) + ) def test_get_last_state_changes(hass_recorder): @@ -344,7 +350,7 @@ def test_get_last_state_changes(hass_recorder): hist = history.get_last_state_changes(hass, 2, entity_id) - assert states == hist[entity_id] + assert_multiple_states_equal_without_context(states, hist[entity_id]) def test_ensure_state_can_be_copied(hass_recorder): @@ -377,8 +383,8 @@ def test_ensure_state_can_be_copied(hass_recorder): hist = history.get_last_state_changes(hass, 2, entity_id) - assert copy(hist[entity_id][0]) == hist[entity_id][0] - assert copy(hist[entity_id][1]) == hist[entity_id][1] + assert_states_equal_without_context(copy(hist[entity_id][0]), hist[entity_id][0]) + assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1]) def test_get_significant_states(hass_recorder): @@ -391,7 +397,7 @@ def test_get_significant_states(hass_recorder): hass = hass_recorder() zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_minimal_response(hass_recorder): @@ -431,7 +437,31 @@ def test_get_significant_states_minimal_response(hass_recorder): "last_changed": orig_last_changed, "state": orig_state, } - assert states == hist + + assert len(hist) == len(states) + assert_states_equal_without_context( + states["media_player.test"][0], hist["media_player.test"][0] + ) + assert states["media_player.test"][1] == hist["media_player.test"][1] + assert states["media_player.test"][2] == hist["media_player.test"][2] + + assert_multiple_states_equal_without_context( + states["media_player.test2"], hist["media_player.test2"] + ) + assert_states_equal_without_context( + states["media_player.test3"][0], hist["media_player.test3"][0] + ) + assert states["media_player.test3"][1] == hist["media_player.test3"][1] + + assert_multiple_states_equal_without_context( + states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test2"], hist["thermostat.test2"] + ) @pytest.mark.parametrize("time_zone", ["Europe/Berlin", "US/Hawaii", "UTC"]) @@ -460,7 +490,7 @@ def test_get_significant_states_with_initial(time_zone, hass_recorder): four, include_start_time_state=True, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_without_initial(hass_recorder): @@ -486,7 +516,7 @@ def test_get_significant_states_without_initial(hass_recorder): four, include_start_time_state=False, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_entity_id(hass_recorder): @@ -500,17 +530,13 @@ def test_get_significant_states_entity_id(hass_recorder): del states["script.can_cancel_this_one"] hist = history.get_significant_states(hass, zero, four, ["media_player.test"]) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_multiple_entity_ids(hass_recorder): """Test that only significant states are returned for one entity.""" hass = hass_recorder() zero, four, states = record_states(hass) - del states["media_player.test2"] - del states["media_player.test3"] - del states["thermostat.test2"] - del states["script.can_cancel_this_one"] hist = history.get_significant_states( hass, @@ -518,7 +544,13 @@ def test_get_significant_states_multiple_entity_ids(hass_recorder): four, ["media_player.test", "thermostat.test"], ) - assert states == hist + + assert_multiple_states_equal_without_context_and_last_changed( + states["media_player.test"], hist["media_player.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) def test_get_significant_states_are_ordered(hass_recorder): @@ -583,14 +615,22 @@ def test_get_significant_states_only(hass_recorder): hist = history.get_significant_states(hass, start, significant_changes_only=True) assert len(hist[entity_id]) == 2 - assert states[0] not in hist[entity_id] - assert states[1] in hist[entity_id] - assert states[2] in hist[entity_id] + assert not any( + state.last_updated == states[0].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[1].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[2].last_updated for state in hist[entity_id] + ) hist = history.get_significant_states(hass, start, significant_changes_only=False) assert len(hist[entity_id]) == 3 - assert states == hist[entity_id] + assert_multiple_states_equal_without_context_and_last_changed( + states, hist[entity_id] + ) async def test_get_significant_states_only_minimal_response(recorder_mock, hass): @@ -885,8 +925,8 @@ async def test_get_full_significant_states_handles_empty_last_changed( states = await recorder.get_instance(hass).async_add_executor_job(_get_entries) sensor_one_states: list[State] = states["sensor.one"] - assert sensor_one_states[0] == state0 - assert sensor_one_states[1] == state1 + assert_states_equal_without_context(sensor_one_states[0], state0) + assert_states_equal_without_context(sensor_one_states[1], state1) assert sensor_one_states[0].last_changed == sensor_one_states[1].last_changed assert sensor_one_states[0].last_updated != sensor_one_states[1].last_updated @@ -908,8 +948,8 @@ async def test_get_full_significant_states_handles_empty_last_changed( native_sensor_one_states = await recorder.get_instance(hass).async_add_executor_job( _fetch_native_states ) - assert native_sensor_one_states[0] == state0 - assert native_sensor_one_states[1] == state1 + assert_states_equal_without_context(native_sensor_one_states[0], state0) + assert_states_equal_without_context(native_sensor_one_states[1], state1) assert ( native_sensor_one_states[0].last_changed == native_sensor_one_states[1].last_changed @@ -1004,7 +1044,7 @@ async def test_get_full_significant_states_past_year_2038( states = await recorder.get_instance(hass).async_add_executor_job(_get_entries) sensor_one_states: list[State] = states["sensor.one"] - assert sensor_one_states[0] == state0 - assert sensor_one_states[1] == state1 + assert_states_equal_without_context(sensor_one_states[0], state0) + assert_states_equal_without_context(sensor_one_states[1], state1) assert sensor_one_states[0].last_changed == past_2038_time assert sensor_one_states[0].last_updated == past_2038_time diff --git a/tests/components/recorder/test_history_db_schema_30.py b/tests/components/recorder/test_history_db_schema_30.py index 5e944ce454a..4384f284fe8 100644 --- a/tests/components/recorder/test_history_db_schema_30.py +++ b/tests/components/recorder/test_history_db_schema_30.py @@ -21,7 +21,13 @@ from homeassistant.core import State from homeassistant.helpers.json import JSONEncoder import homeassistant.util.dt as dt_util -from .common import wait_recording_done +from .common import ( + assert_dict_of_states_equal_without_context_and_last_changed, + assert_multiple_states_equal_without_context, + assert_multiple_states_equal_without_context_and_last_changed, + assert_states_equal_without_context, + wait_recording_done, +) CREATE_ENGINE_TARGET = "homeassistant.components.recorder.core.create_engine" SCHEMA_MODULE = "tests.components.recorder.db_schema_30" @@ -175,7 +181,7 @@ def test_state_changes_during_period(hass_recorder, attributes, no_attributes, l hass, start, end, entity_id, no_attributes, limit=limit ) - assert states[:limit] == hist[entity_id] + assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) def test_state_changes_during_period_descending(hass_recorder): @@ -228,12 +234,14 @@ def test_state_changes_during_period_descending(hass_recorder): hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False ) - assert states == hist[entity_id] + assert_multiple_states_equal_without_context(states, hist[entity_id]) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=True ) - assert states == list(reversed(list(hist[entity_id]))) + assert_multiple_states_equal_without_context( + states, list(reversed(list(hist[entity_id]))) + ) def test_get_last_state_changes(hass_recorder): @@ -269,7 +277,7 @@ def test_get_last_state_changes(hass_recorder): hist = history.get_last_state_changes(hass, 2, entity_id) - assert states == hist[entity_id] + assert_multiple_states_equal_without_context(states, hist[entity_id]) def test_ensure_state_can_be_copied(hass_recorder): @@ -302,8 +310,8 @@ def test_ensure_state_can_be_copied(hass_recorder): hist = history.get_last_state_changes(hass, 2, entity_id) - assert copy(hist[entity_id][0]) == hist[entity_id][0] - assert copy(hist[entity_id][1]) == hist[entity_id][1] + assert_states_equal_without_context(copy(hist[entity_id][0]), hist[entity_id][0]) + assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1]) def test_get_significant_states(hass_recorder): @@ -316,7 +324,7 @@ def test_get_significant_states(hass_recorder): hass = hass_recorder() zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_minimal_response(hass_recorder): @@ -355,7 +363,31 @@ def test_get_significant_states_minimal_response(hass_recorder): "last_changed": orig_last_changed, "state": orig_state, } - assert states == hist + + assert len(hist) == len(states) + assert_states_equal_without_context( + states["media_player.test"][0], hist["media_player.test"][0] + ) + assert states["media_player.test"][1] == hist["media_player.test"][1] + assert states["media_player.test"][2] == hist["media_player.test"][2] + + assert_multiple_states_equal_without_context( + states["media_player.test2"], hist["media_player.test2"] + ) + assert_states_equal_without_context( + states["media_player.test3"][0], hist["media_player.test3"][0] + ) + assert states["media_player.test3"][1] == hist["media_player.test3"][1] + + assert_multiple_states_equal_without_context( + states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test2"], hist["thermostat.test2"] + ) def test_get_significant_states_with_initial(hass_recorder): @@ -375,6 +407,7 @@ def test_get_significant_states_with_initial(hass_recorder): for state in states[entity_id]: if state.last_changed == one: state.last_changed = one_and_half + state.last_updated = one_and_half hist = history.get_significant_states( hass, @@ -382,7 +415,7 @@ def test_get_significant_states_with_initial(hass_recorder): four, include_start_time_state=True, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_without_initial(hass_recorder): @@ -408,7 +441,7 @@ def test_get_significant_states_without_initial(hass_recorder): four, include_start_time_state=False, ) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_entity_id(hass_recorder): @@ -422,7 +455,7 @@ def test_get_significant_states_entity_id(hass_recorder): del states["script.can_cancel_this_one"] hist = history.get_significant_states(hass, zero, four, ["media_player.test"]) - assert states == hist + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) def test_get_significant_states_multiple_entity_ids(hass_recorder): @@ -440,7 +473,12 @@ def test_get_significant_states_multiple_entity_ids(hass_recorder): four, ["media_player.test", "thermostat.test"], ) - assert states == hist + assert_multiple_states_equal_without_context_and_last_changed( + states["media_player.test"], hist["media_player.test"] + ) + assert_multiple_states_equal_without_context_and_last_changed( + states["thermostat.test"], hist["thermostat.test"] + ) def test_get_significant_states_are_ordered(hass_recorder): @@ -505,14 +543,22 @@ def test_get_significant_states_only(hass_recorder): hist = history.get_significant_states(hass, start, significant_changes_only=True) assert len(hist[entity_id]) == 2 - assert states[0] not in hist[entity_id] - assert states[1] in hist[entity_id] - assert states[2] in hist[entity_id] + assert not any( + state.last_updated == states[0].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[1].last_updated for state in hist[entity_id] + ) + assert any( + state.last_updated == states[2].last_updated for state in hist[entity_id] + ) hist = history.get_significant_states(hass, start, significant_changes_only=False) assert len(hist[entity_id]) == 3 - assert states == hist[entity_id] + assert_multiple_states_equal_without_context_and_last_changed( + states, hist[entity_id] + ) def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: diff --git a/tests/components/recorder/test_init.py b/tests/components/recorder/test_init.py index c06865fb5a3..1a47f4f17ff 100644 --- a/tests/components/recorder/test_init.py +++ b/tests/components/recorder/test_init.py @@ -221,7 +221,7 @@ async def test_saving_state(recorder_mock, hass: HomeAssistant): assert len(db_states) == 1 assert db_states[0].event_id is None - assert state == _state_with_context(hass, entity_id) + assert state.as_dict() == _state_with_context(hass, entity_id).as_dict() @pytest.mark.parametrize( @@ -257,7 +257,7 @@ async def test_saving_state_with_nul( expected = _state_with_context(hass, entity_id) expected.attributes = expected_attributes - assert state == expected + assert state.as_dict() == expected.as_dict() async def test_saving_many_states( @@ -547,7 +547,7 @@ def test_saving_state_include_domains(hass_recorder): hass = hass_recorder({"include": {"domains": "test2"}}) states = _add_entities(hass, ["test.recorder", "test2.recorder"]) assert len(states) == 1 - assert _state_with_context(hass, "test2.recorder") == states[0] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() def test_saving_state_include_domains_globs(hass_recorder): @@ -559,8 +559,11 @@ def test_saving_state_include_domains_globs(hass_recorder): hass, ["test.recorder", "test2.recorder", "test3.included_entity"] ) assert len(states) == 2 - assert _state_with_context(hass, "test2.recorder") == states[0] - assert _state_with_context(hass, "test3.included_entity") == states[1] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() + assert ( + _state_with_context(hass, "test3.included_entity").as_dict() + == states[1].as_dict() + ) def test_saving_state_incl_entities(hass_recorder): @@ -568,7 +571,7 @@ def test_saving_state_incl_entities(hass_recorder): hass = hass_recorder({"include": {"entities": "test2.recorder"}}) states = _add_entities(hass, ["test.recorder", "test2.recorder"]) assert len(states) == 1 - assert _state_with_context(hass, "test2.recorder") == states[0] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() def test_saving_event_exclude_event_type(hass_recorder): @@ -597,7 +600,7 @@ def test_saving_state_exclude_domains(hass_recorder): hass = hass_recorder({"exclude": {"domains": "test"}}) states = _add_entities(hass, ["test.recorder", "test2.recorder"]) assert len(states) == 1 - assert _state_with_context(hass, "test2.recorder") == states[0] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() def test_saving_state_exclude_domains_globs(hass_recorder): @@ -609,7 +612,7 @@ def test_saving_state_exclude_domains_globs(hass_recorder): hass, ["test.recorder", "test2.recorder", "test2.excluded_entity"] ) assert len(states) == 1 - assert _state_with_context(hass, "test2.recorder") == states[0] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() def test_saving_state_exclude_entities(hass_recorder): @@ -617,7 +620,7 @@ def test_saving_state_exclude_entities(hass_recorder): hass = hass_recorder({"exclude": {"entities": "test.recorder"}}) states = _add_entities(hass, ["test.recorder", "test2.recorder"]) assert len(states) == 1 - assert _state_with_context(hass, "test2.recorder") == states[0] + assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict() def test_saving_state_exclude_domain_include_entity(hass_recorder): @@ -650,7 +653,7 @@ def test_saving_state_include_domain_exclude_entity(hass_recorder): ) states = _add_entities(hass, ["test.recorder", "test2.recorder", "test.ok"]) assert len(states) == 1 - assert _state_with_context(hass, "test.ok") == states[0] + assert _state_with_context(hass, "test.ok").as_dict() == states[0].as_dict() assert _state_with_context(hass, "test.ok").state == "state2" @@ -666,7 +669,7 @@ def test_saving_state_include_domain_glob_exclude_entity(hass_recorder): hass, ["test.recorder", "test2.recorder", "test.ok", "test2.included_entity"] ) assert len(states) == 1 - assert _state_with_context(hass, "test.ok") == states[0] + assert _state_with_context(hass, "test.ok").as_dict() == states[0].as_dict() assert _state_with_context(hass, "test.ok").state == "state2" @@ -1314,7 +1317,10 @@ def test_service_disable_states_not_recording(hass, hass_recorder): db_states = list(session.query(States)) assert len(db_states) == 1 assert db_states[0].event_id is None - assert db_states[0].to_native() == _state_with_context(hass, "test.two") + assert ( + db_states[0].to_native().as_dict() + == _state_with_context(hass, "test.two").as_dict() + ) def test_service_disable_run_information_recorded(tmpdir): diff --git a/tests/components/recorder/test_models.py b/tests/components/recorder/test_models.py index 646b865477a..cb656f6dde9 100644 --- a/tests/components/recorder/test_models.py +++ b/tests/components/recorder/test_models.py @@ -32,7 +32,7 @@ def test_from_event_to_db_event(): event = ha.Event("test_event", {"some_data": 15}) db_event = Events.from_event(event) db_event.event_data = EventData.from_event(event).shared_data - assert event == db_event.to_native() + assert event.as_dict() == db_event.to_native().as_dict() def test_from_event_to_db_state(): @@ -43,7 +43,7 @@ def test_from_event_to_db_state(): {"entity_id": "sensor.temperature", "old_state": None, "new_state": state}, context=state.context, ) - assert state == States.from_event(event).to_native() + assert state.as_dict() == States.from_event(event).to_native().as_dict() def test_from_event_to_db_state_attributes(): @@ -293,11 +293,11 @@ async def test_event_to_db_model(): db_event = Events.from_event(event) db_event.event_data = EventData.from_event(event).shared_data native = db_event.to_native() - assert native == event + assert native.as_dict() == event.as_dict() native = Events.from_event(event).to_native() event.data = {} - assert native == event + assert native.as_dict() == event.as_dict() async def test_lazy_state_handles_include_json(caplog): diff --git a/tests/components/recorder/test_statistics.py b/tests/components/recorder/test_statistics.py index ba012fd949c..635b3f0fde6 100644 --- a/tests/components/recorder/test_statistics.py +++ b/tests/components/recorder/test_statistics.py @@ -37,6 +37,7 @@ from homeassistant.setup import setup_component import homeassistant.util.dt as dt_util from .common import ( + assert_dict_of_states_equal_without_context_and_last_changed, async_wait_recording_done, do_adhoc_statistics, statistics_during_period, @@ -55,7 +56,7 @@ def test_compile_hourly_statistics(hass_recorder): setup_component(hass, "sensor", {}) zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) # Should not fail if there is nothing there yet stats = get_latest_short_term_statistics( @@ -316,7 +317,7 @@ def test_rename_entity(hass_recorder): zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}): stats = statistics_during_period(hass, zero, period="5minute", **kwargs) @@ -382,7 +383,7 @@ def test_rename_entity_collision(hass_recorder, caplog): zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}): stats = statistics_during_period(hass, zero, period="5minute", **kwargs) @@ -447,7 +448,7 @@ def test_statistics_duplicated(hass_recorder, caplog): setup_component(hass, "sensor", {}) zero, four, states = record_states(hass) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) wait_recording_done(hass) assert "Compiling statistics for" not in caplog.text diff --git a/tests/components/sensor/__init__.py b/tests/components/sensor/__init__.py index 17c225c67d6..6563041ce99 100644 --- a/tests/components/sensor/__init__.py +++ b/tests/components/sensor/__init__.py @@ -1 +1,4 @@ """The tests for Sensor platforms.""" +import pytest + +pytest.register_assert_rewrite("tests.components.recorder.common") diff --git a/tests/components/sensor/test_recorder.py b/tests/components/sensor/test_recorder.py index 12d1fd855f7..e3df80d54df 100644 --- a/tests/components/sensor/test_recorder.py +++ b/tests/components/sensor/test_recorder.py @@ -34,6 +34,8 @@ from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM from tests.common import async_fire_time_changed from tests.components.recorder.common import ( + assert_dict_of_states_equal_without_context_and_last_changed, + assert_multiple_states_equal_without_context_and_last_changed, async_recorder_block_till_done, async_wait_recording_done, do_adhoc_statistics, @@ -139,7 +141,7 @@ def test_compile_hourly_statistics( } four, states = record_states(hass, zero, "sensor.test1", attributes) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -201,7 +203,7 @@ def test_compile_hourly_statistics_purged_state_changes( } four, states = record_states(hass, zero, "sensor.test1", attributes) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) mean = min = max = float(hist["sensor.test1"][-1].state) @@ -282,7 +284,7 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes) states = {**states, **_states} hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -474,7 +476,9 @@ async def test_compile_hourly_sum_statistics_amount( hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) await async_wait_recording_done(hass) @@ -667,7 +671,9 @@ def test_compile_hourly_sum_statistics_amount_reset_every_state_change( two + timedelta.resolution, significant_changes_only=False, ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=zero) do_adhoc_statistics(hass, start=zero + timedelta(minutes=5)) @@ -765,7 +771,9 @@ def test_compile_hourly_sum_statistics_amount_invalid_last_reset( one + timedelta.resolution, significant_changes_only=False, ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -849,7 +857,9 @@ def test_compile_hourly_sum_statistics_nan_inf_state( one + timedelta.resolution, significant_changes_only=False, ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -978,7 +988,9 @@ def test_compile_hourly_sum_statistics_negative_state( one + timedelta.resolution, significant_changes_only=False, ) - assert dict(states)[entity_id] == dict(hist)[entity_id] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)[entity_id], dict(hist)[entity_id] + ) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -1060,7 +1072,9 @@ def test_compile_hourly_sum_statistics_total_no_reset( hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) wait_recording_done(hass) @@ -1160,7 +1174,9 @@ def test_compile_hourly_sum_statistics_total_increasing( hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) wait_recording_done(hass) @@ -1258,7 +1274,9 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip( hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) wait_recording_done(hass) @@ -1363,7 +1381,9 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog): hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) wait_recording_done(hass) @@ -1453,7 +1473,9 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog): hist = history.get_significant_states( hass, period0 - timedelta.resolution, eight + timedelta.resolution ) - assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"] + assert_multiple_states_equal_without_context_and_last_changed( + dict(states)["sensor.test1"], dict(hist)["sensor.test1"] + ) do_adhoc_statistics(hass, start=period0) wait_recording_done(hass) @@ -1635,7 +1657,7 @@ def test_compile_hourly_statistics_unchanged( } four, states = record_states(hass, zero, "sensor.test1", attributes) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=four) wait_recording_done(hass) @@ -1667,7 +1689,7 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog): hass, zero, "sensor.test1", TEMPERATURE_SENSOR_ATTRIBUTES ) hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -1736,7 +1758,7 @@ def test_compile_hourly_statistics_unavailable( _, _states = record_states(hass, zero, "sensor.test2", attributes) states = {**states, **_states} hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=four) wait_recording_done(hass) @@ -1944,7 +1966,7 @@ def test_compile_hourly_statistics_changing_units_1( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -2054,7 +2076,7 @@ def test_compile_hourly_statistics_changing_units_2( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero + timedelta(seconds=30 * 5)) wait_recording_done(hass) @@ -2122,7 +2144,7 @@ def test_compile_hourly_statistics_changing_units_3( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -2270,7 +2292,7 @@ def test_compile_hourly_statistics_convert_units_1( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero + timedelta(minutes=10)) wait_recording_done(hass) assert "The unit of sensor.test1 is changing" not in caplog.text @@ -2362,7 +2384,7 @@ def test_compile_hourly_statistics_equivalent_units_1( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero) wait_recording_done(hass) @@ -2476,7 +2498,7 @@ def test_compile_hourly_statistics_equivalent_units_2( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=zero + timedelta(seconds=30 * 5)) wait_recording_done(hass) @@ -2591,7 +2613,7 @@ def test_compile_hourly_statistics_changing_device_class_1( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) # Run statistics again, additional statistics is generated do_adhoc_statistics(hass, start=zero + timedelta(minutes=10)) @@ -2646,7 +2668,7 @@ def test_compile_hourly_statistics_changing_device_class_1( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) # Run statistics again, additional statistics is generated do_adhoc_statistics(hass, start=zero + timedelta(minutes=20)) @@ -2781,7 +2803,7 @@ def test_compile_hourly_statistics_changing_device_class_2( ) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, zero, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) # Run statistics again, additional statistics is generated do_adhoc_statistics(hass, start=zero + timedelta(minutes=10)) @@ -2897,7 +2919,7 @@ def test_compile_hourly_statistics_changing_state_class( four, _states = record_states(hass, period1, "sensor.test1", attributes_2) states["sensor.test1"] += _states["sensor.test1"] hist = history.get_significant_states(hass, period0, four) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) do_adhoc_statistics(hass, start=period1) wait_recording_done(hass) @@ -3083,7 +3105,7 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog): hist = history.get_significant_states( hass, zero - timedelta.resolution, four, significant_changes_only=False ) - assert dict(states) == dict(hist) + assert_dict_of_states_equal_without_context_and_last_changed(states, hist) wait_recording_done(hass) # Generate 5-minute statistics for two hours diff --git a/tests/test_core.py b/tests/test_core.py index d3fa14c7d22..411a87965e3 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -331,7 +331,7 @@ def test_event_eq(): ha.Event("some_type", data, time_fired=now, context=context) for _ in range(2) ) - assert event1 == event2 + assert event1.as_dict() == event2.as_dict() def test_event_repr(): @@ -685,7 +685,7 @@ def test_state_name_if_friendly_name_attr(): def test_state_dict_conversion(): """Test conversion of dict.""" state = ha.State("domain.hello", "world", {"some": "attr"}) - assert state == ha.State.from_dict(state.as_dict()) + assert state.as_dict() == ha.State.from_dict(state.as_dict()).as_dict() def test_state_dict_conversion_with_wrong_data():