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