From be1c5a81f4975c65373fa8828aa83d2b13a1faa9 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 00:08:50 +0800 Subject: [PATCH 1/7] testing --- ex4nicegui/utils/scheduler.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ex4nicegui/utils/scheduler.py b/ex4nicegui/utils/scheduler.py index da4a151..2ef390a 100644 --- a/ex4nicegui/utils/scheduler.py +++ b/ex4nicegui/utils/scheduler.py @@ -1,8 +1,10 @@ +from __future__ import annotations + from collections import deque import signe -from typing import TypeVar, Callable, Literal +from typing import ClassVar, Dict, TypeVar, Callable, Literal from functools import lru_cache - +from nicegui import ui T = TypeVar("T") @@ -11,6 +13,8 @@ class UiScheduler(signe.ExecutionScheduler): + instances: ClassVar[Dict[str, UiScheduler]] = {} + def __init__(self) -> None: super().__init__() @@ -55,9 +59,21 @@ def run_next_tick_deque(self): self._next_tick_deque.pop()() -@lru_cache(maxsize=1) def get_uiScheduler(): - return UiScheduler() + client = ui.context.client + client_id = client.id + + if client_id in UiScheduler.instances: + return UiScheduler.instances[client_id] + + scheduler = UiScheduler() + UiScheduler.instances[client_id] = scheduler + + @client.on_disconnect + def on_disconnect(): + del UiScheduler.instances[client_id] + + return scheduler def next_tick(job: T_JOB_FN): From e74de4e93fca35dc6f89b3077f3aa186fb0daf46 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 00:12:45 +0800 Subject: [PATCH 2/7] remove unuse import --- ex4nicegui/utils/scheduler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ex4nicegui/utils/scheduler.py b/ex4nicegui/utils/scheduler.py index 2ef390a..0683e50 100644 --- a/ex4nicegui/utils/scheduler.py +++ b/ex4nicegui/utils/scheduler.py @@ -3,7 +3,6 @@ from collections import deque import signe from typing import ClassVar, Dict, TypeVar, Callable, Literal -from functools import lru_cache from nicegui import ui T = TypeVar("T") From 9fa1c7ac76beecf25302925986a34c1eff16d7f9 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 01:19:25 +0800 Subject: [PATCH 3/7] testings --- __tests/test_avatar.py | 22 ++++---- __tests/test_badge.py | 3 +- __tests/test_button.py | 18 ++++--- __tests/test_card.py | 3 +- __tests/test_checkbox.py | 12 +++-- __tests/test_chip.py | 3 +- __tests/test_circular_progress.py | 9 ++-- __tests/test_colort_picker.py | 3 +- __tests/test_column.py | 3 +- __tests/test_date.py | 41 ++++++++++----- __tests/test_dialog.py | 7 ++- __tests/test_drawer.py | 26 +++++----- __tests/test_echarts.py | 83 +++++++++++++++---------------- __tests/test_html.py | 10 ++-- __tests/test_icon.py | 20 +++++--- __tests/test_image.py | 9 +++- __tests/test_input.py | 18 ++++--- __tests/test_knob.py | 3 +- __tests/test_label.py | 25 ++++++---- __tests/test_lazy_input.py | 13 +++-- __tests/test_lazy_range.py | 14 +++--- __tests/test_lazy_textarea.py | 13 +++-- __tests/test_linear_progress.py | 10 ++-- __tests/test_number.py | 22 +++++--- __tests/test_pagination.py | 17 ++++--- __tests/test_radio.py | 20 ++++---- __tests/test_range.py | 39 +++++++-------- __tests/test_ref_computed.py | 3 +- __tests/test_row.py | 3 +- __tests/test_select.py | 54 ++++++++++---------- __tests/test_signe.py | 5 +- __tests/test_slider.py | 3 +- __tests/test_switch.py | 13 +++-- __tests/test_table.py | 28 +++++++---- __tests/test_tabs.py | 8 ++- __tests/test_textarea.py | 14 ++++-- __tests/test_toggle.py | 14 ++++-- __tests/test_tree.py | 1 - __tests/test_vfor.py | 3 +- ex4nicegui/reactive/view_model.py | 18 +++++-- 40 files changed, 359 insertions(+), 274 deletions(-) diff --git a/__tests/test_avatar.py b/__tests/test_avatar.py index 7b2bc8b..8e5fef7 100644 --- a/__tests/test_avatar.py +++ b/__tests/test_avatar.py @@ -5,10 +5,9 @@ def test_display(browser: BrowserManager, page_path: str): - icon = to_ref("home") - @ui.page(page_path) def _(): + icon = to_ref("home") rxui.avatar(icon).classes("target") page = browser.open(page_path) @@ -18,53 +17,58 @@ def _(): def test_change_icon(browser: BrowserManager, page_path: str): - icon = to_ref("home") - @ui.page(page_path) def _(): + icon = to_ref("home") rxui.avatar(icon).classes("target") + ui.button("change icon", on_click=lambda: icon.set_value("add")).classes("btn") page = browser.open(page_path) target = page.Base(".target") + btn = page.Button(".btn") target.expect_to_have_text("home") - icon.value = "add" + btn.click() target.expect_to_have_text("add") def test_bind_background_color(browser: BrowserManager, page_path: str): - bg_color = to_ref("red") @ui.page(page_path) def _(): + bg_color = to_ref("red") rxui.avatar("home").classes("target").bind_color(bg_color) + ui.button("change color", on_click=lambda: bg_color.set_value("green")).classes("btn") page = browser.open(page_path) target = page.Base(".target") + btn = page.Button(".btn") # page.pause() target.expect_to_contain_class("bg-red") - bg_color.value = "green" + btn.click() target.expect_not_to_contain_class("bg-red") target.expect_to_contain_class("bg-green") def test_bind_text_color(browser: BrowserManager, page_path: str): - text_color = to_ref("red") @ui.page(page_path) def _(): + text_color = to_ref("red") rxui.avatar("home").classes("target").bind_text_color(text_color) + ui.button("change color", on_click=lambda: text_color.set_value("green")).classes("btn") page = browser.open(page_path) target = page.Base(".target") + btn = page.Button(".btn") # page.pause() target.expect_to_contain_class("text-red") - text_color.value = "green" + btn.click() target.expect_not_to_contain_class("text-red") target.expect_to_contain_class("text-green") diff --git a/__tests/test_badge.py b/__tests/test_badge.py index a032a23..080f595 100644 --- a/__tests/test_badge.py +++ b/__tests/test_badge.py @@ -5,10 +5,9 @@ def test_badge(browser: BrowserManager, page_path: str): - text = to_ref("badge") - @ui.page(page_path) def _(): + text = to_ref("badge") rxui.input(value=text).classes("input") rxui.badge(text).classes("target") diff --git a/__tests/test_button.py b/__tests/test_button.py index 950557b..53f794a 100644 --- a/__tests/test_button.py +++ b/__tests/test_button.py @@ -5,36 +5,42 @@ def test_ref_text(browser: BrowserManager, page_path: str): - r_text = to_ref("old text") - @ui.page(page_path) def _(): + r_text = to_ref("old text") rxui.button(r_text).props('data-testid="target"').props("no-caps").classes( "btn" ) + ui.button("change text").on_click(lambda: r_text.set_value("new text")).classes( + "btn-change-text" + ) page = browser.open(page_path) btn = page.Button(".btn") + btn_change_text = page.Button(".btn-change-text") btn.expect_to_have_text("old text") - r_text.value = "new text" + btn_change_text.click() btn.expect_to_have_text(text="new text") def test_enabled(browser: BrowserManager, page_path: str): - r_num = to_ref(0) - @ui.page(page_path) def _(): + r_num = to_ref(0) rxui.button("").bind_enabled(lambda: r_num.value % 2 == 0).classes("btn") + ui.button("change num").on_click(lambda: r_num.set_value(1)).classes( + "btn-change-num" + ) page = browser.open(page_path) btn = page.Button(".btn") + btn_change_num = page.Button(".btn-change-num") btn.expect.to_be_enabled() - r_num.value = 1 + btn_change_num.click() btn.expect.not_to_be_enabled() diff --git a/__tests/test_card.py b/__tests/test_card.py index 534216d..6bfe7d2 100644 --- a/__tests/test_card.py +++ b/__tests/test_card.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - align_items = to_ref("start") - @ui.page(page_path) def _(): + align_items = to_ref("start") rxui.select(["start", "center", "end"], value=align_items).classes("select") rxui.card(align_items=align_items).classes("target") # type: ignore diff --git a/__tests/test_checkbox.py b/__tests/test_checkbox.py index 8a8dbf4..73b1b09 100644 --- a/__tests/test_checkbox.py +++ b/__tests/test_checkbox.py @@ -25,10 +25,9 @@ def _(): def test_ref_value(browser: BrowserManager, page_path: str): - r_value = to_ref(False) - @ui.page(page_path) def _(): + r_value = to_ref(False) rxui.checkbox("test checkbox", value=r_value).classes("target") rxui.label(r_value).classes("value") @@ -48,18 +47,21 @@ def _(): def test_ref_str_change_value(browser: BrowserManager, page_path: str): - r_value = to_ref(False) - @ui.page(page_path) def _(): + r_value = to_ref(False) rxui.checkbox("test checkbox", value=r_value).classes("target") + ui.button("change value").on_click(lambda: r_value.set_value(True)).classes( + "change-value" + ) page = browser.open(page_path) target = page.Checkbox(".target") + change_value_btn = page.Button(".change-value") target.expect_to_be_visible() - r_value.value = True + change_value_btn.click() target.expect.to_be_checked() diff --git a/__tests/test_chip.py b/__tests/test_chip.py index 3d688d4..97db4e0 100644 --- a/__tests/test_chip.py +++ b/__tests/test_chip.py @@ -5,10 +5,9 @@ def test_chip(browser: BrowserManager, page_path: str): - r_text = to_ref("chip") - @ui.page(page_path) def _(): + r_text = to_ref("chip") rxui.input(value=r_text).classes("input") rxui.chip(r_text).classes("chip") diff --git a/__tests/test_circular_progress.py b/__tests/test_circular_progress.py index d96999d..0aac818 100644 --- a/__tests/test_circular_progress.py +++ b/__tests/test_circular_progress.py @@ -5,19 +5,22 @@ def test_base(browser: BrowserManager, page_path: str): - value = to_ref(0.3) - @ui.page(page_path) def _(): + value = to_ref(0.3) rxui.circular_progress(value, show_value=True, size="100px").classes("cp") rxui.number(value=value).classes("number") + ui.button("change value").on_click(lambda: value.set_value(0.9)).classes( + "change-value" + ) page = browser.open(page_path) cp = page.Base(".cp") + btn = page.Button(".change-value") cp.expect.to_contain_text("0.3") - value.value = 0.9 + btn.click() cp.expect.to_contain_text("0.9") diff --git a/__tests/test_colort_picker.py b/__tests/test_colort_picker.py index 2645a1f..4dbfe29 100644 --- a/__tests/test_colort_picker.py +++ b/__tests/test_colort_picker.py @@ -5,10 +5,9 @@ def test_display(browser: BrowserManager, page_path: str): - r_color = to_ref("red") - @ui.page(page_path) def _(): + r_color = to_ref("red") rxui.color_picker(r_color).classes("target") rxui.label(r_color).classes("label") diff --git a/__tests/test_column.py b/__tests/test_column.py index 93bf30c..da82146 100644 --- a/__tests/test_column.py +++ b/__tests/test_column.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - wrap = to_ref(True) - @ui.page(page_path) def _(): + wrap = to_ref(True) rxui.checkbox(value=wrap).classes("checkbox") with rxui.column(wrap=wrap).classes("target"): diff --git a/__tests/test_date.py b/__tests/test_date.py index 76bbc69..2da7771 100644 --- a/__tests/test_date.py +++ b/__tests/test_date.py @@ -28,10 +28,9 @@ def _(): def test_ref_value(browser: BrowserManager, page_path: str): - r_value = to_ref("2023-01-01") - @ui.page(page_path) def _(): + r_value = to_ref("2023-01-01") rxui.date(r_value) page = browser.open(page_path) @@ -41,10 +40,9 @@ def _(): def test_ref_range_value(browser: BrowserManager, page_path: str): - r_value = to_ref([{"from": "2023-01-01", "to": "2023-01-06"}, "2023-01-10"]) - @ui.page(page_path) def _(): + r_value = to_ref([{"from": "2023-01-01", "to": "2023-01-06"}, "2023-01-10"]) rxui.date(r_value) # type: ignore page = browser.open(page_path) @@ -54,27 +52,44 @@ def _(): def test_ref_change_value(browser: BrowserManager, page_path: str): - r_single_value = to_ref("2023-01-01") - r_range_value = to_ref([{"from": "2023-01-01", "to": "2023-01-06"}]) - @ui.page(page_path) def _(): + r_single_value = to_ref("2023-01-01") + r_range_value = to_ref([{"from": "2023-01-01", "to": "2023-01-06"}]) rxui.date(r_single_value).classes("single-date") rxui.date(r_range_value).props("multiple range").classes("range-date") # type: ignore + ui.button("change single date").on_click( + lambda: r_single_value.set_value("2023-01-02") + ).classes("change-single-date") + ui.button("change range date").on_click( + lambda: r_range_value.set_value( + [ + {"from": "2023-01-06", "to": "2023-01-10"}, + {"from": "2023-01-15", "to": "2023-01-16"}, + "2023-01-12", + ] + ) + ).classes("change-range-date") # type: ignore + page = browser.open(page_path) single_date = page.Base(".single-date") range_date = page.Base(".range-date") + change_single_date = page.Button(".change-single-date") + change_range_date = page.Button(".change-range-date") expect(single_date.get_by_text("Sun, Jan 1").first).to_be_visible() - r_single_value.value = "2023-01-02" + change_range_date.click() + # r_single_value.value = "2023-01-02" + expect(single_date.get_by_text("Mon, Jan 2").first).to_be_visible() expect(range_date.get_by_text("6 days").first).to_be_visible() - r_range_value.value = [ - {"from": "2023-01-06", "to": "2023-01-10"}, - {"from": "2023-01-15", "to": "2023-01-16"}, - "2023-01-12", # type: ignore - ] + change_single_date.click() + # r_range_value.value = [ + # {"from": "2023-01-06", "to": "2023-01-10"}, + # {"from": "2023-01-15", "to": "2023-01-16"}, + # "2023-01-12", # type: ignore + # ] expect(range_date.get_by_text("8 days").first).to_be_visible() diff --git a/__tests/test_dialog.py b/__tests/test_dialog.py index d253d77..7c2e0f8 100644 --- a/__tests/test_dialog.py +++ b/__tests/test_dialog.py @@ -5,10 +5,10 @@ def test_value_change(browser: BrowserManager, page_path: str): - show = to_ref(False) - @ui.page(page_path) def _(): + show = to_ref(False) + def open_dialog(): show.value = True @@ -33,10 +33,9 @@ def close_dialog(): def test_ref_change(browser: BrowserManager, page_path: str): - show = to_ref(False) - @ui.page(page_path) def _(): + show = to_ref(False) rxui.checkbox(value=show).classes("checkbox") with rxui.dialog(value=show), ui.card(): diff --git a/__tests/test_drawer.py b/__tests/test_drawer.py index b17dc57..9ca572e 100644 --- a/__tests/test_drawer.py +++ b/__tests/test_drawer.py @@ -17,16 +17,16 @@ def _(): def test_toggle_side(browser: BrowserManager, page_path: str): - r_side = to_ref("left") - - def toggle_side(): - if r_side.value == "left": - r_side.value = "right" - else: - r_side.value = "left" - @ui.page(page_path) def _(): + r_side = to_ref("left") + + def toggle_side(): + if r_side.value == "left": + r_side.value = "right" + else: + r_side.value = "left" + with rxui.drawer(r_side): # type: ignore ui.label("drawer showed") rxui.label(r_side) @@ -52,13 +52,13 @@ def onclick(): def test_toggle_show(browser: BrowserManager, page_path: str): - r_show = to_ref(True) - - def toggle_show(): - r_show.value = not r_show.value - @ui.page(page_path) def _(): + r_show = to_ref(True) + + def toggle_show(): + r_show.value = not r_show.value + with rxui.drawer(value=r_show): ui.label("drawer showed").classes("label") diff --git a/__tests/test_echarts.py b/__tests/test_echarts.py index 35f12dc..274263a 100644 --- a/__tests/test_echarts.py +++ b/__tests/test_echarts.py @@ -118,52 +118,51 @@ def _(): def test_js_function_opt(browser: BrowserManager, page_path: str): - r_unit = to_ref("kg") + @ui.page(page_path) + def _(): + r_unit = to_ref("kg") - yAxis_formatter = ref_computed( - lambda: f"""function (value, index) {{ - return value + '{r_unit.value}'; - }} - """ - ) + yAxis_formatter = ref_computed( + lambda: f"""function (value, index) {{ + return value + '{r_unit.value}'; + }} + """ + ) - opts = ref_computed( - lambda: { - "xAxis": { - "type": "category", - "data": [ - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", - "Sun", - ], - }, - "yAxis": { - "type": "value", - "axisLabel": {":formatter": yAxis_formatter.value}, - }, - "series": [ - { + opts = ref_computed( + lambda: { + "xAxis": { + "type": "category", "data": [ - 120, - 200, - 150, - 80, - 70, - 110, - 130, + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + "Sun", ], - "type": "bar", - } - ], - } - ) - - @ui.page(page_path) - def _(): + }, + "yAxis": { + "type": "value", + "axisLabel": {":formatter": yAxis_formatter.value}, + }, + "series": [ + { + "data": [ + 120, + 200, + 150, + 80, + 70, + 110, + 130, + ], + "type": "bar", + } + ], + } + ) rxui.echarts(opts).classes("target") page = browser.open(page_path) diff --git a/__tests/test_html.py b/__tests/test_html.py index 25914b0..ac56b42 100644 --- a/__tests/test_html.py +++ b/__tests/test_html.py @@ -5,16 +5,20 @@ def test_base(browser: BrowserManager, page_path: str): - current = to_ref("

