From ec411f271bb0f0179d80a98cc1a1cbdfd0fcc553 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Mon, 30 Mar 2009 19:40:09 +0000 Subject: [PATCH] Indexed objects (arrays/maps/lists) now settable git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@878 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../expression/spel/SetValueTests.java | 91 ++++++++++++++++--- .../spel/testresources/ArrayContainer.java | 32 +++++++ .../spel/testresources/Inventor.java | 7 +- 3 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/ArrayContainer.java diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java index 8325425890c..8e7bdefc321 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java @@ -16,15 +16,19 @@ package org.springframework.expression.spel; +import java.util.ArrayList; + import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.expression.spel.testresources.PlaceOfBirth; /** * Tests set value expressions. * * @author Keith Donald + * @author Andy Clement */ public class SetValueTests extends ExpressionTestCase { @@ -33,35 +37,96 @@ public class SetValueTests extends ExpressionTestCase { public void testSetProperty() { setValue("wonNobelPrize", true); } - + public void testSetNestedProperty() { setValue("placeOfBirth.city", "Wien"); } - //public void testSetPropertyTypeCoersion() { - // setValue("wonNobelPrize", "true"); - //} + public void testSetArrayElementValue() { + setValue("inventions[0]", "Just the telephone"); + } - //public void testSetArrayElementValue() { - // setValue("inventions[0]", "Just the telephone"); - //} + public void testSetArrayElementValueAllPrimitiveTypes() { + setValue("arrayContainer.ints[1]", 3); + setValue("arrayContainer.floats[1]", 3.0f); + setValue("arrayContainer.booleans[1]", false); + setValue("arrayContainer.doubles[1]", 3.4d); + setValue("arrayContainer.shorts[1]", (short)3); + setValue("arrayContainer.longs[1]", 3L); + setValue("arrayContainer.bytes[1]", (byte) 3); + setValue("arrayContainer.chars[1]", (char) 3); + } + + public void testSetArrayElementValueAllPrimitiveTypesErrors() { + // none of these sets are possible due to (expected) conversion problems + setValueExpectError("arrayContainer.ints[1]", "wibble"); + setValueExpectError("arrayContainer.floats[1]", "dribble"); + setValueExpectError("arrayContainer.booleans[1]", "nein"); + setValueExpectError("arrayContainer.doubles[1]", new ArrayList()); + setValueExpectError("arrayContainer.shorts[1]", new ArrayList()); + setValueExpectError("arrayContainer.longs[1]", new ArrayList()); + setValueExpectError("arrayContainer.bytes[1]", "NaB"); + setValueExpectError("arrayContainer.chars[1]", "NaC"); + } public void testSetArrayElementNestedValue() { setValue("placesLived[0].city", "Wien"); } - //public void testSetListElementValue() { - // setValue("placesLivedList[0]", new PlaceOfBirth("Wien")); - //} + public void testSetListElementValue() { + setValue("placesLivedList[0]", new PlaceOfBirth("Wien")); + } - //public void testSetGenericListElementValueTypeCoersion() { - // setValue("placesLivedList[0]", "Wien"); - //} + public void testSetGenericListElementValueTypeCoersion() { + setValue("placesLivedList[0]", "Wien"); + } public void testSetListElementNestedValue() { setValue("placesLived[0].city", "Wien"); } + public void testSetArrayElementInvalidIndex() { + setValueExpectError("placesLived[23]", "Wien"); + setValueExpectError("placesLivedList[23]", "Wien"); + } + + public void testSetMapElements() { + setValue("testMap['montag']","lundi"); + } + + public void testIndexingIntoUnsupportedType() { + setValueExpectError("'hello'[3]", 'p'); + } + +// public void testSetPropertyTypeCoersion() { +// setValue("publicBoolean", "true"); +// } + + + /** + * Call setValue() but expect it to fail. + */ + protected void setValueExpectError(String expression, Object value) { + try { + Expression e = parser.parseExpression(expression); + if (e == null) { + fail("Parser returned null for expression"); + } + if (DEBUG) { + SpelUtilities.printAbstractSyntaxTree(System.out, e); + } + StandardEvaluationContext lContext = TestScenarioCreator.getTestEvaluationContext(); +// assertTrue("Expression is not writeable but should be", e.isWritable(lContext)); + e.setValue(lContext, value); + fail("expected an error"); + } catch (ParseException pe) { + pe.printStackTrace(); + fail("Unexpected Exception: " + pe.getMessage()); + } catch (EvaluationException ee) { + // success! + } + } + protected void setValue(String expression, Object value) { try { Expression e = parser.parseExpression(expression); diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/ArrayContainer.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/ArrayContainer.java new file mode 100644 index 00000000000..169d66327f8 --- /dev/null +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/ArrayContainer.java @@ -0,0 +1,32 @@ +/** + * + */ +package org.springframework.expression.spel.testresources; + +/** + * Hold the various kinds of primitive array for access through the test evaluation context. + * + * @author Andy Clement + */ +public class ArrayContainer { + public int[] ints = new int[3]; + public long[] longs = new long[3]; + public double[] doubles = new double[3]; + public byte[] bytes = new byte[3]; + public char[] chars = new char[3]; + public short[] shorts = new short[3]; + public boolean[] booleans = new boolean[3]; + public float[] floats = new float[3]; + + public ArrayContainer() { + // setup some values + ints[0] = 42; + longs[0] = 42L; + doubles[0] = 42.0d; + bytes[0] = 42; + chars[0] = 42; + shorts[0] = 42; + booleans[0] = true; + floats[0] = 42.0f; + } +} \ No newline at end of file diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java index 2f549e3c078..bebb1a6cd05 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java @@ -15,16 +15,19 @@ public class Inventor { private String nationality; private String[] inventions; public String randomField; - public Map testMap; + public Map testMap; private boolean wonNobelPrize; private PlaceOfBirth[] placesLived; private List placesLivedList = new ArrayList(); + public ArrayContainer arrayContainer; + public boolean publicBoolean; public Inventor(String name, Date birthdate, String nationality) { this.name = name; this.birthdate = birthdate; this.nationality = nationality; - testMap = new HashMap(); + this.arrayContainer = new ArrayContainer(); + testMap = new HashMap(); testMap.put("monday", "montag"); testMap.put("tuesday", "dienstag"); testMap.put("wednesday", "mittwoch");