Organize and clean up SpEL documentation tests

This commit is contained in:
Sam Brannen 2024-02-01 16:22:14 +01:00
parent a82108ec73
commit 17ee82e004
3 changed files with 528 additions and 541 deletions

View File

@ -40,11 +40,7 @@ Java::
public abstract class StringUtils { public abstract class StringUtils {
public static String reverseString(String input) { public static String reverseString(String input) {
StringBuilder backwards = new StringBuilder(input.length()); return new StringBuilder(input).reverse().toString();
for (int i = 0; i < input.length(); i++) {
backwards.append(input.charAt(input.length() - 1 - i));
}
return backwards.toString();
} }
} }
---- ----
@ -54,11 +50,7 @@ Kotlin::
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] [source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
---- ----
fun reverseString(input: String): String { fun reverseString(input: String): String {
val backwards = StringBuilder(input.length) return StringBuilder(input).reverse().toString()
for (i in 0 until input.length) {
backwards.append(input[input.length - 1 - i])
}
return backwards.toString()
} }
---- ----
====== ======
@ -161,9 +153,9 @@ Java::
.bindTo(varargs); //here we have to provide arguments in a single array binding .bindTo(varargs); //here we have to provide arguments in a single array binding
context.setVariable("message", mh); context.setVariable("message", mh);
// evaluates to "This is a prerecorded message with 3 words: <Oh Hello World!>"
String message = parser.parseExpression("#message()") String message = parser.parseExpression("#message()")
.getValue(context, String.class); .getValue(context, String.class);
//returns "This is a prerecorded message with 3 words: <Oh Hello World!>"
---- ----
Kotlin:: Kotlin::
@ -182,6 +174,7 @@ Kotlin::
.bindTo(varargs) //here we have to provide arguments in a single array binding .bindTo(varargs) //here we have to provide arguments in a single array binding
context.setVariable("message", mh) context.setVariable("message", mh)
// evaluates to "This is a prerecorded message with 3 words: <Oh Hello World!>"
val message = parser.parseExpression("#message()") val message = parser.parseExpression("#message()")
.getValue(context, String::class.java) .getValue(context, String::class.java)
---- ----

View File

@ -1,5 +1,5 @@
[[expressions-templating]] [[expressions-templating]]
= Expression templating = Expression Templating
Expression templates allow mixing literal text with one or more evaluation blocks. Expression templates allow mixing literal text with one or more evaluation blocks.
Each evaluation block is delimited with prefix and suffix characters that you can Each evaluation block is delimited with prefix and suffix characters that you can
@ -32,53 +32,13 @@ Kotlin::
====== ======
The string is evaluated by concatenating the literal text `'random number is '` with the The string is evaluated by concatenating the literal text `'random number is '` with the
result of evaluating the expression inside the `#{ }` delimiter (in this case, the result result of evaluating the expression inside the `#{ }` delimiters (in this case, the
of calling that `random()` method). The second argument to the `parseExpression()` method result of calling that `random()` method). The second argument to the `parseExpression()`
is of the type `ParserContext`. The `ParserContext` interface is used to influence how method is of the type `ParserContext`. The `ParserContext` interface is used to influence
the expression is parsed in order to support the expression templating functionality. how the expression is parsed in order to support the expression templating functionality.
The definition of `TemplateParserContext` follows: The `TemplateParserContext` used in the previous example resides in the
`org.springframework.expression.common` package and is an implementation of the
[tabs] `ParserContext` which by default configures the prefix and suffix to `#{` and `}`,
====== respectively.
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
public class TemplateParserContext implements ParserContext {
public String getExpressionPrefix() {
return "#{";
}
public String getExpressionSuffix() {
return "}";
}
public boolean isTemplate() {
return true;
}
}
----
Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
class TemplateParserContext : ParserContext {
override fun getExpressionPrefix(): String {
return "#{"
}
override fun getExpressionSuffix(): String {
return "}"
}
override fun isTemplate(): Boolean {
return true
}
}
----
======

View File

@ -26,12 +26,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser; import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext; import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext; import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.expression.spel.support.StandardEvaluationContext;
@ -53,9 +54,9 @@ import static org.assertj.core.api.Assertions.within;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
class SpelDocumentationTests extends AbstractExpressionTests { class SpelDocumentationTests extends AbstractExpressionTests {
static Inventor tesla; private static final Inventor tesla;
static Inventor pupin; private static final Inventor pupin;
static { static {
GregorianCalendar c = new GregorianCalendar(); GregorianCalendar c = new GregorianCalendar();
@ -71,6 +72,9 @@ class SpelDocumentationTests extends AbstractExpressionTests {
} }
@Nested
class Miscellaneous {
@Test @Test
void methodInvocation() { void methodInvocation() {
evaluate("'Hello World'.concat('!')", "Hello World!", String.class); evaluate("'Hello World'.concat('!')", "Hello World!", String.class);
@ -115,15 +119,20 @@ class SpelDocumentationTests extends AbstractExpressionTests {
boolean isEqual = exp.getValue(context, Boolean.class); // evaluates to true boolean isEqual = exp.getValue(context, Boolean.class); // evaluates to true
assertThat(isEqual).isTrue(); assertThat(isEqual).isTrue();
} }
}
// Section 7.4.1 @Nested
class ExpressionsInBeanDefinitions {
@Test @Test
void xmlBasedConfig() { void xmlBasedConfig() {
evaluate("(T(java.lang.Math).random() * 100.0 )>0",true,Boolean.class); evaluate("(T(java.lang.Math).random() * 100.0 )>0",true,Boolean.class);
} }
}
@Nested
class LiteralExpressions {
// Section 7.5
@Test @Test
void literals() { void literals() {
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
@ -143,6 +152,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
Object nullValue = parser.parseExpression("null").getValue(); Object nullValue = parser.parseExpression("null").getValue();
assertThat(nullValue).isNull(); assertThat(nullValue).isNull();
} }
}
@Nested
class PropertiesArraysListsMapsAndIndexers {
@Test @Test
void propertyAccess() { void propertyAccess() {
@ -183,10 +196,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
} }
@Test @Test
void dictionaryAccess() { void maps() {
StandardEvaluationContext societyContext = new StandardEvaluationContext(); StandardEvaluationContext societyContext = new StandardEvaluationContext();
societyContext.setRootObject(new IEEE()); societyContext.setRootObject(new IEEE());
// Officer's Dictionary // Officer's map
Inventor pupin = parser.parseExpression("officers['president']").getValue(societyContext, Inventor.class); Inventor pupin = parser.parseExpression("officers['president']").getValue(societyContext, Inventor.class);
assertThat(pupin).isNotNull(); assertThat(pupin).isNotNull();
@ -203,9 +216,13 @@ class SpelDocumentationTests extends AbstractExpressionTests {
Inventor i2 = parser.parseExpression("reverse[0]['advisors'][0]").getValue(societyContext,Inventor.class); Inventor i2 = parser.parseExpression("reverse[0]['advisors'][0]").getValue(societyContext,Inventor.class);
assertThat(i2.getName()).isEqualTo("Nikola Tesla"); assertThat(i2.getName()).isEqualTo("Nikola Tesla");
} }
}
@Nested
class Methods {
@Test @Test
void methodInvocation2() { void methodInvocation() {
// string literal, evaluates to "bc" // string literal, evaluates to "bc"
String c = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class); String c = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);
assertThat(c).isEqualTo("bc"); assertThat(c).isEqualTo("bc");
@ -216,9 +233,13 @@ class SpelDocumentationTests extends AbstractExpressionTests {
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class); boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class);
assertThat(isMember).isTrue(); assertThat(isMember).isTrue();
} }
}
@Nested
class Operators {
@Test @Test
void relationalOperators() { void standardRelationalOperators() {
boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class); boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class);
assertThat(result).isTrue(); assertThat(result).isTrue();
@ -232,7 +253,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
} }
@Test @Test
void otherOperators() { void otherRelationalOperators() {
boolean result; boolean result;
// evaluates to true // evaluates to true
@ -426,6 +447,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
assertThat(parser.parseExpression("foo").getValue(context, inventor, String.class)).isEqualTo("Alexandar Seovic"); assertThat(parser.parseExpression("foo").getValue(context, inventor, String.class)).isEqualTo("Alexandar Seovic");
assertThat(aleks).isEqualTo("Alexandar Seovic"); assertThat(aleks).isEqualTo("Alexandar Seovic");
} }
}
@Nested
class Types {
@Test @Test
void types() { void types() {
@ -434,6 +459,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
boolean trueValue = parser.parseExpression("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR").getValue(Boolean.class); boolean trueValue = parser.parseExpression("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR").getValue(Boolean.class);
assertThat(trueValue).isTrue(); assertThat(trueValue).isTrue();
} }
}
@Nested
class Constructors {
@Test @Test
void constructors() { void constructors() {
@ -445,6 +474,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
//create new inventor instance within add method of List //create new inventor instance within add method of List
parser.parseExpression("Members2.add(new org.springframework.expression.spel.testresources.Inventor('Albert Einstein', 'German'))").getValue(societyContext); parser.parseExpression("Members2.add(new org.springframework.expression.spel.testresources.Inventor('Albert Einstein', 'German'))").getValue(societyContext);
} }
}
@Nested
class Variables {
@Test @Test
void variables() { void variables() {
@ -504,6 +537,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
"Nikola Tesla invented the Telephone repeater.", "Nikola Tesla invented the Telephone repeater.",
"Nikola Tesla invented the Tesla coil transformer."); "Nikola Tesla invented the Tesla coil transformer.");
} }
}
@Nested
class Functions {
@Test @Test
void functions() throws Exception { void functions() throws Exception {
@ -516,7 +553,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
} }
@Test @Test
void methodHandlesNotBound() throws Throwable { void methodHandlesNotBound() throws Exception {
ExpressionParser parser = new SpelExpressionParser(); ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(); StandardEvaluationContext context = new StandardEvaluationContext();
@ -546,6 +583,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
.getValue(context, String.class); .getValue(context, String.class);
assertThat(message).isEqualTo("This is a prerecorded message with 3 words: <Oh Hello World!>"); assertThat(message).isEqualTo("This is a prerecorded message with 3 words: <Oh Hello World!>");
} }
}
@Nested
class TernaryOperator {
@Test @Test
void ternary() { void ternary() {
@ -566,6 +607,10 @@ class SpelDocumentationTests extends AbstractExpressionTests {
assertThat(queryResultString).isEqualTo("Nikola Tesla is a member of the IEEE Society"); assertThat(queryResultString).isEqualTo("Nikola Tesla is a member of the IEEE Society");
// queryResultString = "Nikola Tesla is a member of the IEEE Society" // queryResultString = "Nikola Tesla is a member of the IEEE Society"
} }
}
@Nested
class CollectionSelection {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -576,31 +621,20 @@ class SpelDocumentationTests extends AbstractExpressionTests {
assertThat(list).hasSize(1); assertThat(list).hasSize(1);
assertThat(list.get(0).getName()).isEqualTo("Nikola Tesla"); assertThat(list.get(0).getName()).isEqualTo("Nikola Tesla");
} }
}
@Nested
class ExpressionTemplating {
@Test @Test
void templating() { void templating() {
String randomPhrase = String randomPhrase =
parser.parseExpression("random number is ${T(java.lang.Math).random()}", new TemplatedParserContext()).getValue(String.class); parser.parseExpression("random number is ${T(java.lang.Math).random()}",
new TemplateParserContext()).getValue(String.class);
assertThat(randomPhrase).startsWith("random number"); assertThat(randomPhrase).startsWith("random number");
} }
static class TemplatedParserContext implements ParserContext {
@Override
public String getExpressionPrefix() {
return "${";
} }
@Override
public String getExpressionSuffix() {
return "}";
}
@Override
public boolean isTemplate() {
return true;
}
}
static class IEEE { static class IEEE {
private String name; private String name;