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