test1

") - @ui.page(page_path) def _(): + current = to_ref("

test1

") rxui.html(current).classes("target") + ui.button( + "change", + on_click=lambda: current.set_value("

test2:inner

"), + ).classes("btn-change") page = browser.open(page_path) target = page.Base(".target") + btn_change = page.Base(".btn-change") target.expect.to_have_text("test1") - current.value = "

test2:inner

" + btn_change.click() target.expect.to_have_text("test2:inner") diff --git a/__tests/test_icon.py b/__tests/test_icon.py index 3a54123..c968314 100644 --- a/__tests/test_icon.py +++ b/__tests/test_icon.py @@ -14,32 +14,40 @@ def _(): def test_ref_str(browser: BrowserManager, page_path: str): - r_str = to_ref("home") - @ui.page(page_path) def _(): + r_str = to_ref("home") rxui.icon(r_str) + ui.button( + "change", + on_click=lambda: r_str.set_value("add"), + ).classes("btn-change") page = browser.open(page_path) + btn = page.Button(".btn-change") page.should_contain("home") - r_str.value = "add" + btn.click() page.should_contain("add") def test_color(browser: BrowserManager, page_path: str): - r_color = to_ref("primary") - @ui.page(page_path) def _(): + r_color = to_ref("primary") rxui.icon("home", color=r_color).classes("target") + ui.button( + "change", + on_click=lambda: r_color.set_value("rgba(224,52,52,1)"), + ).classes("btn-change") page = browser.open(page_path) icon = page.Base(".target") + btn = page.Button(".btn-change") icon.expect_to_have_style("color", "rgb(88, 152, 212)") - r_color.value = "rgba(224,52,52,1)" + btn.click() icon.expect_to_have_style("color", "rgb(224, 52, 52)") diff --git a/__tests/test_image.py b/__tests/test_image.py index 1764662..5e12a69 100644 --- a/__tests/test_image.py +++ b/__tests/test_image.py @@ -30,22 +30,27 @@ def test_source(browser: BrowserManager, page_path: str): "ZiyWIKEo+KJL9F6b4tFfx1jeINMMLcQYWIjijyU2JfpG/tMvsokSSSkAYVytJ5eB/hIoKQxBUdWiHsSy" "cHLlz0gP6T8lepD+xTQjvKnT/mXKlCmzAX8Dl7JCqRHaepQAAAAASUVORK5CYII=" ) - img_source = to_ref(image_file) @ui.page(page_path) def _(): + img_source = to_ref(image_file) rxui.image(img_source).props("fit=contain").classes( "w-[20rem] h-[20rem] target" ) + ui.button( + "change", + on_click=lambda: img_source.set_value(img_bs64), # type: ignore + ).classes("btn-change") page = browser.open(page_path) target = page.Image(".target") + btn_change = page.Button(".btn-change") target.expect_find_by_class("q-img__image") target.expect_load_image() - img_source.value = img_bs64 # type: ignore + btn_change.click() page._page.wait_for_timeout(1000) target.expect_load_image() diff --git a/__tests/test_input.py b/__tests/test_input.py index e067e1d..4394feb 100644 --- a/__tests/test_input.py +++ b/__tests/test_input.py @@ -5,30 +5,34 @@ def test_display(browser: BrowserManager, page_path: str): - r_str = to_ref("ref value") - @ui.page(page_path) def _(): + r_str = to_ref("ref value") rxui.input(value="const value").classes("const-input") rxui.input(value=r_str).classes("ref-input") + ui.button( + "change", + on_click=lambda: r_str.set_value("new"), + ).classes("btn-change") page = browser.open(page_path) target_const = page.Input(".const-input") + btn_change = page.Button(".btn-change") target_const.expect_to_have_text("const value") target_ref = page.Input(".ref-input") target_ref.expect_to_have_text("ref value") - r_str.value = "new" + btn_change.click() target_ref.expect_to_have_text("new") def test_input_change_value(browser: BrowserManager, page_path: str): - r_str = to_ref("old") - dummy = "" - @ui.page(page_path) def _(): + r_str = to_ref("old") + dummy = "" + def onchange(): nonlocal dummy dummy = r_str.value @@ -44,8 +48,6 @@ def onchange(): label.expect_to_have_text("new value") - assert dummy == "new value" - def test_autocomplete(browser: BrowserManager, page_path: str): @ui.page(page_path) diff --git a/__tests/test_knob.py b/__tests/test_knob.py index da98507..a9a3159 100644 --- a/__tests/test_knob.py +++ b/__tests/test_knob.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - value = to_ref(0.3) - @ui.page(page_path) def _(): + value = to_ref(0.3) knob = rxui.knob(value, show_value=True, size="200px").classes("knob") rxui.label(value).classes("label") ui.button("change value", on_click=lambda: knob.element.set_value(0.9)).classes( diff --git a/__tests/test_label.py b/__tests/test_label.py index ae97f2b..78b07b7 100644 --- a/__tests/test_label.py +++ b/__tests/test_label.py @@ -5,11 +5,10 @@ def test_display(browser: BrowserManager, page_path: str): - r_str = to_ref("ref label") - r_bool = to_ref("init") - @ui.page(page_path) def _(): + r_str = to_ref("ref label") + r_bool = to_ref("init") rxui.label("test label").classes("target") rxui.label(r_str).classes("ref-target") @@ -29,33 +28,41 @@ def _(): def test_ref_str_change_value(browser: BrowserManager, page_path: str): - r_str = to_ref("old") - @ui.page(page_path) def _(): + r_str = to_ref("old") rxui.label(r_str).classes("target") + ui.button( + "change", + on_click=lambda: r_str.set_value("new"), + ).classes("btn-change") page = browser.open(page_path) - + btn = page.Button(".btn-change") target = page.Label(".target") target.expect_to_have_text("old") - r_str.value = "new" + btn.click() target.expect_to_have_text("new") def test_bind_color(browser: BrowserManager, page_path: str): - r_color = to_ref("red") @ui.page(page_path) def _(): + r_color = to_ref("red") rxui.label("label").classes("target").bind_color(r_color) + ui.button( + "change", + on_click=lambda: r_color.set_value("green"), + ).classes("btn-change") page = browser.open(page_path) target = page.Label(".target") + btn = page.Button(".btn-change") target.expect_to_have_style("color", "rgb(255, 0, 0)") - r_color.value = "green" + btn.click() target.expect_to_have_style("color", "rgb(0, 128, 0)") diff --git a/__tests/test_lazy_input.py b/__tests/test_lazy_input.py index 5afc50f..239d0d6 100644 --- a/__tests/test_lazy_input.py +++ b/__tests/test_lazy_input.py @@ -5,29 +5,32 @@ def test_display(browser: BrowserManager, page_path: str): - r_str = to_ref("ref value") - @ui.page(page_path) def _(): + r_str = to_ref("ref value") rxui.lazy_input(value="const value").classes("const-input") rxui.lazy_input(value=r_str).classes("ref-input") + ui.button( + "change", + on_click=lambda: r_str.set_value("new"), + ).classes("btn-change") page = browser.open(page_path) target_const = page.Input(".const-input") + btn = page.Button(".btn-change") target_const.expect_to_have_text("const value") target_ref = page.Input(".ref-input") target_ref.expect_to_have_text("ref value") - r_str.value = "new" + btn.click() target_ref.expect_to_have_text("new") def test_input_change_value_when_enter(browser: BrowserManager, page_path: str): - r_str = to_ref("old") - @ui.page(page_path) def _(): + r_str = to_ref("old") rxui.lazy_input(value=r_str).props("clearable").classes("input") rxui.label(r_str).classes("label") diff --git a/__tests/test_lazy_range.py b/__tests/test_lazy_range.py index e83bb9f..159f8d5 100644 --- a/__tests/test_lazy_range.py +++ b/__tests/test_lazy_range.py @@ -29,15 +29,14 @@ def mouse_up( def test_ref_value_change(browser: BrowserManager, page_path: str): - r_value = to_ref( - { - "min": 0, - "max": 100, - } - ) - @ui.page(page_path) def _(): + r_value = to_ref( + { + "min": 0, + "max": 100, + } + ) rxui.lazy_range(min=0, max=100, value=r_value).classes("target") rxui.label(r_value).classes("label") @@ -82,7 +81,6 @@ def on_change(e): label.expect_equal_text("{'min': 8, 'max': 100}") - def test_on_update_event(browser: BrowserManager, page_path: str): r_value = to_ref( { diff --git a/__tests/test_lazy_textarea.py b/__tests/test_lazy_textarea.py index 371338c..9a381a9 100644 --- a/__tests/test_lazy_textarea.py +++ b/__tests/test_lazy_textarea.py @@ -5,29 +5,32 @@ def test_display(browser: BrowserManager, page_path: str): - r_str = to_ref("ref value") - @ui.page(page_path) def _(): + r_str = to_ref("ref value") rxui.lazy_textarea(value="const value").classes("const-input") rxui.lazy_textarea(value=r_str).classes("ref-input") + ui.button( + "change", + on_click=lambda: r_str.set_value("new"), + ).classes("btn-change") page = browser.open(page_path) target_const = page.Textarea(".const-input") + btn = page.Button(".btn-change") target_const.expect_to_have_text("const value") target_ref = page.Textarea(".ref-input") target_ref.expect_to_have_text("ref value") - r_str.value = "new" + btn.click() target_ref.expect_to_have_text("new") def test_input_change_value_when_enter(browser: BrowserManager, page_path: str): - r_str = to_ref("old") - @ui.page(page_path) def _(): + r_str = to_ref("old") rxui.lazy_textarea(value=r_str).classes("target") rxui.label(r_str).classes("label") diff --git a/__tests/test_linear_progress.py b/__tests/test_linear_progress.py index 9985ed4..88e221b 100644 --- a/__tests/test_linear_progress.py +++ b/__tests/test_linear_progress.py @@ -5,14 +5,18 @@ def test_base(browser: BrowserManager, page_path: str): - r_value = to_ref(0.1) - @ui.page(page_path) def _(): + r_value = to_ref(0.1) rxui.linear_progress(value=r_value) + ui.button( + "change", + on_click=lambda: r_value.set_value(0.5), + ).classes("btn-change") page = browser.open(page_path) + btn = page.Button(".btn-change") page.should_contain("0.1") - r_value.value = 0.5 + btn.click() page.should_contain("0.5") diff --git a/__tests/test_number.py b/__tests/test_number.py index afbb809..372b0bc 100644 --- a/__tests/test_number.py +++ b/__tests/test_number.py @@ -17,21 +17,24 @@ def _(): def test_ref(browser: BrowserManager, page_path: str): - r_value = to_ref(1.0) - @ui.page(page_path) def _(): + r_value = to_ref(1.0) rxui.number(value=r_value).classes("target") rxui.label(text=r_value).classes("label") + ui.button( + "change", + on_click=lambda: r_value.set_value(3.11), + ).classes("btn-change") page = browser.open(page_path) - + btn = page.Button(".btn-change") target = page.Number(".target") label = page.Label(".label") target.expect_to_have_text("1") - r_value.value = 3.11 + btn.click() target.expect_to_have_text("3.11") # type input number @@ -81,18 +84,21 @@ def _(): def test_precision(browser: BrowserManager, page_path: str): - value = to_ref(3.14159265359) - precision = to_ref(5) - @ui.page(page_path) def _(): + value = to_ref(3.14159265359) + precision = to_ref(5) rxui.number(value=value, precision=precision).classes("target") + rxui.button("change", on_click=lambda: precision.set_value(2)).classes( + "btn-change" + ) page = browser.open(page_path) target = page.Number(".target") + btn = page.Button(".btn-change") target.expect_to_have_text("3.14159265359") - precision.value = 2 + btn.click() target.expect_to_have_text("3.14") diff --git a/__tests/test_pagination.py b/__tests/test_pagination.py index fe4662a..8c029e5 100644 --- a/__tests/test_pagination.py +++ b/__tests/test_pagination.py @@ -5,19 +5,24 @@ def test_base(browser: BrowserManager, page_path: str): - min = to_ref(1) - max = to_ref(5) - page_value = to_ref(2) - direction_links = to_ref(True) - @ui.page(page_path) def _(): + min = to_ref(1) + max = to_ref(5) + page_value = to_ref(2) + direction_links = to_ref(True) rxui.pagination( min, max, direction_links=direction_links, value=page_value ).classes("pagination") rxui.label(page_value).classes("label") + ui.button( + "change-direction_links", + on_click=lambda: direction_links.set_value(False), + ).classes("change-direction_links") + page = browser.open(page_path) + change_direction_links = page.Button(".change-direction_links") pagination = page.Base(".pagination") label_value = page.Label(".label") @@ -34,5 +39,5 @@ def _(): max.value = 4 pagination.expect.to_contain_text("keyboard_arrow_left234keyboard_arrow_right") - direction_links.value = False + change_direction_links.click() pagination.expect.to_contain_text("234") diff --git a/__tests/test_radio.py b/__tests/test_radio.py index 918204c..1ccfa83 100644 --- a/__tests/test_radio.py +++ b/__tests/test_radio.py @@ -30,10 +30,9 @@ def _(): def test_ref_value(browser: BrowserManager, page_path: str): - r_value = to_ref(None) - @ui.page(page_path) def _(): + r_value = to_ref(None) rxui.radio(["a", "b"], value=r_value).classes("target") rxui.label(r_value).classes("label") @@ -47,8 +46,6 @@ def _(): target.expect_not_to_be_checked("a") target.expect_not_to_be_checked("b") - assert r_value.value is None - target.check_by_label("a") target.expect_to_be_checked("a") @@ -63,33 +60,38 @@ def _(): def test_ref_str_change_value(browser: BrowserManager, page_path: str): - r_value: Ref[Optional[str]] = to_ref(None) + data = iter(["a", "b"]) @ui.page(page_path) def _(): + r_value: Ref[Optional[str]] = to_ref(None) rxui.radio(["a", "b"], value=r_value).classes("target") + ui.button( + "change", + on_click=lambda: r_value.set_value(next(data)), + ).classes("btn-change") page = browser.open(page_path) target = page.Radio(".target") + btn = page.Button(".btn-change") target.expect_to_be_visible() - r_value.value = "a" + btn.click() target.expect_to_be_checked("a") target.expect_not_to_be_checked("b") - r_value.value = "b" + btn.click() target.expect_not_to_be_checked("a") target.expect_to_be_checked("b") def test_ref_value_dict_options(browser: BrowserManager, page_path: str): - r_value: Ref[Optional[str]] = to_ref(None) - @ui.page(page_path) def _(): + r_value: Ref[Optional[str]] = to_ref(None) opts = { "a": "a value", "b": "b value", diff --git a/__tests/test_range.py b/__tests/test_range.py index c5d7018..7772ac4 100644 --- a/__tests/test_range.py +++ b/__tests/test_range.py @@ -24,15 +24,14 @@ def drap_move(type: Literal["min", "max"], page: PageUtils, offset_x: int): def test_min_change(browser: BrowserManager, page_path: str): - r_value = to_ref( - { - "min": 0, - "max": 100, - } - ) - @ui.page(page_path) def _(): + r_value = to_ref( + { + "min": 0, + "max": 100, + } + ) rxui.range(min=0, max=100, value=r_value).classes("target") rxui.label(r_value).classes("label") @@ -45,15 +44,14 @@ def _(): def test_max_change(browser: BrowserManager, page_path: str): - r_value = to_ref( - { - "min": 0, - "max": 100, - } - ) - @ui.page(page_path) def _(): + r_value = to_ref( + { + "min": 0, + "max": 100, + } + ) rxui.range(min=0, max=100, value=r_value).classes("target") rxui.label(r_value).classes("label") @@ -65,15 +63,14 @@ def _(): def test_ref_value_change(browser: BrowserManager, page_path: str): - r_value = to_ref( - { - "min": 0, - "max": 100, - } - ) - @ui.page(page_path) def _(): + r_value = to_ref( + { + "min": 0, + "max": 100, + } + ) rxui.range(min=0, max=100, value=r_value).classes("target").props( "label-always" ) diff --git a/__tests/test_ref_computed.py b/__tests/test_ref_computed.py index 4ae32e9..ab1668e 100644 --- a/__tests/test_ref_computed.py +++ b/__tests/test_ref_computed.py @@ -80,10 +80,9 @@ def __init__(self): def color(self): return "green" if self.count.value % 2 == 0 else "red" - state = MyState() - @ui.page(page_path) def _(): + state = MyState() rxui.label(state.color) ui.button("reload", on_click=ui.navigate.reload).classes("button") diff --git a/__tests/test_row.py b/__tests/test_row.py index 2514af6..7a2ccdd 100644 --- a/__tests/test_row.py +++ b/__tests/test_row.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - wrap = to_ref(True) - @ui.page(page_path) def _(): + wrap = to_ref(True) rxui.checkbox(value=wrap).classes("checkbox") with rxui.row(wrap=wrap).classes("target"): diff --git a/__tests/test_select.py b/__tests/test_select.py index 71c92de..2a0bb65 100644 --- a/__tests/test_select.py +++ b/__tests/test_select.py @@ -18,34 +18,39 @@ def _(): def test_ref_str(browser: BrowserManager, page_path: str): - r_str: Ref[Optional[str]] = to_ref(None) + values = iter(["a", "b", ""]) @ui.page(page_path) def _(): + r_str: Ref[Optional[str]] = to_ref(None) rxui.select(["a", "b"], value=r_str).classes("min-w-[20ch] target") + ui.button( + "change", + on_click=lambda: r_str.set_value(next(values)), + ).classes("btn-change") page = browser.open(page_path) target = page.Select(".target") + btn = page.Button(".btn-change") target.expect_not_to_have_value("a") target.expect_not_to_have_value("b") - r_str.value = "a" + btn.click() target.expect_to_have_value("a") - r_str.value = "b" + btn.click() target.expect_to_have_value("b") - r_str.value = "" + btn.click() target.expect_not_to_have_value("a") target.expect_not_to_have_value("b") def test_clearable(browser: BrowserManager, page_path: str): - r_str = to_ref("a") - @ui.page(page_path) def _(): + r_str = to_ref("a") rxui.select(["a", "b"], value=r_str).classes("min-w-[20ch] target").props( "clearable" ) @@ -60,21 +65,19 @@ def _(): target.expect_not_to_have_value("a") target.expect_not_to_have_value("b") - assert r_str.value is None - def test_option_change(browser: BrowserManager, page_path: str): - r_str = to_ref(None) - r_has_data = to_ref(False) - - @ref_computed - def cp_data(): - if r_has_data.value: - return ["a", "b"] - return [] - @ui.page(page_path) def _(): + r_str = to_ref(None) + r_has_data = to_ref(False) + + @ref_computed + def cp_data(): + if r_has_data.value: + return ["a", "b"] + return [] + rxui.switch("has data", value=r_has_data).classes("switch") rxui.select(cp_data, value=r_str).classes("min-w-[20ch] target") rxui.label(r_str).classes("label-str") @@ -92,10 +95,9 @@ def _(): def test_multiple_list_opts(browser: BrowserManager, page_path: str): - r_value = to_ref(["a", "b"]) - @ui.page(page_path) def _(): + r_value = to_ref(["a", "b"]) rxui.select(["a", "b", "c", "d"], value=r_value, multiple=True).classes( "target" ) @@ -115,10 +117,9 @@ def _(): def test_multiple_dict_opts(browser: BrowserManager, page_path: str): - r_value = to_ref([1, 2]) - @ui.page(page_path) def _(): + r_value = to_ref([1, 2]) rxui.select( {1: "a", 2: "b", 3: "c", 4: "d"}, value=r_value, multiple=True ).classes("min-w-[20ch] target") @@ -139,11 +140,10 @@ def _(): @pytest.mark.skip(reason="not implemented yet") def test_new_value_mode(browser: BrowserManager, page_path: str): - r_str = to_ref(None) - r_opts = to_ref([]) - @ui.page(page_path) def _(): + r_str = to_ref(None) + r_opts = to_ref([]) rxui.select( r_opts, clearable=True, value=r_str, new_value_mode="add-unique" ).classes("min-w-[20ch] target") @@ -177,11 +177,11 @@ def test_opts_value_change_same_time(browser: BrowserManager, page_path: str): "opts2": list("mnxy"), } - value1 = to_ref("opts1") - value2 = to_ref("") - @ui.page(page_path) def _(): + value1 = to_ref("opts1") + value2 = to_ref("") + @ref_computed def opts2(): return data[value1.value] diff --git a/__tests/test_signe.py b/__tests/test_signe.py index dcb3a6b..18dea2d 100644 --- a/__tests/test_signe.py +++ b/__tests/test_signe.py @@ -4,11 +4,10 @@ def test_batch_event(browser: BrowserManager, page_path: str): - a = to_ref(0) - b = to_ref(0) - @ui.page(page_path) def _(): + a = to_ref(0) + b = to_ref(0) lbl_fn_on_times = ui.label("0").classes("label-fn-on-times") lbl_fn_effect_times = ui.label("0").classes("label-fn-effect-times") diff --git a/__tests/test_slider.py b/__tests/test_slider.py index d9a8d34..053eb18 100644 --- a/__tests/test_slider.py +++ b/__tests/test_slider.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - r_value = to_ref(0) - @ui.page(page_path) def _(): + r_value = to_ref(0) rxui.slider(min=0, max=100, value=r_value).classes("target") rxui.label(r_value).classes("label") diff --git a/__tests/test_switch.py b/__tests/test_switch.py index 5e958c1..5e7acf4 100644 --- a/__tests/test_switch.py +++ b/__tests/test_switch.py @@ -23,10 +23,9 @@ def _(): def test_ref_value(browser: BrowserManager, page_path: str): - r_on = to_ref(False) - @ui.page(page_path) def _(): + r_on = to_ref(False) rxui.switch(value=r_on).classes("target") rxui.label(text=r_on).classes("label") @@ -44,18 +43,22 @@ def _(): def test_ref_str_change_value(browser: BrowserManager, page_path: str): - r_on = to_ref(False) - @ui.page(page_path) def _(): + r_on = to_ref(False) rxui.switch(value=r_on).classes("target") + ui.button( + "change", + on_click=lambda: r_on.set_value(True), + ).classes("btn-change") page = browser.open(page_path) target = page.Switch(".target") + btn = page.Button(".btn-change") target.expect_to_be_visible() target.expect_not_checked() - r_on.value = True + btn.click() target.expect_checked() diff --git a/__tests/test_table.py b/__tests/test_table.py index 7ffacd5..ec112a9 100644 --- a/__tests/test_table.py +++ b/__tests/test_table.py @@ -96,29 +96,35 @@ def onclick(): def test_from_pandas(browser: BrowserManager, page_path: str): - data = to_ref( - pd.DataFrame( - { - "date": pd.date_range("today", periods=3), - "name": ["a", "b", "c"], - "age": [1, 2, 3], - } - ) - ) - @ui.page(page_path) def _(): + data = to_ref( + pd.DataFrame( + { + "date": pd.date_range("today", periods=3), + "name": ["a", "b", "c"], + "age": [1, 2, 3], + } + ) + ) rxui.table.from_pandas(data).classes("target") # test lambda display rxui.table.from_pandas(lambda: data.value.head(2)) + ui.button( + "change", + on_click=lambda: data.set_value( + pd.DataFrame({"new name": ["x", "y", "z"], "age": [1, 2, 3]}) + ), + ).classes("btn-change") page = browser.open(page_path) target = page.Table(".target") + btn = page.Button(".btn-change") target.expect_cell_to_be_visible(["name", "a", "b", "c"]) - data.value = pd.DataFrame({"new name": ["x", "y", "z"], "age": [1, 2, 3]}) + btn.click() target.expect_cell_not_to_be_visible(["name", "a", "b", "c"]) diff --git a/__tests/test_tabs.py b/__tests/test_tabs.py index 15e30d8..aeb0366 100644 --- a/__tests/test_tabs.py +++ b/__tests/test_tabs.py @@ -5,10 +5,9 @@ def test_base(browser: BrowserManager, page_path: str): - current = to_ref("a") - @ui.page(page_path) def _(): + current = to_ref("a") rxui.label(current).classes("label") with rxui.tabs(current).classes("tabs"): rxui.tab("a", "a tab") @@ -24,11 +23,10 @@ def _(): def test_should_tab_label_change(browser: BrowserManager, page_path: str): - current = to_ref("a") - b_tab_label = to_ref("b tab") - @ui.page(page_path) def _(): + current = to_ref("a") + b_tab_label = to_ref("b tab") rxui.input(value=b_tab_label).classes("input") with rxui.tabs(current).classes("tabs"): rxui.tab("a", "a tab") diff --git a/__tests/test_textarea.py b/__tests/test_textarea.py index ba0b84a..9663637 100644 --- a/__tests/test_textarea.py +++ b/__tests/test_textarea.py @@ -5,29 +5,33 @@ def test_display(browser: BrowserManager, page_path: str): - r_str = to_ref("ref value") - @ui.page(page_path) def _(): + r_str = to_ref("ref value") rxui.textarea(value="const value").classes("const") rxui.textarea(value=r_str).classes("ref") + ui.button( + "change", + on_click=lambda: r_str.set_value("new"), + ).classes("btn-change") page = browser.open(page_path) target_const = page.Textarea(".const") + btn = page.Button(".btn-change") + target_const.expect_to_have_text("const value") target_ref = page.Textarea(".ref") target_ref.expect_to_have_text("ref value") - r_str.value = "new" + btn.click() target_ref.expect_to_have_text("new") def test_input_change_value(browser: BrowserManager, page_path: str): - r_str = to_ref("old") - @ui.page(page_path) def _(): + r_str = to_ref("old") rxui.textarea(value=r_str).classes("target") rxui.label(r_str).classes("label") diff --git a/__tests/test_toggle.py b/__tests/test_toggle.py index de396d7..370e52f 100644 --- a/__tests/test_toggle.py +++ b/__tests/test_toggle.py @@ -17,25 +17,31 @@ def _(): def test_ref_str(browser: BrowserManager, page_path: str): - r_str: Ref[Optional[str]] = to_ref(None) + values = iter(["a", "b", None]) @ui.page(page_path) def _(): + r_str: Ref[Optional[str]] = to_ref(None) rxui.toggle(["a", "b"], value=r_str).classes("min-w-[20ch] target") + ui.button( + "change", + on_click=lambda: r_str.set_value(next(values)), + ).classes("btn-change") page = browser.open(page_path) target = page.Toggle(".target") + btn = page.Button(".btn-change") target.expect_not_selected("a") target.expect_not_selected("b") - r_str.value = "a" + btn.click() target.expect_selected("a") - r_str.value = "b" + btn.click() target.expect_selected("b") - r_str.value = None + btn.click() target.expect_not_selected("a") target.expect_not_selected("b") diff --git a/__tests/test_tree.py b/__tests/test_tree.py index fb5a3cb..4bed04c 100644 --- a/__tests/test_tree.py +++ b/__tests/test_tree.py @@ -2,7 +2,6 @@ from nicegui import ui from ex4nicegui import to_ref from .screen import BrowserManager -from playwright.sync_api import expect def test_nodes(browser: BrowserManager, page_path: str): diff --git a/__tests/test_vfor.py b/__tests/test_vfor.py index 48ab59b..818e891 100644 --- a/__tests/test_vfor.py +++ b/__tests/test_vfor.py @@ -283,10 +283,9 @@ def _(store: rxui.VforStore[str]): page.should_contain("abc") def test_deep_ref(self, browser: BrowserManager, page_path: str): - data = deep_ref([1, 2, 3, 4]) - @ui.page(page_path) def _(): + data = deep_ref([1, 2, 3, 4]) with ui.column().classes("for_box"): @rxui.vfor(data) diff --git a/ex4nicegui/reactive/view_model.py b/ex4nicegui/reactive/view_model.py index 644e706..ea0e740 100644 --- a/ex4nicegui/reactive/view_model.py +++ b/ex4nicegui/reactive/view_model.py @@ -21,6 +21,7 @@ from ex4nicegui.utils.proxy import to_value_if_base_type_proxy from ex4nicegui.utils.proxy.descriptor import ProxyDescriptor +_VAR_FLAG = "__vm_var__" _CACHED_VARS_FLAG = "__vm_cached__" _LIST_VAR_FLAG = "__vm_list_var__" @@ -67,8 +68,8 @@ def add_data(self): def __init__(self): for name, value in self.__class__.__dict__.items(): - if is_ref(value): - setattr(self, name, deep_ref(to_value(value))) + if hasattr(value, _VAR_FLAG): + setattr(self, name, _create_from_var(value)) if callable(value) and hasattr(value, _CACHED_VARS_FLAG): setattr(self, name, computed(partial(value, self))) @@ -229,6 +230,14 @@ def handle_ref(value): return result +def _create_from_var( + value: Union[_T_Var_Value, Callable[[], _T_Var_Value]], +) -> Ref[_T_Var_Value]: + if callable(value): + return deep_ref(value()) # type: ignore + return deep_ref(value) + + _T_Var_Value = TypeVar("_T_Var_Value") @@ -247,9 +256,8 @@ class MyVm(rxui.ViewModel): """ - if callable(value): - return deep_ref(value()) - return deep_ref(value) + setattr(value, _VAR_FLAG, None) + return value # type: ignore def list_var(factory: Callable[[], List[_T_Var_Value]]) -> List[_T_Var_Value]: From bd7d399b968f28bd9c840cf7b7d6367da3f946a3 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 01:37:35 +0800 Subject: [PATCH 4/7] fix testing --- __tests/test_pagination.py | 16 ++++++++++++++-- __tests/test_toggle.py | 27 +++++++++++++-------------- __tests/test_use_pagination.py | 31 +++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/__tests/test_pagination.py b/__tests/test_pagination.py index 8c029e5..56704c6 100644 --- a/__tests/test_pagination.py +++ b/__tests/test_pagination.py @@ -16,6 +16,16 @@ def _(): ).classes("pagination") rxui.label(page_value).classes("label") + ui.button( + "change-min", + on_click=lambda: min.set_value(2), + ).classes("change-min") + + ui.button( + "change-max", + on_click=lambda: max.set_value(2), + ).classes("change-max") + ui.button( "change-direction_links", on_click=lambda: direction_links.set_value(False), @@ -23,6 +33,8 @@ def _(): page = browser.open(page_path) change_direction_links = page.Button(".change-direction_links") + change_min = page.Button(".change-min") + change_max = page.Button(".change-max") pagination = page.Base(".pagination") label_value = page.Label(".label") @@ -33,10 +45,10 @@ def _(): pagination.target_locator.get_by_role("button").filter(has_text="4").click() label_value.expect_contain_text("4") - min.value = 2 + change_min.click() pagination.expect.to_contain_text("keyboard_arrow_left2345keyboard_arrow_right") - max.value = 4 + change_max.click() pagination.expect.to_contain_text("keyboard_arrow_left234keyboard_arrow_right") change_direction_links.click() diff --git a/__tests/test_toggle.py b/__tests/test_toggle.py index 370e52f..2671b28 100644 --- a/__tests/test_toggle.py +++ b/__tests/test_toggle.py @@ -47,10 +47,9 @@ def _(): def test_clearable(browser: BrowserManager, page_path: str): - r_str = to_ref("a") - @ui.page(page_path) def _(): + r_str = to_ref("a") rxui.toggle(["a", "b"], value=r_str, clearable=True).classes( "min-w-[20ch] target" ) @@ -71,17 +70,17 @@ def _(): def test_option_change(browser: BrowserManager, page_path: str): - r_value = to_ref(None) - r_has_data = to_ref(False) - - @ref_computed - def cp_data(): - if r_has_data.value: - return ["a", "b"] - return [] - @ui.page(page_path) def _(): + r_value = to_ref(None) + r_has_data = to_ref(False) + + @ref_computed + def cp_data(): + if r_has_data.value: + return ["a", "b"] + return [] + rxui.switch("has data", value=r_has_data).classes("switch") rxui.toggle(cp_data, value=r_value).classes("min-w-[20ch] target") rxui.label(r_value).classes("label-str") @@ -104,11 +103,11 @@ def test_opts_value_change_same_time(browser: BrowserManager, page_path: str): "opts2": list("mnxy"), } - value1 = to_ref("opts1") - value2 = to_ref("") - @ui.page(page_path) def _(): + value1 = to_ref("opts1") + value2 = to_ref("") + @ref_computed def opts2(): return data[value1.value] diff --git a/__tests/test_use_pagination.py b/__tests/test_use_pagination.py index 1cc1516..de0f85e 100644 --- a/__tests/test_use_pagination.py +++ b/__tests/test_use_pagination.py @@ -28,70 +28,81 @@ def _(): def test_set_current_page(browser: BrowserManager, page_path: str): - r_cur_page = to_ref(2) + values = iter([1, 10, 11]) @ui.page(page_path) def _(): + r_cur_page = to_ref(2) page_size = 10 data = list(range(105)) pagination = rxui.use_pagination(data, page_size, r_cur_page) rxui.label(pagination.current_source).classes("result") + ui.button("change current page").on_click( + lambda: r_cur_page.set_value(next(values)) + ).classes("btn-change-page") page = browser.open(page_path) lbl_result = page.Label(".result") + btn_change_page = page.Button(".btn-change-page") lbl_result.expect_contain_text("[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]") - r_cur_page.value = 1 + btn_change_page.click() lbl_result.expect_contain_text("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]") - r_cur_page.value = 10 + btn_change_page.click() lbl_result.expect_contain_text("[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]") - r_cur_page.value = 11 + btn_change_page.click() lbl_result.expect_contain_text("[100, 101, 102, 103, 104]") def test_set_current_page_over_max_size(browser: BrowserManager, page_path: str): - r_cur_page = to_ref(12) - @ui.page(page_path) def _(): + r_cur_page = to_ref(12) page_size = 10 data = list(range(105)) pagination = rxui.use_pagination(data, page_size, r_cur_page) rxui.label(pagination.current_source).classes("result") + ui.button("change current page").on_click( + lambda: r_cur_page.set_value(0) + ).classes("btn-change-page") page = browser.open(page_path) lbl_result = page.Label(".result") + btn_change_page = page.Button(".btn-change-page") lbl_result.expect_contain_text("[100, 101, 102, 103, 104]") - r_cur_page.value = 0 + btn_change_page.click() lbl_result.expect_contain_text("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]") def test_first_last_page(browser: BrowserManager, page_path: str): - r_cur_page = to_ref(12) - @ui.page(page_path) def _(): + r_cur_page = to_ref(12) page_size = 10 data = list(range(105)) pagination = rxui.use_pagination(data, page_size, r_cur_page) rxui.label(pagination.is_first_page).classes("is-first-page") rxui.label(pagination.is_last_page).classes("is-last-page") + ui.button("change current page").on_click( + lambda: r_cur_page.set_value(0) + ).classes("btn-change-page") page = browser.open(page_path) lbl_is_first_page = page.Label(".is-first-page") lbl_is_last_page = page.Label(".is-last-page") + btn_change_page = page.Button(".btn-change-page") lbl_is_first_page.expect_contain_text("False") lbl_is_last_page.expect_contain_text("True") - r_cur_page.value = 0 + btn_change_page.click() lbl_is_first_page.expect_contain_text("True") lbl_is_last_page.expect_contain_text("False") From 92ee7e9facac6affb1de3f70daec3644eb914542 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 01:37:49 +0800 Subject: [PATCH 5/7] check_cross_client_binding --- ex4nicegui/utils/signals.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ex4nicegui/utils/signals.py b/ex4nicegui/utils/signals.py index 165ec19..3185af9 100644 --- a/ex4nicegui/utils/signals.py +++ b/ex4nicegui/utils/signals.py @@ -14,7 +14,7 @@ ) from nicegui import ui from .effect import effect -from .scheduler import get_uiScheduler +from .scheduler import get_uiScheduler, UiScheduler from .types import ( _TMaybeRef, TGetterOrReadonlyRef, @@ -31,6 +31,7 @@ to_value_if_base_type_proxy, ) + T = TypeVar("T") @@ -278,3 +279,11 @@ def real_event_fn(): signe.batch(real_event_fn, scheduler=get_uiScheduler()) return wrap + + +def check_cross_client_binding(scheduler: UiScheduler, *refs: Any): + for ref_obj in refs: + if is_ref(ref_obj) and hasattr(ref_obj, "scheduler"): + assert ( + ref_obj.scheduler is scheduler # type: ignore + ), "cross client binding detected" From b2f0fdd8a4f46865475c9e3e572b3be2c72f94d7 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 02:11:18 +0800 Subject: [PATCH 6/7] fix testing --- __tests/test_viewmodel.py | 6 +++--- ex4nicegui/reactive/view_model.py | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/__tests/test_viewmodel.py b/__tests/test_viewmodel.py index 85c1258..8c024e9 100644 --- a/__tests/test_viewmodel.py +++ b/__tests/test_viewmodel.py @@ -157,11 +157,11 @@ def add_person(): def test_class_var(browser: BrowserManager, page_path: str): - class Person(rxui.ViewModel): - name = rxui.var("") - @ui.page(page_path) def _(): + class Person(rxui.ViewModel): + name = rxui.var("") + rxui.label(lambda: f"Hello, {Person.name.value}!").classes("label-name") rxui.input(value=Person.name).classes("input-name") diff --git a/ex4nicegui/reactive/view_model.py b/ex4nicegui/reactive/view_model.py index ea0e740..384abb7 100644 --- a/ex4nicegui/reactive/view_model.py +++ b/ex4nicegui/reactive/view_model.py @@ -68,8 +68,9 @@ def add_data(self): def __init__(self): for name, value in self.__class__.__dict__.items(): - if hasattr(value, _VAR_FLAG): - setattr(self, name, _create_from_var(value)) + if is_ref(value) or hasattr(value, _VAR_FLAG): + setattr(self, name, _create_from_var(to_value(value))) + continue if callable(value) and hasattr(value, _CACHED_VARS_FLAG): setattr(self, name, computed(partial(value, self))) @@ -256,8 +257,10 @@ class MyVm(rxui.ViewModel): """ - setattr(value, _VAR_FLAG, None) - return value # type: ignore + if callable(value): + setattr(value, _VAR_FLAG, None) + return value # type: ignore + return deep_ref(value) def list_var(factory: Callable[[], List[_T_Var_Value]]) -> List[_T_Var_Value]: From ffc3511771add33e6ac78aec9ea54883d13f3cf5 Mon Sep 17 00:00:00 2001 From: CrystalWindSnake <568166495@qq.com> Date: Thu, 12 Dec 2024 02:43:50 +0800 Subject: [PATCH 7/7] fix --- __tests/test_date.py | 11 +++-------- __tests/test_pagination.py | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/__tests/test_date.py b/__tests/test_date.py index 2da7771..6feca19 100644 --- a/__tests/test_date.py +++ b/__tests/test_date.py @@ -80,16 +80,11 @@ def _(): change_range_date = page.Button(".change-range-date") expect(single_date.get_by_text("Sun, Jan 1").first).to_be_visible() - change_range_date.click() - # r_single_value.value = "2023-01-02" + change_single_date.click() expect(single_date.get_by_text("Mon, Jan 2").first).to_be_visible() expect(range_date.get_by_text("6 days").first).to_be_visible() - change_single_date.click() - # r_range_value.value = [ - # {"from": "2023-01-06", "to": "2023-01-10"}, - # {"from": "2023-01-15", "to": "2023-01-16"}, - # "2023-01-12", # type: ignore - # ] + change_range_date.click() + expect(range_date.get_by_text("8 days").first).to_be_visible() diff --git a/__tests/test_pagination.py b/__tests/test_pagination.py index 56704c6..7623536 100644 --- a/__tests/test_pagination.py +++ b/__tests/test_pagination.py @@ -23,7 +23,7 @@ def _(): ui.button( "change-max", - on_click=lambda: max.set_value(2), + on_click=lambda: max.set_value(4), ).classes("change-max") ui.button(