reflex/tests/components/core/test_debounce.py
Khaleel Al-Adhami a5c73ad8e5
Use old serializer system in LiteralVar (#3875)
* use serializer system

* add checks for unsupported operands

* and and or are now supported

* format

* remove unnecessary call to JSON

* put base before rest

* fix failing testcase

* add hinting to get static analysis to complain

* damn

* big changes

* get typeguard from extensions

* please darglint

* dangit darglint

* remove one from vars

* add without data and use it in plotly

* DARGLINT

* change format for special props

* add pyi

* delete instances of Var.create

* modify client state to work

* fixed so much

* remove every Var.create

* delete all basevar stuff

* checkpoint

* fix pyi

* get older python to work

* dangit darglint

* add simple fix to last failing testcase

* remove var name unwrapped and put client state on immutable var

* fix older python

* fox event issues

* change forms pyi

* make test less strict

* use rx state directly

* add typeignore to page_id

* implement foreach

* delete .web states folder silly

* update reflex chakra

* fix issue when on mount or on unmount is not set

* nuke Var

* run pyi

* import immutablevar in critical location

* delete unwrap vars

* bring back array ref

* fix style props in app

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* Update find_replace (#3886)

* [REF-3592]Promote `rx.progress` from radix themes (#3878)

* Promote `rx.progress` from radix themes

* fix pyi

* add warning when accessing `rx._x.progress`

* Use correct flexgen backend URL (#3891)

* Remove demo template (#3888)

* gitignore .web (#3885)

* update overflowY in AUTO_HEIGHT_JS from hidden to scroll (#3882)

* Retain mutability inside `async with self` block (#3884)

When emitting a state update, restore `_self_mutable` to the value it had
previously so that `yield` in the middle of `async with self` does not result
in an immutable StateProxy.

Fix #3869

* Include child imports in markdown component_map (#3883)

If a component in the markdown component_map contains children components, use
`_get_all_imports` to recursively enumerate them.

Fix #3880

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* mixin computed vars should only be applied to highest level state (#3833)

* improve state hierarchy validation, drop old testing special case (#3894)

* fix var dependency dicts (#3842)

* Adding array to array pluck operation. (#3868)

* fix initial state without cv fallback (#3670)

* add fragment to foreach (#3877)

* Update docker-example (#3324)

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* Merge branch 'main' into use-old-serializer-in-literalvar

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* remove extra var

Co-authored-by: Masen Furer <m_github@0x26.net>

* resolve typo

* write better doc for var.create

* return var value when we know it's literal var

* fix unit test

* less bloat for ToOperations

* simplify ImmutableComputedVar.__get__ (#3902)

* simplify ImmutableComputedVar.__get__

* ruff it

---------

Co-authored-by: Samarth Bhadane <samarthbhadane119@gmail.com>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Vishnu Deva <vishnu.deva12@gmail.com>
Co-authored-by: abulvenz <a.eismann@senbax.de>
2024-09-10 11:43:37 -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 ImmutableVar, 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 = ImmutableVar.create_safe("{foo_bar}")
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 == ""