down to 20 errors

This commit is contained in:
Khaleel Al-Adhami 2024-08-13 17:02:50 -07:00
parent 2f49ce0201
commit 82a3498d02
14 changed files with 127 additions and 115 deletions

View File

@ -42,7 +42,7 @@ class Tag(Base):
# Convert any props to vars. # Convert any props to vars.
if "props" in kwargs: if "props" in kwargs:
kwargs["props"] = { kwargs["props"] = {
name: ImmutableVar.create(value) name: LiteralVar.create(value)
for name, value in kwargs["props"].items() for name, value in kwargs["props"].items()
} }
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View File

@ -545,7 +545,7 @@ def set_focus(ref: str) -> EventSpec:
return server_side( return server_side(
"_set_focus", "_set_focus",
get_fn_signature(set_focus), get_fn_signature(set_focus),
ref=ImmutableVar.create_safe(format.format_ref(ref)), ref=LiteralVar.create(format.format_ref(ref)),
) )
@ -576,7 +576,7 @@ def set_value(ref: str, value: Any) -> EventSpec:
return server_side( return server_side(
"_set_value", "_set_value",
get_fn_signature(set_value), get_fn_signature(set_value),
ref=ImmutableVar.create_safe(format.format_ref(ref)), ref=LiteralVar.create(format.format_ref(ref)),
value=value, value=value,
) )

View File

