test_cond.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import json
  2. from typing import Any, Union
  3. import pytest
  4. from reflex.components.core.cond import cond
  5. from reflex.components.radix.themes.typography.text import Text
  6. from reflex.state import BaseState
  7. from reflex.utils.format import format_state_name
  8. from reflex.vars.base import LiteralVar, Var, computed_var
  9. @pytest.fixture
  10. def cond_state(request):
  11. class CondState(BaseState):
  12. value: request.param["value_type"] = request.param["value"] # pyright: ignore [reportInvalidTypeForm, reportUndefinedVariable] # noqa: F821
  13. return CondState
  14. def test_f_string_cond_interpolation():
  15. # make sure backticks inside interpolation don't get escaped
  16. var = LiteralVar.create(f"x {cond(True, 'a', 'b')}")
  17. assert str(var) == '("x "+(true ? "a" : "b"))'
  18. @pytest.mark.parametrize(
  19. "cond_state",
  20. [
  21. pytest.param({"value_type": bool, "value": True}),
  22. pytest.param({"value_type": int, "value": 0}),
  23. pytest.param({"value_type": str, "value": "true"}),
  24. ],
  25. indirect=True,
  26. )
  27. def test_validate_cond(cond_state: BaseState):
  28. """Test if cond can be a rx.Var with any values.
  29. Args:
  30. cond_state: A fixture.
  31. """
  32. first_component = Text.create("cond is True")
  33. second_component = Text.create("cond is False")
  34. cond_var = cond(
  35. cond_state.value,
  36. first_component,
  37. second_component,
  38. )
  39. assert isinstance(cond_var, Var)
  40. assert (
  41. str(cond_var)
  42. == f'({cond_state.value.bool()!s} ? (jsx(RadixThemesText, ({{ ["as"] : "p" }}), (jsx(Fragment, ({{ }}), "cond is True")))) : (jsx(RadixThemesText, ({{ ["as"] : "p" }}), (jsx(Fragment, ({{ }}), "cond is False")))))'
  43. )
  44. var_data = cond_var._get_all_var_data()
  45. assert var_data is not None
  46. assert var_data.components == (first_component, second_component)
  47. @pytest.mark.parametrize(
  48. "c1, c2",
  49. [
  50. (True, False),
  51. (32, 0),
  52. ("hello", ""),
  53. (2.3, 0.0),
  54. (LiteralVar.create("a"), LiteralVar.create("b")),
  55. ],
  56. )
  57. def test_prop_cond(c1: Any, c2: Any):
  58. """Test if cond can be a prop.
  59. Args:
  60. c1: truth condition value
  61. c2: false condition value
  62. """
  63. prop_cond = cond(
  64. True,
  65. c1,
  66. c2,
  67. )
  68. assert isinstance(prop_cond, Var)
  69. if not isinstance(c1, Var):
  70. c1 = json.dumps(c1)
  71. if not isinstance(c2, Var):
  72. c2 = json.dumps(c2)
  73. assert str(prop_cond) == f"(true ? {c1!s} : {c2!s})"
  74. def test_cond_mix():
  75. """Test if cond can mix components and props."""
  76. x = cond(True, LiteralVar.create("hello"), Text.create("world"))
  77. assert isinstance(x, Var)
  78. assert (
  79. str(x)
  80. == '(true ? "hello" : (jsx(RadixThemesText, ({ ["as"] : "p" }), (jsx(Fragment, ({ }), "world")))))'
  81. )
  82. def test_cond_no_else():
  83. """Test if cond can be used without else."""
  84. # Components should support the use of cond without else
  85. comp = cond(True, Text.create("hello"))
  86. assert isinstance(comp, Var)
  87. assert (
  88. str(comp)
  89. == '(true ? (jsx(RadixThemesText, ({ ["as"] : "p" }), (jsx(Fragment, ({ }), "hello")))) : (jsx(Fragment, ({ }))))'
  90. )
  91. # Props do not support the use of cond without else
  92. with pytest.raises(ValueError):
  93. cond(True, "hello") # pyright: ignore [reportArgumentType]
  94. def test_cond_computed_var():
  95. """Test if cond works with computed vars."""
  96. class CondStateComputed(BaseState):
  97. @computed_var
  98. def computed_int(self) -> int:
  99. return 0
  100. @computed_var
  101. def computed_str(self) -> str:
  102. return "a string"
  103. comp = cond(True, CondStateComputed.computed_int, CondStateComputed.computed_str)
  104. # TODO: shouldn't this be a ComputedVar?
  105. assert isinstance(comp, Var)
  106. state_name = format_state_name(CondStateComputed.get_full_name())
  107. assert (
  108. str(comp) == f"(true ? {state_name}.computed_int : {state_name}.computed_str)"
  109. )
  110. assert comp._var_type == Union[int, str]