mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-10-28 22:27:06 +01:00
97 lines
2.7 KiB
Python
97 lines
2.7 KiB
Python
"""Native request snapshots and completed-invocation retention contracts."""
|
|
|
|
import gc
|
|
import weakref
|
|
from unittest.mock import Mock
|
|
|
|
import pytest
|
|
from homeassistant.components.adaptive_lighting.adaptation_utils import (
|
|
LightControlAttributes,
|
|
)
|
|
from homeassistant.components.adaptive_lighting.native_group_models import (
|
|
AttributePolicy,
|
|
BatchExecution,
|
|
NativeIntent,
|
|
NativePlan,
|
|
)
|
|
from homeassistant.core import Context
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("attribute", "vector"),
|
|
[
|
|
("rgb_color", [255, 56, 0]),
|
|
("xy_color", [0.4, 0.3]),
|
|
("hs_color", [30, 75]),
|
|
("rgbw_color", [255, 56, 0, 80]),
|
|
("rgbww_color", [255, 56, 0, 80, 100]),
|
|
],
|
|
)
|
|
def test_colour_intent_detaches_mutable_colour_vectors(attribute, vector):
|
|
"""Queued colour is fixed even when the preparation payload changes later."""
|
|
expected = tuple(vector)
|
|
source = {attribute: vector, "transition": 1}
|
|
intent = NativeIntent(
|
|
colour=source,
|
|
explicit=LightControlAttributes.NONE,
|
|
version=0,
|
|
source="light.member",
|
|
policies={LightControlAttributes.COLOR: AttributePolicy(Mock(), 0)},
|
|
)
|
|
|
|
source["transition"] = 2
|
|
vector[0] = 0
|
|
dispatch = dict(intent.colour)
|
|
dispatch[attribute] = tuple(0 for _ in vector)
|
|
|
|
assert intent.colour[attribute] == expected
|
|
assert intent.colour["transition"] == 1
|
|
with pytest.raises(TypeError):
|
|
intent.colour[attribute][0] = 0
|
|
|
|
|
|
def test_complete_request_snapshot_detaches_scene_colour_vectors():
|
|
"""Later scene payload edits cannot change the request used for child matching."""
|
|
colour = [255, 56, 0]
|
|
request = {"state": "on", "rgb_color": colour}
|
|
requests = {"light.member": request}
|
|
plan = NativePlan(Context(), requests, {}, {})
|
|
|
|
colour[0] = 0
|
|
request["state"] = "off"
|
|
requests.clear()
|
|
|
|
assert plan.requests["light.member"] == {
|
|
"state": "on",
|
|
"rgb_color": (255, 56, 0),
|
|
}
|
|
|
|
|
|
def test_closed_execution_releases_error_traceback_payload():
|
|
"""A late-report claim retaining outcomes must not retain failed request frames."""
|
|
execution = BatchExecution()
|
|
|
|
class RequestPayload:
|
|
"""Stand in for request data reachable through a failed handler frame."""
|
|
|
|
def fail_request():
|
|
raise ValueError
|
|
|
|
def record_failure():
|
|
payload = RequestPayload()
|
|
reference = weakref.ref(payload)
|
|
try:
|
|
fail_request()
|
|
except ValueError as error:
|
|
execution.errors.append(error)
|
|
return reference
|
|
|
|
reference = record_failure()
|
|
gc.collect()
|
|
assert reference() is not None
|
|
|
|
execution.close()
|
|
gc.collect()
|
|
|
|
assert execution.closed
|
|
assert reference() is None
|