@ -70,6 +70,8 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
fixed_type = ( fixed_type = (
self._var_type if isclass(self._var_type) else get_origin(self._var_type) self._var_type if isclass(self._var_type) else get_origin(self._var_type)
) )
if not isclass(fixed_type):
return Any
args = get_args(self._var_type) if issubclass(fixed_type, dict) else () args = get_args(self._var_type) if issubclass(fixed_type, dict) else ()
return args[1] if args else Any return args[1] if args else Any
@ -246,7 +248,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
fixed_type = ( fixed_type = (
self._var_type if isclass(self._var_type) else get_origin(self._var_type) self._var_type if isclass(self._var_type) else get_origin(self._var_type)
) )
if not issubclass(fixed_type, dict): if isclass(fixed_type) and not issubclass(fixed_type, dict):
attribute_type = get_attribute_access_type(self._var_type, name) attribute_type = get_attribute_access_type(self._var_type, name)
if attribute_type is None: if attribute_type is None:
raise VarAttributeError( raise VarAttributeError(

View File

@ -126,8 +126,7 @@ def convert_item(
The formatted style item and any associated VarData. The formatted style item and any associated VarData.
""" """
if isinstance(style_item, Var): if isinstance(style_item, Var):
# If the value is a Var, extract the var_data and cast as str. return style_item, style_item._get_all_var_data()
return str(style_item), style_item._get_all_var_data()
# Otherwise, convert to Var to collapse VarData encoded in f-string. # Otherwise, convert to Var to collapse VarData encoded in f-string.
new_var = LiteralVar.create(style_item) new_var = LiteralVar.create(style_item)

View File

@ -489,17 +489,6 @@ def format_props(*single_props, **key_value_props) -> list[str]:
# Format all the props. # Format all the props.
from reflex.ivars.base import ImmutableVar, LiteralVar from reflex.ivars.base import ImmutableVar, LiteralVar
# print(
# *[
# f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
# for name, prop in sorted(key_value_props.items())
# if prop is not None
# ],
# sep="\n",
# )
# if single_props:
# print("single_props", single_props)
return [ return [
( (

View File

@ -411,7 +411,7 @@ def _decode_var_immutable(value: str) -> tuple[ImmutableVarData | None, str]:
): ):
# This is a global immutable var. # This is a global immutable var.
var = _global_vars[int(serialized_data)] var = _global_vars[int(serialized_data)]
var_data = var._var_data var_data = var._get_all_var_data()
if var_data is not None: if var_data is not None:
realstart = start + offset realstart = start + offset
@ -753,7 +753,10 @@ class Var:
return self._var_name return self._var_name
try: try:
return json.loads(self._var_name) return json.loads(self._var_name)
except ValueError: except:
try:
return json.loads(self.json())
except:
return self._var_name return self._var_name
def equals(self, other: Var) -> bool: def equals(self, other: Var) -> bool:

View File

@ -1,16 +1,20 @@
import pytest import pytest
from reflex.components.base.bare import Bare from reflex.components.base.bare import Bare
from reflex.ivars.base import ImmutableVar
STATE_VAR = ImmutableVar.create_safe("default_state.name")
@pytest.mark.parametrize( @pytest.mark.parametrize(
"contents,expected", "contents,expected",
[ [
("hello", '{"hello"}'), ("hello", '{"hello"}'),
("{}", '{"{}"}'), ("{}", '{"{}"}'),
(None, ""), (None, '{""}'),
("${default_state.name}", "${default_state.name}"), (STATE_VAR, "{default_state.name}"),
("{state.name}", "{state.name}"), # This behavior is now unsupported.
# ("${default_state.name}", "${default_state.name}"),
# ("{state.name}", "{state.name}"),
], ],
) )
def test_fstrings(contents, expected): def test_fstrings(contents, expected):

View File

@ -23,7 +23,7 @@ def test_script_src():
assert render_dict["name"] == "Script" assert render_dict["name"] == "Script"
assert not render_dict["contents"] assert not render_dict["contents"]
assert not render_dict["children"] assert not render_dict["children"]
assert "src={`foo.js`}" in render_dict["props"] assert 'src={"foo.js"}' in render_dict["props"]
def test_script_neither(): def test_script_neither():
@ -58,14 +58,14 @@ def test_script_event_handler():
) )
render_dict = component.render() render_dict = component.render()
assert ( assert (
f'onReady={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_ready", {{}})], args, {{}})}}' f'onReady={{((...args) => ((addEvents([(Event("{EvState.get_full_name()}.on_ready", ({{ }})))], args, ({{ }})))))}}'
in render_dict["props"] in render_dict["props"]
) )
assert ( assert (
f'onLoad={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_load", {{}})], args, {{}})}}' f'onLoad={{((...args) => ((addEvents([(Event("{EvState.get_full_name()}.on_load", ({{ }})))], args, ({{ }})))))}}'
in render_dict["props"] in render_dict["props"]
) )
assert ( assert (
f'onError={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_error", {{}})], args, {{}})}}' f'onError={{((...args) => ((addEvents([(Event("{EvState.get_full_name()}.on_error", ({{ }})))], args, ({{ }})))))}}'
in render_dict["props"] in render_dict["props"]
) )

View File

@ -108,9 +108,9 @@ def test_color_with_conditionals(cond_var, expected):
(create_color_var(rx.color("red")), '"var(--red-7)"'), (create_color_var(rx.color("red")), '"var(--red-7)"'),
(create_color_var(rx.color("green", shade=1)), '"var(--green-1)"'), (create_color_var(rx.color("green", shade=1)), '"var(--green-1)"'),
(create_color_var(rx.color("blue", alpha=True)), '"var(--blue-a7)"'), (create_color_var(rx.color("blue", alpha=True)), '"var(--blue-a7)"'),
("red", "red"), ("red", '"red"'),
("green", "green"), ("green", '"green"'),
("blue", "blue"), ("blue", '"blue"'),
], ],
) )
def test_radix_color(color, expected): def test_radix_color(color, expected):

View File

@ -35,8 +35,8 @@ def test_component_state():
assert cs1.State.increment != cs2.State.increment assert cs1.State.increment != cs2.State.increment
assert len(cs1.children) == 1 assert len(cs1.children) == 1
assert cs1.children[0].render() == Bare.create("{`a`}").render() assert cs1.children[0].render() == Bare.create("a").render()
assert cs1.id == "a" assert cs1.id == "a"
assert len(cs2.children) == 1 assert len(cs2.children) == 1
assert cs2.children[0].render() == Bare.create("{`b`}").render() assert cs2.children[0].render() == Bare.create("b").render()
assert cs2.id == "b" assert cs2.id == "b"

View File

