001package org.junit.internal; 002 003import java.lang.reflect.Method; 004import java.util.Arrays; 005import java.util.Comparator; 006 007import org.junit.FixMethodOrder; 008 009public class MethodSorter { 010 /** 011 * DEFAULT sort order 012 */ 013 public static final Comparator<Method> DEFAULT = new Comparator<Method>() { 014 public int compare(Method m1, Method m2) { 015 int i1 = m1.getName().hashCode(); 016 int i2 = m2.getName().hashCode(); 017 if (i1 != i2) { 018 return i1 < i2 ? -1 : 1; 019 } 020 return NAME_ASCENDING.compare(m1, m2); 021 } 022 }; 023 024 /** 025 * Method name ascending lexicographic sort order, with {@link Method#toString()} as a tiebreaker 026 */ 027 public static final Comparator<Method> NAME_ASCENDING = new Comparator<Method>() { 028 public int compare(Method m1, Method m2) { 029 final int comparison = m1.getName().compareTo(m2.getName()); 030 if (comparison != 0) { 031 return comparison; 032 } 033 return m1.toString().compareTo(m2.toString()); 034 } 035 }; 036 037 /** 038 * Gets declared methods of a class in a predictable order, unless @FixMethodOrder(MethodSorters.JVM) is specified. 039 * 040 * Using the JVM order is unwise since the Java platform does not 041 * specify any particular order, and in fact JDK 7 returns a more or less 042 * random order; well-written test code would not assume any order, but some 043 * does, and a predictable failure is better than a random failure on 044 * certain platforms. By default, uses an unspecified but deterministic order. 045 * 046 * @param clazz a class 047 * @return same as {@link Class#getDeclaredMethods} but sorted 048 * @see <a href="http://bugs.sun.com/view_bug.do?bug_id=7023180">JDK 049 * (non-)bug #7023180</a> 050 */ 051 public static Method[] getDeclaredMethods(Class<?> clazz) { 052 Comparator<Method> comparator = getSorter(clazz.getAnnotation(FixMethodOrder.class)); 053 054 Method[] methods = clazz.getDeclaredMethods(); 055 if (comparator != null) { 056 Arrays.sort(methods, comparator); 057 } 058 059 return methods; 060 } 061 062 private MethodSorter() { 063 } 064 065 private static Comparator<Method> getSorter(FixMethodOrder fixMethodOrder) { 066 if (fixMethodOrder == null) { 067 return DEFAULT; 068 } 069 070 return fixMethodOrder.value().getComparator(); 071 } 072}