reflex/tests/components/core/test_debounce.py
Khaleel Al-Adhami ea15b184c0
fully migrate vars into new system (#3743)
* 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>
2024-08-26 13:28:18 -07:00

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 == ""