@ -3,6 +3,7 @@ from typing import Dict, List
import pytest import pytest
from reflex.components.tags import CondTag, Tag, tagless from reflex.components.tags import CondTag, Tag, tagless
from reflex.ivars.base import LiteralVar
from reflex.vars import BaseVar, Var from reflex.vars import BaseVar, Var
@ -12,8 +13,8 @@ from reflex.vars import BaseVar, Var
({}, []), ({}, []),
({"key-hypen": 1}, ["key-hypen={1}"]), ({"key-hypen": 1}, ["key-hypen={1}"]),
({"key": 1}, ["key={1}"]), ({"key": 1}, ["key={1}"]),
({"key": "value"}, ["key={`value`}"]), ({"key": "value"}, ['key={"value"}']),
({"key": True, "key2": "value2"}, ["key={true}", "key2={`value2`}"]), ({"key": True, "key2": "value2"}, ["key={true}", 'key2={"value2"}']),
], ],
) )
def test_format_props(props: Dict[str, Var], test_props: List): def test_format_props(props: Dict[str, Var], test_props: List):
@ -53,8 +54,8 @@ def test_is_valid_prop(prop: Var, valid: bool):
def test_add_props(): def test_add_props():
"""Test that the props are added.""" """Test that the props are added."""
tag = Tag().add_props(key="value", key2=42, invalid=None, invalid2={}) tag = Tag().add_props(key="value", key2=42, invalid=None, invalid2={})
assert tag.props["key"].equals(Var.create("value")) assert tag.props["key"].equals(LiteralVar.create("value"))
assert tag.props["key2"].equals(Var.create(42)) assert tag.props["key2"].equals(LiteralVar.create(42))
assert "invalid" not in tag.props assert "invalid" not in tag.props
assert "invalid2" not in tag.props assert "invalid2" not in tag.props
@ -102,7 +103,7 @@ def test_format_tag(tag: Tag, expected: Dict):
assert tag_dict["name"] == expected["name"] assert tag_dict["name"] == expected["name"]
assert tag_dict["contents"] == expected["contents"] assert tag_dict["contents"] == expected["contents"]
for prop, prop_value in tag_dict["props"].items(): for prop, prop_value in tag_dict["props"].items():
assert prop_value.equals(Var.create_safe(expected["props"][prop])) assert prop_value.equals(LiteralVar.create(expected["props"][prop]))
def test_format_cond_tag(): def test_format_cond_tag():

View File

