diff --git a/reflex/components/core/banner.py b/reflex/components/core/banner.py index 0b79375b5..7e899079b 100644 --- a/reflex/components/core/banner.py +++ b/reflex/components/core/banner.py @@ -4,7 +4,6 @@ from __future__ import annotations from typing import Optional -from reflex.components.base.bare import Bare from reflex.components.component import Component from reflex.components.core.cond import cond from reflex.components.el.elements.typography import Div @@ -57,7 +56,7 @@ has_too_many_connection_errors: Var = ImmutableVar.create_safe( ).to(BooleanVar) -class WebsocketTargetURL(Bare): +class WebsocketTargetURL: """A component that renders the websocket target URL.""" def add_imports(self) -> ImportDict: diff --git a/reflex/components/core/banner.pyi b/reflex/components/core/banner.pyi index 27efdaabf..4c7de2fbe 100644 --- a/reflex/components/core/banner.pyi +++ b/reflex/components/core/banner.pyi @@ -5,12 +5,12 @@ # ------------------------------------------------------ from typing import Any, Callable, Dict, Literal, Optional, Union, overload -from reflex.components.base.bare import Bare from reflex.components.component import Component from reflex.components.el.elements.typography import Div from reflex.components.lucide.icon import Icon from reflex.components.sonner.toast import Toaster, ToastProps from reflex.event import EventHandler, EventSpec +from reflex.ivars.base import ImmutableVar from reflex.style import Style from reflex.utils.imports import ImportDict, ImportVar from reflex.vars import Var, VarData @@ -22,63 +22,10 @@ connection_errors_count: Var has_connection_errors: Var has_too_many_connection_errors: Var -class WebsocketTargetURL(Bare): +class WebsocketTargetURL: def add_imports(self) -> ImportDict: ... - @overload @classmethod - def create( # type: ignore - cls, - *children, - contents: Optional[Union[Var[Any], Any]] = None, - style: Optional[Style] = None, - key: Optional[Any] = None, - id: Optional[Any] = None, - class_name: Optional[Any] = None, - autofocus: Optional[bool] = None, - custom_attrs: Optional[Dict[str, Union[Var, str]]] = None, - on_blur: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None, - on_click: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None, - on_context_menu: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_double_click: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_focus: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None, - on_mount: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None, - on_mouse_down: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_enter: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_leave: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_move: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_out: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_over: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_mouse_up: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - on_scroll: Optional[Union[EventHandler, EventSpec, list, Callable, Var]] = None, - on_unmount: Optional[ - Union[EventHandler, EventSpec, list, Callable, Var] - ] = None, - **props, - ) -> "WebsocketTargetURL": - """Create a websocket target URL component. - - Returns: - The websocket target URL component. - """ - ... + def create(cls) -> ImmutableVar: ... # type: ignore def default_connection_error() -> list[str | Var | Component]: ... diff --git a/reflex/components/core/match.py b/reflex/components/core/match.py index 9725c1754..3ddef38c6 100644 --- a/reflex/components/core/match.py +++ b/reflex/components/core/match.py @@ -94,6 +94,9 @@ class Match(MemoizationLeaf): if len([case for case in cases if not isinstance(case, tuple)]) > 1: raise ValueError("rx.match can only have one default case.") + if not cases: + raise ValueError("rx.match should have at least one case.") + # Get the default case which should be the last non-tuple arg if not isinstance(cases[-1], tuple): default = cases.pop() diff --git a/reflex/ivars/base.py b/reflex/ivars/base.py index 61a873631..540528eba 100644 --- a/reflex/ivars/base.py +++ b/reflex/ivars/base.py @@ -180,7 +180,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]): kwargs.get("_var_data", self._var_data), merge_var_data ), ) - return type(self)(**field_values) + return dataclasses.replace(self, **field_values) @classmethod def create( @@ -780,10 +780,14 @@ class LiteralVar(ImmutableVar): event_name = LiteralVar.create( ".".join(get_event_handler_parts(value.handler)) ) - event_args = LiteralVar.create({name: value for name, value in value.args}) + event_args = LiteralVar.create( + {str(name): value for name, value in value.args} + ) event_client_name = LiteralVar.create(value.client_handler_name) return FunctionStringVar("Event").call( - event_name, event_args, event_client_name + event_name, + event_args, + *([event_client_name] if value.client_handler_name else []), ) if isinstance(value, EventChain): @@ -944,7 +948,7 @@ def unionize(*args: Type) -> Type: return Union[first, unionize(*rest)] -def figure_out_type(value: Any) -> Type: +def figure_out_type(value: Any) -> types.GenericType: """Figure out the type of the value. Args: @@ -964,6 +968,8 @@ def figure_out_type(value: Any) -> Type: unionize(*(figure_out_type(k) for k in value)), unionize(*(figure_out_type(v) for v in value.values())), ] + if isinstance(value, Var): + return value._var_type return type(value) diff --git a/reflex/ivars/object.py b/reflex/ivars/object.py index d78be122c..722d14378 100644 --- a/reflex/ivars/object.py +++ b/reflex/ivars/object.py @@ -343,15 +343,10 @@ class LiteralObjectVar(LiteralVar, ObjectVar[OBJECT_TYPE]): """ return ImmutableVarData.merge( *[ - value._get_all_var_data() + LiteralVar.create(value)._get_all_var_data() for value in self._var_value.values() - if isinstance(value, Var) - ], - *[ - key._get_all_var_data() - for key in self._var_value - if isinstance(key, Var) ], + *[LiteralVar.create(key)._get_all_var_data() for key in self._var_value], self._var_data, ) diff --git a/reflex/ivars/sequence.py b/reflex/ivars/sequence.py index 1f434fa3e..486c0c96f 100644 --- a/reflex/ivars/sequence.py +++ b/reflex/ivars/sequence.py @@ -794,8 +794,15 @@ class LiteralStringVar(LiteralVar, StringVar): strings_and_vals.append(value) + filtered_strings_and_vals = [ + s for s in strings_and_vals if isinstance(s, Var) or s + ] + + if len(filtered_strings_and_vals) == 1: + return filtered_strings_and_vals[0].to(StringVar) # type: ignore + return ConcatVarOperation.create( - *filter(lambda s: isinstance(s, Var) or s, strings_and_vals), + *filtered_strings_and_vals, _var_data=_var_data, ) @@ -853,7 +860,22 @@ class ConcatVarOperation(StringVar): Returns: The name of the var. """ - return "(" + "+".join([str(element) for element in self._var_value]) + ")" + list_of_strs = [""] + for var in self._var_value: + if isinstance(var, LiteralStringVar): + list_of_strs[-1] += var._var_value + else: + list_of_strs.append(var) + list_of_strs.append("") + + list_of_strs_filtered = [ + str(LiteralVar.create(s)) for s in list_of_strs if isinstance(s, Var) or s + ] + + if len(list_of_strs_filtered) == 1: + return list_of_strs_filtered[0] + + return "(" + "+".join(list_of_strs_filtered) + ")" @cached_property def _cached_get_all_var_data(self) -> ImmutableVarData | None: @@ -1201,11 +1223,7 @@ class LiteralArrayVar(LiteralVar, ArrayVar[ARRAY_VAR_TYPE]): The VarData of the components and all of its children. """ return ImmutableVarData.merge( - *[ - var._get_all_var_data() - for var in self._var_value - if isinstance(var, Var) - ], + *[LiteralVar.create(var)._get_all_var_data() for var in self._var_value], self._var_data, ) diff --git a/reflex/style.py b/reflex/style.py index 5a34449a0..0e93082ea 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -132,11 +132,7 @@ def convert_item( # Otherwise, convert to Var to collapse VarData encoded in f-string. new_var = LiteralVar.create(style_item) var_data = new_var._get_all_var_data() if new_var is not None else None - if var_data: - # The wrapped backtick is used to identify the Var for interpolation. - return f"{str(new_var)}", var_data - - return style_item, None + return new_var, var_data def convert_list( diff --git a/reflex/vars.py b/reflex/vars.py index 951a00375..35ff5de5c 100644 --- a/reflex/vars.py +++ b/reflex/vars.py @@ -771,8 +771,8 @@ class Var: return ( self._var_name == other._var_name and self._var_type == other._var_type - and ImmutableVarData.merge(self._var_data) - == ImmutableVarData.merge(other._var_data) + and ImmutableVarData.merge(self._get_all_var_data()) + == ImmutableVarData.merge(other._get_all_var_data()) ) return ( diff --git a/tests/components/base/test_bare.py b/tests/components/base/test_bare.py index 264d136cb..df3f862d4 100644 --- a/tests/components/base/test_bare.py +++ b/tests/components/base/test_bare.py @@ -6,8 +6,8 @@ from reflex.components.base.bare import Bare @pytest.mark.parametrize( "contents,expected", [ - ("hello", "hello"), - ("{}", "{}"), + ("hello", '{"hello"}'), + ("{}", '{"{}"}'), (None, ""), ("${default_state.name}", "${default_state.name}"), ("{state.name}", "{state.name}"), diff --git a/tests/components/base/test_script.py b/tests/components/base/test_script.py index 372178d5f..62e6b0054 100644 --- a/tests/components/base/test_script.py +++ b/tests/components/base/test_script.py @@ -13,7 +13,7 @@ def test_script_inline(): assert render_dict["name"] == "Script" assert not render_dict["contents"] assert len(render_dict["children"]) == 1 - assert render_dict["children"][0]["contents"] == "{`let x = 42`}" + assert render_dict["children"][0]["contents"] == '{"let x = 42"}' def test_script_src(): diff --git a/tests/components/core/test_banner.py b/tests/components/core/test_banner.py index 184a65cc9..f46ee16b1 100644 --- a/tests/components/core/test_banner.py +++ b/tests/components/core/test_banner.py @@ -9,8 +9,11 @@ from reflex.components.radix.themes.typography.text import Text def test_websocket_target_url(): url = WebsocketTargetURL.create() - _imports = url._get_all_imports(collapse=True) - assert tuple(_imports) == ("/utils/state", "/env.json") + var_data = url._get_all_var_data() + assert var_data is not None + assert sorted(tuple((key for key, _ in var_data.imports))) == sorted( + ("/utils/state", "/env.json") + ) def test_connection_banner(): diff --git a/tests/components/core/test_colors.py b/tests/components/core/test_colors.py index 0c14c8a7c..069113afb 100644 --- a/tests/components/core/test_colors.py +++ b/tests/components/core/test_colors.py @@ -3,7 +3,7 @@ import pytest import reflex as rx from reflex.components.datadisplay.code import CodeBlock from reflex.constants.colors import Color -from reflex.vars import Var +from reflex.ivars.base import LiteralVar class ColorState(rx.State): @@ -18,38 +18,38 @@ color_state_name = ColorState.get_full_name().replace(".", "__") def create_color_var(color): - return Var.create(color) + return LiteralVar.create(color) @pytest.mark.parametrize( "color, expected", [ - (create_color_var(rx.color("mint")), "var(--mint-7)"), - (create_color_var(rx.color("mint", 3)), "var(--mint-3)"), - (create_color_var(rx.color("mint", 3, True)), "var(--mint-a3)"), + (create_color_var(rx.color("mint")), '"var(--mint-7)"'), + (create_color_var(rx.color("mint", 3)), '"var(--mint-3)"'), + (create_color_var(rx.color("mint", 3, True)), '"var(--mint-a3)"'), ( create_color_var(rx.color(ColorState.color, ColorState.shade)), # type: ignore - f"var(--${{{color_state_name}.color}}-${{{color_state_name}.shade}})", + f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")', ), ( create_color_var(rx.color(f"{ColorState.color}", f"{ColorState.shade}")), # type: ignore - f"var(--${{{color_state_name}.color}}-${{{color_state_name}.shade}})", + f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")', ), ( create_color_var( rx.color(f"{ColorState.color_part}ato", f"{ColorState.shade}") # type: ignore ), - f"var(--${{{color_state_name}.color_part}}ato-${{{color_state_name}.shade}})", + f'("var(--"+{str(color_state_name)}.color_part+"ato-"+{str(color_state_name)}.shade+")")', ), ( create_color_var(f'{rx.color(ColorState.color, f"{ColorState.shade}")}'), # type: ignore - f"var(--${{{color_state_name}.color}}-${{{color_state_name}.shade}})", + f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")', ), ( create_color_var( f'{rx.color(f"{ColorState.color}", f"{ColorState.shade}")}' # type: ignore ), - f"var(--${{{color_state_name}.color}}-${{{color_state_name}.shade}})", + f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")', ), ], ) @@ -67,11 +67,11 @@ def test_color(color, expected): [ ( rx.cond(True, rx.color("mint"), rx.color("tomato", 5)), - "{isTrue(true) ? `var(--mint-7)` : `var(--tomato-5)`}", + '(Boolean(true) ? "var(--mint-7)" : "var(--tomato-5)")', ), ( rx.cond(True, rx.color(ColorState.color), rx.color(ColorState.color, 5)), # type: ignore - f"{{isTrue(true) ? `var(--${{{color_state_name}.color}}-7)` : `var(--${{{color_state_name}.color}}-5)`}}", + f'(Boolean(true) ? ("var(--"+{str(color_state_name)}.color+"-7)") : ("var(--"+{str(color_state_name)}.color+"-5)"))', ), ( rx.match( @@ -80,9 +80,9 @@ def test_color(color, expected): ("second", rx.color("tomato", 5)), rx.color(ColorState.color, 2), # type: ignore ), - "{(() => { switch (JSON.stringify(`condition`)) {case JSON.stringify(`first`): return (`var(--mint-7)`);" - " break;case JSON.stringify(`second`): return (`var(--tomato-5)`); break;default: " - f"return (`var(--${{{color_state_name}.color}}-2)`); break;}};}})()}}", + '(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): return ("var(--mint-7)");' + ' break;case JSON.stringify("second"): return ("var(--tomato-5)"); break;default: ' + f'return (("var(--"+{str(color_state_name)}.color+"-2)")); break;}};}})()', ), ( rx.match( @@ -91,10 +91,10 @@ def test_color(color, expected): ("second", rx.color(ColorState.color, 5)), # type: ignore rx.color(ColorState.color, 2), # type: ignore ), - "{(() => { switch (JSON.stringify(`condition`)) {case JSON.stringify(`first`): " - f"return (`var(--${{{color_state_name}.color}}-7)`); break;case JSON.stringify(`second`): " - f"return (`var(--${{{color_state_name}.color}}-5)`); break;default: " - f"return (`var(--${{{color_state_name}.color}}-2)`); break;}};}})()}}", + '(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): ' + f'return (("var(--"+{str(color_state_name)}.color+"-7)")); break;case JSON.stringify("second"): ' + f'return (("var(--"+{str(color_state_name)}.color+"-5)")); break;default: ' + f'return (("var(--"+{str(color_state_name)}.color+"-2)")); break;}};}})()', ), ], ) @@ -105,9 +105,9 @@ def test_color_with_conditionals(cond_var, expected): @pytest.mark.parametrize( "color, expected", [ - (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("blue", alpha=True)), "{`var(--blue-a7)`}"), + (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("blue", alpha=True)), '"var(--blue-a7)"'), ("red", "red"), ("green", "green"), ("blue", "blue"), @@ -122,4 +122,4 @@ def test_radix_color(color, expected): expected (str): The expected custom_style string, radix or literal """ code_block = CodeBlock.create("Hello World", background_color=color) - assert code_block.custom_style["backgroundColor"].__format__("") == expected # type: ignore + assert str(code_block.custom_style["backgroundColor"]) == expected # type: ignore diff --git a/tests/components/core/test_cond.py b/tests/components/core/test_cond.py index 082834d50..a98a68f41 100644 --- a/tests/components/core/test_cond.py +++ b/tests/components/core/test_cond.py @@ -6,10 +6,10 @@ import pytest from reflex.components.base.fragment import Fragment from reflex.components.core.cond import Cond, cond from reflex.components.radix.themes.typography.text import Text -from reflex.ivars.number import NumberVar +from reflex.ivars.base import ImmutableVar, LiteralVar, immutable_computed_var from reflex.state import BaseState, State from reflex.utils.format import format_state_name -from reflex.vars import Var, computed_var +from reflex.vars import Var @pytest.fixture @@ -22,8 +22,8 @@ def cond_state(request): def test_f_string_cond_interpolation(): # make sure backticks inside interpolation don't get escaped - var = Var.create(f"x {cond(True, 'a', 'b')}") - assert str(var) == "x ${isTrue(true) ? `a` : `b`}" + var = LiteralVar.create(f"x {cond(True, 'a', 'b')}") + assert str(var) == '("x "+(Boolean(true) ? "a" : "b"))' @pytest.mark.parametrize( @@ -102,10 +102,10 @@ def test_prop_cond(c1: Any, c2: Any): assert isinstance(prop_cond, Var) if not isinstance(c1, Var): - c1 = json.dumps(c1).replace('"', "`") + c1 = json.dumps(c1) if not isinstance(c2, Var): - c2 = json.dumps(c2).replace('"', "`") - assert str(prop_cond) == f"{{Boolean(true) ? {c1} : {c2}}}" + c2 = json.dumps(c2) + assert str(prop_cond) == f"(Boolean(true) ? {c1} : {c2})" def test_cond_no_mix(): @@ -134,23 +134,23 @@ def test_cond_computed_var(): """Test if cond works with computed vars.""" class CondStateComputed(State): - @computed_var + @immutable_computed_var def computed_int(self) -> int: return 0 - @computed_var + @immutable_computed_var def computed_str(self) -> str: return "a string" comp = cond(True, CondStateComputed.computed_int, CondStateComputed.computed_str) # TODO: shouln't this be a ComputedVar? - assert isinstance(comp, NumberVar) + assert isinstance(comp, ImmutableVar) state_name = format_state_name(CondStateComputed.get_full_name()) assert ( str(comp) - == f"{{Boolean(true) ? {state_name}.computed_int : {state_name}.computed_str}}" + == f"(Boolean(true) ? {state_name}.computed_int : {state_name}.computed_str)" ) assert comp._var_type == Union[int, str] diff --git a/tests/components/core/test_debounce.py b/tests/components/core/test_debounce.py index 8ad15ea58..95feb7ae6 100644 --- a/tests/components/core/test_debounce.py +++ b/tests/components/core/test_debounce.py @@ -4,8 +4,8 @@ import pytest import reflex as rx from reflex.components.core.debounce import DEFAULT_DEBOUNCE_TIMEOUT +from reflex.ivars.base import LiteralVar from reflex.state import BaseState -from reflex.vars import BaseVar def test_create_no_child(): @@ -60,11 +60,7 @@ def test_render_child_props(): assert "css" in tag.props and isinstance(tag.props["css"], rx.Var) for prop in ["foo", "bar", "baz", "quuc"]: assert prop in str(tag.props["css"]) - assert tag.props["value"].equals( - BaseVar( - _var_name="real", _var_type=str, _var_is_local=True, _var_is_string=False - ) - ) + assert tag.props["value"].equals(LiteralVar.create("real")) assert len(tag.props["onChange"].events) == 1 assert tag.props["onChange"].events[0].handler == S.on_change assert tag.contents == "" @@ -156,11 +152,7 @@ def test_render_child_props_recursive(): assert "css" in tag.props and isinstance(tag.props["css"], rx.Var) for prop in ["foo", "bar", "baz", "quuc"]: assert prop in str(tag.props["css"]) - assert tag.props["value"].equals( - BaseVar( - _var_name="outer", _var_type=str, _var_is_local=True, _var_is_string=False - ) - ) + assert tag.props["value"].equals(LiteralVar.create("outer")) assert tag.props["forceNotifyOnBlur"]._var_name == "false" assert tag.props["forceNotifyByEnter"]._var_name == "false" assert tag.props["debounceTimeout"]._var_name == "42" diff --git a/tests/components/core/test_foreach.py b/tests/components/core/test_foreach.py index 6e4fa6b5e..f1fae2577 100644 --- a/tests/components/core/test_foreach.py +++ b/tests/components/core/test_foreach.py @@ -278,7 +278,7 @@ def test_foreach_component_styles(): ) ) component._add_style_recursive({box: {"color": "red"}}) - assert 'css={{"color": "red"}}' in str(component) + assert 'css={({ ["color"] : "red" })}' in str(component) def test_foreach_component_state(): diff --git a/tests/components/core/test_html.py b/tests/components/core/test_html.py index 325bdcaf9..9c1a0c28d 100644 --- a/tests/components/core/test_html.py +++ b/tests/components/core/test_html.py @@ -15,8 +15,8 @@ def test_html_many_children(): def test_html_create(): html = Html.create("

