12637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpackage org.mockito.internal.util.reflection;
22637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
32637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.junit.Test;
42637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
52637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.lang.reflect.Field;
62637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.*;
72637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
82637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.assertj.core.api.Assertions.assertThat;
92637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.internal.util.reflection.SuperTypesLastSorter.sortSuperTypesLast;
102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin@SuppressWarnings("unused")
122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpublic class SuperTypesLastSorterTest {
132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    /**
142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     * A Comparator that behaves like the old one, so the existing tests
152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     * continue to work.
162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     */
172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static Comparator<Field> cmp = new Comparator<Field>() {
182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        public int compare(Field o1, Field o2) {
192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (o1.equals(o2)) {
202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return 0;
212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            List<Field> l = sortSuperTypesLast(Arrays.asList(o1, o2));
242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (l.get(0) == o1) {
262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return -1;
272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            } else {
282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return 1;
292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    };
322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Object objectA;
342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Object objectB;
352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Number numberA;
372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Number numberB;
382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Integer integerA;
402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Integer integerB;
412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Iterable<?> iterableA;
432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Number xNumber;
452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Iterable<?> yIterable;
462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Integer zInteger;
472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void when_same_type_the_order_is_based_on_field_name() throws Exception {
512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(cmp.compare(field("objectA"), field("objectB"))).isEqualTo(-1);
522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(cmp.compare(field("objectB"), field("objectA"))).isEqualTo(1);
532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(cmp.compare(field("objectB"), field("objectB"))).isEqualTo(0);
542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void when_type_is_different_the_supertype_comes_last() throws Exception {
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(cmp.compare(field("numberA"), field("objectB"))).isEqualTo(-1);
592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(cmp.compare(field("objectB"), field("numberA"))).isEqualTo(1);
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void using_Collections_dot_sort() throws Exception {
642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        List<Field> unsortedFields = Arrays.asList(
652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectB"),
662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("integerB"),
672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("numberA"),
682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("numberB"),
692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectA"),
702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("integerA")
712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        );
722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        List<Field> sortedFields =  sortSuperTypesLast(unsortedFields);
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(sortedFields).containsSequence(
762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("integerA"),
772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("integerB"),
782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("numberA"),
792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("numberB"),
802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectA"),
812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectB")
822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        );
832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void issue_352_order_was_different_between_JDK6_and_JDK7() throws Exception {
882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        List<Field> unsortedFields = Arrays.asList(
892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectB"),
902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectA")
912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        );
922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Collections.sort(unsortedFields, cmp);
942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
952637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(unsortedFields).containsSequence(
962637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectA"),
972637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                field("objectB")
982637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        );
992637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1002637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1012637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1022637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void fields_sort_consistently_when_interfaces_are_included() throws NoSuchFieldException {
1032637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertSortConsistently(field("iterableA"), field("numberA"), field("integerA"));
1042637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1052637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1062637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    @Test
1072637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public void fields_sort_consistently_when_names_and_type_indicate_different_order() throws NoSuchFieldException {
1082637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertSortConsistently(field("xNumber"), field("yIterable"), field("zInteger"));
1092637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    /**
1122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     * Assert that these fields sort in the same order no matter which order
1132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     * they start in.
1142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin     */
1152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static void assertSortConsistently(Field a, Field b, Field c) {
1162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Field[][] initialOrderings = {
1172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {a, b, c},
1182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {a, c, b},
1192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {b, a, c},
1202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {b, c, a},
1212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {c, a, b},
1222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                {c, b, a}
1232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        };
1242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Set<List<Field>> results = new HashSet<List<Field>>();
1262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        for (Field[] o : initialOrderings) {
1282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            results.add(sortSuperTypesLast(Arrays.asList(o)));
1292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        assertThat(results).hasSize(1);
1322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Field field(String field) throws NoSuchFieldException {
1352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return getClass().getDeclaredField(field);
1362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
138