1aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinpackage org.junit.internal; 2aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 3aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinimport java.lang.reflect.Method; 4aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinimport java.util.Arrays; 5aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinimport java.util.Comparator; 6aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 7aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinimport org.junit.FixMethodOrder; 8aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 9aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinpublic class MethodSorter { 10aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin /** 11aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * DEFAULT sort order 12aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin */ 13aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin public static final Comparator<Method> DEFAULT = new Comparator<Method>() { 14aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin public int compare(Method m1, Method m2) { 15aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin int i1 = m1.getName().hashCode(); 16aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin int i2 = m2.getName().hashCode(); 17aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin if (i1 != i2) { 18aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return i1 < i2 ? -1 : 1; 19aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 20aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return NAME_ASCENDING.compare(m1, m2); 21aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 22aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin }; 23aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 24aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin /** 25aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * Method name ascending lexicographic sort order, with {@link Method#toString()} as a tiebreaker 26aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin */ 27aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin public static final Comparator<Method> NAME_ASCENDING = new Comparator<Method>() { 28aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin public int compare(Method m1, Method m2) { 29aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin final int comparison = m1.getName().compareTo(m2.getName()); 30aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin if (comparison != 0) { 31aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return comparison; 32aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 33aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return m1.toString().compareTo(m2.toString()); 34aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 35aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin }; 36aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 37aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin /** 38aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * Gets declared methods of a class in a predictable order, unless @FixMethodOrder(MethodSorters.JVM) is specified. 39aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * 40aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * Using the JVM order is unwise since the Java platform does not 41aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * specify any particular order, and in fact JDK 7 returns a more or less 42aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * random order; well-written test code would not assume any order, but some 43aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * does, and a predictable failure is better than a random failure on 44aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * certain platforms. By default, uses an unspecified but deterministic order. 45aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * 46aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * @param clazz a class 47aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * @return same as {@link Class#getDeclaredMethods} but sorted 48aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * @see <a href="http://bugs.sun.com/view_bug.do?bug_id=7023180">JDK 49aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * (non-)bug #7023180</a> 50aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin */ 51aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin public static Method[] getDeclaredMethods(Class<?> clazz) { 52aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin Comparator<Method> comparator = getSorter(clazz.getAnnotation(FixMethodOrder.class)); 53aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 54aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin Method[] methods = clazz.getDeclaredMethods(); 55aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin if (comparator != null) { 56aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin Arrays.sort(methods, comparator); 57aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 58aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 59aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return methods; 60aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 61aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 62aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin private MethodSorter() { 63aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 64aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 65aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin private static Comparator<Method> getSorter(FixMethodOrder fixMethodOrder) { 66aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin if (fixMethodOrder == null) { 67aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return DEFAULT; 68aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 69aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin 70aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin return fixMethodOrder.value().getComparator(); 71aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin } 72aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin} 73