/* * Copyright 2002-2015 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.awt.Component; import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Date; import org.junit.Ignore; import org.junit.Test; import org.springframework.tests.sample.objects.TestObject; import static org.junit.Assert.*; /** * @author Adrian Colyer */ public class LocalVariableTableParameterNameDiscovererTests { private final LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer(); @Test public void methodParameterNameDiscoveryNoArgs() throws NoSuchMethodException { Method getName = TestObject.class.getMethod("getName", new Class[0]); String[] names = discoverer.getParameterNames(getName); assertNotNull("should find method info", names); assertEquals("no argument names", 0, names.length); } @Test public void methodParameterNameDiscoveryWithArgs() throws NoSuchMethodException { Method setName = TestObject.class.getMethod("setName", new Class[] { String.class }); String[] names = discoverer.getParameterNames(setName); assertNotNull("should find method info", names); assertEquals("one argument", 1, names.length); assertEquals("name", names[0]); } @Test public void consParameterNameDiscoveryNoArgs() throws NoSuchMethodException { Constructor<TestObject> noArgsCons = TestObject.class.getConstructor(new Class[0]); String[] names = discoverer.getParameterNames(noArgsCons); assertNotNull("should find cons info", names); assertEquals("no argument names", 0, names.length); } @Test public void consParameterNameDiscoveryArgs() throws NoSuchMethodException { Constructor<TestObject> twoArgCons = TestObject.class.getConstructor(new Class[] { String.class, int.class }); String[] names = discoverer.getParameterNames(twoArgCons); assertNotNull("should find cons info", names); assertEquals("one argument", 2, names.length); assertEquals("name", names[0]); assertEquals("age", names[1]); } @Test public void staticMethodParameterNameDiscoveryNoArgs() throws NoSuchMethodException { Method m = getClass().getMethod("staticMethodNoLocalVars", new Class[0]); String[] names = discoverer.getParameterNames(m); assertNotNull("should find method info", names); assertEquals("no argument names", 0, names.length); } @Test public void overloadedStaticMethod() throws Exception { Class<? extends LocalVariableTableParameterNameDiscovererTests> clazz = this.getClass(); Method m1 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE }); String[] names = discoverer.getParameterNames(m1); assertNotNull("should find method info", names); assertEquals("two arguments", 2, names.length); assertEquals("x", names[0]); assertEquals("y", names[1]); Method m2 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE, Long.TYPE }); names = discoverer.getParameterNames(m2); assertNotNull("should find method info", names); assertEquals("three arguments", 3, names.length); assertEquals("x", names[0]); assertEquals("y", names[1]); assertEquals("z", names[2]); } @Test public void overloadedStaticMethodInInnerClass() throws Exception { Class<InnerClass> clazz = InnerClass.class; Method m1 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE }); String[] names = discoverer.getParameterNames(m1); assertNotNull("should find method info", names); assertEquals("one argument", 1, names.length); assertEquals("x", names[0]); Method m2 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE }); names = discoverer.getParameterNames(m2); assertNotNull("should find method info", names); assertEquals("two arguments", 2, names.length); assertEquals("x", names[0]); assertEquals("y", names[1]); } @Test public void overloadedMethod() throws Exception { Class<? extends LocalVariableTableParameterNameDiscovererTests> clazz = this.getClass(); Method m1 = clazz.getMethod("instanceMethod", new Class[] { Double.TYPE, Double.TYPE }); String[] names = discoverer.getParameterNames(m1); assertNotNull("should find method info", names); assertEquals("two arguments", 2, names.length); assertEquals("x", names[0]); assertEquals("y", names[1]); Method m2 = clazz.getMethod("instanceMethod", new Class[] { Double.TYPE, Double.TYPE, Double.TYPE }); names = discoverer.getParameterNames(m2); assertNotNull("should find method info", names); assertEquals("three arguments", 3, names.length); assertEquals("x", names[0]); assertEquals("y", names[1]); assertEquals("z", names[2]); } @Test public void overloadedMethodInInnerClass() throws Exception { Class<InnerClass> clazz = InnerClass.class; Method m1 = clazz.getMethod("instanceMethod", new Class[] { String.class }); String[] names = discoverer.getParameterNames(m1); assertNotNull("should find method info", names); assertEquals("one argument", 1, names.length); assertEquals("aa", names[0]); Method m2 = clazz.getMethod("instanceMethod", new Class[] { String.class, String.class }); names = discoverer.getParameterNames(m2); assertNotNull("should find method info", names); assertEquals("two arguments", 2, names.length); assertEquals("aa", names[0]); assertEquals("bb", names[1]); } @Test public void generifiedClass() throws Exception { Class<?> clazz = GenerifiedClass.class; Constructor<?> ctor = clazz.getDeclaredConstructor(Object.class); String[] names = discoverer.getParameterNames(ctor); assertEquals(1, names.length); assertEquals("key", names[0]); ctor = clazz.getDeclaredConstructor(Object.class, Object.class); names = discoverer.getParameterNames(ctor); assertEquals(2, names.length); assertEquals("key", names[0]); assertEquals("value", names[1]); Method m = clazz.getMethod("generifiedStaticMethod", Object.class); names = discoverer.getParameterNames(m); assertEquals(1, names.length); assertEquals("param", names[0]); m = clazz.getMethod("generifiedMethod", Object.class, long.class, Object.class, Object.class); names = discoverer.getParameterNames(m); assertEquals(4, names.length); assertEquals("param", names[0]); assertEquals("x", names[1]); assertEquals("key", names[2]); assertEquals("value", names[3]); m = clazz.getMethod("voidStaticMethod", Object.class, long.class, int.class); names = discoverer.getParameterNames(m); assertEquals(3, names.length); assertEquals("obj", names[0]); assertEquals("x", names[1]); assertEquals("i", names[2]); m = clazz.getMethod("nonVoidStaticMethod", Object.class, long.class, int.class); names = discoverer.getParameterNames(m); assertEquals(3, names.length); assertEquals("obj", names[0]); assertEquals("x", names[1]); assertEquals("i", names[2]); m = clazz.getMethod("getDate"); names = discoverer.getParameterNames(m); assertEquals(0, names.length); } @Ignore("Ignored because Ubuntu packages OpenJDK with debug symbols enabled. See SPR-8078.") @Test public void classesWithoutDebugSymbols() throws Exception { // JDK classes don't have debug information (usually) Class<Component> clazz = Component.class; String methodName = "list"; Method m = clazz.getMethod(methodName); String[] names = discoverer.getParameterNames(m); assertNull(names); m = clazz.getMethod(methodName, PrintStream.class); names = discoverer.getParameterNames(m); assertNull(names); m = clazz.getMethod(methodName, PrintStream.class, int.class); names = discoverer.getParameterNames(m); assertNull(names); } public static void staticMethodNoLocalVars() { } public static long staticMethod(long x, long y) { long u = x * y; return u; } public static long staticMethod(long x, long y, long z) { long u = x * y * z; return u; } public double instanceMethod(double x, double y) { double u = x * y; return u; } public double instanceMethod(double x, double y, double z) { double u = x * y * z; return u; } public static class InnerClass { public int waz = 0; public InnerClass() { } public InnerClass(String firstArg, long secondArg, Object thirdArg) { long foo = 0; short bar = 10; this.waz = (int) (foo + bar); } public String instanceMethod(String aa) { return aa; } public String instanceMethod(String aa, String bb) { return aa + bb; } public static long staticMethod(long x) { long u = x; return u; } public static long staticMethod(long x, long y) { long u = x * y; return u; } } public static class GenerifiedClass<K, V> { private static long date; static { // some custom static bloc or <clinit> date = new Date().getTime(); } public GenerifiedClass() { this(null, null); } public GenerifiedClass(K key) { this(key, null); } public GenerifiedClass(K key, V value) { } public static <P> long generifiedStaticMethod(P param) { return date; } public <P> void generifiedMethod(P param, long x, K key, V value) { // nothing } public static void voidStaticMethod(Object obj, long x, int i) { // nothing } public static long nonVoidStaticMethod(Object obj, long x, int i) { return date; } public static long getDate() { return date; } } }