@ -5,6 +5,7 @@ import pytest
from reflex import event from reflex import event
from reflex.event import Event, EventHandler, EventSpec, call_event_handler, fix_events from reflex.event import Event, EventHandler, EventSpec, call_event_handler, fix_events
from reflex.ivars.base import ImmutableVar, LiteralVar
from reflex.state import BaseState from reflex.state import BaseState
from reflex.utils import format from reflex.utils import format
from reflex.vars import Var from reflex.vars import Var
@ -70,7 +71,7 @@ def test_call_event_handler():
event_spec = handler("first", "second") # type: ignore event_spec = handler("first", "second") # type: ignore
assert ( assert (
format.format_event(event_spec) format.format_event(event_spec)
== 'Event("test_fn_with_args", {arg1:`first`,arg2:`second`})' == 'Event("test_fn_with_args", {arg1:"first",arg2:"second"})'
) )
first, second = 123, "456" first, second = 123, "456"
@ -78,14 +79,14 @@ def test_call_event_handler():
event_spec = handler(first, second) # type: ignore event_spec = handler(first, second) # type: ignore
assert ( assert (
format.format_event(event_spec) format.format_event(event_spec)
== 'Event("test_fn_with_args", {arg1:123,arg2:`456`})' == 'Event("test_fn_with_args", {arg1:123,arg2:"456"})'
) )
assert event_spec.handler == handler assert event_spec.handler == handler
assert event_spec.args[0][0].equals(Var.create_safe("arg1")) assert event_spec.args[0][0].equals(Var.create_safe("arg1"))
assert event_spec.args[0][1].equals(Var.create_safe(first)) assert event_spec.args[0][1].equals(Var.create_safe(first))
assert event_spec.args[1][0].equals(Var.create_safe("arg2")) assert event_spec.args[1][0].equals(Var.create_safe("arg2"))
assert event_spec.args[1][1].equals(Var.create_safe(second)) assert event_spec.args[1][1].equals(LiteralVar.create(second))
handler = EventHandler(fn=test_fn_with_args) handler = EventHandler(fn=test_fn_with_args)
with pytest.raises(TypeError): with pytest.raises(TypeError):
@ -160,15 +161,15 @@ def test_fix_events(arg1, arg2):
[ [
( (
("/path", None, None), ("/path", None, None),
'Event("_redirect", {path:`/path`,external:false,replace:false})', 'Event("_redirect", {path:"/path",external:false,replace:false})',
), ),
( (
("/path", True, None), ("/path", True, None),
'Event("_redirect", {path:`/path`,external:true,replace:false})', 'Event("_redirect", {path:"/path",external:true,replace:false})',
), ),
( (
("/path", False, None), ("/path", False, None),
'Event("_redirect", {path:`/path`,external:false,replace:false})', 'Event("_redirect", {path:"/path",external:false,replace:false})',
), ),
( (
(Var.create_safe("path"), None, None), (Var.create_safe("path"), None, None),
@ -176,11 +177,11 @@ def test_fix_events(arg1, arg2):
), ),
( (
("/path", None, True), ("/path", None, True),
'Event("_redirect", {path:`/path`,external:false,replace:true})', 'Event("_redirect", {path:"/path",external:false,replace:true})',
), ),
( (
("/path", True, True), ("/path", True, True),
'Event("_redirect", {path:`/path`,external:true,replace:true})', 'Event("_redirect", {path:"/path",external:true,replace:true})',
), ),
], ],
) )
@ -213,10 +214,10 @@ def test_event_console_log():
spec = event.console_log("message") spec = event.console_log("message")
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_console" assert spec.handler.fn.__qualname__ == "_console"
assert spec.args[0][0].equals(Var.create_safe("message")) assert spec.args[0][0].equals(ImmutableVar(_var_name="message", _var_type=str))
assert spec.args[0][1].equals(Var.create_safe("message")) assert spec.args[0][1].equals(LiteralVar.create("message"))
assert format.format_event(spec) == 'Event("_console", {message:`message`})' assert format.format_event(spec) == 'Event("_console", {message:"message"})'
spec = event.console_log(Var.create_safe("message")) spec = event.console_log(ImmutableVar.create("message"))
assert format.format_event(spec) == 'Event("_console", {message:message})' assert format.format_event(spec) == 'Event("_console", {message:message})'
@ -225,10 +226,10 @@ def test_event_window_alert():
spec = event.window_alert("message") spec = event.window_alert("message")
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_alert" assert spec.handler.fn.__qualname__ == "_alert"
assert spec.args[0][0].equals(Var.create_safe("message")) assert spec.args[0][0].equals(ImmutableVar(_var_name="message", _var_type=str))
assert spec.args[0][1].equals(Var.create_safe("message")) assert spec.args[0][1].equals(LiteralVar.create("message"))
assert format.format_event(spec) == 'Event("_alert", {message:`message`})' assert format.format_event(spec) == 'Event("_alert", {message:"message"})'
spec = event.window_alert(Var.create_safe("message")) spec = event.window_alert(ImmutableVar.create_safe("message"))
assert format.format_event(spec) == 'Event("_alert", {message:message})' assert format.format_event(spec) == 'Event("_alert", {message:message})'
@ -238,10 +239,10 @@ def test_set_focus():
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_set_focus" assert spec.handler.fn.__qualname__ == "_set_focus"
assert spec.args[0][0].equals(Var.create_safe("ref")) assert spec.args[0][0].equals(Var.create_safe("ref"))
assert spec.args[0][1].equals(Var.create_safe("ref_input1")) assert spec.args[0][1].equals(LiteralVar.create("ref_input1"))
assert format.format_event(spec) == 'Event("_set_focus", {ref:`ref_input1`})' assert format.format_event(spec) == 'Event("_set_focus", {ref:"ref_input1"})'
spec = event.set_focus("input1") spec = event.set_focus("input1")
assert format.format_event(spec) == 'Event("_set_focus", {ref:`ref_input1`})' assert format.format_event(spec) == 'Event("_set_focus", {ref:"ref_input1"})'
def test_set_value(): def test_set_value():
@ -250,16 +251,16 @@ def test_set_value():
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_set_value" assert spec.handler.fn.__qualname__ == "_set_value"
assert spec.args[0][0].equals(Var.create_safe("ref")) assert spec.args[0][0].equals(Var.create_safe("ref"))
assert spec.args[0][1].equals(Var.create_safe("ref_input1")) assert spec.args[0][1].equals(LiteralVar.create("ref_input1"))
assert spec.args[1][0].equals(Var.create_safe("value")) assert spec.args[1][0].equals(Var.create_safe("value"))
assert spec.args[1][1].equals(Var.create_safe("")) assert spec.args[1][1].equals(LiteralVar.create(""))
assert ( assert (
format.format_event(spec) == 'Event("_set_value", {ref:`ref_input1`,value:``})' format.format_event(spec) == 'Event("_set_value", {ref:"ref_input1",value:""})'
) )
spec = event.set_value("input1", Var.create_safe("message")) spec = event.set_value("input1", ImmutableVar.create_safe("message"))
assert ( assert (
format.format_event(spec) format.format_event(spec)
== 'Event("_set_value", {ref:`ref_input1`,value:message})' == 'Event("_set_value", {ref:"ref_input1",value:message})'
) )
@ -269,12 +270,12 @@ def test_remove_cookie():
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_remove_cookie" assert spec.handler.fn.__qualname__ == "_remove_cookie"
assert spec.args[0][0].equals(Var.create_safe("key")) assert spec.args[0][0].equals(Var.create_safe("key"))
assert spec.args[0][1].equals(Var.create_safe("testkey")) assert spec.args[0][1].equals(LiteralVar.create("testkey"))
assert spec.args[1][0].equals(Var.create_safe("options")) assert spec.args[1][0].equals(Var.create_safe("options"))
assert spec.args[1][1].equals(Var.create_safe({"path": "/"})) assert spec.args[1][1].equals(LiteralVar.create({"path": "/"}))
assert ( assert (
format.format_event(spec) format.format_event(spec)
== 'Event("_remove_cookie", {key:`testkey`,options:{"path": "/"}})' == 'Event("_remove_cookie", {key:"testkey",options:({ ["path"] : "/" })})'
) )
@ -290,12 +291,12 @@ def test_remove_cookie_with_options():
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_remove_cookie" assert spec.handler.fn.__qualname__ == "_remove_cookie"
assert spec.args[0][0].equals(Var.create_safe("key")) assert spec.args[0][0].equals(Var.create_safe("key"))
assert spec.args[0][1].equals(Var.create_safe("testkey")) assert spec.args[0][1].equals(LiteralVar.create("testkey"))
assert spec.args[1][0].equals(Var.create_safe("options")) assert spec.args[1][0].equals(Var.create_safe("options"))
assert spec.args[1][1].equals(Var.create_safe(options)) assert spec.args[1][1].equals(LiteralVar.create(options))
assert ( assert (
format.format_event(spec) format.format_event(spec)
== f'Event("_remove_cookie", {{key:`testkey`,options:{json.dumps(options)}}})' == f'Event("_remove_cookie", {{key:"testkey",options:{str(LiteralVar.create(options))}}})'
) )
@ -314,9 +315,9 @@ def test_remove_local_storage():
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_remove_local_storage" assert spec.handler.fn.__qualname__ == "_remove_local_storage"
assert spec.args[0][0].equals(Var.create_safe("key")) assert spec.args[0][0].equals(Var.create_safe("key"))
assert spec.args[0][1].equals(Var.create_safe("testkey")) assert spec.args[0][1].equals(LiteralVar.create("testkey"))
assert ( assert (
format.format_event(spec) == 'Event("_remove_local_storage", {key:`testkey`})' format.format_event(spec) == 'Event("_remove_local_storage", {key:"testkey"})'
) )

