|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2019 the original author or authors. |
|
|
|
* Copyright 2002-2022 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.expression.Expression; |
|
|
|
import org.springframework.expression.Expression; |
|
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser; |
|
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser; |
|
|
|
|
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
|
|
|
|
|
|
@ -27,45 +28,33 @@ import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
* Test construction of arrays. |
|
|
|
* Test construction of arrays. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Andy Clement |
|
|
|
* @author Andy Clement |
|
|
|
|
|
|
|
* @author Sam Brannen |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ArrayConstructorTests extends AbstractExpressionTests { |
|
|
|
class ArrayConstructorTests extends AbstractExpressionTests { |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void simpleArrayWithInitializer() { |
|
|
|
void conversion() { |
|
|
|
evaluateArrayBuildingExpression("new int[]{1,2,3}", "[1,2,3]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new int[]{}", "[]"); |
|
|
|
|
|
|
|
evaluate("new int[]{}.length", "0", Integer.class); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void conversion() { |
|
|
|
|
|
|
|
evaluate("new String[]{1,2,3}[0]", "1", String.class); |
|
|
|
evaluate("new String[]{1,2,3}[0]", "1", String.class); |
|
|
|
evaluate("new int[]{'123'}[0]", 123, Integer.class); |
|
|
|
evaluate("new int[]{'123'}[0]", 123, Integer.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void multidimensionalArrays() { |
|
|
|
void primitiveTypeArrayConstructors() { |
|
|
|
evaluateAndCheckError("new int[][]{{1,2},{3,4}}", SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED); |
|
|
|
evaluateArrayBuildingExpression("new int[]{}", "{}"); |
|
|
|
evaluateAndCheckError("new int[3][]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
evaluateArrayBuildingExpression("new int[]{1,2,3,4}", "{1, 2, 3, 4}"); |
|
|
|
evaluateAndCheckError("new int[]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
evaluateArrayBuildingExpression("new boolean[]{true,false,true}", "{true, false, true}"); |
|
|
|
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
evaluateArrayBuildingExpression("new char[]{'a','b','c'}", "{'a', 'b', 'c'}"); |
|
|
|
evaluateAndCheckError("new int[][1]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
evaluateArrayBuildingExpression("new long[]{1,2,3,4,5}", "{1, 2, 3, 4, 5}"); |
|
|
|
} |
|
|
|
evaluateArrayBuildingExpression("new short[]{2,3,4,5,6}", "{2, 3, 4, 5, 6}"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new double[]{1d,2d,3d,4d}", "{1.0, 2.0, 3.0, 4.0}"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new float[]{1f,2f,3f,4f}", "{1.0, 2.0, 3.0, 4.0}"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new byte[]{1,2,3,4}", "{1, 2, 3, 4}"); |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
evaluate("new int[]{}.length", "0", Integer.class); |
|
|
|
public void primitiveTypeArrayConstructors() { |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new int[]{1,2,3,4}", "[1,2,3,4]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new boolean[]{true,false,true}", "[true,false,true]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new char[]{'a','b','c'}", "[a,b,c]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new long[]{1,2,3,4,5}", "[1,2,3,4,5]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new short[]{2,3,4,5,6}", "[2,3,4,5,6]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new double[]{1d,2d,3d,4d}", "[1.0,2.0,3.0,4.0]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new float[]{1f,2f,3f,4f}", "[1.0,2.0,3.0,4.0]"); |
|
|
|
|
|
|
|
evaluateArrayBuildingExpression("new byte[]{1,2,3,4}", "[1,2,3,4]"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void primitiveTypeArrayConstructorsElements() { |
|
|
|
void primitiveTypeArrayConstructorsElements() { |
|
|
|
evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class); |
|
|
|
evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class); |
|
|
|
evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class); |
|
|
|
evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class); |
|
|
|
evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class); |
|
|
|
evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class); |
|
|
@ -78,15 +67,34 @@ public class ArrayConstructorTests extends AbstractExpressionTests { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void errorCases() { |
|
|
|
void errorCases() { |
|
|
|
|
|
|
|
evaluateAndCheckError("new int[]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
|
|
|
|
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
|
|
|
|
evaluateAndCheckError("new int[3][]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
|
|
|
|
evaluateAndCheckError("new int[][1]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
|
|
|
|
|
|
|
|
evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT); |
|
|
|
evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT); |
|
|
|
evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT); |
|
|
|
evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
evaluateAndCheckError("new int[][]{{1,2},{3,4}}", SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED); |
|
|
|
|
|
|
|
|
|
|
|
evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessage.TYPE_CONVERSION_ERROR); |
|
|
|
evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessage.TYPE_CONVERSION_ERROR); |
|
|
|
|
|
|
|
// Could conceivably be a SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, but it appears
|
|
|
|
|
|
|
|
// that SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY is not actually (no longer?) used
|
|
|
|
|
|
|
|
// in the code base.
|
|
|
|
|
|
|
|
evaluateAndCheckError("new Integer[3]{'3','ghi','5'}", SpelMessage.TYPE_CONVERSION_ERROR); |
|
|
|
|
|
|
|
|
|
|
|
evaluateAndCheckError("new String('a','c','d')", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM); |
|
|
|
evaluateAndCheckError("new String('a','c','d')", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM); |
|
|
|
|
|
|
|
// Root cause: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
|
|
|
|
|
|
|
|
evaluateAndCheckError("new java.util.ArrayList(T(java.lang.Integer).MAX_VALUE)", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int threshold = 256 * 1024; // ConstructorReference.MAX_ARRAY_ELEMENTS
|
|
|
|
|
|
|
|
evaluateAndCheckError("new int[T(java.lang.Integer).MAX_VALUE]", SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, 0, threshold); |
|
|
|
|
|
|
|
evaluateAndCheckError("new int[1024 * 1024][1024 * 1024]", SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, 0, threshold); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void typeArrayConstructors() { |
|
|
|
void typeArrayConstructors() { |
|
|
|
evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class); |
|
|
|
evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class); |
|
|
|
evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessage.METHOD_NOT_FOUND, 30, "size()", |
|
|
|
evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessage.METHOD_NOT_FOUND, 30, "size()", |
|
|
|
"java.lang.String[]"); |
|
|
|
"java.lang.String[]"); |
|
|
@ -94,113 +102,25 @@ public class ArrayConstructorTests extends AbstractExpressionTests { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void basicArray() { |
|
|
|
void basicArray() { |
|
|
|
evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class); |
|
|
|
evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void multiDimensionalArray() { |
|
|
|
void multiDimensionalArrays() { |
|
|
|
evaluate("new String[2][2]", "[Ljava.lang.String;[2]{[2]{null,null},[2]{null,null}}", String[][].class); |
|
|
|
evaluate("new String[2][2]", "[Ljava.lang.String;[2]{[2]{null,null},[2]{null,null}}", String[][].class); |
|
|
|
evaluate("new String[3][2][1]", |
|
|
|
evaluate("new String[3][2][1]", |
|
|
|
"[[Ljava.lang.String;[3]{[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}}}", |
|
|
|
"[[Ljava.lang.String;[3]{[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}}}", |
|
|
|
String[][][].class); |
|
|
|
String[][][].class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
private void evaluateArrayBuildingExpression(String expression, String expectedToString) { |
|
|
|
public void constructorInvocation03() { |
|
|
|
|
|
|
|
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void constructorInvocation04() { |
|
|
|
|
|
|
|
evaluateAndCheckError("new Integer[3]{'3','ghi','5'}", SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String evaluateArrayBuildingExpression(String expression, String expectedToString) { |
|
|
|
|
|
|
|
SpelExpressionParser parser = new SpelExpressionParser(); |
|
|
|
SpelExpressionParser parser = new SpelExpressionParser(); |
|
|
|
Expression e = parser.parseExpression(expression); |
|
|
|
Expression e = parser.parseExpression(expression); |
|
|
|
Object o = e.getValue(); |
|
|
|
Object array = e.getValue(); |
|
|
|
assertThat(o).isNotNull(); |
|
|
|
assertThat(array).isNotNull(); |
|
|
|
assertThat(o.getClass().isArray()).isTrue(); |
|
|
|
assertThat(array.getClass().isArray()).isTrue(); |
|
|
|
StringBuilder s = new StringBuilder(); |
|
|
|
assertThat(ObjectUtils.nullSafeToString(array)).isEqualTo(expectedToString); |
|
|
|
s.append('['); |
|
|
|
|
|
|
|
if (o instanceof int[]) { |
|
|
|
|
|
|
|
int[] array = (int[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof boolean[]) { |
|
|
|
|
|
|
|
boolean[] array = (boolean[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof char[]) { |
|
|
|
|
|
|
|
char[] array = (char[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof long[]) { |
|
|
|
|
|
|
|
long[] array = (long[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof short[]) { |
|
|
|
|
|
|
|
short[] array = (short[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof double[]) { |
|
|
|
|
|
|
|
double[] array = (double[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof float[]) { |
|
|
|
|
|
|
|
float[] array = (float[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (o instanceof byte[]) { |
|
|
|
|
|
|
|
byte[] array = (byte[]) o; |
|
|
|
|
|
|
|
for (int i = 0; i < array.length; i++) { |
|
|
|
|
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
s.append(','); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(array[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
throw new IllegalStateException("Not supported " + o.getClass()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.append(']'); |
|
|
|
|
|
|
|
assertThat(s.toString()).isEqualTo(expectedToString); |
|
|
|
|
|
|
|
return s.toString(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|