test_tag.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. from typing import Dict
  2. import pydantic
  3. import pytest
  4. from pynecone.components.tags import CondTag, Tag
  5. from pynecone.event import EventHandler, EventSpec, EventChain
  6. from pynecone.var import BaseVar, Var
  7. def mock_event(arg):
  8. pass
  9. @pytest.mark.parametrize(
  10. "cond,valid",
  11. [
  12. (BaseVar(name="p", type_=bool), True),
  13. (BaseVar(name="p", type_=int), False),
  14. (BaseVar(name="p", type_=str), False),
  15. ],
  16. )
  17. def test_validate_cond(cond: BaseVar, valid: bool):
  18. """Test that the cond is a boolean.
  19. Args:
  20. cond: The cond to test.
  21. valid: The expected validity of the cond.
  22. """
  23. if not valid:
  24. with pytest.raises(pydantic.ValidationError):
  25. Tag(cond=cond)
  26. else:
  27. assert cond == Tag(cond=cond).cond
  28. @pytest.mark.parametrize(
  29. "attr,formatted",
  30. [
  31. ("string", '"string"'),
  32. ("{wrapped_string}", "{wrapped_string}"),
  33. (True, "{true}"),
  34. (False, "{false}"),
  35. (123, "{123}"),
  36. (3.14, "{3.14}"),
  37. ([1, 2, 3], "{[1, 2, 3]}"),
  38. (["a", "b", "c"], '{["a", "b", "c"]}'),
  39. ({"a": 1, "b": 2, "c": 3}, '{{"a": 1, "b": 2, "c": 3}}'),
  40. (
  41. EventSpec(handler=EventHandler(fn=mock_event)),
  42. '{() => Event([E("mock_event", {})])}',
  43. ),
  44. (
  45. EventSpec(
  46. handler=EventHandler(fn=mock_event),
  47. local_args=("e",),
  48. args=(("arg", "e.target.value"),),
  49. ),
  50. '{(e) => Event([E("mock_event", {arg:e.target.value})])}',
  51. ),
  52. ],
  53. )
  54. def test_format_value(attr: Var, formatted: str):
  55. """Test that the formatted value of an attribute is correct.
  56. Args:
  57. attr: The attribute to test.
  58. formatted: The expected formatted value.
  59. """
  60. assert Tag.format_attr_value(attr) == formatted
  61. @pytest.mark.parametrize(
  62. "attrs,formatted",
  63. [
  64. ({}, ""),
  65. ({"key": 1}, "key={1}"),
  66. ({"key": "value"}, 'key="value"'),
  67. ({"key": True, "key2": "value2"}, 'key={true}\nkey2="value2"'),
  68. ],
  69. )
  70. def test_format_attrs(attrs: Dict[str, Var], formatted: str):
  71. """Test that the formatted attributes are correct.
  72. Args:
  73. attrs: The attributes to test.
  74. formatted: The expected formatted attributes.
  75. """
  76. assert Tag(attrs=attrs).format_attrs() == formatted
  77. @pytest.mark.parametrize(
  78. "attr,valid",
  79. [
  80. (1, True),
  81. (3.14, True),
  82. ("string", True),
  83. (False, True),
  84. ([], True),
  85. ({}, False),
  86. (None, False),
  87. ],
  88. )
  89. def test_is_valid_attr(attr: Var, valid: bool):
  90. """Test that the attribute is valid.
  91. Args:
  92. attr: The attribute to test.
  93. valid: The expected validity of the attribute.
  94. """
  95. assert Tag.is_valid_attr(attr) == valid
  96. def test_add_props():
  97. """Test that the attributes are added."""
  98. tag = Tag().add_props(key="value", key2=42, invalid=None, invalid2={})
  99. assert tag.attrs["key"] == Var.create("value")
  100. assert tag.attrs["key2"] == Var.create(42)
  101. assert "invalid" not in tag.attrs
  102. assert "invalid2" not in tag.attrs
  103. @pytest.mark.parametrize(
  104. "tag,expected",
  105. [
  106. (Tag(), "</>"),
  107. (Tag(name="br"), "<br/>"),
  108. (Tag(contents="hello"), "<>hello</>"),
  109. (Tag(name="h1", contents="hello"), "<h1>hello</h1>"),
  110. (
  111. Tag(name="box", attrs={"color": "red", "textAlign": "center"}),
  112. '<box color="red"\ntextAlign="center"/>',
  113. ),
  114. (
  115. Tag(
  116. name="box",
  117. attrs={"color": "red", "textAlign": "center"},
  118. contents="text",
  119. ),
  120. '<box color="red"\ntextAlign="center">text</box>',
  121. ),
  122. (
  123. Tag(
  124. name="h1",
  125. contents="hello",
  126. cond=BaseVar(name="logged_in", type_=bool),
  127. ),
  128. '{logged_in ? <h1>hello</h1> : ""}',
  129. ),
  130. ],
  131. )
  132. def test_format_tag(tag: Tag, expected: str):
  133. """Test that the formatted tag is correct.
  134. Args:
  135. tag: The tag to test.
  136. expected: The expected formatted tag.
  137. """
  138. assert str(tag) == expected
  139. def test_format_cond_tag():
  140. """Test that the formatted cond tag is correct."""
  141. tag = CondTag(
  142. true_value=str(Tag(name="h1", contents="True content")),
  143. false_value=str(Tag(name="h2", contents="False content")),
  144. cond=BaseVar(name="logged_in", type_=bool),
  145. )
  146. assert str(tag) == "{logged_in ? <h1>True content</h1> : <h2>False content</h2>}"
  147. def test_format_iter_tag():
  148. """Test that the formatted iter tag is correct."""
  149. # def render_todo(todo: str):
  150. # return Tag(name="Text", contents=todo)
  151. # tag = IterTag(
  152. # iterable=BaseVar(name="todos", type_=list),
  153. # render_fn=render_todo
  154. # )
  155. # assert str(tag) == '{state.todos.map(render_todo)}'