Browse Source

Test status quo for null in varargs in SpEL expressions

This commit also points out that `null` supplied as a single value for
a varargs array of type Optional will be kept as `null` instead of being
converted to Optional.empty(); whereas, if more than one value is passed
to such a varargs array a null value will be properly converted to
Optional.empty().

See gh-27719
pull/28694/head
Sam Brannen 4 years ago
parent
commit
e03e62c76a
  1. 63
      spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java
  2. 32
      spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java
  3. 27
      spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java
  4. 21
      spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java

63
spring-expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@ -46,6 +46,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -46,6 +46,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*
* @author Andy Clement
* @author Phillip Webb
* @author Sam Brannen
*/
public class MethodInvocationTests extends AbstractExpressionTests {
@ -232,26 +233,54 @@ public class MethodInvocationTests extends AbstractExpressionTests { @@ -232,26 +233,54 @@ public class MethodInvocationTests extends AbstractExpressionTests {
@Test
public void testVarargsInvocation01() {
// Calling 'public int aVarargsMethod(String... strings)'
//evaluate("aVarargsMethod('a','b','c')", 3, Integer.class);
//evaluate("aVarargsMethod('a')", 1, Integer.class);
evaluate("aVarargsMethod()", 0, Integer.class);
evaluate("aVarargsMethod(1,2,3)", 3, Integer.class); // all need converting to strings
evaluate("aVarargsMethod(1)", 1, Integer.class); // needs string conversion
evaluate("aVarargsMethod(1,'a',3.0d)", 3, Integer.class); // first and last need conversion
// evaluate("aVarargsMethod(new String[]{'a','b','c'})", 3, Integer.class);
// Calling 'public String aVarargsMethod(String... strings)'
evaluate("aVarargsMethod('a','b','c')", "[a, b, c]", String.class);
evaluate("aVarargsMethod('a')", "[a]", String.class);
evaluate("aVarargsMethod()", "[]", String.class);
evaluate("aVarargsMethod(1,2,3)", "[1, 2, 3]", String.class); // all need converting to strings
evaluate("aVarargsMethod(1)", "[1]", String.class); // needs string conversion
evaluate("aVarargsMethod(1,'a',3.0d)", "[1, a, 3.0]", String.class); // first and last need conversion
evaluate("aVarargsMethod(new String[]{'a','b','c'})", "[a, b, c]", String.class);
evaluate("aVarargsMethod(new String[]{})", "[]", String.class);
evaluate("aVarargsMethod(null)", "[null]", String.class);
evaluate("aVarargsMethod(null,'a')", "[null, a]", String.class);
evaluate("aVarargsMethod('a',null,'b')", "[a, null, b]", String.class);
}
@Test
public void testVarargsInvocation02() {
// Calling 'public int aVarargsMethod2(int i, String... strings)' - returns int+length_of_strings
evaluate("aVarargsMethod2(5,'a','b','c')", 8, Integer.class);
evaluate("aVarargsMethod2(2,'a')", 3, Integer.class);
evaluate("aVarargsMethod2(4)", 4, Integer.class);
evaluate("aVarargsMethod2(8,2,3)", 10, Integer.class);
evaluate("aVarargsMethod2(9)", 9, Integer.class);
evaluate("aVarargsMethod2(2,'a',3.0d)", 4, Integer.class);
// evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class);
// Calling 'public String aVarargsMethod2(int i, String... strings)'
evaluate("aVarargsMethod2(5,'a','b','c')", "5-[a, b, c]", String.class);
evaluate("aVarargsMethod2(2,'a')", "2-[a]", String.class);
evaluate("aVarargsMethod2(4)", "4-[]", String.class);
evaluate("aVarargsMethod2(8,2,3)", "8-[2, 3]", String.class);
evaluate("aVarargsMethod2(2,'a',3.0d)", "2-[a, 3.0]", String.class);
evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", "8-[a, b, c]", String.class);
evaluate("aVarargsMethod2(8,new String[]{})", "8-[]", String.class);
evaluate("aVarargsMethod2(8,null)", "8-[null]", String.class);
evaluate("aVarargsMethod2(8,null,'a')", "8-[null, a]", String.class);
evaluate("aVarargsMethod2(8,'a',null,'b')", "8-[a, null, b]", String.class);
}
@Test
public void testVarargsOptionalInvocation() {
// Calling 'public String optionalVarargsMethod(Optional<String>... values)'
evaluate("optionalVarargsMethod()", "[]", String.class);
evaluate("optionalVarargsMethod(new String[0])", "[]", String.class);
evaluate("optionalVarargsMethod('a')", "[Optional[a]]", String.class);
evaluate("optionalVarargsMethod('a','b','c')", "[Optional[a], Optional[b], Optional[c]]", String.class);
evaluate("optionalVarargsMethod(9)", "[Optional[9]]", String.class);
evaluate("optionalVarargsMethod(2,3)", "[Optional[2], Optional[3]]", String.class);
evaluate("optionalVarargsMethod('a',3.0d)", "[Optional[a], Optional[3.0]]", String.class);
evaluate("optionalVarargsMethod(new String[]{'a','b','c'})", "[Optional[a], Optional[b], Optional[c]]", String.class);
// The following should actually evaluate to [Optional.empty] instead of [null],
// but ReflectionHelper.convertArguments() passes the array type instead of
// the array's component type as the target type to the ConversionService, and
// GenericConversionService.convertNullSource() therefore fails to convert null
// to Optional.empty().
evaluate("optionalVarargsMethod(null)", "[null]", String.class);
evaluate("optionalVarargsMethod(null,'a')", "[Optional.empty, Optional[a]]", String.class);
evaluate("optionalVarargsMethod('a',null,'b')", "[Optional[a], Optional.empty, Optional[b]]", String.class);
}
@Test

32
spring-expression/src/test/java/org/springframework/expression/spel/TestScenarioCreator.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2021 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.
@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.expression.spel;
import java.util.Arrays;
import java.util.GregorianCalendar;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@ -51,10 +52,10 @@ public class TestScenarioCreator { @@ -51,10 +52,10 @@ public class TestScenarioCreator {
TestScenarioCreator.class.getDeclaredMethod("reverseInt", Integer.TYPE, Integer.TYPE, Integer.TYPE));
testContext.registerFunction("reverseString",
TestScenarioCreator.class.getDeclaredMethod("reverseString", String.class));
testContext.registerFunction("varargsFunctionReverseStringsAndMerge",
TestScenarioCreator.class.getDeclaredMethod("varargsFunctionReverseStringsAndMerge", String[].class));
testContext.registerFunction("varargsFunctionReverseStringsAndMerge2",
TestScenarioCreator.class.getDeclaredMethod("varargsFunctionReverseStringsAndMerge2", Integer.TYPE, String[].class));
testContext.registerFunction("varargsFunction",
TestScenarioCreator.class.getDeclaredMethod("varargsFunction", String[].class));
testContext.registerFunction("varargsFunction2",
TestScenarioCreator.class.getDeclaredMethod("varargsFunction2", Integer.TYPE, String[].class));
}
catch (Exception ex) {
throw new IllegalStateException(ex);
@ -108,25 +109,12 @@ public class TestScenarioCreator { @@ -108,25 +109,12 @@ public class TestScenarioCreator {
return backwards.toString();
}
public static String varargsFunctionReverseStringsAndMerge(String... strings) {
StringBuilder sb = new StringBuilder();
if (strings != null) {
for (int i = strings.length - 1; i >= 0; i--) {
sb.append(strings[i]);
}
}
return sb.toString();
public static String varargsFunction(String... strings) {
return Arrays.toString(strings);
}
public static String varargsFunctionReverseStringsAndMerge2(int j, String... strings) {
StringBuilder sb = new StringBuilder();
sb.append(j);
if (strings != null) {
for (int i = strings.length - 1; i >= 0; i--) {
sb.append(strings[i]);
}
}
return sb.toString();
public static String varargsFunction2(int i, String... strings) {
return String.valueOf(i) + "-" + Arrays.toString(strings);
}
}

27
spring-expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java

@ -58,16 +58,23 @@ public class VariableAndFunctionTests extends AbstractExpressionTests { @@ -58,16 +58,23 @@ public class VariableAndFunctionTests extends AbstractExpressionTests {
@Test
public void testCallVarargsFunction() {
evaluate("#varargsFunctionReverseStringsAndMerge('a','b','c')", "cba", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge('a')", "a", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge()", "", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge('b',25)", "25b", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge(25)", "25", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge2(1,'a','b','c')", "1cba", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge2(2,'a')", "2a", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge2(3)", "3", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge2(4,'b',25)", "425b", String.class);
evaluate("#varargsFunctionReverseStringsAndMerge2(5,25)", "525", String.class);
evaluate("#varargsFunction()", "[]", String.class);
evaluate("#varargsFunction(new String[0])", "[]", String.class);
evaluate("#varargsFunction('a','b','c')", "[a, b, c]", String.class);
evaluate("#varargsFunction('a')", "[a]", String.class);
evaluate("#varargsFunction('b',25)", "[b, 25]", String.class);
evaluate("#varargsFunction(25)", "[25]", String.class);
evaluate("#varargsFunction(null)", "[null]", String.class);
evaluate("#varargsFunction('a',null,'b')", "[a, null, b]", String.class);
evaluate("#varargsFunction2(9)", "9-[]", String.class);
evaluate("#varargsFunction2(9, new String[0])", "9-[]", String.class);
evaluate("#varargsFunction2(9,'a','b','c')", "9-[a, b, c]", String.class);
evaluate("#varargsFunction2(9,'a')", "9-[a]", String.class);
evaluate("#varargsFunction2(9,'b',25)", "9-[b, 25]", String.class);
evaluate("#varargsFunction2(9,25)", "9-[25]", String.class);
evaluate("#varargsFunction2(9,null)", "9-[null]", String.class);
evaluate("#varargsFunction2(9,'a',null,'b')", "9-[a, null, b]", String.class);
}
@Test

21
spring-expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2021 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.
@ -17,11 +17,13 @@ @@ -17,11 +17,13 @@
package org.springframework.expression.spel.testresources;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.util.ObjectUtils;
@ -190,16 +192,17 @@ public class Inventor { @@ -190,16 +192,17 @@ public class Inventor {
return a + b + c;
}
public int aVarargsMethod(String... strings) {
if (strings == null)
return 0;
return strings.length;
public String aVarargsMethod(String... strings) {
return Arrays.toString(strings);
}
public int aVarargsMethod2(int i, String... strings) {
if (strings == null)
return i;
return strings.length + i;
public String aVarargsMethod2(int i, String... strings) {
return String.valueOf(i) + "-" + Arrays.toString(strings);
}
@SuppressWarnings("unchecked")
public String optionalVarargsMethod(Optional<String>... values) {
return Arrays.toString(values);
}
public Inventor(String... strings) {

Loading…
Cancel
Save