test_debounce.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """Test that DebounceInput collapses nested forms."""
  2. import pytest
  3. import reflex as rx
  4. from reflex.components.core.debounce import DEFAULT_DEBOUNCE_TIMEOUT
  5. from reflex.state import BaseState
  6. from reflex.vars import BaseVar
  7. def test_render_no_child():
  8. """DebounceInput raises RuntimeError if no child is provided."""
  9. with pytest.raises(RuntimeError):
  10. _ = rx.debounce_input().render()
  11. def test_render_no_child_recursive():
  12. """DebounceInput raises RuntimeError if no child is provided."""
  13. with pytest.raises(RuntimeError):
  14. _ = rx.debounce_input(rx.debounce_input(rx.debounce_input())).render()
  15. def test_render_many_child():
  16. """DebounceInput raises RuntimeError if more than 1 child is provided."""
  17. with pytest.raises(RuntimeError):
  18. _ = rx.debounce_input("foo", "bar").render()
  19. class S(BaseState):
  20. """Example state for debounce tests."""
  21. value: str = ""
  22. def on_change(self, v: str):
  23. """Dummy on_change handler.
  24. Args:
  25. v: The changed value.
  26. """
  27. pass
  28. def test_render_child_props():
  29. """DebounceInput should render props from child component."""
  30. tag = rx.debounce_input(
  31. rx.chakra.input(
  32. foo="bar",
  33. baz="quuc",
  34. value="real",
  35. on_change=S.on_change,
  36. )
  37. )._render()
  38. assert tag.props["sx"] == {"foo": "bar", "baz": "quuc"}
  39. assert tag.props["value"].equals(
  40. BaseVar(
  41. _var_name="real", _var_type=str, _var_is_local=True, _var_is_string=False
  42. )
  43. )
  44. assert len(tag.props["onChange"].events) == 1
  45. assert tag.props["onChange"].events[0].handler == S.on_change
  46. assert tag.contents == ""
  47. def test_render_child_props_recursive():
  48. """DebounceInput should render props from child component.
  49. If the child component is a DebounceInput, then props will be copied from it
  50. recursively.
  51. """
  52. tag = rx.debounce_input(
  53. rx.debounce_input(
  54. rx.debounce_input(
  55. rx.debounce_input(
  56. rx.chakra.input(
  57. foo="bar",
  58. baz="quuc",
  59. value="real",
  60. on_change=S.on_change,
  61. ),
  62. value="inner",
  63. debounce_timeout=666,
  64. force_notify_on_blur=False,
  65. ),
  66. debounce_timeout=42,
  67. ),
  68. value="outer",
  69. ),
  70. force_notify_by_enter=False,
  71. )._render()
  72. assert tag.props["sx"] == {"foo": "bar", "baz": "quuc"}
  73. assert tag.props["value"].equals(
  74. BaseVar(
  75. _var_name="outer", _var_type=str, _var_is_local=True, _var_is_string=False
  76. )
  77. )
  78. assert tag.props["forceNotifyOnBlur"]._var_name == "false"
  79. assert tag.props["forceNotifyByEnter"]._var_name == "false"
  80. assert tag.props["debounceTimeout"]._var_name == "42"
  81. assert len(tag.props["onChange"].events) == 1
  82. assert tag.props["onChange"].events[0].handler == S.on_change
  83. assert tag.contents == ""
  84. def test_full_control_implicit_debounce():
  85. """DebounceInput is used when value and on_change are used together."""
  86. tag = rx.chakra.input(
  87. value=S.value,
  88. on_change=S.on_change,
  89. )._render()
  90. assert tag.props["debounceTimeout"]._var_name == str(DEFAULT_DEBOUNCE_TIMEOUT)
  91. assert len(tag.props["onChange"].events) == 1
  92. assert tag.props["onChange"].events[0].handler == S.on_change
  93. assert tag.contents == ""
  94. def test_full_control_implicit_debounce_text_area():
  95. """DebounceInput is used when value and on_change are used together."""
  96. tag = rx.text_area(
  97. value=S.value,
  98. on_change=S.on_change,
  99. )._render()
  100. assert tag.props["debounceTimeout"]._var_name == str(DEFAULT_DEBOUNCE_TIMEOUT)
  101. assert len(tag.props["onChange"].events) == 1
  102. assert tag.props["onChange"].events[0].handler == S.on_change
  103. assert tag.contents == ""