mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:39:29 +00:00
Polish SpEl Ternary operator and compilation tests
This commit is contained in:
+10
-8
@@ -51,12 +51,12 @@ public class Ternary extends SpelNodeImpl {
|
||||
*/
|
||||
@Override
|
||||
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
||||
Boolean value = this.children[0].getValue(state, Boolean.class);
|
||||
if (value == null) {
|
||||
Boolean condition = this.children[0].getValue(state, Boolean.class);
|
||||
if (condition == null) {
|
||||
throw new SpelEvaluationException(getChild(0).getStartPosition(),
|
||||
SpelMessage.TYPE_CONVERSION_ERROR, "null", "boolean");
|
||||
}
|
||||
TypedValue result = this.children[value ? 1 : 2].getValueInternal(state);
|
||||
TypedValue result = this.children[condition ? 1 : 2].getValueInternal(state);
|
||||
computeExitTypeDescriptor();
|
||||
return result;
|
||||
}
|
||||
@@ -67,10 +67,9 @@ public class Ternary extends SpelNodeImpl {
|
||||
}
|
||||
|
||||
private void computeExitTypeDescriptor() {
|
||||
if (this.exitTypeDescriptor == null && this.children[1].exitTypeDescriptor != null &&
|
||||
this.children[2].exitTypeDescriptor != null) {
|
||||
String leftDescriptor = this.children[1].exitTypeDescriptor;
|
||||
String rightDescriptor = this.children[2].exitTypeDescriptor;
|
||||
String leftDescriptor = this.children[1].exitTypeDescriptor;
|
||||
String rightDescriptor = this.children[2].exitTypeDescriptor;
|
||||
if (this.exitTypeDescriptor == null && leftDescriptor != null && rightDescriptor != null) {
|
||||
if (ObjectUtils.nullSafeEquals(leftDescriptor, rightDescriptor)) {
|
||||
this.exitTypeDescriptor = leftDescriptor;
|
||||
}
|
||||
@@ -93,7 +92,10 @@ public class Ternary extends SpelNodeImpl {
|
||||
|
||||
@Override
|
||||
public void generateCode(MethodVisitor mv, CodeFlow cf) {
|
||||
// May reach here without it computed if all elements are literals
|
||||
// If all elements are literals and the expression was not previously
|
||||
// evaluated in interpreted mode, we may get here without the exit descriptor
|
||||
// having been computed, so we must ensure the exit descriptor has been
|
||||
// computed before proceeding.
|
||||
computeExitTypeDescriptor();
|
||||
cf.enterCompilationScope();
|
||||
this.children[0].generateCode(mv, cf);
|
||||
|
||||
+312
-283
@@ -1278,6 +1278,318 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class TernaryTests {
|
||||
|
||||
@Test
|
||||
void ternaryWithTrueConditionAndLiteralsOfSameType() {
|
||||
// True condition and two literals of the same type
|
||||
expression = parser.parseExpression("true ? 'a' : 'b'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryWithFalseConditionAndLiteralsOfSameType() {
|
||||
// False condition and two literals of the same type
|
||||
expression = parser.parseExpression("false ? 'a' : 'b'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("b");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("b");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryWithFalseConditionAndLiteralsOfDifferentTypes() {
|
||||
// False condition and two literals of different types
|
||||
expression = parser.parseExpression("false ? 1 : 'b'");
|
||||
// All literals, so we can compile immediately without having previously
|
||||
// evaluated the expression.
|
||||
assertCanCompile(expression);
|
||||
assertIsCompiled(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("b");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryWithRootVariableAccess() {
|
||||
boolean root = true;
|
||||
expression = parser.parseExpression("(#root and true) ? T(Integer).valueOf(1) : T(Long).valueOf(3L)");
|
||||
assertThat(expression.getValue(root)).isEqualTo(1);
|
||||
assertCannotCompile(expression); // Have not gone down false branch yet
|
||||
|
||||
root = false;
|
||||
assertThat(expression.getValue(root)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(root)).isEqualTo(3L);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
|
||||
root = true;
|
||||
assertThat(expression.getValue(root)).isEqualTo(1);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryWithMapAccess() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
|
||||
expression = parser.parseExpression(
|
||||
"record.get('abc') == null ? record.put('abc', expression.someLong?.longValue()) : null");
|
||||
|
||||
RecordHolder rh = new RecordHolder();
|
||||
rh.expression.someLong = 6L;
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(rh.get("abc")).isEqualTo(6L);
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertCanCompile(expression);
|
||||
|
||||
rh = new RecordHolder();
|
||||
rh.expression.someLong = 6L;
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(rh.get("abc")).isEqualTo(6L);
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
}
|
||||
|
||||
@Test // gh-16876
|
||||
void ternaryWithBooleanWrapperCondition() {
|
||||
expression = parser.parseExpression("T(Boolean).TRUE ? 'abc' : 'def'");
|
||||
assertThat(expression.getValue()).isEqualTo("abc");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("abc");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("T(Boolean).FALSE ? 'abc' : 'def'");
|
||||
assertThat(expression.getValue()).isEqualTo("def");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("def");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test // gh-19758
|
||||
void ternaryMiscellaneous() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
Expression exp;
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("map", Map.of("foo", "qux"));
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'] != null ? #map['foo'] : 'qux')");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 == 3 ? 3 : 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 != 3 ? 3 : 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a double slot primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 == 3 ? 3L : 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 != 3 ? 3L : 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is an empty string
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("'' == '' ? 'abc' : 4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("abc");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("abc");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// null condition
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 == 3 ? null : 4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isNull();
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isNull();
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x == #x ? 50 : 'foo'");
|
||||
context.setVariable("x", 50);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning null
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x != #x ? 50 : 'foo'");
|
||||
context.setVariable("x", null);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning array
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x == #x ? 99 : 'foo'");
|
||||
context.setVariable("x", new int[] { 1, 2, 3 });
|
||||
assertThat(exp.getValue(context, new Foo(), Integer.class)).isEqualTo(99);
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), Integer.class)).isEqualTo(99);
|
||||
assertIsCompiled(exp);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ElvisTests {
|
||||
|
||||
@Test
|
||||
void elvis() {
|
||||
expression = parser.parseExpression("'a' ?: 'b'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("null ?: 'a'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
|
||||
String root = "abc";
|
||||
expression = parser.parseExpression("#root ?: 'b'");
|
||||
assertCannotCompile(expression);
|
||||
assertThat(expression.getValue(root, String.class)).isEqualTo("abc");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(root, String.class)).isEqualTo("abc");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test // gh-19758
|
||||
void elvisMiscellaneous() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
Expression exp;
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar()");
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAR");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAR");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar('baz')");
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAZ");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAZ");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("map", Collections.singletonMap("foo", "qux"));
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'])");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'] ?: 'qux')");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3 ?: 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a double slot primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3L ?: 'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is an empty string
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("'' ?: 4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// null condition
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("null ?: 4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x ?: 'foo'");
|
||||
context.setVariable("x",50);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x ?: 'foo'");
|
||||
context.setVariable("x",null);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning array
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x ?: 'foo'");
|
||||
context.setVariable("x",new int[]{1,2,3});
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertIsCompiled(exp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void elvis_SPR17214() {
|
||||
SpelParserConfiguration spc = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelExpressionParser sep = new SpelExpressionParser(spc);
|
||||
|
||||
RecordHolder rh = null;
|
||||
|
||||
expression = sep.parseExpression("record.get('abc') ?: record.put('abc', expression.someLong?.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
|
||||
expression = sep.parseExpression("record.get('abc') ?: record.put('abc', 3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
|
||||
expression = sep.parseExpression("record.get('abc') ?: record.put('abc', 3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class PropertyVisibilityTests {
|
||||
|
||||
@@ -2054,59 +2366,6 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
assertThat(expression.getValue(b)).asInstanceOf(BOOLEAN).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternary() {
|
||||
expression = parser.parseExpression("true?'a':'b'");
|
||||
String resultI = expression.getValue(String.class);
|
||||
assertCanCompile(expression);
|
||||
String resultC = expression.getValue(String.class);
|
||||
assertThat(resultI).isEqualTo("a");
|
||||
assertThat(resultC).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("false?'a':'b'");
|
||||
resultI = expression.getValue(String.class);
|
||||
assertCanCompile(expression);
|
||||
resultC = expression.getValue(String.class);
|
||||
assertThat(resultI).isEqualTo("b");
|
||||
assertThat(resultC).isEqualTo("b");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("false?1:'b'");
|
||||
// All literals so we can do this straight away
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("b");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
|
||||
boolean root = true;
|
||||
expression = parser.parseExpression("(#root and true)?T(Integer).valueOf(1):T(Long).valueOf(3L)");
|
||||
assertThat(expression.getValue(root)).isEqualTo(1);
|
||||
assertCannotCompile(expression); // Have not gone down false branch
|
||||
root = false;
|
||||
assertThat(expression.getValue(root)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(root)).isEqualTo(3L);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
root = true;
|
||||
assertThat(expression.getValue(root)).isEqualTo(1);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
}
|
||||
|
||||
@Test // gh-16876
|
||||
void ternaryWithBooleanWrapperCondition() {
|
||||
expression = parser.parseExpression("T(Boolean).TRUE?'abc':'def'");
|
||||
assertThat(expression.getValue()).isEqualTo("abc");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("abc");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("T(Boolean).FALSE?'abc':'def'");
|
||||
assertThat(expression.getValue()).isEqualTo("def");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue()).isEqualTo("def");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullsafeFieldPropertyDereferencing_SPR16489() {
|
||||
FooObjectHolder foh = new FooObjectHolder();
|
||||
@@ -2294,30 +2553,6 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
assertThat(expression.getValue(context)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void elvis() {
|
||||
expression = parser.parseExpression("'a' ?: 'b'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
|
||||
expression = parser.parseExpression("null ?: 'a'");
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(String.class)).isEqualTo("a");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
|
||||
String root = "abc";
|
||||
expression = parser.parseExpression("#root ?: 'b'");
|
||||
assertCannotCompile(expression);
|
||||
assertThat(expression.getValue(root, String.class)).isEqualTo("abc");
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(root, String.class)).isEqualTo("abc");
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
|
||||
public static String concat(String a, String b) {
|
||||
return a + b;
|
||||
}
|
||||
@@ -6065,138 +6300,6 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
assertThat(expression.getValue(root)).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void elvisOperator_SPR15192() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
Expression exp;
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar()");
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAR");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAR");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar('baz')");
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAZ");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(new Foo(), String.class)).isEqualTo("BAZ");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("map", Collections.singletonMap("foo", "qux"));
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'])");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'] ?: 'qux')");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3?:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a double slot primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3L?:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is an empty string
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("''?:4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// null condition
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("null?:4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("4");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x?:'foo'");
|
||||
context.setVariable("x",50);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x?:'foo'");
|
||||
context.setVariable("x",null);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning array
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x?:'foo'");
|
||||
context.setVariable("x",new int[]{1,2,3});
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertIsCompiled(exp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void elvisOperator_SPR17214() {
|
||||
SpelParserConfiguration spc = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelExpressionParser sep = new SpelExpressionParser(spc);
|
||||
|
||||
RecordHolder rh = null;
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',expression.someLong?.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(expression.getValue(rh)).isEqualTo(3L);
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')==null?record.put('abc',expression.someLong?.longValue()):null");
|
||||
rh = new RecordHolder();
|
||||
rh.expression.someLong=6L;
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(rh.get("abc")).isEqualTo(6L);
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
rh.expression.someLong=6L;
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
assertThat(rh.get("abc")).isEqualTo(6L);
|
||||
assertThat(expression.getValue(rh)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullComparison_SPR22358() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null);
|
||||
@@ -6278,80 +6381,6 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void ternaryOperator_SPR15192() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
Expression exp;
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("map", Collections.singletonMap("foo", "qux"));
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("bar(#map['foo'] != null ? #map['foo'] : 'qux')");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("QUX");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3==3?3:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3!=3?3:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is a double slot primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3==3?3L:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("3");
|
||||
assertIsCompiled(exp);
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3!=3?3L:'foo'");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// When the condition is an empty string
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("''==''?'abc':4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("abc");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("abc");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// null condition
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("3==3?null:4L");
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isNull();
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isNull();
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning primitive
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x==#x?50:'foo'");
|
||||
context.setVariable("x",50);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("50");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x!=#x?50:'foo'");
|
||||
context.setVariable("x",null);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("foo");
|
||||
assertIsCompiled(exp);
|
||||
|
||||
// variable access returning array
|
||||
exp = new SpelExpressionParser(configuration).parseExpression("#x==#x?'1,2,3':'foo'");
|
||||
context.setVariable("x",new int[]{1,2,3});
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertCanCompile(exp);
|
||||
assertThat(exp.getValue(context, new Foo(), String.class)).isEqualTo("1,2,3");
|
||||
assertIsCompiled(exp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void repeatedCompilation() throws Exception {
|
||||
// Verifying that after a number of compilations, the classloaders
|
||||
|
||||
Reference in New Issue
Block a user