1
0
Эх сурвалжийг харах

what if we simply didn't have match

Khaleel Al-Adhami 4 сар өмнө
parent
commit
94b4443afc

+ 4 - 4
reflex/components/core/banner.py

@@ -175,7 +175,7 @@ class ConnectionBanner(Component):
         Returns:
         Returns:
             The connection banner component.
             The connection banner component.
         """
         """
-        from reflex.components.base.bare import Bare
+        from reflex.components.base.fragment import Fragment
 
 
         if not comp:
         if not comp:
             comp = Flex.create(
             comp = Flex.create(
@@ -191,7 +191,7 @@ class ConnectionBanner(Component):
                 position="fixed",
                 position="fixed",
             )
             )
 
 
-        return Bare.create(cond(has_connection_errors, comp))
+        return Fragment.create(cond(has_connection_errors, comp))
 
 
 
 
 class ConnectionModal(Component):
 class ConnectionModal(Component):
@@ -207,11 +207,11 @@ class ConnectionModal(Component):
         Returns:
         Returns:
             The connection banner component.
             The connection banner component.
         """
         """
-        from reflex.components.base.bare import Bare
+        from reflex.components.base.fragment import Fragment
 
 
         if not comp:
         if not comp:
             comp = Text.create(*default_connection_error())
             comp = Text.create(*default_connection_error())
