1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 package org.codehaus.groovy.runtime;
37
38 import groovy.lang.GString;
39 import groovy.lang.GroovyRuntimeException;
40 import groovy.lang.IntRange;
41 import groovy.util.GroovyTestCase;
42
43 import java.math.BigDecimal;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collection;
48 import java.util.Date;
49 import java.util.List;
50
51 import junit.framework.AssertionFailedError;
52
53 /***
54 * Tests method invocation
55 *
56 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
57 * @version $Revision: 1.29 $
58 */
59 public class InvokeMethodTest extends GroovyTestCase {
60
61 protected Invoker invoker = InvokerHelper.getInstance();
62
63
64
65
66 public void testInvokeMethodNoParams() throws Throwable {
67 Object value = invoke(this, "mockCallWithNoParams", null);
68 assertEquals("return value", "NoParams", value);
69
70 value = invoke(this, "mockCallWithNoParams", new Object[0]);
71 assertEquals("return value", "NoParams", value);
72 }
73
74 public void testInvokeMethodOneParam() throws Throwable {
75 Object value = invoke(this, "mockCallWithOneParam", "abc");
76 assertEquals("return value", "OneParam", value);
77 }
78
79 public void testInvokeMethodOneParamWhichIsNull() throws Throwable {
80 Object value = invoke(this, "mockCallWithOneNullParam", new Object[] { null });
81 assertEquals("return value", "OneParamWithNull", value);
82
83 value = invoke(this, "mockCallWithOneNullParam", null);
84 assertEquals("return value", "OneParamWithNull", value);
85 }
86
87 public void testInvokeOverloadedMethodWithOneParamWhichIsNull() throws Throwable {
88 Object value = invoke(this, "mockOverloadedMethod", new Object[] { null });
89 assertEquals("return value", "Object", value);
90 }
91
92 public void testInvokeMethodOneCollectionParameter() throws Throwable {
93 Object[] foo = { "a", "b", "c" };
94
95 Object value = invoke(this, "mockCallWithOneCollectionParam", new Object[] { foo });
96 assertEquals("return value", new Integer(3), value);
97
98 List list = new ArrayList();
99 list.add("a");
100 list.add("b");
101 value = invoke(this, "mockCallWithOneCollectionParam", list);
102 assertEquals("return value", new Integer(2), value);
103 }
104
105 public void testInvokePrintlnMethod() throws Throwable {
106 Object value = invoke(System.out, "println", "testing System.out.println...");
107 assertEquals("return value", null, value);
108 }
109
110 public void testMethodChooserNull() throws Throwable {
111 assertMethodChooser("Object", new Object[] { null });
112 }
113
114 public void testMethodChooserNoParams() throws Throwable {
115 assertMethodChooser("void", null);
116 }
117
118 public void testMethodChooserObject() throws Throwable {
119 assertMethodChooser("Object", new Object());
120 assertMethodChooser("Object", new Date());
121 }
122
123 public void testMethodChooserString() throws Throwable {
124 assertMethodChooser("String", "foo");
125
126 /*** @todo some type cooercion would be cool here... */
127
128
129 }
130
131 public void testMethodChooserNumber() throws Throwable {
132 assertMethodChooser("Number", new Integer(2));
133 assertMethodChooser("Number", new Double(2));
134 }
135
136 public void testMethodChooserTwoParams() throws Throwable {
137 List list = new ArrayList();
138 list.add("foo");
139 list.add("bar");
140 assertMethodChooser("Object,Object", list.toArray());
141
142 Object[] blah = { "a", "b" };
143 assertMethodChooser("Object,Object", blah);
144 }
145
146 public void testInstanceofWorksForArray() {
147 Class type = Object[].class;
148 Object value = new Object[1];
149 assertTrue("instanceof works for array", type.isInstance(value));
150 }
151
152 public void testMethodChooserTwoParamsWithSecondAnObjectArray() throws Throwable {
153 Object[] blah = { "a", new Object[] { "b" }
154 };
155 assertMethodChooser("Object,Object[]", blah);
156 }
157
158 public void testCollectionMethods() throws Throwable {
159 Object list = InvokerHelper.createList(new Object[] { "a", "b" });
160
161 Object value = invoke(list, "size", null);
162 assertEquals("size of collection", new Integer(2), value);
163
164 value = invoke(list, "contains", "a");
165 assertEquals("contains method", Boolean.TRUE, value);
166 }
167
168 public void testNewMethods() throws Throwable {
169 Object value = invoke("hello", "size", null);
170 assertEquals("size of string", new Integer(5), value);
171 }
172
173 public void testStaticMethod() throws Throwable {
174 Object value = invoke(DummyBean.class, "dummyStaticMethod", "abc");
175 assertEquals("size of string", "ABC", value);
176 }
177
178 public void testBaseClassMethod() throws Throwable {
179 Object object = new DummyBean();
180 Object value = invoke(object, "toString", null);
181 assertEquals("toString", object.toString(), value);
182 }
183
184
185
186 public void testDivideNumbers() throws Throwable {
187 assertMethodCall(new Double(10), "div", new Double(2), new Double(5));
188 assertMethodCall(new Double(10), "div", new Integer(2), new Double(5));
189 assertMethodCall(new Integer(10), "div", new Double(2), new Double(5));
190 assertMethodCall(new Integer(10), "div", new Integer(2), new java.math.BigDecimal("5"));
191 }
192
193 public void testBaseFailMethod() throws Throwable {
194 Object value;
195 try {
196 value = invoke(this, "fail", "hello");
197 }
198 catch (AssertionFailedError e) {
199
200 }
201 }
202
203 public void testToArrayOnList() throws Throwable {
204 List object = new ArrayList();
205 object.add("Hello");
206
207 Object[] value = (Object[]) invoke(object, "toArray", null);
208 assertArrayEquals(object.toArray(), value);
209 assertEquals(1, value.length);
210 assertEquals("Hello", value[0]);
211
212 value = (Object[]) invoke(object, "toArray", new Object[0]);
213 assertArrayEquals(object.toArray(), value);
214 }
215
216 public void testInvalidOverloading() throws Throwable {
217 try {
218 invoke(this, "badOverload", new Object[] { "a", "b" });
219 fail("Should fail as an unambiguous method is invoked");
220 }
221 catch (GroovyRuntimeException e) {
222 System.out.println("Caught: " + e);
223 }
224 }
225
226 public void testPlusWithNull() throws Throwable {
227 String param = "called with: ";
228 Object value = invoke(param, "plus", new Object[] { null });
229 assertEquals("called with null", param + null, value);
230 }
231
232 public void testCallIntMethodWithInteger() throws Throwable {
233 Object value = invoke(this, "overloadedRemove", new Object[] { new Integer(5)});
234 assertEquals("called with integer", "int5", value);
235 }
236
237 public void testCallListRemove() throws Throwable {
238 List list = new ArrayList();
239 list.add("foo");
240 list.add("bar");
241
242 Object value = invoke(list, "remove", new Object[] { new Integer(0)});
243
244 assertEquals("Should have just 1 item left: " + list, 1, list.size());
245 }
246
247 public void testCoerceGStringToString() throws Throwable {
248 GString param = new GString(new Object[] { "James" }) {
249 public String[] getStrings() {
250 return new String[] { "Hello " };
251 }
252 };
253 Object value = invoke(this, "methodTakesString", new Object[] { param });
254 assertEquals("converted GString to string", param.toString(), value);
255 }
256
257 public void testCoerceGStringToStringOnGetBytes() throws Throwable {
258 GString param = new GString(new Object[] { "US-ASCII" }) {
259 public String[] getStrings() {
260 return new String[] { "" };
261 }
262 };
263 Object value = invoke("test", "getBytes", new Object[] { param });
264 assertEquals("converted GString to string", "test".getBytes("US-ASCII").getClass(), value.getClass());
265 }
266
267 public void testBadBDToDoubleCoerce() throws Throwable {
268 try {
269 Object value = invoke(Math.class, "floor", new BigDecimal("1.7E309"));
270 } catch (GroovyRuntimeException e) {
271 assertTrue("Math.floor(1.7E309) should fail because it is out of range for a Double. "
272 +e,e.getMessage().indexOf("out of range") > 0);
273 return;
274 }
275 fail("Math.floor(1.7E309) should fail because it is out of range for a Double.");
276 }
277
278 public void testClassMethod() throws Throwable {
279 Class c = String.class;
280 Object value = invoke(c, "getName", null);
281 assertEquals("Class.getName()", c.getName(), value);
282 c = getClass();
283 value = invoke(c, "getName", null);
284 assertEquals("Class.getName()", c.getName(), value);
285 }
286
287 public void testProtectedMethod() throws Throwable {
288 String param = "hello";
289 Object value = invoke(this, "aProtectedMethod", param);
290 assertEquals("protected method call", aProtectedMethod(param), value);
291 }
292
293 public void testPrivateMethod() throws Throwable {
294 String param = "hello";
295 Object value = invoke(this, "aPrivateMethod", param);
296 assertEquals("private method call", aPrivateMethod(param), value);
297 }
298
299 public void testStringSubstringMethod() throws Throwable {
300 String object = "hello";
301 Object value = invoke(object, "substring", new Integer(2));
302 assertEquals("substring(2)", object.substring(2), value);
303
304 value = invoke(object, "substring", new Object[] { new Integer(1), new Integer(3)});
305 assertEquals("substring(1,3)", object.substring(1, 3), value);
306 }
307
308 public void testListGetWithRange() throws Throwable {
309 List list = Arrays.asList(new Object[] { "a", "b", "c" });
310 Object range = new IntRange(0, 2);
311 Object value = invoke(list, "getAt", range);
312 assertTrue("Returned List: " + value, value instanceof List);
313 List retList = (List) value;
314 assertEquals("List size", 3, retList.size());
315 }
316
317 public void testSetLenientOnDateFormat() throws Throwable {
318 SimpleDateFormat a = new SimpleDateFormat( "MM/dd/yyyy" );
319
320 Object value = invoke(a, "setLenient", new Object[] { Boolean.FALSE });
321 assertEquals("void method", null, value);
322 }
323
324 public void testInvokeUnknownMethod() throws Throwable {
325 try {
326 Object value = invoke(this, "unknownMethod", "abc");
327 fail("Should have thrown an exception");
328 }
329 catch (GroovyRuntimeException e) {
330
331 }
332 }
333
334 public void testInvokeMethodWithWrongNumberOfParameters() throws Throwable {
335 try {
336 Object[] args = { "a", "b" };
337 Object value = invoke(this, "unknownMethod", args);
338 fail("Should have thrown an exception");
339 }
340 catch (GroovyRuntimeException e) {
341
342 }
343 }
344
345 public void testInvokeMethodOnNullObject() throws Throwable {
346 try {
347 invoke(null, "mockCallWithNoParams", null);
348 fail("Should have thrown an exception");
349 }
350 catch (NullPointerException e) {
351
352 }
353 }
354
355
356
357
358 public Object mockCallWithNoParams() {
359 return "NoParams";
360 }
361
362 public Object mockCallWithOneParam(Object value) {
363 assertEquals("Method not passed in the correct value", "abc", value);
364 return "OneParam";
365 }
366
367 public Object mockCallWithOneNullParam(Object value) {
368 assertEquals("Method not passed in the correct value", null, value);
369 return "OneParamWithNull";
370 }
371
372 public Integer mockCallWithOneCollectionParam(Object collection) {
373 Collection coll = InvokerHelper.asCollection(collection);
374 return new Integer(coll.size());
375 }
376
377 public Object mockOverloadedMethod() {
378 return "void";
379 }
380
381 public Object mockOverloadedMethod(Object object) {
382 return "Object";
383 }
384
385 public Object mockOverloadedMethod(Number object) {
386 return "Number";
387 }
388
389 public Object mockOverloadedMethod(String object) {
390 return "String";
391 }
392
393 public Object mockOverloadedMethod(Object object, Object bar) {
394 return "Object,Object";
395 }
396
397 public Object mockOverloadedMethod(Object object, Object[] array) {
398 return "Object,Object[]";
399 }
400
401 public Object badOverload(String a, Object b) {
402 return "String, Object";
403 }
404
405 public Object badOverload(Object a, String b) {
406 return "Object, String";
407 }
408
409 public Object methodTakesString(String x) {
410 return x;
411 }
412
413 public Object overloadedRemove(int idx) {
414 return "int" + idx;
415 }
416
417 public Object overloadedRemove(Object value) {
418 return "Object" + value;
419 }
420
421
422
423
424 protected Object aProtectedMethod(String param) {
425 return param + " there!";
426 }
427
428 private Object aPrivateMethod(String param) {
429 return param + " James!";
430 }
431
432 protected void assertMethodCall(Object object, String method, Object param, Object expected) {
433 Object value = InvokerHelper.invokeMethod(object, method, new Object[] { param });
434 assertEquals("result of method: " + method, expected, value);
435 }
436
437 /***
438 * Asserts that invoking the method chooser finds the right overloaded
439 * method implementation
440 *
441 * @param expected
442 * is the expected value of the method
443 * @param arguments
444 * the argument(s) to the method invocation
445 */
446 protected void assertMethodChooser(Object expected, Object arguments) throws Throwable {
447 Object value = invoke(this, "mockOverloadedMethod", arguments);
448
449 assertEquals("Invoking overloaded method for arguments: " + InvokerHelper.toString(arguments), expected, value);
450 }
451
452 protected Object invoke(Object object, String method, Object args) throws Throwable {
453 try {
454 return invoker.invokeMethod(object, method, args);
455 }
456 catch (InvokerInvocationException e) {
457 throw e.getCause();
458 }
459 }
460 }