More tests. First pass on messages review.
This commit is contained in:
@@ -94,7 +94,7 @@ public class EvaluationTests extends ExpressionTestCase {
|
||||
public void testPropertyField01() {
|
||||
evaluate("name", "Nikola Tesla", String.class, false);
|
||||
// not writable because (1) name is private (2) there is no setter, only a getter
|
||||
evaluateAndCheckError("madeup", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 0, "madeup",
|
||||
evaluateAndCheckError("madeup", SpelMessages.PROPERTY_OR_FIELD_NOT_READABLE, 0, "madeup",
|
||||
"org.springframework.expression.spel.testresources.Inventor");
|
||||
}
|
||||
|
||||
|
||||
@@ -203,9 +203,8 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
try {
|
||||
expr.setValue(ctx, Color.blue);
|
||||
fail("Should not be allowed to set oranges to be blue !");
|
||||
}
|
||||
catch (SpelException ee) {
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
} catch (SpelException ee) {
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +224,7 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
fail("Should not be allowed to set peas to be blue !");
|
||||
}
|
||||
catch (SpelException ee) {
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,15 @@ package org.springframework.expression.spel;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.ast.FormatHelper;
|
||||
import org.springframework.expression.spel.support.ReflectionHelper;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.expression.spel.support.ReflectionHelper.ArgsMatchKind;
|
||||
|
||||
/**
|
||||
* Tests for any helper code.
|
||||
@@ -71,4 +77,100 @@ public class HelperTests extends ExpressionTestCase {
|
||||
assertTrue(s.indexOf("===> Expression '3+4+5+6+7-2' - AST start")!=-1);
|
||||
assertTrue(s.indexOf(" OperatorPlus value:((((3 + 4) + 5) + 6) + 7) #children:2")!=-1);
|
||||
}
|
||||
|
||||
public void testTypedValue() {
|
||||
TypedValue tValue = new TypedValue("hello");
|
||||
assertEquals(String.class,tValue.getTypeDescriptor().getType());
|
||||
assertEquals("TypedValue: hello of type java.lang.String",tValue.toString());
|
||||
}
|
||||
|
||||
public void testReflectionHelperCompareArguments_ExactMatching() {
|
||||
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
// Calling foo(String) with (String) is exact match
|
||||
checkMatch(new Class[]{String.class},new Class[]{String.class},typeConverter,ArgsMatchKind.EXACT);
|
||||
|
||||
// Calling foo(String,Integer) with (String,Integer) is exact match
|
||||
checkMatch(new Class[]{String.class,Integer.class},new Class[]{String.class,Integer.class},typeConverter,ArgsMatchKind.EXACT);
|
||||
}
|
||||
|
||||
public void testReflectionHelperCompareArguments_Varargs_ExactMatching() {
|
||||
StandardTypeConverter tc = new StandardTypeConverter();
|
||||
|
||||
// Calling foo(String) with (String) is exact match
|
||||
checkMatch(new Class[]{String.class},new Class[]{String.class},tc,ArgsMatchKind.EXACT);
|
||||
}
|
||||
|
||||
public void testReflectionHelperCompareArguments_CloseMatching() {
|
||||
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
// Calling foo(List) with (ArrayList) is close match (no conversion required)
|
||||
checkMatch(new Class[]{ArrayList.class},new Class[]{List.class},typeConverter,ArgsMatchKind.CLOSE);
|
||||
|
||||
// Passing (Sub,String) on call to foo(Super,String) is close match
|
||||
checkMatch(new Class[]{Sub.class,String.class},new Class[]{Super.class,String.class},typeConverter,ArgsMatchKind.CLOSE);
|
||||
|
||||
// Passing (String,Sub) on call to foo(String,Super) is close match
|
||||
checkMatch(new Class[]{String.class,Sub.class},new Class[]{String.class,Super.class},typeConverter,ArgsMatchKind.CLOSE);
|
||||
}
|
||||
|
||||
public void testReflectionHelperCompareArguments_RequiresConversionMatching() {
|
||||
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
// Calling foo(String,int) with (String,Integer) requires boxing conversion of argument one
|
||||
checkMatch(new Class[]{String.class,Integer.TYPE},new Class[]{String.class,Integer.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,1);
|
||||
|
||||
// Passing (int,String) on call to foo(Integer,String) requires boxing conversion of argument zero
|
||||
checkMatch(new Class[]{Integer.TYPE,String.class},new Class[]{Integer.class, String.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0);
|
||||
|
||||
// Passing (int,Sub) on call to foo(Integer,Super) requires boxing conversion of argument zero
|
||||
checkMatch(new Class[]{Integer.TYPE,Sub.class},new Class[]{Integer.class, Super.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0);
|
||||
|
||||
// Passing (int,Sub,boolean) on call to foo(Integer,Super,Boolean) requires boxing conversion of arguments zero and two
|
||||
checkMatch(new Class[]{Integer.TYPE,Sub.class,Boolean.TYPE},new Class[]{Integer.class, Super.class,Boolean.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0,2);
|
||||
}
|
||||
|
||||
public void testReflectionHelperCompareArguments_NotAMatch() {
|
||||
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
// Passing (Super,String) on call to foo(Sub,String) is not a match
|
||||
checkMatch(new Class[]{Super.class,String.class},new Class[]{Sub.class,String.class},typeConverter,null);
|
||||
}
|
||||
|
||||
static class Super {
|
||||
}
|
||||
|
||||
static class Sub extends Super {
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
/**
|
||||
* Used to validate the match returned from a compareArguments call.
|
||||
*/
|
||||
private void checkMatch(Class[] inputTypes, Class[] expectedTypes, StandardTypeConverter typeConverter,ArgsMatchKind expectedMatchKind,int... argsForConversion) {
|
||||
ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArguments(expectedTypes, inputTypes, typeConverter);
|
||||
if (expectedMatchKind==null) {
|
||||
assertNull("Did not expect them to match in any way", matchInfo);
|
||||
} else {
|
||||
assertNotNull("Should not be a null match", matchInfo);
|
||||
}
|
||||
|
||||
if (expectedMatchKind==ArgsMatchKind.EXACT) {
|
||||
assertTrue(matchInfo.isExactMatch());
|
||||
assertNull(matchInfo.argsRequiringConversion);
|
||||
} else if (expectedMatchKind==ArgsMatchKind.CLOSE) {
|
||||
assertTrue(matchInfo.isCloseMatch());
|
||||
assertNull(matchInfo.argsRequiringConversion);
|
||||
} else if (expectedMatchKind==ArgsMatchKind.REQUIRES_CONVERSION) {
|
||||
assertTrue("expected to be a match requiring conversion, but was "+matchInfo,matchInfo.isMatchRequiringConversion());
|
||||
if (argsForConversion==null) {
|
||||
fail("there are arguments that need conversion");
|
||||
}
|
||||
assertEquals("The array of args that need conversion is different length to that expected",argsForConversion.length, matchInfo.argsRequiringConversion.length);
|
||||
for (int a=0;a<argsForConversion.length;a++) {
|
||||
assertEquals(argsForConversion[a],matchInfo.argsRequiringConversion[a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public void testInvocationOnNullContextObject() {
|
||||
evaluateAndCheckError("null.toString()",SpelMessages.ATTEMPTED_METHOD_CALL_ON_NULL_CONTEXT_OBJECT);
|
||||
evaluateAndCheckError("null.toString()",SpelMessages.METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,10 +47,41 @@ public class PropertyAccessTests extends ExpressionTestCase {
|
||||
|
||||
public void testNonExistentPropertiesAndMethods() {
|
||||
// madeup does not exist as a property
|
||||
evaluateAndCheckError("madeup", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 0);
|
||||
evaluateAndCheckError("madeup", SpelMessages.PROPERTY_OR_FIELD_NOT_READABLE, 0);
|
||||
|
||||
// name is ok but foobar does not exist:
|
||||
evaluateAndCheckError("name.foobar", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 5);
|
||||
evaluateAndCheckError("name.foobar", SpelMessages.PROPERTY_OR_FIELD_NOT_READABLE, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard reflection resolver cannot find properties on null objects but some
|
||||
* supplied resolver might be able to - so null shouldn't crash the reflection resolver.
|
||||
*/
|
||||
public void testAccessingOnNullObject() throws Exception {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("madeup");
|
||||
EvaluationContext context = new StandardEvaluationContext(null);
|
||||
try {
|
||||
expr.getValue(context);
|
||||
fail("Should have failed - default property resolver cannot resolve on null");
|
||||
} catch (Exception e) {
|
||||
checkException(e,SpelMessages.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL);
|
||||
}
|
||||
assertFalse(expr.isWritable(context));
|
||||
try {
|
||||
expr.setValue(context,"abc");
|
||||
fail("Should have failed - default property resolver cannot resolve on null");
|
||||
} catch (Exception e) {
|
||||
checkException(e,SpelMessages.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkException(Exception e, SpelMessages expectedMessage) {
|
||||
if (e instanceof SpelException) {
|
||||
SpelMessages sm = ((SpelException)e).getMessageUnformatted();
|
||||
assertEquals("Expected exception type did not occur",expectedMessage,sm);
|
||||
} else {
|
||||
fail("Should be a SpelException "+e);
|
||||
}
|
||||
}
|
||||
|
||||
// Adding a new property accessor just for a particular type
|
||||
|
||||
Reference in New Issue
Block a user