Final commit before the great 'stripdown'. Used clover to determine coverage and added tests as necessary.
This commit is contained in:
parent
23db8b58da
commit
59a4427525
|
|
@ -7,6 +7,6 @@
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
|
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
|
||||||
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.4.0/com.springsource.org.junit-4.4.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-sources-3.8.2.jar"/>
|
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.4.0/com.springsource.org.junit-4.4.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-sources-3.8.2.jar"/>
|
||||||
<classpathentry kind="var" path="IVY_CACHE/org.antlr/com.springsource.org.antlr/3.0.1/com.springsource.org.antlr-3.0.1.jar"/>
|
<classpathentry kind="var" path="IVY_CACHE/org.antlr/com.springsource.org.antlr/3.0.1/com.springsource.org.antlr-3.0.1.jar" sourcepath="/IVY_CACHE/org.antlr/com.springsource.org.antlr/3.0.1/com.springsource.org.antlr-sources-3.0.1.jar"/>
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ High Importance
|
||||||
in a different context then the stored executor may be incorrect. It may harmless 'fail' which would cause us to retrieve a new one, but
|
in a different context then the stored executor may be incorrect. It may harmless 'fail' which would cause us to retrieve a new one, but
|
||||||
can it do anything malicious? In which case we either need to forget them when the context changes or store them elsewhere. Should caching be
|
can it do anything malicious? In which case we either need to forget them when the context changes or store them elsewhere. Should caching be
|
||||||
something that can be switched on/off by the context? (shouldCacheExecutors() on the interface?)
|
something that can be switched on/off by the context? (shouldCacheExecutors() on the interface?)
|
||||||
|
- Expression serialization needs supporting
|
||||||
|
- expression basic interface and common package. Should LiteralExpression be settable? should getExpressionString return quoted value?
|
||||||
|
|
||||||
Low Importance
|
Low Importance
|
||||||
|
|
||||||
|
|
@ -13,6 +15,7 @@ Low Importance
|
||||||
would have taken? At the moment ternary expressions are just considered NOT writable.
|
would have taken? At the moment ternary expressions are just considered NOT writable.
|
||||||
- Enhance type locator interface with direct support for register/unregister imports and ability to set class loader?
|
- Enhance type locator interface with direct support for register/unregister imports and ability to set class loader?
|
||||||
- Should some of the common errors (like SpelMessages.TYPE_NOT_FOUND) be promoted to top level exceptions?
|
- Should some of the common errors (like SpelMessages.TYPE_NOT_FOUND) be promoted to top level exceptions?
|
||||||
|
- Expression comparison - is it necessary?
|
||||||
|
|
||||||
Syntax
|
Syntax
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,15 @@ public class LiteralExpression implements Expression {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExpressionString() {
|
public String getExpressionString() {
|
||||||
return new StringBuilder().append("'").append(literalValue).append("'").toString();
|
return literalValue;
|
||||||
|
// return new StringBuilder().append("'").append(literalValue).append("'").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue() throws EvaluationException {
|
public String getValue() throws EvaluationException {
|
||||||
return literalValue;
|
return literalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue(EvaluationContext context) throws EvaluationException {
|
public String getValue(EvaluationContext context) throws EvaluationException {
|
||||||
return literalValue;
|
return literalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import org.springframework.expression.Operation;
|
||||||
import org.springframework.expression.OperatorOverloader;
|
import org.springframework.expression.OperatorOverloader;
|
||||||
import org.springframework.expression.PropertyAccessor;
|
import org.springframework.expression.PropertyAccessor;
|
||||||
import org.springframework.expression.TypeComparator;
|
import org.springframework.expression.TypeComparator;
|
||||||
|
import org.springframework.expression.TypeConverter;
|
||||||
import org.springframework.expression.TypeUtils;
|
import org.springframework.expression.TypeUtils;
|
||||||
import org.springframework.expression.spel.internal.VariableScope;
|
import org.springframework.expression.spel.internal.VariableScope;
|
||||||
|
|
||||||
|
|
@ -42,21 +43,21 @@ public class ExpressionState {
|
||||||
|
|
||||||
private EvaluationContext relatedContext;
|
private EvaluationContext relatedContext;
|
||||||
|
|
||||||
private final Stack<VariableScope> environment = new Stack<VariableScope>();
|
private final Stack<VariableScope> variableScopes = new Stack<VariableScope>();
|
||||||
|
|
||||||
private final Stack<Object> contextObjects = new Stack<Object>();
|
private final Stack<Object> contextObjects = new Stack<Object>();
|
||||||
|
|
||||||
public ExpressionState(EvaluationContext context) {
|
public ExpressionState(EvaluationContext context) {
|
||||||
this.relatedContext = context;
|
relatedContext = context;
|
||||||
createEnvironment();
|
createVariableScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExpressionState() {
|
public ExpressionState() {
|
||||||
createEnvironment();
|
createVariableScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createEnvironment() {
|
private void createVariableScope() {
|
||||||
environment.add(new VariableScope()); // create an empty top level VariableScope
|
variableScopes.add(new VariableScope()); // create an empty top level VariableScope
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -97,37 +98,42 @@ public class ExpressionState {
|
||||||
return getTypeUtilities().getTypeLocator().findType(type);
|
return getTypeUtilities().getTypeLocator().findType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO all these methods that grab the type converter will fail badly if there isn't one...
|
||||||
public boolean toBoolean(Object value) throws EvaluationException {
|
public boolean toBoolean(Object value) throws EvaluationException {
|
||||||
// TODO cache TypeConverter when it is set/changed?
|
return ((Boolean) getTypeConverter().convertValue(value, Boolean.TYPE)).booleanValue();
|
||||||
return ((Boolean) getTypeUtilities().getTypeConverter().convertValue(value, Boolean.TYPE)).booleanValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public char toCharacter(Object value) throws EvaluationException {
|
public char toCharacter(Object value) throws EvaluationException {
|
||||||
return ((Character) getTypeUtilities().getTypeConverter().convertValue(value, Character.TYPE)).charValue();
|
return ((Character) getTypeConverter().convertValue(value, Character.TYPE)).charValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short toShort(Object value) throws EvaluationException {
|
public short toShort(Object value) throws EvaluationException {
|
||||||
return ((Short) getTypeUtilities().getTypeConverter().convertValue(value, Short.TYPE)).shortValue();
|
return ((Short) getTypeConverter().convertValue(value, Short.TYPE)).shortValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toInteger(Object value) throws EvaluationException {
|
public int toInteger(Object value) throws EvaluationException {
|
||||||
return ((Integer) getTypeUtilities().getTypeConverter().convertValue(value, Integer.TYPE)).intValue();
|
return ((Integer) getTypeConverter().convertValue(value, Integer.TYPE)).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double toDouble(Object value) throws EvaluationException {
|
public double toDouble(Object value) throws EvaluationException {
|
||||||
return ((Double) getTypeUtilities().getTypeConverter().convertValue(value, Double.TYPE)).doubleValue();
|
return ((Double) getTypeConverter().convertValue(value, Double.TYPE)).doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float toFloat(Object value) throws EvaluationException {
|
public float toFloat(Object value) throws EvaluationException {
|
||||||
return ((Float) getTypeUtilities().getTypeConverter().convertValue(value, Float.TYPE)).floatValue();
|
return ((Float) getTypeConverter().convertValue(value, Float.TYPE)).floatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long toLong(Object value) throws EvaluationException {
|
public long toLong(Object value) throws EvaluationException {
|
||||||
return ((Long) getTypeUtilities().getTypeConverter().convertValue(value, Long.TYPE)).longValue();
|
return ((Long) getTypeConverter().convertValue(value, Long.TYPE)).longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte toByte(Object value) throws EvaluationException {
|
public byte toByte(Object value) throws EvaluationException {
|
||||||
return ((Byte) getTypeUtilities().getTypeConverter().convertValue(value, Byte.TYPE)).byteValue();
|
return ((Byte) getTypeConverter().convertValue(value, Byte.TYPE)).byteValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeConverter getTypeConverter() {
|
||||||
|
// TODO cache TypeConverter when it is set/changed?
|
||||||
|
return getTypeUtilities().getTypeConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVariable(String name, Object value) {
|
public void setVariable(String name, Object value) {
|
||||||
|
|
@ -142,26 +148,26 @@ public class ExpressionState {
|
||||||
* A new scope is entered when a function is invoked
|
* A new scope is entered when a function is invoked
|
||||||
*/
|
*/
|
||||||
public void enterScope(Map<String, Object> argMap) {
|
public void enterScope(Map<String, Object> argMap) {
|
||||||
environment.push(new VariableScope(argMap));
|
variableScopes.push(new VariableScope(argMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enterScope(String name, Object value) {
|
public void enterScope(String name, Object value) {
|
||||||
environment.push(new VariableScope(name, value));
|
variableScopes.push(new VariableScope(name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exitScope() {
|
public void exitScope() {
|
||||||
environment.pop();
|
variableScopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocalVariable(String name, Object value) {
|
public void setLocalVariable(String name, Object value) {
|
||||||
environment.peek().setVariable(name, value);
|
variableScopes.peek().setVariable(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object lookupLocalVariable(String name) {
|
public Object lookupLocalVariable(String name) {
|
||||||
int scopeNumber = environment.size() - 1;
|
int scopeNumber = variableScopes.size() - 1;
|
||||||
for (int i = scopeNumber; i >= 0; i--) {
|
for (int i = scopeNumber; i >= 0; i--) {
|
||||||
if (environment.get(i).definesVariable(name)) {
|
if (variableScopes.get(i).definesVariable(name)) {
|
||||||
return environment.get(i).lookupVariable(name);
|
return variableScopes.get(i).lookupVariable(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,10 @@ public class SpelUtilities {
|
||||||
private static void printAST(PrintStream out, SpelNode t, String indent) {
|
private static void printAST(PrintStream out, SpelNode t, String indent) {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
String s = null;
|
String s = (t.getType() == -1 ? "EOF" : t.getClass().getSimpleName());
|
||||||
if (t.getType() == -1)
|
sb.append(indent).append(s);
|
||||||
s = "EOF";
|
sb.append(" value=").append(t.getText());
|
||||||
else {
|
sb.append(t.getChildCount() < 2 ? "" : " children=#" + t.getChildCount());
|
||||||
s = t.getClass().getSimpleName();
|
|
||||||
}
|
|
||||||
sb.append(indent + s + (t.getChildCount() < 2 ? "" : " #" + t.getChildCount()));
|
|
||||||
out.println(sb.toString());
|
out.println(sb.toString());
|
||||||
for (int i = 0; i < t.getChildCount(); i++) {
|
for (int i = 0; i < t.getChildCount(); i++) {
|
||||||
printAST(out, t.getChild(i), indent + " ");
|
printAST(out, t.getChild(i), indent + " ");
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,13 @@ import org.springframework.expression.spel.SpelMessages;
|
||||||
* The AverageProcessor operates upon an input collection and computes the average value of the elements within it. It
|
* The AverageProcessor operates upon an input collection and computes the average value of the elements within it. It
|
||||||
* will currently only operate upon Numbers and its return value type is an Integer if the input values were integers,
|
* will currently only operate upon Numbers and its return value type is an Integer if the input values were integers,
|
||||||
* otherwise it is a double.
|
* otherwise it is a double.
|
||||||
|
*
|
||||||
|
* @author Andy Clement
|
||||||
*/
|
*/
|
||||||
public class AverageProcessor implements DataProcessor {
|
public class AverageProcessor implements DataProcessor {
|
||||||
|
|
||||||
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
|
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
|
||||||
// TypeUtilities typeUtilities = state.getTypeUtilities();
|
// TODO could support average of other types if delegated to OperatorOverloader for addition and division
|
||||||
boolean allIntegerObjects = true;
|
boolean allIntegerObjects = true;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
int numberOfElements = 0;
|
int numberOfElements = 0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-2008 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.expression.common;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
import org.springframework.expression.Expression;
|
||||||
|
import org.springframework.expression.spel.SpelExpressionParser;
|
||||||
|
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test LiteralExpression
|
||||||
|
*
|
||||||
|
* @author Andy Clement
|
||||||
|
*/
|
||||||
|
public class CompositeStringExpressionTests extends TestCase {
|
||||||
|
|
||||||
|
public void testGetValue() throws Exception {
|
||||||
|
SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
|
Expression ex = parser.parseExpression("hello ${'world'}", DefaultTemplateParserContext.INSTANCE);
|
||||||
|
checkString("hello world", ex.getValue());
|
||||||
|
checkString("hello world", ex.getValue(String.class));
|
||||||
|
EvaluationContext ctx = new StandardEvaluationContext();
|
||||||
|
checkString("hello world", ex.getValue(ctx));
|
||||||
|
checkString("hello world", ex.getValue(ctx, String.class));
|
||||||
|
assertEquals("hello ${'world'}", ex.getExpressionString());
|
||||||
|
assertFalse(ex.isWritable(new StandardEvaluationContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void testSetValue() {
|
||||||
|
// try {
|
||||||
|
// LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||||
|
// lEx.setValue(new StandardEvaluationContext(), "flibble");
|
||||||
|
// fail("Should have got an exception that the value cannot be set");
|
||||||
|
// } catch (EvaluationException ee) {
|
||||||
|
// // success, not allowed - whilst here, check the expression value in the exception
|
||||||
|
// assertEquals(ee.getExpressionString(), "somevalue");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void testGetValueType() throws Exception {
|
||||||
|
// LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||||
|
// assertEquals(String.class, lEx.getValueType());
|
||||||
|
// assertEquals(String.class, lEx.getValueType(new StandardEvaluationContext()));
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void checkString(String expectedString, Object value) {
|
||||||
|
if (!(value instanceof String)) {
|
||||||
|
fail("Result was not a string, it was of type " + value.getClass() + " (value=" + value + ")");
|
||||||
|
}
|
||||||
|
if (!((String) value).equals(expectedString)) {
|
||||||
|
fail("Did not get expected result. Should have been '" + expectedString + "' but was '" + value + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-2008 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.expression.common;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
import org.springframework.expression.EvaluationException;
|
||||||
|
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test LiteralExpression
|
||||||
|
*
|
||||||
|
* @author Andy Clement
|
||||||
|
*/
|
||||||
|
public class LiteralExpressionTests extends TestCase {
|
||||||
|
|
||||||
|
public void testGetValue() throws Exception {
|
||||||
|
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||||
|
checkString("somevalue", lEx.getValue());
|
||||||
|
checkString("somevalue", lEx.getValue(String.class));
|
||||||
|
EvaluationContext ctx = new StandardEvaluationContext();
|
||||||
|
checkString("somevalue", lEx.getValue(ctx));
|
||||||
|
checkString("somevalue", lEx.getValue(ctx, String.class));
|
||||||
|
assertEquals("somevalue", lEx.getExpressionString());
|
||||||
|
assertFalse(lEx.isWritable(new StandardEvaluationContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSetValue() {
|
||||||
|
try {
|
||||||
|
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||||
|
lEx.setValue(new StandardEvaluationContext(), "flibble");
|
||||||
|
fail("Should have got an exception that the value cannot be set");
|
||||||
|
} catch (EvaluationException ee) {
|
||||||
|
// success, not allowed - whilst here, check the expression value in the exception
|
||||||
|
assertEquals(ee.getExpressionString(), "somevalue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetValueType() throws Exception {
|
||||||
|
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||||
|
assertEquals(String.class, lEx.getValueType());
|
||||||
|
assertEquals(String.class, lEx.getValueType(new StandardEvaluationContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkString(String expectedString, Object value) {
|
||||||
|
if (!(value instanceof String)) {
|
||||||
|
fail("Result was not a string, it was of type " + value.getClass() + " (value=" + value + ")");
|
||||||
|
}
|
||||||
|
if (!((String) value).equals(expectedString)) {
|
||||||
|
fail("Did not get expected result. Should have been '" + expectedString + "' but was '" + value + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,9 @@ package org.springframework.expression.spel;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.springframework.expression.common.CompositeStringExpressionTests;
|
||||||
|
import org.springframework.expression.common.LiteralExpressionTests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pulls together all the tests for Spring EL into a single suite.
|
* Pulls together all the tests for Spring EL into a single suite.
|
||||||
*
|
*
|
||||||
|
|
@ -42,9 +45,12 @@ public class AllTests {
|
||||||
suite.addTestSuite(TypeReferencing.class);
|
suite.addTestSuite(TypeReferencing.class);
|
||||||
suite.addTestSuite(PerformanceTests.class);
|
suite.addTestSuite(PerformanceTests.class);
|
||||||
suite.addTestSuite(DefaultComparatorUnitTests.class);
|
suite.addTestSuite(DefaultComparatorUnitTests.class);
|
||||||
suite.addTestSuite(TemplateExpressionParsing.class);
|
suite.addTestSuite(TemplateExpressionParsingTests.class);
|
||||||
suite.addTestSuite(ExpressionLanguageScenarioTests.class);
|
suite.addTestSuite(ExpressionLanguageScenarioTests.class);
|
||||||
suite.addTestSuite(ScenariosForSpringSecurity.class);
|
suite.addTestSuite(ScenariosForSpringSecurity.class);
|
||||||
|
suite.addTestSuite(SpelUtilitiesTests.class);
|
||||||
|
suite.addTestSuite(LiteralExpressionTests.class);
|
||||||
|
suite.addTestSuite(CompositeStringExpressionTests.class);
|
||||||
// $JUnit-END$
|
// $JUnit-END$
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,12 @@ public class BooleanExpressionTests extends ExpressionTestCase {
|
||||||
evaluate("true and false or false", Boolean.FALSE, Boolean.class);
|
evaluate("true and false or false", Boolean.FALSE, Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testWritability() {
|
||||||
|
evaluate("true and true", Boolean.TRUE, Boolean.class, false);
|
||||||
|
evaluate("true or true", Boolean.TRUE, Boolean.class, false);
|
||||||
|
evaluate("!false", Boolean.TRUE, Boolean.class, false);
|
||||||
|
}
|
||||||
|
|
||||||
public void testBooleanErrors01() {
|
public void testBooleanErrors01() {
|
||||||
evaluateAndCheckError("1.0 or false", SpelMessages.TYPE_CONVERSION_ERROR, 0);
|
evaluateAndCheckError("1.0 or false", SpelMessages.TYPE_CONVERSION_ERROR, 0);
|
||||||
evaluateAndCheckError("false or 39.4", SpelMessages.TYPE_CONVERSION_ERROR, 9);
|
evaluateAndCheckError("false or 39.4", SpelMessages.TYPE_CONVERSION_ERROR, 9);
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ public class ParsingTests extends TestCase {
|
||||||
parseCheck("true");
|
parseCheck("true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLiteralBoolean03() {
|
||||||
|
parseCheck("!true");
|
||||||
|
}
|
||||||
|
|
||||||
public void testLiteralInteger01() {
|
public void testLiteralInteger01() {
|
||||||
parseCheck("1");
|
parseCheck("1");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-2008 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.expression.spel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the SpelUtilities
|
||||||
|
*
|
||||||
|
* @author Andy Clement
|
||||||
|
*/
|
||||||
|
public class SpelUtilitiesTests extends TestCase {
|
||||||
|
|
||||||
|
public void testPrintAbstractSyntaxTree01() throws Exception {
|
||||||
|
SpelExpression sEx = new SpelExpressionParser().parseExpression("1 + 2");
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
SpelUtilities.printAbstractSyntaxTree(new PrintStream(baos), sEx);
|
||||||
|
String theAst = baos.toString();
|
||||||
|
System.out.println(theAst);
|
||||||
|
String[] expectedLines = new String[] { "===> Expression '1 + 2' - AST start",
|
||||||
|
"OperatorPlus value=+ children=#2", " CompoundExpression value=EXPRESSION",
|
||||||
|
" IntLiteral value=1", " CompoundExpression value=EXPRESSION", " IntLiteral value=2",
|
||||||
|
"===> Expression '1 + 2' - AST end" };
|
||||||
|
checkExpected(theAst, expectedLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkExpected(String theData, String[] expectedLines) {
|
||||||
|
String[] theDataSplit = theData.split("\n");
|
||||||
|
if (theDataSplit.length != expectedLines.length) {
|
||||||
|
System.out.println("TheData:");
|
||||||
|
System.out.println(theData);
|
||||||
|
System.out.println("ExpectedData:\n" + expectedLines);
|
||||||
|
fail("Data incorrect, expected " + expectedLines.length + " but got " + theDataSplit.length + " lines");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < expectedLines.length; i++) {
|
||||||
|
assertEquals("Failure in comparison at line " + i, expectedLines[i], theDataSplit[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ import org.springframework.expression.common.DefaultTemplateParserContext;
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
*/
|
*/
|
||||||
public class TemplateExpressionParsing extends ExpressionTestCase {
|
public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
||||||
|
|
||||||
public void testParsingSimpleTemplateExpression01() throws Exception {
|
public void testParsingSimpleTemplateExpression01() throws Exception {
|
||||||
SpelExpressionParser parser = new SpelExpressionParser();
|
SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
@ -61,10 +61,11 @@ public class TestScenarioCreator {
|
||||||
new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE }));
|
new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE }));
|
||||||
testContext.registerFunction("reverseString", TestScenarioCreator.class.getDeclaredMethod("reverseString",
|
testContext.registerFunction("reverseString", TestScenarioCreator.class.getDeclaredMethod("reverseString",
|
||||||
new Class[] { String.class }));
|
new Class[] { String.class }));
|
||||||
testContext.registerFunction("varargsFunctionReverseStringsAndMerge", TestScenarioCreator.class.getDeclaredMethod("varargsFunctionReverseStringsAndMerge",
|
testContext.registerFunction("varargsFunctionReverseStringsAndMerge", TestScenarioCreator.class
|
||||||
new Class[] { String[].class }));
|
.getDeclaredMethod("varargsFunctionReverseStringsAndMerge", new Class[] { String[].class }));
|
||||||
testContext.registerFunction("varargsFunctionReverseStringsAndMerge2", TestScenarioCreator.class.getDeclaredMethod("varargsFunctionReverseStringsAndMerge2",
|
testContext.registerFunction("varargsFunctionReverseStringsAndMerge2", TestScenarioCreator.class
|
||||||
new Class[] { Integer.TYPE,String[].class }));
|
.getDeclaredMethod("varargsFunctionReverseStringsAndMerge2", new Class[] { Integer.TYPE,
|
||||||
|
String[].class }));
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
|
|
@ -86,8 +87,8 @@ public class TestScenarioCreator {
|
||||||
*/
|
*/
|
||||||
private static void createTestClassloader(StandardEvaluationContext testContext) {
|
private static void createTestClassloader(StandardEvaluationContext testContext) {
|
||||||
try {
|
try {
|
||||||
ClassLoader cl = new URLClassLoader(new URL[] { new File("target/test-classes/testcode.jar").toURI().toURL() },
|
ClassLoader cl = new URLClassLoader(new URL[] { new File("target/test-classes/testcode.jar").toURI()
|
||||||
Thread.currentThread().getContextClassLoader());
|
.toURL() }, Thread.currentThread().getContextClassLoader());
|
||||||
testContext.setClassLoader(cl);
|
testContext.setClassLoader(cl);
|
||||||
} catch (MalformedURLException mue) {
|
} catch (MalformedURLException mue) {
|
||||||
mue.printStackTrace();
|
mue.printStackTrace();
|
||||||
|
|
@ -97,7 +98,7 @@ public class TestScenarioCreator {
|
||||||
/**
|
/**
|
||||||
* Create the root context object, an Inventor instance. Non-qualified property and method references will be
|
* Create the root context object, an Inventor instance. Non-qualified property and method references will be
|
||||||
* resolved against this context object.
|
* resolved against this context object.
|
||||||
*
|
*
|
||||||
* @param testContext the evaluation context in which to set the root object
|
* @param testContext the evaluation context in which to set the root object
|
||||||
*/
|
*/
|
||||||
private static void setupRootContextObject(StandardEvaluationContext testContext) {
|
private static void setupRootContextObject(StandardEvaluationContext testContext) {
|
||||||
|
|
@ -113,11 +114,10 @@ public class TestScenarioCreator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a context configuration that tests can reference into using the
|
* Create a context configuration that tests can reference into using the
|
||||||
* @() language construct.
|
* @() language construct. at(context:objectName) will index a particular object within a particular context. The
|
||||||
* at(context:objectName) will index a particular object within a particular context. The 'root' context will be used
|
* 'root' context will be used for references where no context is specified, eg.
|
||||||
* for references where no context is specified, eg.
|
|
||||||
* @(orange).
|
* @(orange).
|
||||||
*
|
*
|
||||||
* @param testContext the evaluation context in which to register the new references
|
* @param testContext the evaluation context in which to register the new references
|
||||||
*/
|
*/
|
||||||
private static void populateContextMap(StandardEvaluationContext testContext) {
|
private static void populateContextMap(StandardEvaluationContext testContext) {
|
||||||
|
|
@ -205,21 +205,21 @@ public class TestScenarioCreator {
|
||||||
return backwards.toString();
|
return backwards.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String varargsFunctionReverseStringsAndMerge(String...strings) {
|
public static String varargsFunctionReverseStringsAndMerge(String... strings) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (strings!=null) {
|
if (strings != null) {
|
||||||
for (int i=strings.length-1;i>=0;i--) {
|
for (int i = strings.length - 1; i >= 0; i--) {
|
||||||
sb.append(strings[i]);
|
sb.append(strings[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String varargsFunctionReverseStringsAndMerge2(int j, String...strings) {
|
public static String varargsFunctionReverseStringsAndMerge2(int j, String... strings) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(j);
|
sb.append(j);
|
||||||
if (strings!=null) {
|
if (strings != null) {
|
||||||
for (int i=strings.length-1;i>=0;i--) {
|
for (int i = strings.length - 1; i >= 0; i--) {
|
||||||
sb.append(strings[i]);
|
sb.append(strings[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue