diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 46fa41436..d79fc1e50 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -255,16 +255,20 @@ def format_cond( # Format prop conds. if is_prop: - prop1 = Var.create_safe( - true_value, - _var_is_string=type(true_value) is str, + if not isinstance(true_value, Var): + true_value = Var.create_safe( + true_value, + _var_is_string=type(true_value) is str, + ) + prop1 = true_value._replace( + _var_is_local=True, ) - prop1._var_is_local = True - prop2 = Var.create_safe( - false_value, - _var_is_string=type(false_value) is str, - ) - prop2._var_is_local = True + if not isinstance(false_value, Var): + false_value = Var.create_safe( + false_value, + _var_is_string=type(false_value) is str, + ) + prop2 = false_value._replace(_var_is_local=True) prop1, prop2 = str(prop1), str(prop2) # avoid f-string semantics for Var return f"{cond} ? {prop1} : {prop2}".replace("{", "").replace("}", "") diff --git a/tests/utils/test_format.py b/tests/utils/test_format.py index 8c62f734a..dee55886a 100644 --- a/tests/utils/test_format.py +++ b/tests/utils/test_format.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime from typing import Any, List @@ -276,22 +278,107 @@ def test_format_route(route: str, format_case: bool, expected: bool): @pytest.mark.parametrize( - "condition,true_value,false_value,expected", + "condition,true_value,false_value,is_prop,expected", [ - ("cond", "", '""', '{isTrue(cond) ? : ""}'), - ("cond", "", "", "{isTrue(cond) ? : }"), + ("cond", "", '""', False, '{isTrue(cond) ? : ""}'), + ("cond", "", "", False, "{isTrue(cond) ? : }"), + ( + "cond", + Var.create_safe(""), + "", + False, + "{isTrue(cond) ? : }", + ), + ( + "cond", + Var.create_safe(""), + Var.create_safe(""), + False, + "{isTrue(cond) ? : }", + ), + ( + "cond", + Var.create_safe("", _var_is_local=False), + Var.create_safe(""), + False, + "{isTrue(cond) ? ${} : }", + ), + ( + "cond", + Var.create_safe("", _var_is_string=True), + Var.create_safe(""), + False, + "{isTrue(cond) ? {``} : }", + ), + ("cond", "", '""', True, 'isTrue(cond) ? `` : `""`'), + ("cond", "", "", True, "isTrue(cond) ? `` : ``"), + ( + "cond", + Var.create_safe(""), + "", + True, + "isTrue(cond) ? : ``", + ), + ( + "cond", + Var.create_safe(""), + Var.create_safe(""), + True, + "isTrue(cond) ? : ", + ), + ( + "cond", + Var.create_safe("", _var_is_local=False), + Var.create_safe(""), + True, + "isTrue(cond) ? : ", + ), + ( + "cond", + Var.create_safe(""), + Var.create_safe("", _var_is_local=False), + True, + "isTrue(cond) ? : ", + ), + ( + "cond", + Var.create_safe("", _var_is_string=True), + Var.create_safe(""), + True, + "isTrue(cond) ? `` : ", + ), ], ) -def test_format_cond(condition: str, true_value: str, false_value: str, expected: str): +def test_format_cond( + condition: str, + true_value: str | Var, + false_value: str | Var, + is_prop: bool, + expected: str, +): """Test formatting a cond. Args: condition: The condition to check. true_value: The value to return if the condition is true. false_value: The value to return if the condition is false. + is_prop: Whether the values are rendered as props or not. expected: The expected output string. """ - assert format.format_cond(condition, true_value, false_value) == expected + orig_true_value = ( + true_value._replace() if isinstance(true_value, Var) else Var.create_safe("") + ) + orig_false_value = ( + false_value._replace() if isinstance(false_value, Var) else Var.create_safe("") + ) + + assert format.format_cond(condition, true_value, false_value, is_prop) == expected + + # Ensure the formatting operation didn't change the original Var + if isinstance(true_value, Var): + assert true_value.equals(orig_true_value) + if isinstance(false_value, Var): + assert false_value.equals(orig_false_value) @pytest.mark.parametrize(