from typing import Any, Dict, List
import pytest
from reflex.components.tags import CondTag, Tag, tagless
from reflex.event import EVENT_ARG, EventChain, EventHandler, EventSpec
from reflex.style import Style
from reflex.vars import BaseVar, Var
def mock_event(arg):
pass
@pytest.mark.parametrize(
"prop,formatted",
[
("string", '"string"'),
("{wrapped_string}", "{wrapped_string}"),
(True, "{true}"),
(False, "{false}"),
(123, "{123}"),
(3.14, "{3.14}"),
([1, 2, 3], "{[1, 2, 3]}"),
(["a", "b", "c"], '{["a", "b", "c"]}'),
({"a": 1, "b": 2, "c": 3}, '{{"a": 1, "b": 2, "c": 3}}'),
({"a": 'foo "bar" baz'}, r'{{"a": "foo \"bar\" baz"}}'),
(
{
"a": 'foo "{ "bar" }" baz',
"b": BaseVar(name="val", type_="str"),
},
r'{{"a": "foo \"{ \"bar\" }\" baz", "b": val}}',
),
(
EventChain(events=[EventSpec(handler=EventHandler(fn=mock_event))]),
'{_e => Event([E("mock_event", {})], _e)}',
),
(
EventChain(
events=[
EventSpec(
handler=EventHandler(fn=mock_event),
args=((Var.create_safe("arg"), EVENT_ARG.target.value),),
)
]
),
'{_e => Event([E("mock_event", {arg:_e.target.value})], _e)}',
),
({"a": "red", "b": "blue"}, '{{"a": "red", "b": "blue"}}'),
(BaseVar(name="var", type_="int"), "{var}"),
(
BaseVar(
name="_",
type_=Any,
state="",
is_local=True,
is_string=False,
),
"{_}",
),
(BaseVar(name='state.colors["a"]', type_="str"), '{state.colors["a"]}'),
({"a": BaseVar(name="val", type_="str")}, '{{"a": val}}'),
({"a": BaseVar(name='"val"', type_="str")}, '{{"a": "val"}}'),
(
{"a": BaseVar(name='state.colors["val"]', type_="str")},
'{{"a": state.colors["val"]}}',
),
# tricky real-world case from markdown component
(
{
"h1": f"{{({{node, ...props}}) => }}"
},
'{{"h1": ({node, ...props}) => }}',
),
],
)
def test_format_prop(prop: Var, formatted: str):
"""Test that the formatted value of an prop is correct.
Args:
prop: The prop to test.
formatted: The expected formatted value.
"""
assert Tag.format_prop(prop) == formatted
@pytest.mark.parametrize(
"props,test_props",
[
({}, []),
({"key": 1}, ["key={1}"]),
({"key": "value"}, ["key={`value`}"]),
({"key": True, "key2": "value2"}, ["key={true}", "key2={`value2`}"]),
],
)
def test_format_props(props: Dict[str, Var], test_props: List):
"""Test that the formatted props are correct.
Args:
props: The props to test.
test_props: The expected props.
"""
tag_props = Tag(props=props).format_props()
for i, tag_prop in enumerate(tag_props):
assert tag_prop == test_props[i]
@pytest.mark.parametrize(
"prop,valid",
[
(1, True),
(3.14, True),
("string", True),
(False, True),
([], True),
({}, False),
(None, False),
],
)
def test_is_valid_prop(prop: Var, valid: bool):
"""Test that the prop is valid.
Args:
prop: The prop to test.
valid: The expected validity of the prop.
"""
assert Tag.is_valid_prop(prop) == valid
def test_add_props():
"""Test that the props are added."""
tag = Tag().add_props(key="value", key2=42, invalid=None, invalid2={})
assert tag.props["key"] == Var.create("value")
assert tag.props["key2"] == Var.create(42)
assert "invalid" not in tag.props
assert "invalid2" not in tag.props
@pytest.mark.parametrize(
"tag,expected",
[
(Tag(), {"name": "", "contents": "", "props": {}}),
(Tag(name="br"), {"name": "br", "contents": "", "props": {}}),
(Tag(contents="hello"), {"name": "", "contents": "hello", "props": {}}),
(
Tag(name="h1", contents="hello"),
{"name": "h1", "contents": "hello", "props": {}},
),
(
Tag(name="box", props={"color": "red", "textAlign": "center"}),
{
"name": "box",
"contents": "",
"props": {"color": "red", "textAlign": "center"},
},
),
(
Tag(
name="box",
props={"color": "red", "textAlign": "center"},
contents="text",
),
{
"name": "box",
"contents": "text",
"props": {"color": "red", "textAlign": "center"},
},
),
],
)
def test_format_tag(tag: Tag, expected: Dict):
"""Test that the tag dict is correct.
Args:
tag: The tag to test.
expected: The expected tag dictionary.
"""
tag_dict = dict(tag)
assert tag_dict["name"] == expected["name"]
assert tag_dict["contents"] == expected["contents"]
assert tag_dict["props"] == expected["props"]
def test_format_cond_tag():
"""Test that the cond tag dict is correct."""
tag = CondTag(
true_value=dict(Tag(name="h1", contents="True content")),
false_value=dict(Tag(name="h2", contents="False content")),
cond=BaseVar(name="logged_in", type_=bool),
)
tag_dict = dict(tag)
cond, true_value, false_value = (
tag_dict["cond"],
tag_dict["true_value"],
tag_dict["false_value"],
)
assert cond == "logged_in"
assert true_value["name"] == "h1"
assert true_value["contents"] == "True content"
assert false_value["name"] == "h2"
assert false_value["contents"] == "False content"
def test_tagless_string_representation():
"""Test that the string representation of a tagless is correct."""
tag = tagless.Tagless(contents="Hello world")
expected_output = "Hello world"
assert str(tag) == expected_output