-        return Bare.create(
+        return Fragment.create(
             cond(
             cond(
                 has_too_many_connection_errors,
                 has_too_many_connection_errors,
                 DialogRoot.create(
                 DialogRoot.create(

+ 28 - 135
reflex/components/core/match.py

@@ -1,17 +1,14 @@
 """rx.match."""
 """rx.match."""
 
 
 import textwrap
 import textwrap
-from typing import Any, Dict, List, Optional, Tuple, Union
+from typing import Any, List, Optional, Sequence, Tuple, Union
 
 
 from reflex.components.base import Fragment
 from reflex.components.base import Fragment
 from reflex.components.component import BaseComponent, Component, MemoizationLeaf
 from reflex.components.component import BaseComponent, Component, MemoizationLeaf
-from reflex.components.tags import MatchTag, Tag
-from reflex.style import Style
-from reflex.utils import format, types
+from reflex.utils import types
 from reflex.utils.exceptions import MatchTypeError
 from reflex.utils.exceptions import MatchTypeError
-from reflex.utils.imports import ImportDict
-from reflex.vars import VarData
-from reflex.vars.base import LiteralVar, Var
+from reflex.vars.base import Var
+from reflex.vars.number import MatchOperation
 
 
 
 
 class Match(MemoizationLeaf):
 class Match(MemoizationLeaf):
@@ -40,43 +37,32 @@ class Match(MemoizationLeaf):
         Raises:
         Raises:
             ValueError: When a default case is not provided for cases with Var return types.
             ValueError: When a default case is not provided for cases with Var return types.
         """
         """
-        match_cond_var = cls._create_condition_var(cond)
-        cases, default = cls._process_cases(list(cases))
-        match_cases = cls._process_match_cases(cases)
+        cases, default = cls._process_cases(cases)
+        cls._process_match_cases(cases)
 
 
-        cls._validate_return_types(match_cases)
+        cls._validate_return_types(cases)
 
 
-        if default is None and types._issubclass(type(match_cases[0][-1]), Var):
+        if default is None and any(
+            not (
+                isinstance((return_type := case[-1]), Component)
+                or (
+                    isinstance(return_type, Var)
+                    and types.typehint_issubclass(return_type._var_type, Component)
+                )
+            )
+            for case in cases
+        ):
             raise ValueError(
             raise ValueError(
                 "For cases with return types as Vars, a default case must be provided"
                 "For cases with return types as Vars, a default case must be provided"
             )
             )
+        elif default is None:
+            default = Fragment.create()
 
 
-        return cls._create_match_cond_var_or_component(
-            match_cond_var, match_cases, default
-        )
-
-    @classmethod
-    def _create_condition_var(cls, cond: Any) -> Var:
-        """Convert the condition to a Var.
-
-        Args:
-            cond: The condition.
-
-        Returns:
-            The condition as a base var
-
-        Raises:
-            ValueError: If the condition is not provided.
-        """
-        match_cond_var = LiteralVar.create(cond)
-
-        if match_cond_var is None:
-            raise ValueError("The condition must be set")
-        return match_cond_var
+        return cls._create_match_cond_var_or_component(cond, cases, default)
 
 
     @classmethod
     @classmethod
     def _process_cases(
     def _process_cases(
-        cls, cases: List
+        cls, cases: Sequence
     ) -> Tuple[List, Optional[Union[Var, BaseComponent]]]:
     ) -> Tuple[List, Optional[Union[Var, BaseComponent]]]:
         """Process the list of match cases and the catchall default case.
         """Process the list of match cases and the catchall default case.
 
 
@@ -99,33 +85,13 @@ class Match(MemoizationLeaf):
 
 
         # Get the default case which should be the last non-tuple arg
         # Get the default case which should be the last non-tuple arg
         if not isinstance(cases[-1], tuple):
         if not isinstance(cases[-1], tuple):
-            default = cases.pop()
-            default = (
-                cls._create_case_var_with_var_data(default)
-                if not isinstance(default, BaseComponent)
-                else default
-            )
+            default = cases[-1]
+            cases = cases[:-1]
 
 
-        return cases, default
+        return list(cases), default
 
 
     @classmethod
     @classmethod
-    def _create_case_var_with_var_data(cls, case_element):
-        """Convert a case element into a Var.If the case
-        is a Style type, we extract the var data and merge it with the
-        newly created Var.
-
-        Args:
-            case_element: The case element.
-
-        Returns:
-            The case element Var.
-        """
-        _var_data = case_element._var_data if isinstance(case_element, Style) else None
-        case_element = LiteralVar.create(case_element, _var_data=_var_data)
-        return case_element
-
-    @classmethod
-    def _process_match_cases(cls, cases: List) -> List[List[Var]]:
+    def _process_match_cases(cls, cases: Sequence):
         """Process the individual match cases.
         """Process the individual match cases.
 
 
         Args:
         Args:
@@ -137,34 +103,18 @@ class Match(MemoizationLeaf):
         Raises:
         Raises:
             ValueError: If the default case is not the last case or the tuple elements are less than 2.
             ValueError: If the default case is not the last case or the tuple elements are less than 2.
         """
         """
-        match_cases = []
         for case in cases:
         for case in cases:
             if not isinstance(case, tuple):
             if not isinstance(case, tuple):
                 raise ValueError(
                 raise ValueError(
                     "rx.match should have tuples of cases and a default case as the last argument."
                     "rx.match should have tuples of cases and a default case as the last argument."
                 )
                 )
+
             # There should be at least two elements in a case tuple(a condition and return value)
             # There should be at least two elements in a case tuple(a condition and return value)
             if len(case) < 2:
             if len(case) < 2:
                 raise ValueError(
                 raise ValueError(
                     "A case tuple should have at least a match case element and a return value."
                     "A case tuple should have at least a match case element and a return value."
                 )
                 )
 
 
-            case_list = []
-            for element in case:
-                # convert all non component element to vars.
-                el = (
-                    cls._create_case_var_with_var_data(element)
-                    if not isinstance(element, BaseComponent)
-                    else element
-                )
-                if not isinstance(el, (Var, BaseComponent)):
-                    raise ValueError("Case element must be a var or component")
-                case_list.append(el)
-
-            match_cases.append(case_list)
-
-        return match_cases
-
     @classmethod
     @classmethod
     def _validate_return_types(cls, match_cases: List[List[Var]]) -> None:
     def _validate_return_types(cls, match_cases: List[List[Var]]) -> None:
         """Validate that match cases have the same return types.
         """Validate that match cases have the same return types.
@@ -202,7 +152,7 @@ class Match(MemoizationLeaf):
         cls,
         cls,
         match_cond_var: Var,
         match_cond_var: Var,
         match_cases: List[List[Var]],
         match_cases: List[List[Var]],
-        default: Optional[Union[Var, BaseComponent]],
+        default: Union[Var, BaseComponent],
     ) -> Union[Component, Var]:
     ) -> Union[Component, Var]:
         """Create and return the match condition var or component.
         """Create and return the match condition var or component.
 
 
@@ -217,64 +167,7 @@ class Match(MemoizationLeaf):
         Raises:
         Raises:
             ValueError: If the return types are not vars when creating a match var for Var types.
             ValueError: If the return types are not vars when creating a match var for Var types.
         """
         """
-        if default is None and types._issubclass(
-            type(match_cases[0][-1]), BaseComponent
-        ):
-            default = Fragment.create()
-
-        if types._issubclass(type(match_cases[0][-1]), BaseComponent):
-            return Fragment.create(
-                cls(
-                    cond=match_cond_var,
-                    match_cases=match_cases,
-                    default=default,
-                    children=[case[-1] for case in match_cases] + [default],  # type: ignore
-                )
-            )
-
-        # Validate the match cases (as well as the default case) to have Var return types.
-        if any(
-            case for case in match_cases if not types._isinstance(case[-1], Var)
-        ) or not types._isinstance(default, Var):
-            raise ValueError("Return types of match cases should be Vars.")
-
-        return Var(
-            _js_expr=format.format_match(
-                cond=str(match_cond_var),
-                match_cases=match_cases,
-                default=default,  # type: ignore
-            ),
-            _var_type=default._var_type,  # type: ignore
-            _var_data=VarData.merge(
-                match_cond_var._get_all_var_data(),
-                *[el._get_all_var_data() for case in match_cases for el in case],
-                default._get_all_var_data(),  # type: ignore
-            ),
-        )
-
-    def _render(self) -> Tag:
-        return MatchTag(
-            cond=self.cond, match_cases=self.match_cases, default=self.default
-        )
-
-    def render(self) -> Dict:
-        """Render the component.
-
-        Returns:
-            The dictionary for template of component.
-        """
-        tag = self._render()
-        tag.name = "match"
-        return dict(tag)
-
-    def add_imports(self) -> ImportDict:
-        """Add imports for the Match component.
-
-        Returns:
-            The import dict.
-        """
-        var_data = VarData.merge(self.cond._get_all_var_data())
-        return var_data.old_school_imports() if var_data else {}
+        return MatchOperation.create(match_cond_var, match_cases, default)
 
 
 
 
 match = Match.create
 match = Match.create

+ 125 - 1
reflex/vars/number.py

@@ -7,18 +7,30 @@ import functools
 import json
 import json
 import math
 import math
 import sys
 import sys
-from typing import TYPE_CHECKING, Any, Callable, NoReturn, TypeVar, Union, overload
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Callable,
+    NoReturn,
+    Sequence,
+    TypeVar,
+    Union,
+    overload,
+)
 
 
 from reflex.constants.base import Dirs
 from reflex.constants.base import Dirs
 from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
 from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
 from reflex.utils.imports import ImportDict, ImportVar
 from reflex.utils.imports import ImportDict, ImportVar
 
 
 from .base import (
 from .base import (
+    VAR_TYPE,
+    CachedVarOperation,
     CustomVarOperationReturn,
     CustomVarOperationReturn,
     LiteralVar,
     LiteralVar,
     ReflexCallable,
     ReflexCallable,
     Var,
     Var,
     VarData,
     VarData,
+    cached_property_no_lock,
     nary_type_computer,
     nary_type_computer,
     passthrough_unary_type_computer,
     passthrough_unary_type_computer,
     unionize,
     unionize,
@@ -1056,4 +1068,116 @@ def ternary_operation(
     return value
     return value
 
 
 
 
+TUPLE_ENDS_IN_VAR = (
+    tuple[Var[VAR_TYPE]]
+    | tuple[Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]]
+    | tuple[
+        Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var, Var[VAR_TYPE]
+    ]
+)
+
+
+@dataclasses.dataclass(
+    eq=False,
+    frozen=True,
+    **{"slots": True} if sys.version_info >= (3, 10) else {},
+)
+class MatchOperation(CachedVarOperation, Var[VAR_TYPE]):
+    """Base class for immutable match operations."""
+
+    _cond: Var[bool] = dataclasses.field(
+        default_factory=lambda: LiteralBooleanVar.create(True)
+    )
+    _cases: tuple[TUPLE_ENDS_IN_VAR[VAR_TYPE], ...] = dataclasses.field(
+        default_factory=tuple
+    )
+    _default: Var[VAR_TYPE] = dataclasses.field(
+        default_factory=lambda: Var.create(None)
+    )
+
+    @cached_property_no_lock
+    def _cached_var_name(self) -> str:
+        """Get the name of the var.
+
+        Returns:
+            The name of the var.
+        """
+        switch_code = f"(() => {{ switch (JSON.stringify({self._cond!s})) {{"
+
+        for case in self._cases:
+            conditions = case[:-1]
+            return_value = case[-1]
+
+            case_conditions = " ".join(
+                [f"case JSON.stringify({condition!s}):" for condition in conditions]
+            )
+            case_code = f"{case_conditions}  return ({return_value!s});  break;"
+            switch_code += case_code
+
+        switch_code += f"default:  return ({self._default!s});  break;"
+        switch_code += "};})()"
+
+        return switch_code
+
+    @cached_property_no_lock
+    def _cached_get_all_var_data(self) -> VarData | None:
+        """Get the VarData for the var.
+
+        Returns:
+            The VarData for the var.
+        """
+        return VarData.merge(
+            self._cond._get_all_var_data(),
+            *(
+                case._get_all_var_data()
+                for cond_or_return in self._cases
+                for case in cond_or_return
+            ),
+            self._default._get_all_var_data(),
+            self._var_data,
+        )
+
+    @classmethod
+    def create(
+        cls,
+        cond: Any,
+        cases: Sequence[Sequence[Any | Var[VAR_TYPE]]],
+        default: Var[VAR_TYPE] | VAR_TYPE,
+        _var_data: VarData | None = None,
+        _var_type: type[VAR_TYPE] | None = None,
+    ):
+        """Create the match operation.
+
+        Args:
+            cond: The condition.
+            cases: The cases.
+            default: The default case.
+            _var_data: Additional hooks and imports associated with the Var.
+            _var_type: The type of the Var.
+
+        Returns:
+            The match operation.
+        """
+        cases = tuple(tuple(Var.create(c) for c in case) for case in cases)
+        return cls(
+            _js_expr="",
+            _var_data=_var_data,
+            _var_type=_var_type,
+            _cond=Var.create(cond),
+            _cases=cases,
+            _default=Var.create(default),
+        )
+
+
 NUMBER_TYPES = (int, float, NumberVar)
 NUMBER_TYPES = (int, float, NumberVar)

+ 3 - 3
tests/units/components/core/test_colors.py

@@ -39,7 +39,7 @@ def create_color_var(color):
             create_color_var(
             create_color_var(
                 rx.color(ColorState.color, ColorState.shade, ColorState.alpha)  # type: ignore
                 rx.color(ColorState.color, ColorState.shade, ColorState.alpha)  # type: ignore
             ),
             ),
-            f'("var(--"+{color_state_name!s}.color+"-"+({color_state_name!s}.alpha ? "a" : "")+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")',
+            f'("var(--"+{color_state_name!s}.color+"-"+(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))({color_state_name!s}.alpha, "a", ""))+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")',
             Color,
             Color,
         ),
         ),
         (
         (
@@ -78,11 +78,11 @@ def test_color(color, expected, expected_type: Union[Type[str], Type[Color]]):
     [
     [
         (
         (
             rx.cond(True, rx.color("mint"), rx.color("tomato", 5)),
             rx.cond(True, rx.color("mint"), rx.color("tomato", 5)),
-            '(true ? "var(--mint-7)" : "var(--tomato-5)")',
+            '((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))(true, (() => "var(--mint-7)"), (() => "var(--tomato-5)")))())',
         ),
         ),
         (
         (
             rx.cond(True, rx.color(ColorState.color), rx.color(ColorState.color, 5)),  # type: ignore
             rx.cond(True, rx.color(ColorState.color), rx.color(ColorState.color, 5)),  # type: ignore
-            f'(true ? ("var(--"+{color_state_name!s}.color+"-7)") : ("var(--"+{color_state_name!s}.color+"-5)"))',
+            f'((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))(true, (() => ("var(--"+{color_state_name!s}.color+"-7)")), (() => ("var(--"+{color_state_name!s}.color+"-5)"))))())',
         ),
         ),
         (
         (
             rx.match(
             rx.match(

+ 1 - 1
tests/units/components/core/test_foreach.py

@@ -128,7 +128,7 @@ def display_colors_set(color):
 def display_nested_list_element(
 def display_nested_list_element(
     element: ArrayVar[Sequence[str]], index: NumberVar[int]
     element: ArrayVar[Sequence[str]], index: NumberVar[int]
 ):
 ):
-    assert element._var_type == Sequence[str]
+    assert element._var_type == List[str]
     assert index._var_type is int
     assert index._var_type is int
     return box(text(element[index]))
     return box(text(element[index]))
 
 

+ 7 - 77
tests/units/components/core/test_match.py

@@ -1,4 +1,4 @@
-from typing import Dict, List, Tuple
+from typing import Tuple
 
 
 import pytest
 import pytest
 
 
@@ -17,73 +17,6 @@ class MatchState(BaseState):
     string: str = "random string"
     string: str = "random string"
 
 
 
 
-def test_match_components():
-    """Test matching cases with return values as components."""
-    match_case_tuples = (
-        (1, rx.text("first value")),
-        (2, 3, rx.text("second value")),
-        ([1, 2], rx.text("third value")),
-        ("random", rx.text("fourth value")),
-        ({"foo": "bar"}, rx.text("fifth value")),
-        (MatchState.num + 1, rx.text("sixth value")),
-        rx.text("default value"),
-    )
-    match_comp = Match.create(MatchState.value, *match_case_tuples)
-    match_dict = match_comp.render()  # type: ignore
-    assert match_dict["name"] == "Fragment"
-
-    [match_child] = match_dict["children"]
-
-    assert match_child["name"] == "match"
-    assert str(match_child["cond"]) == f"{MatchState.get_name()}.value"
-
-    match_cases = match_child["match_cases"]
-    assert len(match_cases) == 6
-
-    assert match_cases[0][0]._js_expr == "1"
-    assert match_cases[0][0]._var_type is 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 match_cases[1][0]._js_expr == "2"
-    assert match_cases[1][0]._var_type is int
-    assert match_cases[1][1]._js_expr == "3"
-    assert match_cases[1][1]._var_type is 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 match_cases[2][0]._js_expr == "[1, 2]"
-    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 match_cases[3][0]._js_expr == '"random"'
-    assert match_cases[3][0]._var_type is 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 match_cases[4][0]._js_expr == '({ ["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 match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)"
-    assert match_cases[5][0]._var_type is 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"}'
-
-    default = match_child["default"].render()
-
-    assert default["name"] == "RadixThemesText"
-    assert default["children"][0]["contents"] == '{"default value"}'
-
-
 @pytest.mark.parametrize(
 @pytest.mark.parametrize(
     "cases, expected",
     "cases, expected",
     [
     [
@@ -102,7 +35,7 @@ def test_match_components():
             f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1):  return ("first");  break;case JSON.stringify(2): case JSON.stringify(3):  return '
             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"):  '
             '("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");  '
             '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'break;case JSON.stringify((((_lhs, _rhs) => (_lhs + _rhs))({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;case JSON.stringify({MatchState.get_name()}.string):  return (({MatchState.get_name()}.value+" - string"));  break;default:  '
             'return ("default value");  break;};})()',
             'return ("default value");  break;};})()',
         ),
         ),
@@ -121,7 +54,7 @@ def test_match_components():
             f'(() => {{ switch (JSON.stringify({MatchState.get_name()}.value)) {{case JSON.stringify(1):  return ("first");  break;case JSON.stringify(2): case JSON.stringify(3):  return '
             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"):  '
             '("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");  '
             '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'break;case JSON.stringify((((_lhs, _rhs) => (_lhs + _rhs))({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;case JSON.stringify({MatchState.get_name()}.string):  return (({MatchState.get_name()}.value+" - string"));  break;default:  '
             f"return ({MatchState.get_name()}.string);  break;}};}})()",
             f"return ({MatchState.get_name()}.string);  break;}};}})()",
         ),
         ),
@@ -143,17 +76,14 @@ def test_match_on_component_without_default():
     """Test that matching cases with return values as components returns a Fragment
     """Test that matching cases with return values as components returns a Fragment
     as the default case if not provided.
     as the default case if not provided.
     """
     """
-    from reflex.components.base.fragment import Fragment
-
     match_case_tuples = (
     match_case_tuples = (
         (1, rx.text("first value")),
         (1, rx.text("first value")),
         (2, 3, rx.text("second value")),
         (2, 3, rx.text("second value")),
     )
     )
 
 
     match_comp = Match.create(MatchState.value, *match_case_tuples)
     match_comp = Match.create(MatchState.value, *match_case_tuples)
-    default = match_comp.render()["children"][0]["default"]  # type: ignore
 
 
-    assert isinstance(default, Fragment)
+    assert isinstance(match_comp, Var)
 
 
 
 
 def test_match_on_var_no_default():
 def test_match_on_var_no_default():
@@ -247,8 +177,8 @@ def test_match_case_tuple_elements(match_case):
                 (MatchState.num + 1, "black"),
                 (MatchState.num + 1, "black"),
                 rx.text("default value"),
                 rx.text("default value"),
             ),
             ),
-            'Match cases should have the same return types. Case 3 with return value `"red"` of type '
-            "<class 'reflex.vars.sequence.LiteralStringVar'> is not <class 'reflex.components.component.BaseComponent'>",
+            "Match cases should have the same return types. Case 3 with return value `red` of type "
+            "<class 'str'> is not <class 'reflex.components.component.BaseComponent'>",
         ),
         ),
         (
         (
             (
             (
@@ -261,7 +191,7 @@ def test_match_case_tuple_elements(match_case):
                 rx.text("default value"),
                 rx.text("default value"),
             ),
             ),
             'Match cases should have the same return types. Case 3 with return value `<RadixThemesText as={"p"}> {"first value"} </RadixThemesText>` '
             'Match cases should have the same return types. Case 3 with return value `<RadixThemesText as={"p"}> {"first value"} </RadixThemesText>` '
-            "of type <class 'reflex.components.radix.themes.typography.text.Text'> is not <class 'reflex.vars.base.Var'>",
+            "of type <class 'reflex.components.radix.themes.typography.text.Text'> is not <class 'str'>",
         ),
         ),
     ],
     ],
 )
 )

+ 4 - 4
tests/units/components/markdown/test_markdown.py

@@ -148,7 +148,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
         (
         (
             "code",
             "code",
             {},
             {},
-            """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';   if (_language) {     (async () => {       try {         const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`);         SyntaxHighlighter.registerLanguage(_language, module.default);       } catch (error) {         console.error(`Error importing language module for ${_language}:`, error);       }     })();   }  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <SyntaxHighlighter children={((Array.isArray(children)) ? children.join("\\n") : children)} css={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} customStyle={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} language={_language} style={((resolvedColorMode === "light") ? oneLight : oneDark)} wrapLongLines={true} {...props}/>             );         })""",
+            '(({node, inline, className, children, ...props}) => { const match = (className || \'\').match(/language-(?<lang>.*)/); const _language = match ? match[1] : \'\';   if (_language) {     (async () => {       try {         const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`);         SyntaxHighlighter.registerLanguage(_language, module.default);       } catch (error) {         console.error(`Error importing language module for ${_language}:`, error);       }     })();   }  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <SyntaxHighlighter children={(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} css={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} customStyle={({ ["marginTop"] : "1em", ["marginBottom"] : "1em" })} language={_language} style={((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((((_lhs, _rhs) => (_lhs === _rhs))(resolvedColorMode, "light")), (() => oneLight), (() => oneDark)))())} wrapLongLines={true} {...props}/>             );         })',
         ),
         ),
         (
         (
             "code",
             "code",
@@ -157,7 +157,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
                     value, **props
                     value, **props
                 )
                 )
             },
             },
-            """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <RadixThemesBox css={({ ["pre"] : ({ ["margin"] : "0", ["padding"] : "24px", ["background"] : "transparent", ["overflow-x"] : "auto", ["border-radius"] : "6px" }) })} {...props}><ShikiCode code={((Array.isArray(children)) ? children.join("\\n") : children)} decorations={[]} language={_language} theme={((resolvedColorMode === "light") ? "one-light" : "one-dark-pro")} transformers={[]}/></RadixThemesBox>             );         })""",
+            '(({node, inline, className, children, ...props}) => { const match = (className || \'\').match(/language-(?<lang>.*)/); const _language = match ? match[1] : \'\';  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <RadixThemesBox css={({ ["pre"] : ({ ["margin"] : "0", ["padding"] : "24px", ["background"] : "transparent", ["overflow-x"] : "auto", ["border-radius"] : "6px" }) })} {...props}><ShikiCode code={(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} decorations={[]} language={_language} theme={((((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((((_lhs, _rhs) => (_lhs === _rhs))(resolvedColorMode, "light")), (() => "one-light"), (() => "one-dark-pro")))())} transformers={[]}/></RadixThemesBox>             );         })',
         ),
         ),
         (
         (
             "h1",
             "h1",
@@ -171,7 +171,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
         (
         (
             "code",
             "code",
             {"codeblock": syntax_highlighter_memoized_component(CodeBlock)},
             {"codeblock": syntax_highlighter_memoized_component(CodeBlock)},
-            """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';   if (_language) {     (async () => {       try {         const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`);         SyntaxHighlighter.registerLanguage(_language, module.default);       } catch (error) {         console.error(`Error importing language module for ${_language}:`, error);       }     })();   }  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <CodeBlock code={((Array.isArray(children)) ? children.join("\\n") : children)} language={_language} {...props}/>             );         })""",
+            "(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';   if (_language) {     (async () => {       try {         const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`);         SyntaxHighlighter.registerLanguage(_language, module.default);       } catch (error) {         console.error(`Error importing language module for ${_language}:`, error);       }     })();   }  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <CodeBlock code={(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = \"\") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))(\"\\n\")), children))} language={_language} {...props}/>             );         })",
         ),
         ),
         (
         (
             "code",
             "code",
@@ -180,7 +180,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
                     ShikiHighLevelCodeBlock
                     ShikiHighLevelCodeBlock
                 )
                 )
             },
             },
-            """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <CodeBlock code={((Array.isArray(children)) ? children.join("\\n") : children)} language={_language} {...props}/>             );         })""",
+            """(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?<lang>.*)/); const _language = match ? match[1] : '';  ;             return inline ? (                 <RadixThemesCode {...props}>{children}</RadixThemesCode>             ) : (                 <CodeBlock code={(((_condition, _if_true, _if_false) => (_condition ? _if_true : _if_false))((Array.isArray(children)), (((...args) => (((_array, _sep = "") => Array.prototype.join.apply(_array,[_sep]))(children, ...args)))("\\n")), children))} language={_language} {...props}/>             );         })""",
         ),
         ),
     ],
     ],
 )
 )