what if we simply didn't have match
This commit is contained in:
parent
f9d45d5562
commit
94b4443afc
@ -175,7 +175,7 @@ class ConnectionBanner(Component):
|
||||
Returns:
|
||||
The connection banner component.
|
||||
"""
|
||||
from reflex.components.base.bare import Bare
|
||||
from reflex.components.base.fragment import Fragment
|
||||
|
||||
if not comp:
|
||||
comp = Flex.create(
|
||||
@ -191,7 +191,7 @@ class ConnectionBanner(Component):
|
||||
position="fixed",
|
||||
)
|
||||
|
||||
return Bare.create(cond(has_connection_errors, comp))
|
||||
return Fragment.create(cond(has_connection_errors, comp))
|
||||
|
||||
|
||||
class ConnectionModal(Component):
|
||||
@ -207,11 +207,11 @@ class ConnectionModal(Component):
|
||||
Returns:
|
||||
The connection banner component.
|
||||
"""
|
||||
from reflex.components.base.bare import Bare
|
||||
from reflex.components.base.fragment import Fragment
|
||||
|
||||
if not comp:
|
||||
comp = Text.create(*default_connection_error())
|
||||
return Bare.create(
|
||||
return Fragment.create(
|
||||
cond(
|
||||
has_too_many_connection_errors,
|
||||
DialogRoot.create(
|
||||
|
@ -1,17 +1,14 @@
|
||||
"""rx.match."""
|
||||
|
||||
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.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.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):
|
||||
@ -40,43 +37,32 @@ class Match(MemoizationLeaf):
|
||||
Raises:
|
||||
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(
|
||||
"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
|
||||
def _process_cases(
|
||||
cls, cases: List
|
||||
cls, cases: Sequence
|
||||
) -> Tuple[List, Optional[Union[Var, BaseComponent]]]:
|
||||
"""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
|
||||
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
|
||||
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.
|
||||
|
||||
Args:
|
||||
@ -137,34 +103,18 @@ class Match(MemoizationLeaf):
|
||||
Raises:
|
||||
ValueError: If the default case is not the last case or the tuple elements are less than 2.
|
||||
"""
|
||||
match_cases = []
|
||||
for case in cases:
|
||||
if not isinstance(case, tuple):
|
||||
raise ValueError(
|
||||
"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)
|
||||
if len(case) < 2:
|
||||
raise ValueError(
|
||||
"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
|
||||
def _validate_return_types(cls, match_cases: List[List[Var]]) -> None:
|
||||
"""Validate that match cases have the same return types.
|
||||
@ -202,7 +152,7 @@ class Match(MemoizationLeaf):
|
||||
cls,
|
||||
match_cond_var: Var,
|
||||
match_cases: List[List[Var]],
|
||||
default: Optional[Union[Var, BaseComponent]],
|
||||
default: Union[Var, BaseComponent],
|
||||
) -> Union[Component, Var]:
|
||||
"""Create and return the match condition var or component.
|
||||
|
||||
@ -217,64 +167,7 @@ class Match(MemoizationLeaf):
|
||||
Raises:
|
||||
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
|
||||
|
@ -7,18 +7,30 @@ import functools
|
||||
import json
|
||||
import math
|
||||
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.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
|
||||
from reflex.utils.imports import ImportDict, ImportVar
|
||||
|
||||
from .base import (
|
||||
VAR_TYPE,
|
||||
CachedVarOperation,
|
||||
CustomVarOperationReturn,
|
||||
LiteralVar,
|
||||
ReflexCallable,
|
||||
Var,
|
||||
VarData,
|
||||
cached_property_no_lock,
|
||||
nary_type_computer,
|
||||
passthrough_unary_type_computer,
|
||||
unionize,
|
||||
@ -1056,4 +1068,116 @@ def ternary_operation(
|
||||
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)
|
||||
|
@ -39,7 +39,7 @@ def create_color_var(color):
|
||||
create_color_var(
|
||||
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,
|
||||
),
|
||||
(
|
||||
@ -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)),
|
||||
'(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
|
||||
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(
|
||||
|
@ -128,7 +128,7 @@ def display_colors_set(color):
|
||||
def display_nested_list_element(
|
||||
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
|
||||
return box(text(element[index]))
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Dict, List, Tuple
|
||||
from typing import Tuple
|
||||
|
||||
import pytest
|
||||
|
||||
@ -17,73 +17,6 @@ class MatchState(BaseState):
|
||||
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(
|
||||
"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 '
|
||||
'("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'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: '
|
||||
'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 '
|
||||
'("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'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;}};}})()",
|
||||
),
|
||||
@ -143,17 +76,14 @@ def test_match_on_component_without_default():
|
||||
"""Test that matching cases with return values as components returns a Fragment
|
||||
as the default case if not provided.
|
||||
"""
|
||||
from reflex.components.base.fragment import Fragment
|
||||
|
||||
match_case_tuples = (
|
||||
(1, rx.text("first value")),
|
||||
(2, 3, rx.text("second value")),
|
||||
)
|
||||
|
||||
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():
|
||||
@ -247,8 +177,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 '
|
||||
"<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"),
|
||||
),
|
||||
'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'>",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -148,7 +148,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
|
||||
(
|
||||
"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",
|
||||
@ -157,7 +157,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
|
||||
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",
|
||||
@ -171,7 +171,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
|
||||
(
|
||||
"code",
|
||||
{"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",
|
||||
@ -180,7 +180,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe
|
||||
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}/> ); })""",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user