|
| 1 | +import importlib.resources |
| 2 | +import logging |
| 3 | +from contextlib import contextmanager |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +import ipywidgets |
| 7 | +import solara |
| 8 | +from solara.server import reload |
| 9 | +from solara.server.app import AppScript |
| 10 | + |
| 11 | +logger = logging.getLogger("solara.server.app_test") |
| 12 | + |
| 13 | +APP_SRC = importlib.resources.files("test.unit.ui") / "app.py" |
| 14 | +reload.reloader.start() |
| 15 | + |
| 16 | + |
| 17 | +@contextmanager |
| 18 | +def app_box_and_rc(app_name, kernel_context): |
| 19 | + app = AppScript(str(app_name)) |
| 20 | + app.init() |
| 21 | + try: |
| 22 | + with kernel_context: |
| 23 | + # get root widget |
| 24 | + el = app.run() |
| 25 | + root = solara.RoutingProvider( |
| 26 | + children=[el], routes=app.routes, pathname="/" |
| 27 | + ) |
| 28 | + # rc = render context |
| 29 | + box, rc = solara.render(root, handle_error=False) |
| 30 | + yield box, rc |
| 31 | + finally: |
| 32 | + app.close() |
| 33 | + |
| 34 | + |
| 35 | +def test_notebook_widget(kernel_context, no_kernel_context): |
| 36 | + """ |
| 37 | + The fixture no_kernel_context is not used directly in this test but is required, though, to |
| 38 | + make the test pass. |
| 39 | + """ |
| 40 | + with app_box_and_rc(APP_SRC, kernel_context) as (box, rc): |
| 41 | + button = rc.find(ipywidgets.Button).widget |
| 42 | + text = rc.find(ipywidgets.Text).widget |
| 43 | + assert isinstance(button, ipywidgets.Button) |
| 44 | + assert isinstance(text, ipywidgets.Text) |
| 45 | + assert text.value == "init" |
| 46 | + button.click() |
| 47 | + assert text.value == "click" |
| 48 | + |
| 49 | + |
| 50 | +def test_ipywidgets_update_global_state(): |
| 51 | + """ |
| 52 | + Test that clicking an ipywidgets.Button correctly updates a global state dictionary |
| 53 | + with the current value of an ipywidgets.Text widget. |
| 54 | +
|
| 55 | + This test simulates user input by setting the value of the Text widget, |
| 56 | + confirms that the global state does not update before the button is clicked, |
| 57 | + and then checks that clicking the button updates the global state as expected. |
| 58 | + """ |
| 59 | + import ipywidgets as widgets |
| 60 | + |
| 61 | + global_state = {"username": ""} |
| 62 | + textbox = widgets.Text() |
| 63 | + button = widgets.Button(description="Submit") |
| 64 | + |
| 65 | + def on_click(b): |
| 66 | + global_state["username"] = textbox.value |
| 67 | + |
| 68 | + button.on_click(on_click) |
| 69 | + textbox.value = "alice" # Simulate user input |
| 70 | + assert global_state["username"] == "" # assert global state is unchanged |
| 71 | + button.click() # Simulate button click |
| 72 | + assert global_state["username"] == "alice" |
0 commit comments