
* fully migrate vars into new system * i hate rufffff (no i don't) * fix silly pright issues (except colormode and state) * remove all instances of Var.create * create immutable callable var and get rid of more base vars * implement hash for all functions * get reflex-web to compile * get it to compile reflex-web successfully * fix tests * fix pyi * use override from typing_extension * put plotly inside of a catch * dicts are unusable sadly * fix silly mistake * overload equals to special case immutable var * improve test_cond * solve more CI issues, down to 94 failures * down to 20 errors * down to 13 errors * pass all testcases * fix pyright issues * reorder things * use get origin more * use fixed_type logic * various optimizations * go back to passing test cases * use less boilerplate * remove unnecessary print message * remove weird comment * add test for html issue * add type ignore * fix another silly issue * override get all var data for var operations call * make integration tests pass * fix immutable call var * better logic for finding parent class * use even better logic for finding state wrt computedvar * only choose the ones that are defined in the same module * small dict to large dict * [REF-3591] Remove chakra-related files from immutable vars PR (#3821) * Add comments to html metadata component (#3731) * fix: add verification for path /404 (#3723) Co-authored-by: coolstorm <manas.gupta@fampay.in> * Use the new state name when setting `is_hydrated` to false (#3738) * Use `._is_mutable()` to account for parent state proxy (#3739) When a parent state proxy is set, also allow child StateProxy._self_mutable to override the parent's `_is_mutable()`. * bump to 0.5.9 (#3746) * add message when installing requirements.txt is needed for chosen template during init (#3750) * #3752 bugfix add domain for XAxis (#3764) * fix appharness app_source typing (#3777) * fix import clash between connectionToaster and hooks.useState (#3749) * use different registry when in china, fixes #3700 (#3702) * do not reload compilation if using local app in AppHarness (#3790) * do not reload if using local app * Update reflex/testing.py Co-authored-by: Masen Furer <m_github@0x26.net> --------- Co-authored-by: Masen Furer <m_github@0x26.net> * Bump memory on relevant actions (#3781) Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local> * [REF-3334] Validate Toast Props (#3793) * [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798) * fix get_uuid_string_var (#3795) * minor State cleanup (#3768) * Fix code wrap in markdown (#3755) --------- Co-authored-by: Alek Petuskey <alek@pynecone.io> Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com> Co-authored-by: coolstorm <manas.gupta@fampay.in> Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com> Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com> Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com> Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com> Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local> Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com> * pyproject.toml: bump to 0.6.0a1 * pyproject.toml: depend on reflex-chakra>=0.6.0a New Var system support in reflex-chakra 0.6.0a1 * poetry.lock: relock dependencies * integration: bump listening timeout to 1200 seconds * integration: bump listening timeout to 1800 seconds * Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835) * Use cached_var_no_lock to avoid ImmutableVar deadlocks ImmutableVar subclasses will always return the same value for a _var_name or _get_all_var_data so there is no need to use a per-class lock to protect a cached attribute on an instance, and doing so actually is observed to cause deadlocks when a particular _cached_var_name creates new LiteralVar instances and attempts to serialize them. * remove unused module global --------- Co-authored-by: Masen Furer <m_github@0x26.net> Co-authored-by: Alek Petuskey <alek@pynecone.io> Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com> Co-authored-by: coolstorm <manas.gupta@fampay.in> Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com> Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com> Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com> Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local> Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
186 lines
5.5 KiB
Python
186 lines
5.5 KiB
Python
"""Test that DebounceInput collapses nested forms."""
|
|
|
|
import pytest
|
|
|
|
import reflex as rx
|
|
from reflex.components.core.debounce import DEFAULT_DEBOUNCE_TIMEOUT
|
|
from reflex.ivars.base import LiteralVar
|
|
from reflex.state import BaseState
|
|
|
|
|
|
def test_create_no_child():
|
|
"""DebounceInput raises RuntimeError if no child is provided."""
|
|
with pytest.raises(RuntimeError):
|
|
_ = rx.debounce_input()
|
|
|
|
|
|
def test_create_no_child_recursive():
|
|
"""DebounceInput raises RuntimeError if no child is provided."""
|
|
with pytest.raises(RuntimeError):
|
|
_ = rx.debounce_input(rx.debounce_input(rx.debounce_input()))
|
|
|
|
|
|
def test_create_many_child():
|
|
"""DebounceInput raises RuntimeError if more than 1 child is provided."""
|
|
with pytest.raises(RuntimeError):
|
|
_ = rx.debounce_input("foo", "bar")
|
|
|
|
|
|
def test_create_no_on_change():
|
|
"""DebounceInput raises ValueError if child has no on_change handler."""
|
|
with pytest.raises(ValueError):
|
|
_ = rx.debounce_input(rx.input())
|
|
|
|
|
|
class S(BaseState):
|
|
"""Example state for debounce tests."""
|
|
|
|
value: str = ""
|
|
|
|
def on_change(self, v: str):
|
|
"""Dummy on_change handler.
|
|
|
|
|
|
Args:
|
|
v: The changed value.
|
|
"""
|
|
pass
|
|
|
|
|
|
def test_render_child_props():
|
|
"""DebounceInput should render props from child component."""
|
|
tag = rx.debounce_input(
|
|
rx.input(
|
|
foo="bar",
|
|
baz="quuc",
|
|
value="real",
|
|
on_change=S.on_change,
|
|
)
|
|
)._render()
|
|
assert "css" in tag.props and isinstance(tag.props["css"], rx.Var)
|
|
for prop in ["foo", "bar", "baz", "quuc"]:
|
|
assert prop in str(tag.props["css"])
|
|
assert tag.props["value"].equals(LiteralVar.create("real"))
|
|
assert len(tag.props["onChange"].events) == 1
|
|
assert tag.props["onChange"].events[0].handler == S.on_change
|
|
assert tag.contents == ""
|
|
|
|
|
|
def test_render_with_class_name():
|
|
tag = rx.debounce_input(
|
|
rx.input(
|
|
on_change=S.on_change,
|
|
class_name="foo baz",
|
|
)
|
|
)._render()
|
|
assert isinstance(tag.props["className"], rx.Var)
|
|
assert "foo baz" in str(tag.props["className"])
|
|
|
|
|
|
def test_render_with_ref():
|
|
tag = rx.debounce_input(
|
|
rx.input(
|
|
on_change=S.on_change,
|
|
id="foo_bar",
|
|
)
|
|
)._render()
|
|
assert isinstance(tag.props["inputRef"], rx.Var)
|
|
assert "foo_bar" in str(tag.props["inputRef"])
|
|
|
|
|
|
def test_render_with_key():
|
|
tag = rx.debounce_input(
|
|
rx.input(
|
|
on_change=S.on_change,
|
|
key="foo_bar",
|
|
)
|
|
)._render()
|
|
assert isinstance(tag.props["key"], rx.Var)
|
|
assert "foo_bar" in str(tag.props["key"])
|
|
|
|
|
|
def test_render_with_special_props():
|
|
special_prop = rx.Var.create_safe("{foo_bar}", _var_is_string=False)
|
|
tag = rx.debounce_input(
|
|
rx.input(
|
|
on_change=S.on_change,
|
|
special_props=[special_prop],
|
|
)
|
|
)._render()
|
|
assert len(tag.special_props) == 1
|
|
assert list(tag.special_props)[0].equals(special_prop)
|
|
|
|
|
|
def test_event_triggers():
|
|
debounced_input = rx.debounce_input(
|
|
rx.input(
|
|
on_change=S.on_change,
|
|
)
|
|
)
|
|
assert tuple(debounced_input.get_event_triggers()) == (
|
|
*rx.Component().get_event_triggers(), # default event triggers
|
|
"on_change",
|
|
)
|
|
|
|
|
|
def test_render_child_props_recursive():
|
|
"""DebounceInput should render props from child component.
|
|
|
|
If the child component is a DebounceInput, then props will be copied from it
|
|
recursively.
|
|
"""
|
|
tag = rx.debounce_input(
|
|
rx.debounce_input(
|
|
rx.debounce_input(
|
|
rx.debounce_input(
|
|
rx.input(
|
|
foo="bar",
|
|
baz="quuc",
|
|
value="real",
|
|
on_change=S.on_change,
|
|
),
|
|
value="inner",
|
|
debounce_timeout=666,
|
|
force_notify_on_blur=False,
|
|
),
|
|
debounce_timeout=42,
|
|
),
|
|
value="outer",
|
|
),
|
|
force_notify_by_enter=False,
|
|
)._render()
|
|
assert "css" in tag.props and isinstance(tag.props["css"], rx.Var)
|
|
for prop in ["foo", "bar", "baz", "quuc"]:
|
|
assert prop in str(tag.props["css"])
|
|
assert tag.props["value"].equals(LiteralVar.create("outer"))
|
|
assert tag.props["forceNotifyOnBlur"]._var_name == "false"
|
|
assert tag.props["forceNotifyByEnter"]._var_name == "false"
|
|
assert tag.props["debounceTimeout"]._var_name == "42"
|
|
assert len(tag.props["onChange"].events) == 1
|
|
assert tag.props["onChange"].events[0].handler == S.on_change
|
|
assert tag.contents == ""
|
|
|
|
|
|
def test_full_control_implicit_debounce():
|
|
"""DebounceInput is used when value and on_change are used together."""
|
|
tag = rx.input(
|
|
value=S.value,
|
|
on_change=S.on_change,
|
|
)._render()
|
|
assert tag.props["debounceTimeout"]._var_name == str(DEFAULT_DEBOUNCE_TIMEOUT)
|
|
assert len(tag.props["onChange"].events) == 1
|
|
assert tag.props["onChange"].events[0].handler == S.on_change
|
|
assert tag.contents == ""
|
|
|
|
|
|
def test_full_control_implicit_debounce_text_area():
|
|
"""DebounceInput is used when value and on_change are used together."""
|
|
tag = rx.text_area(
|
|
value=S.value,
|
|
on_change=S.on_change,
|
|
)._render()
|
|
assert tag.props["debounceTimeout"]._var_name == str(DEFAULT_DEBOUNCE_TIMEOUT)
|
|
assert len(tag.props["onChange"].events) == 1
|
|
assert tag.props["onChange"].events[0].handler == S.on_change
|
|
assert tag.contents == ""
|