from __future__ import annotations import typing as t import rio.data_models from rio.debug.layouter import Layouter from rio.testing import BrowserClient __all__ = ["verify_layout"] async def verify_layout(build: t.Callable[[], rio.Component]) -> Layouter: """ Rio contains two layout implementations: One on the client side, which determines the real layout of components, and a second one on the server side which is used entirely for testing. This function verifies that the results from the two layouters are the same. """ async with BrowserClient(build) as client: layouter = await Layouter.create(client.session) for component_id, layout_should in layouter._layouts_should.items(): layout_is = layouter._layouts_are[component_id] differences = list[str]() for attribute in rio.data_models.ComponentLayout.__annotations__: # Not all attributes are meant to be compared if attribute == "parent_id": continue value_should = getattr(layout_should, attribute) value_is = getattr(layout_is, attribute) difference = abs(value_is - value_should) if difference > 0.2: differences.append(f"{attribute}: {value_is} != {value_should}") if differences: component = layouter.get_component_by_id(component_id) raise ValueError( f"Layout of component {component} is incorrect:\n- " + "\n- ".join(differences) ) return layouter