Browse Source

Polish SpelParserTests and TemplateExpressionParsingTests

pull/30416/head
Sam Brannen 3 years ago
parent
commit
5afd94f90f
  1. 39
      spring-expression/src/test/java/org/springframework/expression/spel/TemplateExpressionParsingTests.java
  2. 189
      spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java

39
spring-expression/src/test/java/org/springframework/expression/spel/TemplateExpressionParsingTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2023 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.
@ -34,10 +34,11 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -34,10 +34,11 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Andy Clement
* @author Juergen Hoeller
* @author Sam Brannen
*/
public class TemplateExpressionParsingTests extends AbstractExpressionTests {
class TemplateExpressionParsingTests extends AbstractExpressionTests {
public static final ParserContext DEFAULT_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
static final ParserContext DEFAULT_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
@Override
public String getExpressionPrefix() {
return "${";
@ -52,7 +53,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -52,7 +53,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
};
public static final ParserContext HASH_DELIMITED_PARSER_CONTEXT = new ParserContext() {
static final ParserContext HASH_DELIMITED_PARSER_CONTEXT = new ParserContext() {
@Override
public String getExpressionPrefix() {
return "#{";
@ -68,25 +69,25 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -68,25 +69,25 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
};
private final SpelExpressionParser parser = new SpelExpressionParser();
@Test
public void testParsingSimpleTemplateExpression01() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void parsingSimpleTemplateExpression01() {
Expression expr = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
Object o = expr.getValue();
assertThat(o.toString()).isEqualTo("hello world");
}
@Test
public void testParsingSimpleTemplateExpression02() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void parsingSimpleTemplateExpression02() {
Expression expr = parser.parseExpression("hello ${'to'} you", DEFAULT_TEMPLATE_PARSER_CONTEXT);
Object o = expr.getValue();
assertThat(o.toString()).isEqualTo("hello to you");
}
@Test
public void testParsingSimpleTemplateExpression03() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void parsingSimpleTemplateExpression03() {
Expression expr = parser.parseExpression("The quick ${'brown'} fox jumped over the ${'lazy'} dog",
DEFAULT_TEMPLATE_PARSER_CONTEXT);
Object o = expr.getValue();
@ -94,8 +95,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -94,8 +95,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
@Test
public void testParsingSimpleTemplateExpression04() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void parsingSimpleTemplateExpression04() {
Expression expr = parser.parseExpression("${'hello'} world", DEFAULT_TEMPLATE_PARSER_CONTEXT);
Object o = expr.getValue();
assertThat(o.toString()).isEqualTo("hello world");
@ -114,8 +114,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -114,8 +114,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
@Test
public void testCompositeStringExpression() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void compositeStringExpression() {
Expression ex = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
assertThat(ex.getValue()).isInstanceOf(String.class).isEqualTo("hello world");
assertThat(ex.getValue(String.class)).isInstanceOf(String.class).isEqualTo("hello world");
@ -154,8 +153,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -154,8 +153,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
static class Rooty {}
@Test
public void testNestedExpressions() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
void nestedExpressions() {
// treat the nested ${..} as a part of the expression
Expression ex = parser.parseExpression("hello ${listOfNumbersUpToTen.$[#this<5]} world",DEFAULT_TEMPLATE_PARSER_CONTEXT);
String s = ex.getValue(TestScenarioCreator.getTestEvaluationContext(),String.class);
@ -185,8 +183,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -185,8 +183,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
@Test
public void testClashingWithSuffixes() throws Exception {
void clashingWithSuffixes() {
// Just wanting to use the prefix or suffix within the template:
Expression ex = parser.parseExpression("hello ${3+4} world",DEFAULT_TEMPLATE_PARSER_CONTEXT);
String s = ex.getValue(TestScenarioCreator.getTestEvaluationContext(),String.class);
@ -202,13 +199,13 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -202,13 +199,13 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
@Test
public void testParsingNormalExpressionThroughTemplateParser() throws Exception {
void parsingNormalExpressionThroughTemplateParser() {
Expression expr = parser.parseExpression("1+2+3");
assertThat(expr.getValue()).isEqualTo(6);
}
@Test
public void testErrorCases() throws Exception {
void errorCases() {
assertThatExceptionOfType(ParseException.class).isThrownBy(() ->
parser.parseExpression("hello ${'world'", DEFAULT_TEMPLATE_PARSER_CONTEXT))
.satisfies(pex -> {
@ -224,7 +221,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests { @@ -224,7 +221,7 @@ public class TemplateExpressionParsingTests extends AbstractExpressionTests {
}
@Test
public void testTemplateParserContext() {
void testTemplateParserContext() {
TemplateParserContext tpc = new TemplateParserContext("abc","def");
assertThat(tpc.getExpressionPrefix()).isEqualTo("abc");
assertThat(tpc.getExpressionSuffix()).isEqualTo("def");

189
spring-expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 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.
@ -18,6 +18,8 @@ package org.springframework.expression.spel.standard; @@ -18,6 +18,8 @@ package org.springframework.expression.spel.standard;
import java.util.function.Consumer;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.assertj.core.api.ThrowableAssertAlternative;
import org.junit.jupiter.api.Test;
import org.springframework.expression.EvaluationContext;
@ -31,16 +33,28 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -31,16 +33,28 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.expression.spel.SpelMessage.MISSING_CONSTRUCTOR_ARGS;
import static org.springframework.expression.spel.SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING;
import static org.springframework.expression.spel.SpelMessage.NON_TERMINATING_QUOTED_STRING;
import static org.springframework.expression.spel.SpelMessage.NOT_AN_INTEGER;
import static org.springframework.expression.spel.SpelMessage.NOT_A_LONG;
import static org.springframework.expression.spel.SpelMessage.REAL_CANNOT_BE_LONG;
import static org.springframework.expression.spel.SpelMessage.RUN_OUT_OF_ARGUMENTS;
import static org.springframework.expression.spel.SpelMessage.UNEXPECTED_DATA_AFTER_DOT;
import static org.springframework.expression.spel.SpelMessage.UNEXPECTED_ESCAPE_CHAR;
/**
* @author Andy Clement
* @author Juergen Hoeller
* @author Sam Brannen
*/
class SpelParserTests {
private final SpelExpressionParser parser = new SpelExpressionParser();
@Test
void theMostBasic() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2");
assertThat(expr).isNotNull();
assertThat(expr.getAST()).isNotNull();
@ -51,7 +65,6 @@ class SpelParserTests { @@ -51,7 +65,6 @@ class SpelParserTests {
@Test
void valueType() {
SpelExpressionParser parser = new SpelExpressionParser();
EvaluationContext ctx = new StandardEvaluationContext();
Class<?> c = parser.parseRaw("2").getValueType();
assertThat(c).isEqualTo(Integer.class);
@ -67,7 +80,6 @@ class SpelParserTests { @@ -67,7 +80,6 @@ class SpelParserTests {
@Test
void whitespace() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2 + 3");
assertThat(expr.getValue()).isEqualTo(5);
expr = parser.parseRaw("2 + 3");
@ -80,7 +92,6 @@ class SpelParserTests { @@ -80,7 +92,6 @@ class SpelParserTests {
@Test
void arithmeticPlus1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+2");
assertThat(expr).isNotNull();
assertThat(expr.getAST()).isNotNull();
@ -89,14 +100,12 @@ class SpelParserTests { @@ -89,14 +100,12 @@ class SpelParserTests {
@Test
void arithmeticPlus2() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("37+41");
assertThat(expr.getValue()).isEqualTo(78);
}
@Test
void arithmeticMultiply1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3");
assertThat(expr).isNotNull();
assertThat(expr.getAST()).isNotNull();
@ -105,162 +114,120 @@ class SpelParserTests { @@ -105,162 +114,120 @@ class SpelParserTests {
@Test
void arithmeticPrecedence1() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3+5");
assertThat(expr.getValue()).isEqualTo(11);
}
@Test
void generalExpressions() {
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String");
})
.satisfies(parseExceptionRequirements(SpelMessage.MISSING_CONSTRUCTOR_ARGS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3,");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(");
})
.satisfies(parseExceptionRequirements(SpelMessage.RUN_OUT_OF_ARGUMENTS, 10));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("\"abc");
})
.satisfies(parseExceptionRequirements(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING, 0));
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("'abc");
})
.satisfies(parseExceptionRequirements(SpelMessage.NON_TERMINATING_QUOTED_STRING, 0));
}
private <E extends SpelParseException> Consumer<E> parseExceptionRequirements(
SpelMessage expectedMessage, int expectedPosition) {
return ex -> {
assertThat(ex.getMessageCode()).isEqualTo(expectedMessage);
assertThat(ex.getPosition()).isEqualTo(expectedPosition);
assertThat(ex.getMessage()).contains(ex.getExpressionString());
};
void parseExceptions() {
assertParseException(() -> parser.parseRaw("new String"), MISSING_CONSTRUCTOR_ARGS, 10);
assertParseException(() -> parser.parseRaw("new String(3,"), RUN_OUT_OF_ARGUMENTS, 10);
assertParseException(() -> parser.parseRaw("new String(3"), RUN_OUT_OF_ARGUMENTS, 10);
assertParseException(() -> parser.parseRaw("new String("), RUN_OUT_OF_ARGUMENTS, 10);
assertParseException(() -> parser.parseRaw("\"abc"), NON_TERMINATING_DOUBLE_QUOTED_STRING, 0);
assertParseException(() -> parser.parseRaw("'abc"), NON_TERMINATING_QUOTED_STRING, 0);
}
@Test
void arithmeticPrecedence2() {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+3*5");
assertThat(expr.getValue()).isEqualTo(17);
}
@Test
void arithmeticPrecedence3() {
SpelExpression expr = new SpelExpressionParser().parseRaw("3+10/2");
SpelExpression expr = parser.parseRaw("3+10/2");
assertThat(expr.getValue()).isEqualTo(8);
}
@Test
void arithmeticPrecedence4() {
SpelExpression expr = new SpelExpressionParser().parseRaw("10/2+3");
SpelExpression expr = parser.parseRaw("10/2+3");
assertThat(expr.getValue()).isEqualTo(8);
}
@Test
void arithmeticPrecedence5() {
SpelExpression expr = new SpelExpressionParser().parseRaw("(4+10)/2");
SpelExpression expr = parser.parseRaw("(4+10)/2");
assertThat(expr.getValue()).isEqualTo(7);
}
@Test
void arithmeticPrecedence6() {
SpelExpression expr = new SpelExpressionParser().parseRaw("(3+2)*2");
SpelExpression expr = parser.parseRaw("(3+2)*2");
assertThat(expr.getValue()).isEqualTo(10);
}
@Test
void booleanOperators() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("false and false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("true and (true or false)");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("true and true or false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("!true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("!(false or true)");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
SpelExpression expr = parser.parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("false");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("false and false");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("true and (true or false)");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("true and true or false");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("!true");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("!(false or true)");
assertThat(expr.getValue(Boolean.class)).isFalse();
}
@Test
void booleanOperators_symbolic_spr9614() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("false && false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("true && (true || false)");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("true && true || false");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.TRUE);
expr = new SpelExpressionParser().parseRaw("!true");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
expr = new SpelExpressionParser().parseRaw("!(false || true)");
assertThat(expr.getValue(Boolean.class)).isEqualTo(Boolean.FALSE);
SpelExpression expr = parser.parseRaw("true");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("false");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("false && false");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("true && (true || false)");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("true && true || false");
assertThat(expr.getValue(Boolean.class)).isTrue();
expr = parser.parseRaw("!true");
assertThat(expr.getValue(Boolean.class)).isFalse();
expr = parser.parseRaw("!(false || true)");
assertThat(expr.getValue(Boolean.class)).isFalse();
}
@Test
void stringLiterals() {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'");
SpelExpression expr = parser.parseRaw("'howdy'");
assertThat(expr.getValue()).isEqualTo("howdy");
expr = new SpelExpressionParser().parseRaw("'hello '' world'");
expr = parser.parseRaw("'hello '' world'");
assertThat(expr.getValue()).isEqualTo("hello ' world");
}
@Test
void stringLiterals2() {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'.substring(0,2)");
SpelExpression expr = parser.parseRaw("'howdy'.substring(0,2)");
assertThat(expr.getValue()).isEqualTo("ho");
}
@Test
void testStringLiterals_DoubleQuotes_spr9620() {
SpelExpression expr = new SpelExpressionParser().parseRaw("\"double quote: \"\".\"");
SpelExpression expr = parser.parseRaw("\"double quote: \"\".\"");
assertThat(expr.getValue()).isEqualTo("double quote: \".");
expr = new SpelExpressionParser().parseRaw("\"hello \"\" world\"");
expr = parser.parseRaw("\"hello \"\" world\"");
assertThat(expr.getValue()).isEqualTo("hello \" world");
}
@Test
void testStringLiterals_DoubleQuotes_spr9620_2() {
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() ->
new SpelExpressionParser().parseRaw("\"double quote: \\\"\\\".\""))
assertParseExceptionThrownBy(() -> parser.parseRaw("\"double quote: \\\"\\\".\""))
.satisfies(ex -> {
assertThat(ex.getPosition()).isEqualTo(17);
assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.UNEXPECTED_ESCAPE_CHAR);
assertThat(ex.getMessageCode()).isEqualTo(UNEXPECTED_ESCAPE_CHAR);
});
}
@Test
void positionalInformation() {
SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false");
SpelExpression expr = parser.parseRaw("true and true or false");
SpelNode rootAst = expr.getAST();
OpOr operatorOr = (OpOr) rootAst;
OpAnd operatorAnd = (OpAnd) operatorOr.getLeftOperand();
@ -355,10 +322,10 @@ class SpelParserTests { @@ -355,10 +322,10 @@ class SpelParserTests {
checkNumber("0xa", 10, Integer.class);
checkNumber("0xAL", 10L, Long.class);
checkNumberError("0x", SpelMessage.NOT_AN_INTEGER);
checkNumberError("0xL", SpelMessage.NOT_A_LONG);
checkNumberError(".324", SpelMessage.UNEXPECTED_DATA_AFTER_DOT);
checkNumberError("3.4L", SpelMessage.REAL_CANNOT_BE_LONG);
checkNumberError("0x", NOT_AN_INTEGER);
checkNumberError("0xL", NOT_A_LONG);
checkNumberError(".324", UNEXPECTED_DATA_AFTER_DOT);
checkNumberError("3.4L", REAL_CANNOT_BE_LONG);
checkNumber("3.5f", 3.5f, Float.class);
checkNumber("1.2e3", 1.2e3d, Double.class);
@ -371,7 +338,6 @@ class SpelParserTests { @@ -371,7 +338,6 @@ class SpelParserTests {
private void checkNumber(String expression, Object value, Class<?> type) {
try {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw(expression);
Object exprVal = expr.getValue();
assertThat(exprVal).isEqualTo(value);
@ -383,9 +349,26 @@ class SpelParserTests { @@ -383,9 +349,26 @@ class SpelParserTests {
}
private void checkNumberError(String expression, SpelMessage expectedMessage) {
SpelExpressionParser parser = new SpelExpressionParser();
assertThatExceptionOfType(SpelParseException.class).isThrownBy(() -> parser.parseRaw(expression))
assertParseExceptionThrownBy(() -> parser.parseRaw(expression))
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(expectedMessage));
}
private static ThrowableAssertAlternative<SpelParseException> assertParseExceptionThrownBy(ThrowingCallable throwingCallable) {
return assertThatExceptionOfType(SpelParseException.class).isThrownBy(throwingCallable);
}
private static void assertParseException(ThrowingCallable throwingCallable, SpelMessage expectedMessage, int expectedPosition) {
assertParseExceptionThrownBy(throwingCallable)
.satisfies(parseExceptionRequirements(expectedMessage, expectedPosition));
}
private static <E extends SpelParseException> Consumer<E> parseExceptionRequirements(
SpelMessage expectedMessage, int expectedPosition) {
return ex -> {
assertThat(ex.getMessageCode()).isEqualTo(expectedMessage);
assertThat(ex.getPosition()).isEqualTo(expectedPosition);
assertThat(ex.getMessage()).contains(ex.getExpressionString());
};
}
}

Loading…
Cancel
Save