Ensure SpEL ternary and Elvis expressions are enclosed in parentheses in toStringAST()
Prior to this commit, ternary and Elvis expressions enclosed in parentheses (to account for operator precedence) were properly parsed and evaluated; however, the corresponding toStringAST() implementations did not enclose the results in parentheses. Consequently, the string representation of the ASTs did not reflect the original semantics of such expressions. For example, given "(4 % 2 == 0 ? 1 : 0) * 10" as the expression to parse and evaluate, the result of toStringAST() was previously "(((4 % 2) == 0) ? 1 : 0 * 10)" instead of "((((4 % 2) == 0) ? 1 : 0) * 10)", implying that 0 should be multiplied by 10 instead of multiplying the result of the ternary expression by 10. This commit addresses this by ensuring that SpEL ternary and Elvis expressions are enclosed in parentheses in toStringAST(). Closes gh-29463
This commit is contained in:
@@ -116,6 +116,10 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
void elvisOperator() {
|
||||
evaluate("'Andy'?:'Dave'", "Andy", String.class);
|
||||
evaluate("null?:'Dave'", "Dave", String.class);
|
||||
evaluate("3?:1", 3, Integer.class);
|
||||
evaluate("(2*3)?:1*10", 6, Integer.class);
|
||||
evaluate("null?:2*10", 20, Integer.class);
|
||||
evaluate("(null?:1)*10", 10, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -624,6 +628,24 @@ class EvaluationTests extends AbstractExpressionTests {
|
||||
evaluate("2>4?(3>2?true:false):(5<3?true:false)", false, Boolean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryOperator06() {
|
||||
evaluate("3?:#var=5", 3, Integer.class);
|
||||
evaluate("null?:#var=5", 5, Integer.class);
|
||||
evaluate("2>4?(3>2?true:false):(5<3?true:false)", false, Boolean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryExpressionWithImplicitGrouping() {
|
||||
evaluate("4 % 2 == 0 ? 2 : 3 * 10", 2, Integer.class);
|
||||
evaluate("4 % 2 == 1 ? 2 : 3 * 10", 30, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryExpressionWithExplicitGrouping() {
|
||||
evaluate("((4 % 2 == 0) ? 2 : 1) * 10", 20, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryOperatorWithNullValue() {
|
||||
assertThatExceptionOfType(EvaluationException.class).isThrownBy(
|
||||
|
||||
@@ -162,7 +162,9 @@ class ParsingTests {
|
||||
|
||||
@Test
|
||||
void elvis() {
|
||||
parseCheck("3?:1", "3 ?: 1");
|
||||
parseCheck("3?:1", "(3 ?: 1)");
|
||||
parseCheck("(2*3)?:1*10", "((2 * 3) ?: (1 * 10))");
|
||||
parseCheck("((2*3)?:1)*10", "(((2 * 3) ?: 1) * 10)");
|
||||
}
|
||||
|
||||
// void relOperatorsIn01() {
|
||||
@@ -404,13 +406,17 @@ class ParsingTests {
|
||||
|
||||
@Test
|
||||
void ternaryOperator01() {
|
||||
parseCheck("1>2?3:4", "(1 > 2) ? 3 : 4");
|
||||
parseCheck("1>2?3:4", "((1 > 2) ? 3 : 4)");
|
||||
parseCheck("(a ? 1 : 0) * 10", "((a ? 1 : 0) * 10)");
|
||||
parseCheck("(a?1:0)*10", "((a ? 1 : 0) * 10)");
|
||||
parseCheck("(4 % 2 == 0 ? 1 : 0) * 10", "((((4 % 2) == 0) ? 1 : 0) * 10)");
|
||||
parseCheck("((4 % 2 == 0) ? 1 : 0) * 10", "((((4 % 2) == 0) ? 1 : 0) * 10)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryOperator02() {
|
||||
parseCheck("{1}.#isEven(#this) == 'y'?'it is even':'it is odd'",
|
||||
"({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd'");
|
||||
"(({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd')");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user