16
16
17
17
package org .springframework .expression .spel ;
18
18
19
+ import org .junit .jupiter .api .Disabled ;
19
20
import org .junit .jupiter .api .Test ;
20
21
21
22
import org .springframework .expression .spel .standard .SpelExpressionParser ;
@@ -80,9 +81,11 @@ void functionWithVarargs() {
80
81
evaluate ("#varargsFunction(new String[0])" , "[]" , String .class );
81
82
evaluate ("#varargsFunction('a')" , "[a]" , String .class );
82
83
evaluate ("#varargsFunction('a','b','c')" , "[a, b, c]" , String .class );
84
+ evaluate ("#varargsFunction(new String[]{'a','b','c'})" , "[a, b, c]" , String .class );
83
85
// Conversion from int to String
84
86
evaluate ("#varargsFunction(25)" , "[25]" , String .class );
85
87
evaluate ("#varargsFunction('b',25)" , "[b, 25]" , String .class );
88
+ evaluate ("#varargsFunction(new int[]{1, 2, 3})" , "[1, 2, 3]" , String .class );
86
89
// Strings that contain a comma
87
90
evaluate ("#varargsFunction('a,b')" , "[a,b]" , String .class );
88
91
evaluate ("#varargsFunction('a', 'x,y', 'd')" , "[a, x,y, d]" , String .class );
@@ -103,24 +106,47 @@ void functionWithVarargs() {
103
106
// null values
104
107
evaluate ("#varargsFunction2(9,null)" , "9-[null]" , String .class );
105
108
evaluate ("#varargsFunction2(9,'a',null,'b')" , "9-[a, null, b]" , String .class );
109
+
110
+ evaluate ("#varargsObjectFunction()" , "[]" , String .class );
111
+ evaluate ("#varargsObjectFunction(new String[0])" , "[]" , String .class );
112
+ evaluate ("#varargsObjectFunction('a')" , "[a]" , String .class );
113
+ evaluate ("#varargsObjectFunction('a','b','c')" , "[a, b, c]" , String .class );
114
+ evaluate ("#varargsObjectFunction(new String[]{'a','b','c'})" , "[a, b, c]" , String .class );
115
+ // Conversion from int to String
116
+ evaluate ("#varargsObjectFunction(25)" , "[25]" , String .class );
117
+ evaluate ("#varargsObjectFunction('b',25)" , "[b, 25]" , String .class );
118
+ // Strings that contain a comma
119
+ evaluate ("#varargsObjectFunction('a,b')" , "[a,b]" , String .class );
120
+ evaluate ("#varargsObjectFunction('a', 'x,y', 'd')" , "[a, x,y, d]" , String .class );
121
+ // null values
122
+ evaluate ("#varargsObjectFunction(null)" , "[null]" , String .class );
123
+ evaluate ("#varargsObjectFunction('a',null,'b')" , "[a, null, b]" , String .class );
106
124
}
107
125
108
126
@ Test // gh-33013
109
127
void functionWithVarargsViaMethodHandle () {
110
128
// Calling 'public static String formatObjectVarargs(String format, Object... args)' -> String.format(format, args)
111
129
112
130
// No var-args and no conversion necessary
131
+ evaluate ("#message('x')" , "x" , String .class );
113
132
evaluate ("#formatObjectVarargs('x')" , "x" , String .class );
114
133
115
134
// No var-args but conversion necessary
135
+ evaluate ("#message(9)" , "9" , String .class );
116
136
evaluate ("#formatObjectVarargs(9)" , "9" , String .class );
117
137
118
138
// No conversion necessary
119
139
evaluate ("#add(3, 4)" , 7 , Integer .class );
140
+ evaluate ("#message('x -> %s %s %s', 'a', 'b', 'c')" , "x -> a b c" , String .class );
120
141
evaluate ("#formatObjectVarargs('x -> %s', '')" , "x -> " , String .class );
121
142
evaluate ("#formatObjectVarargs('x -> %s', ' ')" , "x -> " , String .class );
122
143
evaluate ("#formatObjectVarargs('x -> %s', 'a')" , "x -> a" , String .class );
123
144
evaluate ("#formatObjectVarargs('x -> %s %s %s', 'a', 'b', 'c')" , "x -> a b c" , String .class );
145
+ evaluate ("#message('x -> %s %s %s', new Object[]{'a', 'b', 'c'})" , "x -> a b c" , String .class ); // Object[] instanceof Object[]
146
+ evaluate ("#message('x -> %s %s %s', new String[]{'a', 'b', 'c'})" , "x -> a b c" , String .class ); // String[] instanceof Object[]
147
+ evaluate ("#message('x -> %s %s %s', new Integer[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // Integer[] instanceof Object[]
148
+ evaluate ("#formatObjectVarargs('x -> %s %s', 2, 3)" , "x -> 2 3" , String .class ); // Integer instanceof Object
149
+ evaluate ("#formatObjectVarargs('x -> %s %s', 'a', 3.0F)" , "x -> a 3.0" , String .class ); // String/Float instanceof Object
124
150
evaluate ("#formatObjectVarargs('x -> %s', new Object[]{''})" , "x -> " , String .class );
125
151
evaluate ("#formatObjectVarargs('x -> %s', new String[]{''})" , "x -> " , String .class );
126
152
evaluate ("#formatObjectVarargs('x -> %s', new Object[]{' '})" , "x -> " , String .class );
@@ -131,9 +157,12 @@ void functionWithVarargsViaMethodHandle() {
131
157
evaluate ("#formatObjectVarargs('x -> %s %s %s', new String[]{'a', 'b', 'c'})" , "x -> a b c" , String .class );
132
158
133
159
// Conversion necessary
134
- evaluate ("#add('2', 5.0)" , 7 , Integer .class );
135
- evaluate ("#formatObjectVarargs('x -> %s %s', 2, 3)" , "x -> 2 3" , String .class );
136
- evaluate ("#formatObjectVarargs('x -> %s %s', 'a', 3.0d)" , "x -> a 3.0" , String .class );
160
+ evaluate ("#add('2', 5.0)" , 7 , Integer .class ); // String/Double to Integer
161
+ evaluate ("#messageStatic('x -> %s %s %s', 1, 2, 3)" , "x -> 1 2 3" , String .class ); // Integer to String
162
+ evaluate ("#messageStatic('x -> %s %s %s', new Integer[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // Integer[] to String[]
163
+ evaluate ("#messageStatic('x -> %s %s %s', new int[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // int[] to String[]
164
+ evaluate ("#messageStatic('x -> %s %s %s', new short[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // short[] to String[]
165
+ evaluate ("#formatObjectVarargs('x -> %s %s %s', new Integer[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // Integer[] to String[]
137
166
138
167
// Individual string contains a comma with multiple varargs arguments
139
168
evaluate ("#formatObjectVarargs('foo -> %s %s', ',', 'baz')" , "foo -> , baz" , String .class );
@@ -147,6 +176,44 @@ void functionWithVarargsViaMethodHandle() {
147
176
evaluate ("#formatObjectVarargs('foo -> %s', 'bar,baz')" , "foo -> bar,baz" , String .class );
148
177
}
149
178
179
+ @ Test
180
+ void functionWithPrimitiveVarargsViaMethodHandle () {
181
+ // Calling 'public String formatPrimitiveVarargs(String format, int... nums)' -> effectively String.format(format, args)
182
+
183
+ // No var-args and no conversion necessary
184
+ evaluate ("#formatPrimitiveVarargs(9)" , "9" , String .class );
185
+
186
+ // No var-args but conversion necessary
187
+ evaluate ("#formatPrimitiveVarargs('7')" , "7" , String .class );
188
+
189
+ // No conversion necessary
190
+ evaluate ("#formatPrimitiveVarargs('x -> %s', 9)" , "x -> 9" , String .class );
191
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s %s', 1, 2, 3)" , "x -> 1 2 3" , String .class );
192
+ evaluate ("#formatPrimitiveVarargs('x -> %s', new int[]{1})" , "x -> 1" , String .class );
193
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s %s', new int[]{1, 2, 3})" , "x -> 1 2 3" , String .class );
194
+
195
+ // Conversion necessary
196
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s', '2', '3')" , "x -> 2 3" , String .class ); // String to int
197
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s', '2', 3.0F)" , "x -> 2 3" , String .class ); // String/Float to int
198
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s %s', new Integer[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // Integer[] to int[]
199
+ evaluate ("#formatPrimitiveVarargs('x -> %s %s %s', new String[]{'1', '2', '3'})" , "x -> 1 2 3" , String .class ); // String[] to int[]
200
+ }
201
+
202
+ @ Disabled ("Primitive array to Object[] conversion is not currently supported" )
203
+ @ Test
204
+ void functionFromMethodWithVarargsAndPrimitiveArrayToObjectArrayConversion () {
205
+ evaluate ("#varargsObjectFunction(new short[]{1, 2, 3})" , "[1, 2, 3]" , String .class ); // short[] to Object[]
206
+ evaluate ("#varargsObjectFunction(new int[]{1, 2, 3})" , "[1, 2, 3]" , String .class ); // int[] to Object[]
207
+ }
208
+
209
+ @ Disabled ("Primitive array to Object[] conversion is not currently supported" )
210
+ @ Test
211
+ void functionFromMethodHandleWithVarargsAndPrimitiveArrayToObjectArrayConversion () {
212
+ evaluate ("#message('x -> %s %s %s', new short[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // short[] to Object[]
213
+ evaluate ("#message('x -> %s %s %s', new int[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // int[] to Object[]
214
+ evaluate ("#formatObjectVarargs('x -> %s %s %s', new int[]{1, 2, 3})" , "x -> 1 2 3" , String .class ); // int[] to Object[]
215
+ }
216
+
150
217
@ Test
151
218
void functionMethodMustBeStatic () throws Exception {
152
219
SpelExpressionParser parser = new SpelExpressionParser ();
0 commit comments