lightning/tests/tests_app/frontend/panel/test_app_state_watcher.py

86 lines
2.1 KiB
Python

"""The AppStateWatcher enables a Frontend to.
- subscribe to App state changes.
- to access and change the App state.
This is particularly useful for the PanelFrontend, but can be used by other Frontends too.
"""
# pylint: disable=protected-access
import os
from unittest import mock
import pytest
from lightning_app.frontend.panel.app_state_watcher import AppStateWatcher
from lightning_app.utilities.state import AppState
FLOW_SUB = "lit_flow"
FLOW = f"root.{FLOW_SUB}"
PORT = 61896
@pytest.fixture(autouse=True)
def mock_settings_env_vars():
"""Set the LIGHTNING environment variables."""
with mock.patch.dict(
os.environ,
{
"LIGHTNING_FLOW_NAME": FLOW,
"LIGHTNING_RENDER_ADDRESS": "localhost",
"LIGHTNING_RENDER_PORT": f"{PORT}",
},
):
yield
def test_init(flow_state_state: dict):
"""We can instantiate the AppStateWatcher.
- the .state is set
- the .state is scoped to the flow state
"""
# When
app = AppStateWatcher()
# Needed as AppStateWatcher is singleton and might have been
# instantiated and the state changed in other tests
app._update_flow_state()
# Then
assert isinstance(app.state, AppState)
assert app.state._state == flow_state_state
def test_update_flow_state(flow_state_state: dict):
"""We can update the state.
- the .state is scoped to the flow state
"""
app = AppStateWatcher()
org_state = app.state
app._update_flow_state()
assert app.state is not org_state
assert app.state._state == flow_state_state
def test_is_singleton():
"""The AppStateWatcher is a singleton for efficiency reasons.
Its key that __new__ and __init__ of AppStateWatcher is only called once. See
https://github.com/holoviz/param/issues/643
"""
# When
app1 = AppStateWatcher()
name1 = app1.name
state1 = app1.state
app2 = AppStateWatcher()
name2 = app2.name
state2 = app2.state
# Then
assert app1 is app2
assert name1 == name2
assert app1.name == name2
assert state1 is state2
assert app1.state is state2