Hello !

") - assert str(html.dangerouslySetInnerHTML) == '{"__html": "

Hello !

"}' # type: ignore + assert str(html.dangerouslySetInnerHTML) == '({ ["__html"] : "

Hello !

" })' # type: ignore assert ( str(html) - == '
Hello !

"}}/>' + == '
Hello !

" })}/>' ) diff --git a/tests/components/core/test_match.py b/tests/components/core/test_match.py index 883386ebd..1843b914d 100644 --- a/tests/components/core/test_match.py +++ b/tests/components/core/test_match.py @@ -1,4 +1,4 @@ -from typing import Tuple +from typing import Dict, List, Tuple import pytest @@ -6,7 +6,7 @@ import reflex as rx from reflex.components.core.match import Match from reflex.state import BaseState from reflex.utils.exceptions import MatchTypeError -from reflex.vars import BaseVar +from reflex.vars import Var class MatchState(BaseState): @@ -35,7 +35,7 @@ def test_match_components(): [match_child] = match_dict["children"] assert match_child["name"] == "match" - assert str(match_child["cond"]) == f"{{{MatchState.get_name()}.value}}" + assert str(match_child["cond"]) == f"{MatchState.get_name()}.value" match_cases = match_child["match_cases"] assert len(match_cases) == 6 @@ -44,7 +44,7 @@ def test_match_components(): assert match_cases[0][0]._var_type == int first_return_value_render = match_cases[0][1].render() assert first_return_value_render["name"] == "RadixThemesText" - assert first_return_value_render["children"][0]["contents"] == "{`first value`}" + assert first_return_value_render["children"][0]["contents"] == '{"first value"}' assert match_cases[1][0]._var_name == "2" assert match_cases[1][0]._var_type == int @@ -52,36 +52,36 @@ def test_match_components(): assert match_cases[1][1]._var_type == int second_return_value_render = match_cases[1][2].render() assert second_return_value_render["name"] == "RadixThemesText" - assert second_return_value_render["children"][0]["contents"] == "{`second value`}" + assert second_return_value_render["children"][0]["contents"] == '{"second value"}' assert match_cases[2][0]._var_name == "[1, 2]" - assert match_cases[2][0]._var_type == list + assert match_cases[2][0]._var_type == List[int] third_return_value_render = match_cases[2][1].render() assert third_return_value_render["name"] == "RadixThemesText" - assert third_return_value_render["children"][0]["contents"] == "{`third value`}" + assert third_return_value_render["children"][0]["contents"] == '{"third value"}' - assert match_cases[3][0]._var_name == "random" + assert match_cases[3][0]._var_name == '"random"' assert match_cases[3][0]._var_type == str fourth_return_value_render = match_cases[3][1].render() assert fourth_return_value_render["name"] == "RadixThemesText" - assert fourth_return_value_render["children"][0]["contents"] == "{`fourth value`}" + assert fourth_return_value_render["children"][0]["contents"] == '{"fourth value"}' - assert match_cases[4][0]._var_name == '{"foo": "bar"}' - assert match_cases[4][0]._var_type == dict + assert match_cases[4][0]._var_name == '({ ["foo"] : "bar" })' + assert match_cases[4][0]._var_type == Dict[str, str] fifth_return_value_render = match_cases[4][1].render() assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == "{`fifth value`}" + assert fifth_return_value_render["children"][0]["contents"] == '{"fifth value"}' - assert match_cases[5][0]._var_name == f"(({MatchState.get_name()}.num) + (1))" + assert match_cases[5][0]._var_name == f"({MatchState.get_name()}.num + 1)" assert match_cases[5][0]._var_type == int fifth_return_value_render = match_cases[5][1].render() assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == "{`sixth value`}" + assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}' default = match_child["default"].render() assert default["name"] == "RadixThemesText" - assert default["children"][0]["contents"] == "{`default value`}" + assert default["children"][0]["contents"] == '{"default value"}' @pytest.mark.parametrize( @@ -99,12 +99,12 @@ def test_match_components(): (MatchState.string, f"{MatchState.value} - string"), "default value", ), - f"(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return (`first`); break;case JSON.stringify(2): case JSON.stringify(3): return " - "(`second value`); break;case JSON.stringify([1, 2]): return (`third-value`); break;case JSON.stringify(`random`): " - 'return (`fourth_value`); break;case JSON.stringify({"foo": "bar"}): return (`fifth value`); ' - f"break;case JSON.stringify((({MatchState.get_name()}.num) + (1))): return (`sixth value`); break;case JSON.stringify(`${{{MatchState.get_name()}.value}} - string`): " - f"return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (`${{{MatchState.get_name()}.value}} - string`); break;default: " - "return (`default value`); break;};})()", + f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return ("first"); break;case JSON.stringify(2): case JSON.stringify(3): return ' + '("second value"); break;case JSON.stringify([1, 2]): return ("third-value"); break;case JSON.stringify("random"): ' + 'return ("fourth_value"); break;case JSON.stringify(({ ["foo"] : "bar" })): return ("fifth value"); ' + f'break;case JSON.stringify(({MatchState.get_name()}.num + 1)): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' + f'return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (({MatchState.get_name()}.value+" - string")); break;default: ' + 'return ("default value"); break;};})()', ), ( ( @@ -118,11 +118,11 @@ def test_match_components(): (MatchState.string, f"{MatchState.value} - string"), MatchState.string, ), - f"(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return (`first`); break;case JSON.stringify(2): case JSON.stringify(3): return " - "(`second value`); break;case JSON.stringify([1, 2]): return (`third-value`); break;case JSON.stringify(`random`): " - 'return (`fourth_value`); break;case JSON.stringify({"foo": "bar"}): return (`fifth value`); ' - f"break;case JSON.stringify((({MatchState.get_name()}.num) + (1))): return (`sixth value`); break;case JSON.stringify(`${{{MatchState.get_name()}.value}} - string`): " - f"return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (`${{{MatchState.get_name()}.value}} - string`); break;default: " + f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1): return ("first"); break;case JSON.stringify(2): case JSON.stringify(3): return ' + '("second value"); break;case JSON.stringify([1, 2]): return ("third-value"); break;case JSON.stringify("random"): ' + 'return ("fourth_value"); break;case JSON.stringify(({ ["foo"] : "bar" })): return ("fifth value"); ' + f'break;case JSON.stringify(({MatchState.get_name()}.num + 1)): return ("sixth value"); break;case JSON.stringify(({MatchState.get_name()}.value+" - string")): ' + f'return ({MatchState.get_name()}.string); break;case JSON.stringify({MatchState.get_name()}.string): return (({MatchState.get_name()}.value+" - string")); break;default: ' f"return ({MatchState.get_name()}.string); break;}};}})()", ), ], @@ -135,7 +135,7 @@ def test_match_vars(cases, expected): expected: The expected var full name. """ match_comp = Match.create(MatchState.value, *cases) - assert isinstance(match_comp, BaseVar) + assert isinstance(match_comp, Var) assert match_comp._var_full_name == expected @@ -247,8 +247,8 @@ def test_match_case_tuple_elements(match_case): (MatchState.num + 1, "black"), rx.text("default value"), ), - "Match cases should have the same return types. Case 3 with return value `red` of type " - " is not ", + 'Match cases should have the same return types. Case 3 with return value `"red"` of type ' + " is not ", ), ( ( @@ -260,8 +260,8 @@ def test_match_case_tuple_elements(match_case): ([1, 2], rx.text("third value")), rx.text("default value"), ), - "Match cases should have the same return types. Case 3 with return value ` {`first value`} ` " - "of type is not ", + 'Match cases should have the same return types. Case 3 with return value ` {"first value"} ` ' + "of type is not ", ), ], ) diff --git a/tests/components/datadisplay/test_code.py b/tests/components/datadisplay/test_code.py index 64452e90c..49fbae09f 100644 --- a/tests/components/datadisplay/test_code.py +++ b/tests/components/datadisplay/test_code.py @@ -4,7 +4,7 @@ from reflex.components.datadisplay.code import CodeBlock @pytest.mark.parametrize( - "theme, expected", [("light", "one-light"), ("dark", "one-dark")] + "theme, expected", [("light", '"one-light"'), ("dark", '"one-dark"')] ) def test_code_light_dark_theme(theme, expected): code_block = CodeBlock.create(theme=theme) diff --git a/tests/components/forms/test_uploads.py b/tests/components/forms/test_uploads.py index f8856a20f..3b2ee014f 100644 --- a/tests/components/forms/test_uploads.py +++ b/tests/components/forms/test_uploads.py @@ -83,11 +83,11 @@ def test_upload_root_component_render(upload_root_component): # upload assert upload["name"] == "ReactDropzone" assert upload["props"] == [ - "id={`default`}", + 'id={"default"}', "multiple={true}", "onDrop={e => setFilesById(filesById => {\n" " const updatedFilesById = Object.assign({}, filesById);\n" - " updatedFilesById[`default`] = e;\n" + ' updatedFilesById["default"] = e;\n' " return updatedFilesById;\n" " })\n" " }", @@ -99,23 +99,23 @@ def test_upload_root_component_render(upload_root_component): [box] = upload["children"] assert box["name"] == "RadixThemesBox" assert box["props"] == [ - "className={`rx-Upload`}", - 'css={{"border": "1px dotted black"}}', + 'className={"rx-Upload"}', + 'css={({ ["border"] : "1px dotted black" })}', "{...getRootProps()}", ] # input, button and text inside of box [input, button, text] = box["children"] assert input["name"] == "input" - assert input["props"] == ["type={`file`}", "{...getInputProps()}"] + assert input["props"] == ['type={"file"}', "{...getInputProps()}"] assert button["name"] == "RadixThemesButton" - assert button["children"][0]["contents"] == "{`select file`}" + assert button["children"][0]["contents"] == '{"select file"}' assert text["name"] == "RadixThemesText" assert ( text["children"][0]["contents"] - == "{`Drag and drop files here or click to select files`}" + == '{"Drag and drop files here or click to select files"}' ) @@ -130,11 +130,11 @@ def test_upload_component_render(upload_component): # upload assert upload["name"] == "ReactDropzone" assert upload["props"] == [ - "id={`default`}", + 'id={"default"}', "multiple={true}", "onDrop={e => setFilesById(filesById => {\n" " const updatedFilesById = Object.assign({}, filesById);\n" - " updatedFilesById[`default`] = e;\n" + ' updatedFilesById["default"] = e;\n' " return updatedFilesById;\n" " })\n" " }", @@ -146,23 +146,23 @@ def test_upload_component_render(upload_component): [box] = upload["children"] assert box["name"] == "RadixThemesBox" assert box["props"] == [ - "className={`rx-Upload`}", - 'css={{"border": "1px dotted black", "padding": "5em", "textAlign": "center"}}', + 'className={"rx-Upload"}', + 'css={({ ["border"] : "1px dotted black", ["padding"] : "5em", ["textAlign"] : "center" })}', "{...getRootProps()}", ] # input, button and text inside of box [input, button, text] = box["children"] assert input["name"] == "input" - assert input["props"] == ["type={`file`}", "{...getInputProps()}"] + assert input["props"] == ['type={"file"}', "{...getInputProps()}"] assert button["name"] == "RadixThemesButton" - assert button["children"][0]["contents"] == "{`select file`}" + assert button["children"][0]["contents"] == '{"select file"}' assert text["name"] == "RadixThemesText" assert ( text["children"][0]["contents"] - == "{`Drag and drop files here or click to select files`}" + == '{"Drag and drop files here or click to select files"}' ) @@ -175,13 +175,13 @@ def test_upload_component_with_props_render(upload_component_with_props): upload = upload_component_with_props.render() assert upload["props"] == [ - "id={`default`}", + 'id={"default"}', "maxFiles={2}", "multiple={true}", "noDrag={true}", "onDrop={e => setFilesById(filesById => {\n" " const updatedFilesById = Object.assign({}, filesById);\n" - " updatedFilesById[`default`] = e;\n" + ' updatedFilesById["default"] = e;\n' " return updatedFilesById;\n" " })\n" " }", @@ -193,11 +193,11 @@ def test_upload_component_id_with_special_chars(upload_component_id_special): upload = upload_component_id_special.render() assert upload["props"] == [ - r"id={`#spec!\`al-_98ID`}", + r'id={"#spec!`al-_98ID"}', "multiple={true}", "onDrop={e => setFilesById(filesById => {\n" " const updatedFilesById = Object.assign({}, filesById);\n" - " updatedFilesById[`#spec!\\`al-_98ID`] = e;\n" + ' updatedFilesById["#spec!`al-_98ID"] = e;\n' " return updatedFilesById;\n" " })\n" " }", diff --git a/tests/components/media/test_image.py b/tests/components/media/test_image.py index a39895c67..e0dd771f7 100644 --- a/tests/components/media/test_image.py +++ b/tests/components/media/test_image.py @@ -36,9 +36,13 @@ def test_set_src_str(): """Test that setting the src works.""" image = rx.image(src="pic2.jpeg") # when using next/image, we explicitly create a _var_is_str Var - # assert str(image.src) == "{`pic2.jpeg`}" # type: ignore + assert str(image.src) in ( + '"pic2.jpeg"', + "'pic2.jpeg'", + "`pic2.jpeg`", + ) # For plain rx.el.img, an explicit var is not created, so the quoting happens later - assert str(image.src) == "pic2.jpeg" # type: ignore + # assert str(image.src) == "pic2.jpeg" # type: ignore def test_set_src_img(pil_image: Img): diff --git a/tests/components/test_component.py b/tests/components/test_component.py index 78c42f177..3732eeb01 100644 --- a/tests/components/test_component.py +++ b/tests/components/test_component.py @@ -17,6 +17,7 @@ from reflex.components.component import ( ) from reflex.constants import EventTriggers from reflex.event import EventChain, EventHandler, parse_args_spec +from reflex.ivars.base import LiteralVar from reflex.state import BaseState from reflex.style import Style from reflex.utils import imports @@ -229,8 +230,8 @@ def test_set_style_attrs(component1): component1: A test component. """ component = component1(color="white", text_align="center") - assert component.style["color"] == "white" - assert component.style["textAlign"] == "center" + assert str(component.style["color"]) == '"white"' + assert str(component.style["textAlign"]) == '"center"' def test_custom_attrs(component1): @@ -254,7 +255,10 @@ def test_create_component(component1): c = component1.create(*children, **attrs) assert isinstance(c, component1) assert c.children == children - assert c.style == {"color": "white", "textAlign": "center"} + assert ( + str(LiteralVar.create(c.style)) + == '({ ["color"] : "white", ["textAlign"] : "center" })' + ) @pytest.mark.parametrize( @@ -418,8 +422,8 @@ def test_add_style(component1, component2): } c1 = component1()._add_style_recursive(style) # type: ignore c2 = component2()._add_style_recursive(style) # type: ignore - assert c1.style["color"] == "white" - assert c2.style["color"] == "black" + assert str(c1.style["color"]) == '"white"' + assert str(c2.style["color"]) == '"black"' def test_add_style_create(component1, component2): @@ -435,8 +439,8 @@ def test_add_style_create(component1, component2): } c1 = component1()._add_style_recursive(style) # type: ignore c2 = component2()._add_style_recursive(style) # type: ignore - assert c1.style["color"] == "white" - assert c2.style["color"] == "black" + assert str(c1.style["color"]) == '"white"' + assert str(c2.style["color"]) == '"black"' def test_get_imports(component1, component2): @@ -606,8 +610,8 @@ def test_create_filters_none_props(test_component): assert "prop4" not in component.get_props() # Assert that the style prop is present in the component's props - assert component.style["color"] == "white" - assert component.style["text-align"] == "center" + assert str(component.style["color"]) == '"white"' + assert str(component.style["text-align"]) == '"center"' @pytest.mark.parametrize("children", [((None,),), ("foo", ("bar", (None,)))]) @@ -634,7 +638,7 @@ def test_component_create_unallowed_types(children, test_component): "children": [ { "name": "RadixThemesText", - "props": ["as={`p`}"], + "props": ['as={"p"}'], "contents": "", "args": None, "special_props": set(), @@ -642,7 +646,7 @@ def test_component_create_unallowed_types(children, test_component): { "name": "", "props": [], - "contents": "{`first_text`}", + "contents": '{"first_text"}', "args": None, "special_props": set(), "children": [], @@ -669,7 +673,7 @@ def test_component_create_unallowed_types(children, test_component): "args": None, "autofocus": False, "children": [], - "contents": "{`first_text`}", + "contents": '{"first_text"}', "name": "", "props": [], "special_props": set(), @@ -677,7 +681,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ["as={`p`}"], + "props": ['as={"p"}'], "special_props": set(), }, { @@ -688,7 +692,7 @@ def test_component_create_unallowed_types(children, test_component): "args": None, "autofocus": False, "children": [], - "contents": "{`second_text`}", + "contents": '{"second_text"}', "name": "", "props": [], "special_props": set(), @@ -696,7 +700,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ["as={`p`}"], + "props": ['as={"p"}'], "special_props": set(), }, ], @@ -720,7 +724,7 @@ def test_component_create_unallowed_types(children, test_component): "args": None, "autofocus": False, "children": [], - "contents": "{`first_text`}", + "contents": '{"first_text"}', "name": "", "props": [], "special_props": set(), @@ -728,7 +732,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ["as={`p`}"], + "props": ['as={"p"}'], "special_props": set(), }, { @@ -747,7 +751,7 @@ def test_component_create_unallowed_types(children, test_component): "args": None, "autofocus": False, "children": [], - "contents": "{`second_text`}", + "contents": '{"second_text"}', "name": "", "props": [], "special_props": set(), @@ -755,7 +759,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ["as={`p`}"], + "props": ['as={"p"}'], "special_props": set(), } ], @@ -824,9 +828,9 @@ def test_component_event_trigger_arbitrary_args(): comp = C1.create(on_foo=C1State.mock_handler) assert comp.render()["props"][0] == ( - "onFoo={(__e,_alpha,_bravo,_charlie) => addEvents(" - f'[Event("{C1State.get_full_name()}.mock_handler", {{_e:__e.target.value,_bravo:_bravo["nested"],_charlie:((_charlie.custom) + (42))}})], ' - "[__e,_alpha,_bravo,_charlie], {})}" + "onFoo={((__e, _alpha, _bravo, _charlie) => ((addEvents(" + f'[(Event("{C1State.get_full_name()}.mock_handler", ({{ ["_e"] : __e["target"]["value"], ["_bravo"] : _bravo["nested"], ["_charlie"] : (_charlie["custom"] + 42) }})))], ' + "[__e, _alpha, _bravo, _charlie], ({ })))))}" ) @@ -1002,10 +1006,10 @@ def test_component_with_only_valid_children(fixture, request): @pytest.mark.parametrize( "component,rendered", [ - (rx.text("hi"), "\n {`hi`}\n"), + (rx.text("hi"), '\n {"hi"}\n'), ( rx.box(rx.chakra.heading("test", size="md")), - "\n \n {`test`}\n\n", + '\n \n {"test"}\n\n', ), ], ) @@ -1060,7 +1064,7 @@ def test_stateful_banner(): assert isinstance(stateful_component, StatefulComponent) -TEST_VAR = Var.create_safe("test")._replace( +TEST_VAR = LiteralVar.create("test")._replace( merge_var_data=VarData( hooks={"useTest": None}, imports={"test": [ImportVar(tag="test")]}, @@ -1068,36 +1072,36 @@ TEST_VAR = Var.create_safe("test")._replace( interpolations=[], ) ) -FORMATTED_TEST_VAR = Var.create(f"foo{TEST_VAR}bar") +FORMATTED_TEST_VAR = LiteralVar.create(f"foo{TEST_VAR}bar") STYLE_VAR = TEST_VAR._replace(_var_name="style", _var_is_local=False) EVENT_CHAIN_VAR = TEST_VAR._replace(_var_type=EventChain) ARG_VAR = Var.create("arg") -TEST_VAR_DICT_OF_DICT = Var.create_safe({"a": {"b": "test"}})._replace( +TEST_VAR_DICT_OF_DICT = LiteralVar.create({"a": {"b": "test"}})._replace( merge_var_data=TEST_VAR._var_data ) -FORMATTED_TEST_VAR_DICT_OF_DICT = Var.create_safe({"a": {"b": f"footestbar"}})._replace( +FORMATTED_TEST_VAR_DICT_OF_DICT = LiteralVar.create( + {"a": {"b": f"footestbar"}} +)._replace(merge_var_data=TEST_VAR._var_data) + +TEST_VAR_LIST_OF_LIST = LiteralVar.create([["test"]])._replace( + merge_var_data=TEST_VAR._var_data +) +FORMATTED_TEST_VAR_LIST_OF_LIST = LiteralVar.create([["footestbar"]])._replace( merge_var_data=TEST_VAR._var_data ) -TEST_VAR_LIST_OF_LIST = Var.create_safe([["test"]])._replace( - merge_var_data=TEST_VAR._var_data -) -FORMATTED_TEST_VAR_LIST_OF_LIST = Var.create_safe([["footestbar"]])._replace( +TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create([[["test"]]])._replace( merge_var_data=TEST_VAR._var_data ) +FORMATTED_TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create( + [[["footestbar"]]] +)._replace(merge_var_data=TEST_VAR._var_data) -TEST_VAR_LIST_OF_LIST_OF_LIST = Var.create_safe([[["test"]]])._replace( +TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "test"}])._replace( merge_var_data=TEST_VAR._var_data ) -FORMATTED_TEST_VAR_LIST_OF_LIST_OF_LIST = Var.create_safe([[["footestbar"]]])._replace( - merge_var_data=TEST_VAR._var_data -) - -TEST_VAR_LIST_OF_DICT = Var.create_safe([{"a": "test"}])._replace( - merge_var_data=TEST_VAR._var_data -) -FORMATTED_TEST_VAR_LIST_OF_DICT = Var.create_safe([{"a": "footestbar"}])._replace( +FORMATTED_TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "footestbar"}])._replace( merge_var_data=TEST_VAR._var_data ) @@ -1186,7 +1190,7 @@ class EventState(rx.State): id="direct-special_props", ), pytest.param( - rx.fragment(special_props={Var.create(f"foo{TEST_VAR}bar")}), + rx.fragment(special_props={LiteralVar.create(f"foo{TEST_VAR}bar")}), [FORMATTED_TEST_VAR], id="fstring-special_props", ), @@ -1295,6 +1299,8 @@ def test_get_vars(component, exp_vars): comp_vars, sorted(exp_vars, key=lambda v: v._var_name), ): + print(str(comp_var), str(exp_var)) + print(comp_var._get_all_var_data(), exp_var._get_all_var_data()) assert comp_var.equals(exp_var) @@ -1334,9 +1340,11 @@ def test_instantiate_all_components(): continue component = getattr( rx, - component_name - if not isinstance(component_name, tuple) - else component_name[1], + ( + component_name + if not isinstance(component_name, tuple) + else component_name[1] + ), ) if isinstance(component, type) and issubclass(component, Component): component.create() @@ -1594,14 +1602,14 @@ def test_rename_props(): c1 = C1.create(prop1="prop1_1", prop2="prop2_1") rendered_c1 = c1.render() - assert "renamed_prop1={`prop1_1`}" in rendered_c1["props"] - assert "renamed_prop2={`prop2_1`}" in rendered_c1["props"] + assert 'renamed_prop1={"prop1_1"}' in rendered_c1["props"] + assert 'renamed_prop2={"prop2_1"}' in rendered_c1["props"] c2 = C2.create(prop1="prop1_2", prop2="prop2_2", prop3="prop3_2") rendered_c2 = c2.render() - assert "renamed_prop1={`prop1_2`}" in rendered_c2["props"] - assert "subclass_prop2={`prop2_2`}" in rendered_c2["props"] - assert "renamed_prop3={`prop3_2`}" in rendered_c2["props"] + assert 'renamed_prop1={"prop1_2"}' in rendered_c2["props"] + assert 'subclass_prop2={"prop2_2"}' in rendered_c2["props"] + assert 'renamed_prop3={"prop3_2"}' in rendered_c2["props"] def test_deprecated_props(capsys): @@ -1625,9 +1633,9 @@ def test_deprecated_props(capsys): assert not out_err.out c1_1_render = c1_1.render() - assert "type={`type1`}" in c1_1_render["props"] - assert "min={`min1`}" in c1_1_render["props"] - assert "max={`max1`}" in c1_1_render["props"] + assert 'type={"type1"}' in c1_1_render["props"] + assert 'min={"min1"}' in c1_1_render["props"] + assert 'max={"max1"}' in c1_1_render["props"] # Deprecation warning is emitted with underscore suffix, # but the component still works. @@ -1637,9 +1645,9 @@ def test_deprecated_props(capsys): assert not out_err.err c1_2_render = c1_2.render() - assert "type={`type2`}" in c1_2_render["props"] - assert "min={`min2`}" in c1_2_render["props"] - assert "max={`max2`}" in c1_2_render["props"] + assert 'type={"type2"}' in c1_2_render["props"] + assert 'min={"min2"}' in c1_2_render["props"] + assert 'max={"max2"}' in c1_2_render["props"] class C2(Component): tag = "C2" @@ -1655,9 +1663,9 @@ def test_deprecated_props(capsys): assert not out_err.out c2_1_render = c2_1.render() - assert "type={`type1`}" in c2_1_render["props"] - assert "min={`min1`}" in c2_1_render["props"] - assert "max={`max1`}" in c2_1_render["props"] + assert 'type={"type1"}' in c2_1_render["props"] + assert 'min={"min1"}' in c2_1_render["props"] + assert 'max={"max1"}' in c2_1_render["props"] def test_custom_component_get_imports(): @@ -2007,11 +2015,11 @@ def test_add_style_embedded_vars(test_state: BaseState): Args: test_state: A test state. """ - v0 = Var.create_safe("parent")._replace( + v0 = LiteralVar.create("parent")._replace( merge_var_data=VarData(hooks={"useParent": None}), # type: ignore ) v1 = rx.color("plum", 10) - v2 = Var.create_safe("text")._replace( + v2 = LiteralVar.create("text")._replace( merge_var_data=VarData(hooks={"useText": None}), # type: ignore ) @@ -2044,7 +2052,7 @@ def test_add_style_embedded_vars(test_state: BaseState): assert "useParent" in page._get_all_hooks_internal() assert ( str(page).count( - f'css={{{{"fakeParent": "parent", "color": "var(--plum-10)", "fake": "text", "margin": `${{{test_state.get_name()}.num}}%`}}}}' + f'css={{({{ ["fakeParent"] : "parent", ["color"] : "var(--plum-10)", ["fake"] : "text", ["margin"] : ({test_state.get_name()}.num+"%") }})}}' ) == 1 ) @@ -2065,10 +2073,10 @@ def test_add_style_foreach(): assert len(page.children[0].children) == 1 # Expect the style to be added to the child of the foreach - assert 'css={{"color": "red"}}' in str(page.children[0].children[0]) + assert 'css={({ ["color"] : "red" })}' in str(page.children[0].children[0]) # Expect only one instance of this CSS dict in the rendered page - assert str(page).count('css={{"color": "red"}}') == 1 + assert str(page).count('css={({ ["color"] : "red" })}') == 1 class TriggerState(rx.State):