View File

@ -40,7 +40,7 @@ from reflex.state import (
from reflex.testing import chdir from reflex.testing import chdir
from reflex.utils import format, prerequisites, types from reflex.utils import format, prerequisites, types
from reflex.utils.format import json_dumps from reflex.utils.format import json_dumps
from reflex.vars import BaseVar, ComputedVar from reflex.vars import BaseVar, ComputedVar, Var
from tests.states.mutation import MutableSQLAModel, MutableTestState from tests.states.mutation import MutableSQLAModel, MutableTestState
from .states import GenState from .states import GenState
@ -266,8 +266,8 @@ def test_base_class_vars(test_state):
if field in test_state.get_skip_vars(): if field in test_state.get_skip_vars():
continue continue
prop = getattr(cls, field) prop = getattr(cls, field)
assert isinstance(prop, BaseVar) assert isinstance(prop, Var)
assert prop._var_name == field assert prop._var_name.split(".")[-1] == field
assert cls.num1._var_type == int assert cls.num1._var_type == int
assert cls.num2._var_type == float assert cls.num2._var_type == float
@ -395,30 +395,27 @@ def test_default_setters(test_state):
def test_class_indexing_with_vars(): def test_class_indexing_with_vars():
"""Test that we can index into a state var with another var.""" """Test that we can index into a state var with another var."""
prop = TestState.array[TestState.num1] prop = TestState.array[TestState.num1]
assert ( assert str(prop) == f"{TestState.get_name()}.array.at({TestState.get_name()}.num1)"
str(prop) == f"{{{TestState.get_name()}.array.at({TestState.get_name()}.num1)}}"
)
prop = TestState.mapping["a"][TestState.num1] prop = TestState.mapping["a"][TestState.num1]
assert ( assert (
str(prop) str(prop)
== f'{{{TestState.get_name()}.mapping["a"].at({TestState.get_name()}.num1)}}' == f'{TestState.get_name()}.mapping["a"].at({TestState.get_name()}.num1)'
) )
prop = TestState.mapping[TestState.map_key] prop = TestState.mapping[TestState.map_key]
assert ( assert (
str(prop) str(prop) == f"{TestState.get_name()}.mapping[{TestState.get_name()}.map_key]"
== f"{{{TestState.get_name()}.mapping[{TestState.get_name()}.map_key]}}"
) )
def test_class_attributes(): def test_class_attributes():
"""Test that we can get class attributes.""" """Test that we can get class attributes."""
prop = TestState.obj.prop1 prop = TestState.obj.prop1
assert str(prop) == f"{{{TestState.get_name()}.obj.prop1}}" assert str(prop) == f'{TestState.get_name()}.obj["prop1"]'
prop = TestState.complex[1].prop1 prop = TestState.complex[1].prop1
assert str(prop) == f"{{{TestState.get_name()}.complex[1].prop1}}" assert str(prop) == f"{TestState.get_name()}.complex[1][\"prop1\"]"
def test_get_parent_state(): def test_get_parent_state():

View File

@ -1,18 +1,19 @@
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any, Dict
import pytest import pytest
import reflex as rx import reflex as rx
from reflex import style from reflex import style
from reflex.components.component import evaluate_style_namespaces from reflex.components.component import evaluate_style_namespaces
from reflex.ivars.base import ImmutableVar, LiteralVar
from reflex.style import Style from reflex.style import Style
from reflex.vars import Var, VarData from reflex.vars import ImmutableVarData, Var, VarData
test_style = [ test_style = [
({"a": 1}, {"a": 1}), ({"a": 1}, {"a": 1}),
({"a": Var.create("abc")}, {"a": "abc"}), ({"a": LiteralVar.create("abc")}, {"a": "abc"}),
({"test_case": 1}, {"testCase": 1}), ({"test_case": 1}, {"testCase": 1}),
({"test_case": {"a": 1}}, {"testCase": {"a": 1}}), ({"test_case": {"a": 1}}, {"testCase": {"a": 1}}),
({":test_case": {"a": 1}}, {":testCase": {"a": 1}}), ({":test_case": {"a": 1}}, {":testCase": {"a": 1}}),
@ -21,8 +22,8 @@ test_style = [
{"::-webkit-scrollbar": {"display": "none"}}, {"::-webkit-scrollbar": {"display": "none"}},
{"::-webkit-scrollbar": {"display": "none"}}, {"::-webkit-scrollbar": {"display": "none"}},
), ),
({"margin_y": "2rem"}, {"marginBottom": "2rem", "marginTop": "2rem"}), ({"margin_y": "2rem"}, {"marginTop": "2rem", "marginBottom": "2rem"}),
({"marginY": "2rem"}, {"marginBottom": "2rem", "marginTop": "2rem"}), ({"marginY": "2rem"}, {"marginTop": "2rem", "marginBottom": "2rem"}),
( (
{"::-webkit-scrollbar": {"bgColor": "red"}}, {"::-webkit-scrollbar": {"bgColor": "red"}},
{"::-webkit-scrollbar": {"backgroundColor": "red"}}, {"::-webkit-scrollbar": {"backgroundColor": "red"}},
@ -49,7 +50,7 @@ def test_convert(style_dict, expected):
expected: The expected formatted style. expected: The expected formatted style.
""" """
converted_dict, _var_data = style.convert(style_dict) converted_dict, _var_data = style.convert(style_dict)
assert converted_dict == expected assert LiteralVar.create(converted_dict).equals(LiteralVar.create(expected))
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -63,7 +64,9 @@ def test_create_style(style_dict, expected):
style_dict: The style to check. style_dict: The style to check.
expected: The expected formatted style. expected: The expected formatted style.
""" """
assert style.Style(style_dict) == expected assert LiteralVar.create(style.Style(style_dict)).equals(
LiteralVar.create(expected)
)
def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]): def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
@ -87,39 +90,47 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
@pytest.mark.parametrize( @pytest.mark.parametrize(
("kwargs", "style_dict", "expected_get_style"), ("kwargs", "style_dict", "expected_get_style"),
[ [
({}, {}, {"css": None}), ({}, {}, {}),
({"color": "hotpink"}, {}, {"css": Var.create(Style({"color": "hotpink"}))}), (
({}, {"color": "red"}, {"css": Var.create(Style({"color": "red"}))}), {"color": "hotpink"},
{},
{"css": LiteralVar.create(Style({"color": "hotpink"}))},
),
({}, {"color": "red"}, {"css": LiteralVar.create(Style({"color": "red"}))}),
( (
{"color": "hotpink"}, {"color": "hotpink"},
{"color": "red"}, {"color": "red"},
{"css": Var.create(Style({"color": "hotpink"}))}, {"css": LiteralVar.create(Style({"color": "hotpink"}))},
), ),
( (
{"_hover": {"color": "hotpink"}}, {"_hover": {"color": "hotpink"}},
{}, {},
{"css": Var.create(Style({"&:hover": {"color": "hotpink"}}))}, {"css": LiteralVar.create(Style({"&:hover": {"color": "hotpink"}}))},
), ),
( (
{}, {},
{"_hover": {"color": "red"}}, {"_hover": {"color": "red"}},
{"css": Var.create(Style({"&:hover": {"color": "red"}}))}, {"css": LiteralVar.create(Style({"&:hover": {"color": "red"}}))},
), ),
( (
{}, {},
{":hover": {"color": "red"}}, {":hover": {"color": "red"}},
{"css": Var.create(Style({"&:hover": {"color": "red"}}))}, {"css": LiteralVar.create(Style({"&:hover": {"color": "red"}}))},
), ),
( (
{}, {},
{"::-webkit-scrollbar": {"display": "none"}}, {"::-webkit-scrollbar": {"display": "none"}},
{"css": Var.create(Style({"&::-webkit-scrollbar": {"display": "none"}}))}, {
"css": LiteralVar.create(
Style({"&::-webkit-scrollbar": {"display": "none"}})
)
},
), ),
( (
{}, {},
{"::-moz-progress-bar": {"background_color": "red"}}, {"::-moz-progress-bar": {"background_color": "red"}},
{ {
"css": Var.create( "css": LiteralVar.create(
Style({"&::-moz-progress-bar": {"backgroundColor": "red"}}) Style({"&::-moz-progress-bar": {"backgroundColor": "red"}})
) )
}, },
@ -128,7 +139,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
{"color": ["#111", "#222", "#333", "#444", "#555"]}, {"color": ["#111", "#222", "#333", "#444", "#555"]},
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"@media screen and (min-width: 0)": {"color": "#111"}, "@media screen and (min-width: 0)": {"color": "#111"},
@ -148,7 +159,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
}, },
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"@media screen and (min-width: 0)": {"color": "#111"}, "@media screen and (min-width: 0)": {"color": "#111"},
@ -169,7 +180,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
}, },
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"@media screen and (min-width: 0)": { "@media screen and (min-width: 0)": {
@ -209,7 +220,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
}, },
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -236,7 +247,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
{"_hover": {"color": ["#111", "#222", "#333", "#444", "#555"]}}, {"_hover": {"color": ["#111", "#222", "#333", "#444", "#555"]}},
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -268,7 +279,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
}, },
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -307,7 +318,7 @@ def compare_dict_of_var(d1: dict[str, Any], d2: dict[str, Any]):
}, },
{}, {},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -361,20 +372,20 @@ class StyleState(rx.State):
[ [
( (
{"color": StyleState.color}, {"color": StyleState.color},
{"css": Var.create(Style({"color": StyleState.color}))}, {"css": LiteralVar.create(Style({"color": StyleState.color}))},
), ),
( (
{"color": f"dark{StyleState.color}"}, {"color": f"dark{StyleState.color}"},
{ {
"css": Var.create_safe(f'{{"color": `dark{StyleState.color}`}}').to( "css": ImmutableVar.create(
Style f'({{ ["color"] : ("dark"+{StyleState.color}) }})'
) ).to(Dict[str, str])
}, },
), ),
( (
{"color": StyleState.color, "_hover": {"color": StyleState.color2}}, {"color": StyleState.color, "_hover": {"color": StyleState.color2}},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"color": StyleState.color, "color": StyleState.color,
@ -387,7 +398,7 @@ class StyleState(rx.State):
( (
{"color": [StyleState.color, "gray", StyleState.color2, "yellow", "blue"]}, {"color": [StyleState.color, "gray", StyleState.color2, "yellow", "blue"]},
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"@media screen and (min-width: 0)": { "@media screen and (min-width: 0)": {
@ -415,7 +426,7 @@ class StyleState(rx.State):
] ]
}, },
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -453,7 +464,7 @@ class StyleState(rx.State):
} }
}, },
{ {
"css": Var.create( "css": LiteralVar.create(
Style( Style(
{ {
"&:hover": { "&:hover": {
@ -492,7 +503,10 @@ def test_style_via_component_with_state(
""" """
comp = rx.el.div(**kwargs) comp = rx.el.div(**kwargs)
assert comp.style._var_data == expected_get_style["css"]._var_data assert (
ImmutableVarData.merge(comp.style._var_data)
== expected_get_style["css"]._get_all_var_data()
)
# Assert that style values are equal. # Assert that style values are equal.
compare_dict_of_var(comp._get_style(), expected_get_style) compare_dict_of_var(comp._get_style(), expected_get_style)
@ -507,10 +521,10 @@ def test_evaluate_style_namespaces():
def test_style_update_with_var_data(): def test_style_update_with_var_data():
"""Test that .update with a Style containing VarData works.""" """Test that .update with a Style containing VarData works."""
red_var = Var.create_safe("red")._replace( red_var = LiteralVar.create("red")._replace(
merge_var_data=VarData(hooks={"const red = true": None}), # type: ignore merge_var_data=VarData(hooks={"const red = true": None}), # type: ignore
) )
blue_var = Var.create_safe("blue", _var_is_local=False)._replace( blue_var = LiteralVar.create("blue")._replace(
merge_var_data=VarData(hooks={"const blue = true": None}), # type: ignore merge_var_data=VarData(hooks={"const blue = true": None}), # type: ignore
) )
@ -521,7 +535,9 @@ def test_style_update_with_var_data():
) )
s2 = Style() s2 = Style()
s2.update(s1, background_color=f"{blue_var}ish") s2.update(s1, background_color=f"{blue_var}ish")
assert s2 == {"color": "red", "backgroundColor": "`${blue}ish`"} assert str(LiteralVar.create(s2)) == str(
LiteralVar.create({"color": "red", "backgroundColor": "blueish"})
)
assert s2._var_data is not None assert s2._var_data is not None
assert "const red = true" in s2._var_data.hooks assert "const red = true" in s2._var_data.hooks
assert "const blue = true" in s2._var_data.hooks assert "const blue = true" in s2._var_data.hooks