tests now wait for a refresh instead of triggering one

This commit is contained in:
Aran-Fey
2025-04-10 07:52:43 +02:00
parent c83223c0ce
commit c5b982a64f
7 changed files with 38 additions and 38 deletions

View File

@@ -81,7 +81,7 @@ class BaseClient(abc.ABC):
self._recorder_transport = MessageRecorderTransport(
process_sent_message=self._process_sent_message
)
self._first_refresh_completed = asyncio.Event()
self._refresh_completed = asyncio.Event()
self._app_server: rio.app_server.AbstractAppServer | None = None
self._session: rio.Session | None = None
@@ -103,7 +103,7 @@ class BaseClient(abc.ABC):
def _process_sent_message(self, message: JsonDoc) -> None:
if message["method"] == "updateComponentStates":
self._first_refresh_completed.set()
self._refresh_completed.set()
async def __aenter__(self) -> te.Self:
self._app_server = await self._get_app_server()
@@ -112,7 +112,7 @@ class BaseClient(abc.ABC):
self._session = await self._create_session()
await self._first_refresh_completed.wait()
await self._refresh_completed.wait()
return self
@@ -209,5 +209,6 @@ class BaseClient(abc.ABC):
except StopIteration:
raise ValueError(f"No component of type {component_type} found")
async def refresh(self) -> None:
await self.session._refresh()
async def wait_for_refresh(self) -> None:
self._refresh_completed.clear()
await self._refresh_completed.wait()

View File

@@ -23,6 +23,8 @@ class DummyClient(BaseClient):
)
def _process_sent_message(self, message: JsonDoc) -> None:
super()._process_sent_message(message)
if "id" in message:
self._recorder_transport.queue_response(
{
@@ -32,9 +34,6 @@ class DummyClient(BaseClient):
}
)
if message["method"] == "updateComponentStates":
self._first_refresh_completed.set()
async def _get_app_server(self) -> AbstractAppServer:
return self.__app_server

View File

@@ -59,7 +59,7 @@ async def test_mounted():
assert event_counter.unmount_count == 0
mounter.toggle()
await test_client.refresh()
await test_client.wait_for_refresh()
assert event_counter.mount_count == 1
assert event_counter.unmount_count == 0
@@ -74,7 +74,7 @@ async def test_mounted():
}
mounter.toggle()
await test_client.refresh()
await test_client.wait_for_refresh()
assert event_counter.unmount_count == 1
@@ -88,7 +88,7 @@ async def test_double_mount():
for _ in range(4):
mounter.toggle()
await test_client.refresh()
await test_client.wait_for_refresh()
if mounter.child_mounted:
assert event_counter in test_client._last_updated_components
@@ -172,7 +172,7 @@ async def test_populate_dead_child():
# Unmount the child before its `on_populate` handler makes it dirty
mounter.child_mounted = False
await test_client.refresh()
await test_client.wait_for_refresh()
# Wait for the `on_populate` handler and the subsequent refresh
test_client._received_messages.clear()

View File

