Polish SpEL documentation and tests
This commit is contained in:
@@ -21,13 +21,12 @@ import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.ConstructorExecutor;
|
||||
import org.springframework.expression.ConstructorResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
import org.springframework.expression.spel.testresources.Fruit;
|
||||
import org.springframework.expression.spel.testresources.PlaceOfBirth;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -41,19 +40,145 @@ import static org.assertj.core.api.Assertions.assertThatException;
|
||||
class ConstructorInvocationTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void testTypeConstructors() {
|
||||
void constructorWithArgument() {
|
||||
evaluate("new String('hello world')", "hello world", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonExistentType() {
|
||||
void nonExistentType() {
|
||||
evaluateAndCheckError("new FooBar()", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorThrowingException() {
|
||||
// Test ctor on inventor:
|
||||
// On 1 it will throw an IllegalArgumentException
|
||||
// On 2 it will throw a RuntimeException
|
||||
// On 3 it will exit normally
|
||||
// In each case it increments the Tester field 'counter' when invoked
|
||||
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expr = parser.parseExpression("new org.springframework.expression.spel.ConstructorInvocationTests$Tester(#bar).i");
|
||||
|
||||
// Normal exit
|
||||
StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
||||
context.setRootObject(new Tester());
|
||||
context.setVariable("bar", 3);
|
||||
Object o = expr.getValue(context);
|
||||
assertThat(o).isEqualTo(3);
|
||||
assertThat(parser.parseExpression("counter").getValue(context)).isEqualTo(1);
|
||||
|
||||
// Now the expression has cached that throwException(int) is the right thing to
|
||||
// call. Let's change 'bar' to be a PlaceOfBirth which indicates the cached
|
||||
// reference is out of date.
|
||||
context.setVariable("bar", new PlaceOfBirth("London"));
|
||||
o = expr.getValue(context);
|
||||
assertThat(o).isEqualTo(0);
|
||||
// That confirms the logic to mark the cached reference stale and retry is working
|
||||
|
||||
// Now let's cause the method to exit via exception and ensure it doesn't cause
|
||||
// a retry.
|
||||
|
||||
// First, switch back to throwException(int)
|
||||
context.setVariable("bar", 3);
|
||||
o = expr.getValue(context);
|
||||
assertThat(o).isEqualTo(3);
|
||||
assertThat(parser.parseExpression("counter").getValue(context)).isEqualTo(2);
|
||||
|
||||
// 4 will make it throw a checked exception - this will be wrapped by spel on the
|
||||
// way out
|
||||
context.setVariable("bar", 4);
|
||||
assertThatException()
|
||||
.isThrownBy(() -> expr.getValue(context))
|
||||
.withMessageContaining("Tester");
|
||||
// A problem occurred whilst attempting to construct an object of type
|
||||
// 'org.springframework.expression.spel.ConstructorInvocationTests$Tester'
|
||||
// using arguments '(java.lang.Integer)'
|
||||
|
||||
// If counter is 4 then the method got called twice!
|
||||
assertThat(parser.parseExpression("counter").getValue(context)).isEqualTo(3);
|
||||
|
||||
// 1 will make it throw a RuntimeException - SpEL will let this through
|
||||
context.setVariable("bar", 1);
|
||||
assertThatException()
|
||||
.isThrownBy(() -> expr.getValue(context))
|
||||
.isNotInstanceOf(SpelEvaluationException.class);
|
||||
// A problem occurred whilst attempting to construct an object of type
|
||||
// 'org.springframework.expression.spel.ConstructorInvocationTests$Tester'
|
||||
// using arguments '(java.lang.Integer)'
|
||||
|
||||
// If counter is 5 then the method got called twice!
|
||||
assertThat(parser.parseExpression("counter").getValue(context)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorResolvers() {
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
// reflective constructor accessor is the only one by default
|
||||
List<ConstructorResolver> constructorResolvers = ctx.getConstructorResolvers();
|
||||
assertThat(constructorResolvers).hasSize(1);
|
||||
|
||||
ConstructorResolver dummy = (context, typeName, argumentTypes) -> {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
ctx.addConstructorResolver(dummy);
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(2);
|
||||
|
||||
List<ConstructorResolver> copy = new ArrayList<>(ctx.getConstructorResolvers());
|
||||
assertThat(ctx.removeConstructorResolver(dummy)).isTrue();
|
||||
assertThat(ctx.removeConstructorResolver(dummy)).isFalse();
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(1);
|
||||
|
||||
ctx.setConstructorResolvers(copy);
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void varargsConstructors() {
|
||||
((StandardTypeLocator) super.context.getTypeLocator()).registerImport(Fruit.class.getPackageName());
|
||||
|
||||
// Calling 'Fruit(String... strings)' - returns length_of_strings
|
||||
evaluate("new Fruit('a','b','c').stringscount()", 3, Integer.class);
|
||||
evaluate("new Fruit('a').stringscount()", 1, Integer.class);
|
||||
evaluate("new Fruit().stringscount()", 0, Integer.class);
|
||||
// all need converting to strings
|
||||
evaluate("new Fruit(1,2,3).stringscount()", 3, Integer.class);
|
||||
// needs string conversion
|
||||
evaluate("new Fruit(1).stringscount()", 1, Integer.class);
|
||||
// first and last need conversion
|
||||
evaluate("new Fruit(1,'a',3.0d).stringscount()", 3, Integer.class);
|
||||
|
||||
// Calling 'Fruit(int i, String... strings)' - returns int + length_of_strings
|
||||
evaluate("new Fruit(5,'a','b','c').stringscount()", 8, Integer.class);
|
||||
evaluate("new Fruit(2,'a').stringscount()", 3, Integer.class);
|
||||
evaluate("new Fruit(4).stringscount()", 4, Integer.class);
|
||||
evaluate("new Fruit(8,2,3).stringscount()", 10, Integer.class);
|
||||
evaluate("new Fruit(9).stringscount()", 9, Integer.class);
|
||||
evaluate("new Fruit(2,'a',3.0d).stringscount()", 4, Integer.class);
|
||||
evaluate("new Fruit(8,stringArrayOfThreeItems).stringscount()", 11, Integer.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* These tests are attempting to call constructors where we need to widen or convert
|
||||
* the argument in order to satisfy a suitable constructor.
|
||||
*/
|
||||
@Test
|
||||
void widening() {
|
||||
// widening of int 3 to double 3 is OK
|
||||
evaluate("new Double(3)", 3.0d, Double.class);
|
||||
// widening of int 3 to long 3 is OK
|
||||
evaluate("new Long(3)", 3L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void argumentConversion() {
|
||||
evaluate("new String(3.0d)", "3.0", String.class);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class TestException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
static class Tester {
|
||||
@@ -80,154 +205,7 @@ class ConstructorInvocationTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
public Tester(PlaceOfBirth pob) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testConstructorThrowingException_SPR6760() {
|
||||
// Test ctor on inventor:
|
||||
// On 1 it will throw an IllegalArgumentException
|
||||
// On 2 it will throw a RuntimeException
|
||||
// On 3 it will exit normally
|
||||
// In each case it increments the Tester field 'counter' when invoked
|
||||
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expr = parser.parseExpression("new org.springframework.expression.spel.ConstructorInvocationTests$Tester(#bar).i");
|
||||
|
||||
// Normal exit
|
||||
StandardEvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext();
|
||||
eContext.setRootObject(new Tester());
|
||||
eContext.setVariable("bar", 3);
|
||||
Object o = expr.getValue(eContext);
|
||||
assertThat(o).isEqualTo(3);
|
||||
assertThat(parser.parseExpression("counter").getValue(eContext)).isEqualTo(1);
|
||||
|
||||
// Now the expression has cached that throwException(int) is the right thing to
|
||||
// call. Let's change 'bar' to be a PlaceOfBirth which indicates the cached
|
||||
// reference is out of date.
|
||||
eContext.setVariable("bar", new PlaceOfBirth("London"));
|
||||
o = expr.getValue(eContext);
|
||||
assertThat(o).isEqualTo(0);
|
||||
// That confirms the logic to mark the cached reference stale and retry is working
|
||||
|
||||
// Now let's cause the method to exit via exception and ensure it doesn't cause
|
||||
// a retry.
|
||||
|
||||
// First, switch back to throwException(int)
|
||||
eContext.setVariable("bar", 3);
|
||||
o = expr.getValue(eContext);
|
||||
assertThat(o).isEqualTo(3);
|
||||
assertThat(parser.parseExpression("counter").getValue(eContext)).isEqualTo(2);
|
||||
|
||||
// 4 will make it throw a checked exception - this will be wrapped by spel on the
|
||||
// way out
|
||||
eContext.setVariable("bar", 4);
|
||||
assertThatException()
|
||||
.isThrownBy(() -> expr.getValue(eContext))
|
||||
.withMessageContaining("Tester");
|
||||
// A problem occurred whilst attempting to construct an object of type
|
||||
// 'org.springframework.expression.spel.ConstructorInvocationTests$Tester'
|
||||
// using arguments '(java.lang.Integer)'
|
||||
|
||||
// If counter is 4 then the method got called twice!
|
||||
assertThat(parser.parseExpression("counter").getValue(eContext)).isEqualTo(3);
|
||||
|
||||
// 1 will make it throw a RuntimeException - SpEL will let this through
|
||||
eContext.setVariable("bar", 1);
|
||||
assertThatException()
|
||||
.isThrownBy(() -> expr.getValue(eContext))
|
||||
.isNotInstanceOf(SpelEvaluationException.class);
|
||||
// A problem occurred whilst attempting to construct an object of type
|
||||
// 'org.springframework.expression.spel.ConstructorInvocationTests$Tester'
|
||||
// using arguments '(java.lang.Integer)'
|
||||
|
||||
// If counter is 5 then the method got called twice!
|
||||
assertThat(parser.parseExpression("counter").getValue(eContext)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddingConstructorResolvers() {
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
// reflective constructor accessor is the only one by default
|
||||
List<ConstructorResolver> constructorResolvers = ctx.getConstructorResolvers();
|
||||
assertThat(constructorResolvers).hasSize(1);
|
||||
|
||||
ConstructorResolver dummy = new DummyConstructorResolver();
|
||||
ctx.addConstructorResolver(dummy);
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(2);
|
||||
|
||||
List<ConstructorResolver> copy = new ArrayList<>(ctx.getConstructorResolvers());
|
||||
assertThat(ctx.removeConstructorResolver(dummy)).isTrue();
|
||||
assertThat(ctx.removeConstructorResolver(dummy)).isFalse();
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(1);
|
||||
|
||||
ctx.setConstructorResolvers(copy);
|
||||
assertThat(ctx.getConstructorResolvers()).hasSize(2);
|
||||
}
|
||||
|
||||
|
||||
static class DummyConstructorResolver implements ConstructorResolver {
|
||||
|
||||
@Override
|
||||
public ConstructorExecutor resolve(EvaluationContext context, String typeName,
|
||||
List<TypeDescriptor> argumentTypes) {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testVarargsInvocation01() {
|
||||
// Calling 'Fruit(String... strings)'
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit('a','b','c').stringscount()", 3,
|
||||
Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit('a').stringscount()", 1, Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit().stringscount()", 0, Integer.class);
|
||||
// all need converting to strings
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(1,2,3).stringscount()", 3, Integer.class);
|
||||
// needs string conversion
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(1).stringscount()", 1, Integer.class);
|
||||
// first and last need conversion
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(1,'a',3.0d).stringscount()", 3,
|
||||
Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargsInvocation02() {
|
||||
// Calling 'Fruit(int i, String... strings)' - returns int+length_of_strings
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(5,'a','b','c').stringscount()", 8,
|
||||
Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(2,'a').stringscount()", 3, Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(4).stringscount()", 4, Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(8,2,3).stringscount()", 10, Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(9).stringscount()", 9, Integer.class);
|
||||
evaluate("new org.springframework.expression.spel.testresources.Fruit(2,'a',3.0d).stringscount()", 4,
|
||||
Integer.class);
|
||||
evaluate(
|
||||
"new org.springframework.expression.spel.testresources.Fruit(8,stringArrayOfThreeItems).stringscount()",
|
||||
11, Integer.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* These tests are attempting to call constructors where we need to widen or convert
|
||||
* the argument in order to satisfy a suitable constructor.
|
||||
*/
|
||||
@Test
|
||||
void testWidening01() {
|
||||
// widening of int 3 to double 3 is OK
|
||||
evaluate("new Double(3)", 3.0d, Double.class);
|
||||
// widening of int 3 to long 3 is OK
|
||||
evaluate("new Long(3)", 3L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArgumentConversion01() {
|
||||
evaluate("new String(3.0d)", "3.0", String.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,83 +19,78 @@ package org.springframework.expression.spel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.spel.standard.SpelExpression;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests the evaluation of basic literals: boolean, integer, hex integer, long, real, null, date
|
||||
* Tests the evaluation of basic literals: boolean, string, integer, long,
|
||||
* hex integer, hex long, float, double, null.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class LiteralTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void testLiteralBoolean01() {
|
||||
evaluate("false", "false", Boolean.class);
|
||||
void booleans() {
|
||||
evaluate("false", false, Boolean.class);
|
||||
evaluate("true", true, Boolean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralBoolean02() {
|
||||
evaluate("true", "true", Boolean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralInteger01() {
|
||||
evaluate("1", "1", Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralInteger02() {
|
||||
evaluate("1415", "1415", Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString01() {
|
||||
void strings() {
|
||||
evaluate("'hello'", "hello", String.class);
|
||||
evaluate("'joe bloggs'", "joe bloggs", String.class);
|
||||
evaluate("'Hello World'", "Hello World", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString02() {
|
||||
evaluate("'joe bloggs'", "joe bloggs", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString03() {
|
||||
evaluate("'hello'", "hello", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString04() {
|
||||
void stringsContainingQuotes() {
|
||||
evaluate("'Tony''s Pizza'", "Tony's Pizza", String.class);
|
||||
evaluate("'Tony\\r''s Pizza'", "Tony\\r's Pizza", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString05() {
|
||||
evaluate("\"Hello World\"", "Hello World", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralString06() {
|
||||
evaluate("\"Hello ' World\"", "Hello ' World", String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHexIntLiteral01() {
|
||||
evaluate("0x7FFFF", "524287", Integer.class);
|
||||
evaluate("0x7FFFFL", 524287L, Long.class);
|
||||
evaluate("0X7FFFF", "524287", Integer.class);
|
||||
evaluate("0X7FFFFl", 524287L, Long.class);
|
||||
void integers() {
|
||||
evaluate("1", 1, Integer.class);
|
||||
evaluate("1415", 1415, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLongIntLiteral01() {
|
||||
void longs() {
|
||||
evaluate("1L", 1L, Long.class);
|
||||
evaluate("1415L", 1415L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void signedIntegers() {
|
||||
evaluate("-1", -1, Integer.class);
|
||||
evaluate("-0xa", -10, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void signedLongs() {
|
||||
evaluate("-1L", -1L, Long.class);
|
||||
evaluate("-0x20l", -32L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void hexIntegers() {
|
||||
evaluate("0x7FFFF", 524287, Integer.class);
|
||||
evaluate("0X7FFFF", 524287, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void hexLongs() {
|
||||
evaluate("0X7FFFFl", 524287L, Long.class);
|
||||
evaluate("0x7FFFFL", 524287L, Long.class);
|
||||
evaluate("0xCAFEBABEL", 3405691582L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLongIntInteractions01() {
|
||||
void hexLongAndIntInteractions() {
|
||||
evaluate("0x20 * 2L", 64L, Long.class);
|
||||
// ask for the result to be made into an Integer
|
||||
evaluateAndAskForReturnType("0x20 * 2L", 64, Integer.class);
|
||||
@@ -104,29 +99,8 @@ class LiteralTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSignedIntLiterals() {
|
||||
evaluate("-1", -1, Integer.class);
|
||||
evaluate("-0xa", -10, Integer.class);
|
||||
evaluate("-1L", -1L, Long.class);
|
||||
evaluate("-0x20l", -32L, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralReal01_CreatingDoubles() {
|
||||
evaluate("1.25", 1.25d, Double.class);
|
||||
evaluate("2.99", 2.99d, Double.class);
|
||||
evaluate("-3.141", -3.141d, Double.class);
|
||||
evaluate("1.25d", 1.25d, Double.class);
|
||||
evaluate("2.99d", 2.99d, Double.class);
|
||||
evaluate("-3.141d", -3.141d, Double.class);
|
||||
evaluate("1.25D", 1.25d, Double.class);
|
||||
evaluate("2.99D", 2.99d, Double.class);
|
||||
evaluate("-3.141D", -3.141d, Double.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralReal02_CreatingFloats() {
|
||||
// For now, everything becomes a double...
|
||||
void floats() {
|
||||
// "f" or "F" must be explicitly specified.
|
||||
evaluate("1.25f", 1.25f, Float.class);
|
||||
evaluate("2.5f", 2.5f, Float.class);
|
||||
evaluate("-3.5f", -3.5f, Float.class);
|
||||
@@ -136,7 +110,23 @@ class LiteralTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralReal03_UsingExponents() {
|
||||
void doubles() {
|
||||
// Real numbers are Doubles by default
|
||||
evaluate("1.25", 1.25d, Double.class);
|
||||
evaluate("2.99", 2.99d, Double.class);
|
||||
evaluate("-3.141", -3.141d, Double.class);
|
||||
|
||||
// But "d" or "D" can also be explicitly specified.
|
||||
evaluate("1.25d", 1.25d, Double.class);
|
||||
evaluate("2.99d", 2.99d, Double.class);
|
||||
evaluate("-3.141d", -3.141d, Double.class);
|
||||
evaluate("1.25D", 1.25d, Double.class);
|
||||
evaluate("2.99D", 2.99d, Double.class);
|
||||
evaluate("-3.141D", -3.141d, Double.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doublesUsingExponents() {
|
||||
evaluate("6.0221415E+23", "6.0221415E23", Double.class);
|
||||
evaluate("6.0221415e+23", "6.0221415E23", Double.class);
|
||||
evaluate("6.0221415E+23d", "6.0221415E23", Double.class);
|
||||
@@ -145,30 +135,33 @@ class LiteralTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralReal04_BadExpressions() {
|
||||
void doublesUsingExponentsWithInvalidInput() {
|
||||
parseAndCheckError("6.1e23e22", SpelMessage.MORE_INPUT, 6, "e22");
|
||||
parseAndCheckError("6.1f23e22", SpelMessage.MORE_INPUT, 4, "23e22");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralNull01() {
|
||||
void nullLiteral() {
|
||||
evaluate("null", null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConversions() {
|
||||
void conversions() {
|
||||
// getting the expression type to be what we want - either:
|
||||
evaluate("new Integer(37).byteValue()", (byte) 37, Byte.class); // calling byteValue() on Integer.class
|
||||
evaluateAndAskForReturnType("new Integer(37)", (byte) 37, Byte.class); // relying on registered type converters
|
||||
evaluate("37.byteValue", (byte) 37, Byte.class); // calling byteValue() on Integer.class
|
||||
evaluateAndAskForReturnType("37", (byte) 37, Byte.class); // relying on registered type converters
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNotWritable() {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("37");
|
||||
assertThat(expr.isWritable(new StandardEvaluationContext())).isFalse();
|
||||
expr = (SpelExpression)parser.parseExpression("37L");
|
||||
assertThat(expr.isWritable(new StandardEvaluationContext())).isFalse();
|
||||
expr = (SpelExpression)parser.parseExpression("true");
|
||||
assertThat(expr.isWritable(new StandardEvaluationContext())).isFalse();
|
||||
void notWritable() {
|
||||
SpelExpression expr = (SpelExpression) parser.parseExpression("37");
|
||||
assertThat(expr.isWritable(context)).isFalse();
|
||||
|
||||
expr = (SpelExpression) parser.parseExpression("37L");
|
||||
assertThat(expr.isWritable(context)).isFalse();
|
||||
|
||||
expr = (SpelExpression) parser.parseExpression("true");
|
||||
assertThat(expr.isWritable(context)).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class ParsingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void literalNull() {
|
||||
void nullLiteral() {
|
||||
parseCheck("null");
|
||||
}
|
||||
|
||||
@@ -399,12 +399,12 @@ class ParsingTests {
|
||||
|
||||
@Test
|
||||
void mathOperatorsAddStrings() {
|
||||
parseCheck("'a'+'b'", "('a' + 'b')");
|
||||
parseCheck("'a' + 'b'", "('a' + 'b')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mathOperatorsAddMultipleStrings() {
|
||||
parseCheck("'hello'+' '+'world'", "(('hello' + ' ') + 'world')");
|
||||
parseCheck("'hello' + ' ' + 'world'", "(('hello' + ' ') + 'world')");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -429,7 +429,7 @@ class ParsingTests {
|
||||
}
|
||||
|
||||
@Nested
|
||||
class References {
|
||||
class BeanReferences {
|
||||
|
||||
@Test
|
||||
void references() {
|
||||
|
||||
Reference in New Issue
Block a user