Home | History | Annotate | Download | only in reflection
      1 /*
      2  * Copyright (c) 2017 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 package org.mockito.internal.util.reflection;
      6 
      7 import org.junit.Test;
      8 
      9 import java.lang.reflect.Field;
     10 import java.util.*;
     11 
     12 import static org.assertj.core.api.Assertions.assertThat;
     13 import static org.mockito.internal.util.reflection.SuperTypesLastSorter.sortSuperTypesLast;
     14 
     15 @SuppressWarnings("unused")
     16 public class SuperTypesLastSorterTest {
     17     /**
     18      * A Comparator that behaves like the old one, so the existing tests
     19      * continue to work.
     20      */
     21     private static Comparator<Field> cmp = new Comparator<Field>() {
     22         public int compare(Field o1, Field o2) {
     23             if (o1.equals(o2)) {
     24                 return 0;
     25             }
     26 
     27             List<Field> l = sortSuperTypesLast(Arrays.asList(o1, o2));
     28 
     29             if (l.get(0) == o1) {
     30                 return -1;
     31             } else {
     32                 return 1;
     33             }
     34         }
     35     };
     36 
     37     private Object objectA;
     38     private Object objectB;
     39 
     40     private Number numberA;
     41     private Number numberB;
     42 
     43     private Integer integerA;
     44     private Integer integerB;
     45 
     46     private Iterable<?> iterableA;
     47 
     48     private Number xNumber;
     49     private Iterable<?> yIterable;
     50     private Integer zInteger;
     51 
     52 
     53     @Test
     54     public void when_same_type_the_order_is_based_on_field_name() throws Exception {
     55         assertThat(cmp.compare(field("objectA"), field("objectB"))).isEqualTo(-1);
     56         assertThat(cmp.compare(field("objectB"), field("objectA"))).isEqualTo(1);
     57         assertThat(cmp.compare(field("objectB"), field("objectB"))).isEqualTo(0);
     58     }
     59 
     60     @Test
     61     public void when_type_is_different_the_supertype_comes_last() throws Exception {
     62         assertThat(cmp.compare(field("numberA"), field("objectB"))).isEqualTo(-1);
     63         assertThat(cmp.compare(field("objectB"), field("numberA"))).isEqualTo(1);
     64     }
     65 
     66     @Test
     67     public void using_Collections_dot_sort() throws Exception {
     68         List<Field> unsortedFields = Arrays.asList(
     69                 field("objectB"),
     70                 field("integerB"),
     71                 field("numberA"),
     72                 field("numberB"),
     73                 field("objectA"),
     74                 field("integerA")
     75         );
     76 
     77         List<Field> sortedFields =  sortSuperTypesLast(unsortedFields);
     78 
     79         assertThat(sortedFields).containsSequence(
     80                 field("integerA"),
     81                 field("integerB"),
     82                 field("numberA"),
     83                 field("numberB"),
     84                 field("objectA"),
     85                 field("objectB")
     86         );
     87     }
     88 
     89 
     90     @Test
     91     public void issue_352_order_was_different_between_JDK6_and_JDK7() throws Exception {
     92         List<Field> unsortedFields = Arrays.asList(
     93                 field("objectB"),
     94                 field("objectA")
     95         );
     96 
     97         Collections.sort(unsortedFields, cmp);
     98 
     99         assertThat(unsortedFields).containsSequence(
    100                 field("objectA"),
    101                 field("objectB")
    102         );
    103     }
    104 
    105     @Test
    106     public void fields_sort_consistently_when_interfaces_are_included() throws NoSuchFieldException {
    107         assertSortConsistently(field("iterableA"), field("numberA"), field("integerA"));
    108     }
    109 
    110     @Test
    111     public void fields_sort_consistently_when_names_and_type_indicate_different_order() throws NoSuchFieldException {
    112         assertSortConsistently(field("xNumber"), field("yIterable"), field("zInteger"));
    113     }
    114 
    115     /**
    116      * Assert that these fields sort in the same order no matter which order
    117      * they start in.
    118      */
    119     private static void assertSortConsistently(Field a, Field b, Field c) {
    120         Field[][] initialOrderings = {
    121                 {a, b, c},
    122                 {a, c, b},
    123                 {b, a, c},
    124                 {b, c, a},
    125                 {c, a, b},
    126                 {c, b, a}
    127         };
    128 
    129         Set<List<Field>> results = new HashSet<List<Field>>();
    130 
    131         for (Field[] o : initialOrderings) {
    132             results.add(sortSuperTypesLast(Arrays.asList(o)));
    133         }
    134 
    135         assertThat(results).hasSize(1);
    136     }
    137 
    138     private Field field(String field) throws NoSuchFieldException {
    139         return getClass().getDeclaredField(field);
    140     }
    141 }
    142