@@ -24,7 +24,7 @@ async def test_session_property_change(attr_name: str, new_value: object):
test_client._received_messages.clear()
setattr(test_client.session, attr_name, new_value)
await test_client.refresh()
await test_client.wait_for_refresh()
# Note: The `Text` component isn't necessarily updated, because the
# value we assigned might be the same as before, so the reconciler
@@ -45,7 +45,7 @@ async def test_session_attachment_change():
test_client._received_messages.clear()
test_client.session.attach("bar")
await test_client.refresh()
await test_client.wait_for_refresh()
assert test_client._last_updated_components == {
test_component,

View File

@@ -19,7 +19,7 @@ async def test_reconciliation():
text_input.min_height = 5
toggler.toggle = False
await test_client.refresh()
await test_client.wait_for_refresh()
# The text should carry over because it was assigned after the component
# was created, which essentially means that the user interactively
@@ -38,7 +38,7 @@ async def test_reconciliation():
# value. (Not really sure how this is different from the `min_width`,
# but there was once a bug like this)
toggler.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
assert not text_input.is_secret
@@ -69,7 +69,7 @@ async def test_reconcile_instance_with_itself() -> None:
# child
assert test_client._session is not None
assert test_client._dirty_components == {child, container}
await test_client.refresh()
await test_client.wait_for_refresh()
assert test_client._last_updated_components == {child, container}
@@ -138,7 +138,7 @@ async def test_reconcile_by_key():
text = test_client.get_component(rio.Text)
root_component.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
assert text.text == "World"
@@ -158,7 +158,7 @@ async def test_key_prevents_structural_match():
text = test_client.get_component(rio.Text)
root_component.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
assert text.text == "Hello"
@@ -175,7 +175,7 @@ async def test_key_interrupts_structure():
text = test_client.get_component(rio.Text)
root_component.key_ = "123"
await test_client.refresh()
await test_client.wait_for_refresh()
# The container's key changed, so even though the structure is the same,
# the old Text component should be unchanged.
@@ -200,7 +200,7 @@ async def test_structural_matching_inside_keyed_component():
text = test_client.get_component(rio.Text)
root_component.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
# The container with key "foo" has moved. Make sure the structure inside
# of it was reconciled correctly.
@@ -231,7 +231,7 @@ async def test_key_matching_inside_keyed_component():
text = test_client.get_component(rio.Text)
root_component.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
# The container with key "foo" has moved. Make sure the structure inside
# of it was reconciled correctly.
@@ -259,7 +259,7 @@ async def test_same_key_on_different_component_type():
text = test_client.get_component(rio.Text)
root_component.toggle = True
await test_client.refresh()
await test_client.wait_for_refresh()
assert text.text == "Hello"
@@ -276,7 +276,7 @@ async def test_text_reconciliation():
text = test_client.get_component(rio.Text)
root.text = "bar"
await test_client.refresh()
await test_client.wait_for_refresh()
assert text.text == root.text
@@ -294,7 +294,7 @@ async def test_grid_reconciliation():
grid = test_client.get_component(rio.Grid)
root.num_rows += 1
await test_client.refresh()
await test_client.wait_for_refresh()
assert {root, grid} < test_client._last_updated_components
assert len(grid._children) == root.num_rows
@@ -323,7 +323,7 @@ async def test_margin_reconciliation():
texts = list(test_client.get_components(rio.Text))
root.switch = False
await test_client.refresh()
await test_client.wait_for_refresh()
assert texts[0].margin_left == 1
assert texts[1].margin_right == 1

View File

@@ -9,7 +9,7 @@ async def test_refresh_with_nothing_to_do() -> None:
async with rio.testing.DummyClient(build) as test_client:
test_client._received_messages.clear()
await test_client.refresh()
await test_client.wait_for_refresh()
assert not test_client._dirty_components
assert not test_client._last_updated_components
@@ -24,7 +24,7 @@ async def test_refresh_with_clean_root_component() -> None:
text_component = test_client.get_component(rio.Text)
text_component.text = "World"
await test_client.refresh()
await test_client.wait_for_refresh()
assert test_client._last_updated_components == {text_component}
@@ -58,7 +58,7 @@ async def test_rebuild_component_with_dead_parent() -> None:
component.state = "Hi"
unmounter.child_is_mounted = False
await test_client.refresh()
await test_client.wait_for_refresh()
# Make sure no data for dead components was sent to JS
assert unmounter in test_client._last_updated_components
@@ -86,7 +86,7 @@ async def test_unmount_and_remount() -> None:
row_component = test_client.get_component(rio.Row)
root_component.show_child = False
await test_client.refresh()
await test_client.wait_for_refresh()
assert not child_component._is_in_component_tree_({})
assert test_client._last_updated_components == {
root_component,
@@ -94,7 +94,7 @@ async def test_unmount_and_remount() -> None:
}
root_component.show_child = True
await test_client.refresh()
await test_client.wait_for_refresh()
assert child_component._is_in_component_tree_({})
assert test_client._last_updated_components == {
root_component,
@@ -130,7 +130,7 @@ async def test_rebuild_component_with_dead_builder():
stateful_component = test_client.get_component(StatefulComponent)
toggler.child_is_alive = False
await test_client.refresh()
await test_client.wait_for_refresh()
# At this point in time, the builder is dead
assert stateful_component._weak_builder_() is None
@@ -138,7 +138,7 @@ async def test_rebuild_component_with_dead_builder():
stateful_component.state = "bye"
test_client._received_messages.clear()
await test_client.refresh()
await test_client.wait_for_refresh()
assert not test_client._received_messages
@@ -179,7 +179,7 @@ async def test_changing_children_of_not_dirty_high_level_component():
text_component = test_client.get_component(rio.Text)
root_component.switch = True
await test_client.refresh()
await test_client.wait_for_refresh()
# Check if the new child, a Switch, was sent to the frontend
assert any(
@@ -211,7 +211,7 @@ async def test_binding_doesnt_update_children() -> None:
test_client._received_messages.clear()
await text_input._on_message_({"type": "confirm", "text": "hello"})
await test_client.refresh()
await test_client.wait_for_refresh()
# Only the Text component has changed in this rebuild
assert test_client._last_updated_components == {root_component, text}
@@ -298,7 +298,7 @@ async def test_value_change_from_frontend():
"text": "hello",
}
)
await test_client.refresh()
await test_client.wait_for_refresh()
assert test_client._last_updated_components == {
parent_component,
@@ -329,6 +329,6 @@ async def test_force_refresh():
component.items.append("foo")
component.force_refresh()
await client.refresh()
await client.wait_for_refresh()
assert text_component.text == "foo"

View File

@@ -32,6 +32,6 @@ async def test_rebuild_resets_crashed_build_functions():
crashing_component = test_client.get_component(CrashingComponent)
crashing_component.fail = False
await test_client.refresh()
await test_client.wait_for_refresh()
assert not test_client.crashed_build_functions