package org.mockito.internal.util.reflection; import org.junit.Test; import java.lang.reflect.Field; import java.util.*; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.internal.util.reflection.SuperTypesLastSorter.sortSuperTypesLast; @SuppressWarnings("unused") public class SuperTypesLastSorterTest { /** * A Comparator that behaves like the old one, so the existing tests * continue to work. */ private static Comparator<Field> cmp = new Comparator<Field>() { public int compare(Field o1, Field o2) { if (o1.equals(o2)) { return 0; } List<Field> l = sortSuperTypesLast(Arrays.asList(o1, o2)); if (l.get(0) == o1) { return -1; } else { return 1; } } }; private Object objectA; private Object objectB; private Number numberA; private Number numberB; private Integer integerA; private Integer integerB; private Iterable<?> iterableA; private Number xNumber; private Iterable<?> yIterable; private Integer zInteger; @Test public void when_same_type_the_order_is_based_on_field_name() throws Exception { assertThat(cmp.compare(field("objectA"), field("objectB"))).isEqualTo(-1); assertThat(cmp.compare(field("objectB"), field("objectA"))).isEqualTo(1); assertThat(cmp.compare(field("objectB"), field("objectB"))).isEqualTo(0); } @Test public void when_type_is_different_the_supertype_comes_last() throws Exception { assertThat(cmp.compare(field("numberA"), field("objectB"))).isEqualTo(-1); assertThat(cmp.compare(field("objectB"), field("numberA"))).isEqualTo(1); } @Test public void using_Collections_dot_sort() throws Exception { List<Field> unsortedFields = Arrays.asList( field("objectB"), field("integerB"), field("numberA"), field("numberB"), field("objectA"), field("integerA") ); List<Field> sortedFields = sortSuperTypesLast(unsortedFields); assertThat(sortedFields).containsSequence( field("integerA"), field("integerB"), field("numberA"), field("numberB"), field("objectA"), field("objectB") ); } @Test public void issue_352_order_was_different_between_JDK6_and_JDK7() throws Exception { List<Field> unsortedFields = Arrays.asList( field("objectB"), field("objectA") ); Collections.sort(unsortedFields, cmp); assertThat(unsortedFields).containsSequence( field("objectA"), field("objectB") ); } @Test public void fields_sort_consistently_when_interfaces_are_included() throws NoSuchFieldException { assertSortConsistently(field("iterableA"), field("numberA"), field("integerA")); } @Test public void fields_sort_consistently_when_names_and_type_indicate_different_order() throws NoSuchFieldException { assertSortConsistently(field("xNumber"), field("yIterable"), field("zInteger")); } /** * Assert that these fields sort in the same order no matter which order * they start in. */ private static void assertSortConsistently(Field a, Field b, Field c) { Field[][] initialOrderings = { {a, b, c}, {a, c, b}, {b, a, c}, {b, c, a}, {c, a, b}, {c, b, a} }; Set<List<Field>> results = new HashSet<List<Field>>(); for (Field[] o : initialOrderings) { results.add(sortSuperTypesLast(Arrays.asList(o))); } assertThat(results).hasSize(1); } private Field field(String field) throws NoSuchFieldException { return getClass().getDeclaredField(field); } }