Best Assertj code snippet using org.assertj.core.internal.Objects.getDeclaredFieldsIncludingInherited
Source:DeepDifference.java
...10 *11 * Copyright 2012-2017 the original author or authors.12 */13package org.assertj.core.internal;14import static org.assertj.core.internal.Objects.getDeclaredFieldsIncludingInherited;15import static org.assertj.core.internal.Objects.propertyOrFieldValuesAreEqual;16import static org.assertj.core.internal.TypeComparators.defaultTypeComparators;17import static org.assertj.core.util.Strings.join;18import static org.assertj.core.util.introspection.PropertyOrFieldSupport.COMPARISON;19import java.lang.reflect.Array;20import java.lang.reflect.Field;21import java.util.ArrayList;22import java.util.Collection;23import java.util.Comparator;24import java.util.Deque;25import java.util.HashMap;26import java.util.HashSet;27import java.util.Iterator;28import java.util.LinkedHashSet;29import java.util.LinkedList;30import java.util.List;31import java.util.Map;32import java.util.Set;33import java.util.SortedMap;34import java.util.SortedSet;35import java.util.TreeMap;36import java.util.concurrent.ConcurrentHashMap;37/**38 * Tests two objects for differences by doing a 'deep' comparison.39 *40 * Based on the deep equals implementation of https://github.com/jdereg/java-util41 *42 * @author John DeRegnaucourt (john@cedarsoftware.com)43 * @author Pascal Schumacher44 */45public class DeepDifference {46 private static final Map<Class<?>, Boolean> customEquals = new ConcurrentHashMap<>();47 private static final Map<Class<?>, Boolean> customHash = new ConcurrentHashMap<>();48 private final static class DualKey {49 private final List<String> path;50 private final Object key1;51 private final Object key2;52 private DualKey(List<String> path, Object key1, Object key2) {53 this.path = path;54 this.key1 = key1;55 this.key2 = key2;56 }57 @Override58 public boolean equals(Object other) {59 if (!(other instanceof DualKey)) {60 return false;61 }62 DualKey that = (DualKey) other;63 return key1 == that.key1 && key2 == that.key2;64 }65 @Override66 public int hashCode() {67 int h1 = key1 != null ? key1.hashCode() : 0;68 int h2 = key2 != null ? key2.hashCode() : 0;69 return h1 + h2;70 }71 @Override72 public String toString() {73 return "DualKey [key1=" + key1 + ", key2=" + key2 + "]";74 }75 public List<String> getPath() {76 return path;77 }78 public String getConcatenatedPath() {79 return join(path).with(".");80 }81 }82 public static class Difference {83 List<String> path;84 Object actual;85 Object other;86 public Difference(List<String> path, Object actual, Object other) {87 this.path = path;88 this.actual = actual;89 this.other = other;90 }91 public List<String> getPath() {92 return path;93 }94 public Object getActual() {95 return actual;96 }97 public Object getOther() {98 return other;99 }100 @Override101 public String toString() {102 return "Difference [path=" + path + ", actual=" + actual + ", other=" + other + "]";103 }104 }105 /**106 * Compare two objects for differences by doing a 'deep' comparison. This will traverse the107 * Object graph and perform either a field-by-field comparison on each108 * object (if not .equals() method has been overridden from Object), or it109 * will call the customized .equals() method if it exists.110 * <p>111 *112 * This method handles cycles correctly, for example A->B->C->A.113 * Suppose a and a' are two separate instances of the A with the same values114 * for all fields on A, B, and C. Then a.deepEquals(a') will return an empty list. It115 * uses cycle detection storing visited objects in a Set to prevent endless116 * loops.117 * 118 * @param a Object one to compare119 * @param b Object two to compare120 * @param comparatorByPropertyOrField comparators to compare properties or fields with the given names121 * @param comparatorByType comparators to compare properties or fields with the given types122 * @return the list of differences found or an empty list if objects are equivalent.123 * Equivalent means that all field values of both subgraphs are the same,124 * either at the field level or via the respectively encountered overridden125 * .equals() methods during traversal.126 */127 public static List<Difference> determineDifferences(Object a, Object b,128 Map<String, Comparator<?>> comparatorByPropertyOrField,129 TypeComparators comparatorByType) {130 // replace null comparators groups by empty one to simplify code afterwards131 comparatorByPropertyOrField = comparatorByPropertyOrField == null132 ? new TreeMap<String, Comparator<?>>()133 : comparatorByPropertyOrField;134 comparatorByType = comparatorByType == null ? defaultTypeComparators() : comparatorByType;135 return determineDifferences(a, b, null, comparatorByPropertyOrField, comparatorByType);136 }137 private static List<Difference> determineDifferences(Object a, Object b, List<String> parentPath,138 Map<String, Comparator<?>> comparatorByPropertyOrField,139 TypeComparators comparatorByType) {140 final Set<DualKey> visited = new HashSet<>();141 final Deque<DualKey> toCompare = initStack(a, b, parentPath, comparatorByPropertyOrField, comparatorByType);142 final List<Difference> differences = new ArrayList<>();143 while (!toCompare.isEmpty()) {144 final DualKey dualKey = toCompare.removeFirst();145 visited.add(dualKey);146 final List<String> currentPath = dualKey.getPath();147 final Object key1 = dualKey.key1;148 final Object key2 = dualKey.key2;149 if (key1 == key2) {150 continue;151 }152 if (hasCustomComparator(dualKey, comparatorByPropertyOrField, comparatorByType)) {153 if (propertyOrFieldValuesAreEqual(key1, key2, dualKey.getConcatenatedPath(),154 comparatorByPropertyOrField, comparatorByType))155 continue;156 }157 if (key1 == null || key2 == null) {158 differences.add(new Difference(currentPath, key1, key2));159 continue;160 }161 if (key1 instanceof Collection) {162 if (!(key2 instanceof Collection)) {163 differences.add(new Difference(currentPath, key1, key2));164 continue;165 }166 } else if (key2 instanceof Collection) {167 differences.add(new Difference(currentPath, key1, key2));168 continue;169 }170 if (key1 instanceof SortedSet) {171 if (!(key2 instanceof SortedSet)) {172 differences.add(new Difference(currentPath, key1, key2));173 continue;174 }175 } else if (key2 instanceof SortedSet) {176 differences.add(new Difference(currentPath, key1, key2));177 continue;178 }179 if (key1 instanceof SortedMap) {180 if (!(key2 instanceof SortedMap)) {181 differences.add(new Difference(currentPath, key1, key2));182 continue;183 }184 } else if (key2 instanceof SortedMap) {185 differences.add(new Difference(currentPath, key1, key2));186 continue;187 }188 if (key1 instanceof Map) {189 if (!(key2 instanceof Map)) {190 differences.add(new Difference(currentPath, key1, key2));191 continue;192 }193 } else if (key2 instanceof Map) {194 differences.add(new Difference(currentPath, key1, key2));195 continue;196 }197 // Handle all [] types. In order to be equal, the arrays must be the198 // same length, be of the same type, be in the same order, and all199 // elements within the array must be deeply equivalent.200 if (key1.getClass().isArray()) {201 if (!compareArrays(key1, key2, currentPath, toCompare, visited)) {202 differences.add(new Difference(currentPath, key1, key2));203 continue;204 }205 continue;206 }207 // Special handle SortedSets because they are fast to compare208 // because their elements must be in the same order to be equivalent Sets.209 if (key1 instanceof SortedSet) {210 if (!compareOrderedCollection((Collection<?>) key1, (Collection<?>) key2, currentPath, toCompare, visited)) {211 differences.add(new Difference(currentPath, key1, key2));212 continue;213 }214 continue;215 }216 // Check List, as element order matters this comparison is faster than using unordered comparison.217 if (key1 instanceof List) {218 if (!compareOrderedCollection((Collection<?>) key1, (Collection<?>) key2, currentPath, toCompare, visited)) {219 differences.add(new Difference(currentPath, key1, key2));220 continue;221 }222 continue;223 }224 // Handle unordered Collection.225 if (key1 instanceof Collection) {226 if (!compareUnorderedCollection((Collection<?>) key1, (Collection<?>) key2, currentPath, toCompare,227 visited, comparatorByPropertyOrField, comparatorByType)) {228 differences.add(new Difference(currentPath, key1, key2));229 continue;230 }231 continue;232 }233 // Compare two SortedMaps. This takes advantage of the fact that these234 // Maps can be compared in O(N) time due to their ordering.235 if (key1 instanceof SortedMap) {236 if (!compareSortedMap((SortedMap<?, ?>) key1, (SortedMap<?, ?>) key2, currentPath, toCompare, visited)) {237 differences.add(new Difference(currentPath, key1, key2));238 continue;239 }240 continue;241 }242 // Compare two Unordered Maps. This is a slightly more expensive comparison because243 // order cannot be assumed, therefore a temporary Map must be created, however the244 // comparison still runs in O(N) time.245 if (key1 instanceof Map) {246 if (!compareUnorderedMap((Map<?, ?>) key1, (Map<?, ?>) key2, currentPath, toCompare, visited)) {247 differences.add(new Difference(currentPath, key1, key2));248 continue;249 }250 continue;251 }252 if (hasCustomEquals(key1.getClass())) {253 if (!key1.equals(key2)) {254 differences.add(new Difference(currentPath, key1, key2));255 continue;256 }257 continue;258 }259 Set<String> key1FieldsNames = getFieldsNames(getDeclaredFieldsIncludingInherited(key1.getClass()));260 Set<String> key2FieldsNames = getFieldsNames(getDeclaredFieldsIncludingInherited(key2.getClass()));261 if (!key2FieldsNames.containsAll(key1FieldsNames)) {262 differences.add(new Difference(currentPath, key1, key2));263 } else {264 for (String fieldName : key1FieldsNames) {265 List<String> path = new ArrayList<>(currentPath);266 path.add(fieldName);267 DualKey dk = new DualKey(path,268 COMPARISON.getSimpleValue(fieldName, key1),269 COMPARISON.getSimpleValue(fieldName, key2));270 if (!visited.contains(dk)) {271 toCompare.addFirst(dk);272 }273 }274 }275 }276 return differences;277 }278 private static boolean hasCustomComparator(DualKey dualKey, Map<String, Comparator<?>> comparatorByPropertyOrField,279 TypeComparators comparatorByType) {280 String fieldName = dualKey.getConcatenatedPath();281 if (comparatorByPropertyOrField.containsKey(fieldName)) return true;282 // we know that dualKey.key1 != dualKey.key2 at this point, so one the key is not null283 Class<?> keyType = dualKey.key1 != null ? dualKey.key1.getClass() : dualKey.key2.getClass();284 return comparatorByType.get(keyType) != null;285 }286 private static Deque<DualKey> initStack(Object a, Object b, List<String> parentPath,287 Map<String, Comparator<?>> comparatorByPropertyOrField,288 TypeComparators comparatorByType) {289 Deque<DualKey> stack = new LinkedList<>();290 boolean isRootObject = parentPath == null;291 List<String> currentPath = isRootObject ? new ArrayList<String>() : parentPath;292 DualKey basicDualKey = new DualKey(currentPath, a, b);293 if (a != null && b != null && !isContainerType(a) && !isContainerType(b)294 && (isRootObject || !hasCustomComparator(basicDualKey, comparatorByPropertyOrField, comparatorByType))) {295 // disregard the equals method and start comparing fields296 Set<String> aFieldsNames = getFieldsNames(getDeclaredFieldsIncludingInherited(a.getClass()));297 if (!aFieldsNames.isEmpty()) {298 Set<String> bFieldsNames = getFieldsNames(getDeclaredFieldsIncludingInherited(b.getClass()));299 if (!bFieldsNames.containsAll(aFieldsNames)) {300 stack.addFirst(basicDualKey);301 } else {302 for (String fieldName : aFieldsNames) {303 List<String> fieldPath = new ArrayList<>(currentPath);304 fieldPath.add(fieldName);305 DualKey dk = new DualKey(fieldPath,306 COMPARISON.getSimpleValue(fieldName, a),307 COMPARISON.getSimpleValue(fieldName, b));308 stack.addFirst(dk);309 }310 }311 } else {312 stack.addFirst(basicDualKey);313 }314 } else {315 stack.addFirst(basicDualKey);316 }317 return stack;318 }319 private static Set<String> getFieldsNames(Collection<Field> fields) {320 Set<String> fieldNames = new LinkedHashSet<>();321 for (Field field : fields) {322 fieldNames.add(field.getName());323 }324 return fieldNames;325 }326 private static boolean isContainerType(Object o) {327 return o instanceof Collection || o instanceof Map;328 }329 /**330 * Deeply compare to Arrays []. Both arrays must be of the same type, same331 * length, and all elements within the arrays must be deeply equal in order332 * to return true.333 * 334 * @param array1 [] type (Object[], String[], etc.)335 * @param array2 [] type (Object[], String[], etc.)336 * @param path the path to the arrays to compare337 * @param toCompare add items to compare to the Stack (Stack versus recursion)338 * @param visited Set of objects already compared (prevents cycles)339 * @return true if the two arrays are the same length and contain deeply340 * equivalent items.341 */342 private static boolean compareArrays(Object array1, Object array2, List<String> path, Deque<DualKey> toCompare,343 Set<DualKey> visited) {344 int len = Array.getLength(array1);345 if (len != Array.getLength(array2)) {346 return false;347 }348 for (int i = 0; i < len; i++) {349 DualKey dk = new DualKey(path, Array.get(array1, i), Array.get(array2, i));350 if (!visited.contains(dk)) {351 toCompare.addFirst(dk);352 }353 }354 return true;355 }356 /**357 * Deeply compare two Collections that must be same length and in same358 * order.359 * 360 * @param col1 First collection of items to compare361 * @param col2 Second collection of items to compare362 * @param path The path to the collections363 * @param toCompare add items to compare to the Stack (Stack versus recursion)364 * @param visited365 * Set of objects already compared (prevents cycles) value of366 * 'true' indicates that the Collections may be equal, and the367 * sets items will be added to the Stack for further comparison.368 */369 private static <K, V> boolean compareOrderedCollection(Collection<K> col1, Collection<V> col2,370 List<String> path, Deque<DualKey> toCompare,371 Set<DualKey> visited) {372 if (col1.size() != col2.size()) return false;373 Iterator<V> i2 = col2.iterator();374 for (K k : col1) {375 DualKey dk = new DualKey(path, k, i2.next());376 if (!visited.contains(dk)) toCompare.addFirst(dk);377 }378 return true;379 }380 /**381 * It places one collection into a temporary Map by deepHashCode(), so that it382 * can walk the other collection and look for each item in the map, which383 * runs in O(N) time, rather than an O(N^2) lookup that would occur if each384 * item from collection one was scanned for in collection two.385 * 386 * @param col1 First collection of items to compare387 * @param col2 Second collection of items to compare388 * @param path the path to the collections to compare389 * @param toCompare add items to compare to the Stack (Stack versus recursion)390 * @param visited Set containing items that have already been compared, so as to391 * prevent cycles.392 * @return boolean false if the Collections are for certain not equals. A393 * value of 'true' indicates that the Collections may be equal, and394 * the sets items will be added to the Stack for further comparison.395 */396 private static <K, V> boolean compareUnorderedCollectionByHashCodes(Collection<K> col1, Collection<V> col2,397 List<String> path, Deque<DualKey> toCompare,398 Set<DualKey> visited) {399 Map<Integer, Object> fastLookup = new HashMap<>();400 for (Object o : col2) {401 fastLookup.put(deepHashCode(o), o);402 }403 for (Object o : col1) {404 Object other = fastLookup.get(deepHashCode(o));405 if (other == null) {406 // Item not even found in other Collection, no need to continue.407 return false;408 }409 DualKey dk = new DualKey(path, o, other);410 if (!visited.contains(dk)) {411 toCompare.addFirst(dk);412 }413 }414 return true;415 }416 /**417 * Deeply compares two collections referenced by dualKey. This method attempts418 * to quickly determine inequality by length, then if lengths match, in case of419 * collection type is Set and there are passed no custom comparators, there is used420 * comparison on hashcodes basis, otherwise each element from one collection is checked421 * for existence in another one using 'deep' comparison.422 */423 private static <K, V> boolean compareUnorderedCollection(Collection<K> col1, Collection<V> col2,424 List<String> path, Deque<DualKey> toCompare,425 Set<DualKey> visited,426 Map<String, Comparator<?>> comparatorByPropertyOrField,427 TypeComparators comparatorByType) {428 if (col1.size() != col2.size()) return false;429 boolean noCustomComparators = comparatorByPropertyOrField.isEmpty() && comparatorByType.isEmpty();430 if (noCustomComparators && col1 instanceof Set) {431 // this comparison is used for performance optimization reasons432 return compareUnorderedCollectionByHashCodes(col1, col2, path, toCompare, visited);433 }434 Collection<V> col2Copy = new LinkedList<>(col2);435 for (Object o1 : col1) {436 Iterator<V> iterator = col2Copy.iterator();437 while (iterator.hasNext()) {438 Object o2 = iterator.next();439 if (determineDifferences(o1, o2, path, comparatorByPropertyOrField, comparatorByType).isEmpty()) {440 iterator.remove();441 break;442 }443 }444 }445 return col2Copy.isEmpty();446 }447 /**448 * Deeply compare two SortedMap instances. This method walks the Maps in449 * order, taking advantage of the fact that the Maps are SortedMaps.450 * 451 * @param map1 SortedMap one452 * @param map2 SortedMap two453 * @param path the path to the maps to compare454 * @param toCompare add items to compare to the Stack (Stack versus recursion)455 * @param visited Set containing items that have already been compared, to456 * prevent cycles.457 * @return false if the Maps are for certain not equals. 'true' indicates458 * that 'on the surface' the maps are equal, however, it will place459 * the contents of the Maps on the stack for further comparisons.460 */461 private static <K1, V1, K2, V2> boolean compareSortedMap(SortedMap<K1, V1> map1, SortedMap<K2, V2> map2,462 List<String> path, Deque<DualKey> toCompare,463 Set<DualKey> visited) {464 if (map1.size() != map2.size()) {465 return false;466 }467 Iterator<Map.Entry<K2, V2>> i2 = map2.entrySet().iterator();468 for (Map.Entry<K1, V1> entry1 : map1.entrySet()) {469 Map.Entry<K2, V2> entry2 = i2.next();470 // Must split the Key and Value so that Map.Entry's equals() method is not used.471 DualKey dk = new DualKey(path, entry1.getKey(), entry2.getKey());472 if (!visited.contains(dk)) {473 toCompare.addFirst(dk);474 }475 dk = new DualKey(path, entry1.getValue(), entry2.getValue());476 if (!visited.contains(dk)) {477 toCompare.addFirst(dk);478 }479 }480 return true;481 }482 /**483 * Deeply compare two Map instances. After quick short-circuit tests, this484 * method uses a temporary Map so that this method can run in O(N) time.485 * 486 * @param map1 Map one487 * @param map2 Map two488 * @param path the path to the maps to compare489 * @param toCompare add items to compare to the Stack (Stack versus recursion)490 * @param visited Set containing items that have already been compared, to491 * prevent cycles.492 * @return false if the Maps are for certain not equals. 'true' indicates493 * that 'on the surface' the maps are equal, however, it will place494 * the contents of the Maps on the stack for further comparisons.495 */496 private static <K1, V1, K2, V2> boolean compareUnorderedMap(Map<K1, V1> map1, Map<K2, V2> map2,497 List<String> path, Deque<DualKey> toCompare,498 Set<DualKey> visited) {499 if (map1.size() != map2.size()) {500 return false;501 }502 Map<Integer, Map.Entry<K2, V2>> fastLookup = new HashMap<>();503 for (Map.Entry<K2, V2> entry : map2.entrySet()) {504 fastLookup.put(deepHashCode(entry.getKey()), entry);505 }506 for (Map.Entry<K1, V1> entry : map1.entrySet()) {507 Map.Entry<K2, V2> other = fastLookup.get(deepHashCode(entry.getKey()));508 if (other == null) {509 return false;510 }511 DualKey dk = new DualKey(path, entry.getKey(), other.getKey());512 if (!visited.contains(dk)) {513 toCompare.addFirst(dk);514 }515 dk = new DualKey(path, entry.getValue(), other.getValue());516 if (!visited.contains(dk)) {517 toCompare.addFirst(dk);518 }519 }520 return true;521 }522 /**523 * Determine if the passed in class has a non-Object.equals() method. This524 * method caches its results in static ConcurrentHashMap to benefit525 * execution performance.526 * 527 * @param c Class to check.528 * @return true, if the passed in Class has a .equals() method somewhere529 * between itself and just below Object in it's inheritance.530 */531 static boolean hasCustomEquals(Class<?> c) {532 if (customEquals.containsKey(c)) {533 return customEquals.get(c);534 }535 Class<?> origClass = c;536 while (!Object.class.equals(c)) {537 try {538 c.getDeclaredMethod("equals", Object.class);539 customEquals.put(origClass, true);540 return true;541 } catch (Exception ignored) {}542 c = c.getSuperclass();543 }544 customEquals.put(origClass, false);545 return false;546 }547 /**548 * Get a deterministic hashCode (int) value for an Object, regardless of549 * when it was created or where it was loaded into memory. The problem with550 * java.lang.Object.hashCode() is that it essentially relies on memory551 * location of an object (what identity it was assigned), whereas this552 * method will produce the same hashCode for any object graph, regardless of553 * how many times it is created.<br>554 * <br>555 *556 * This method will handle cycles correctly (A->B->C->A). In this557 * case, Starting with object A, B, or C would yield the same hashCode. If558 * an object encountered (root, subobject, etc.) has a hashCode() method on559 * it (that is not Object.hashCode()), that hashCode() method will be called560 * and it will stop traversal on that branch.561 * 562 * @param obj Object who hashCode is desired.563 * @return the 'deep' hashCode value for the passed in object.564 */565 static int deepHashCode(Object obj) {566 Set<Object> visited = new HashSet<>();567 LinkedList<Object> stack = new LinkedList<>();568 stack.addFirst(obj);569 int hash = 0;570 while (!stack.isEmpty()) {571 obj = stack.removeFirst();572 if (obj == null || visited.contains(obj)) {573 continue;574 }575 visited.add(obj);576 if (obj.getClass().isArray()) {577 int len = Array.getLength(obj);578 for (int i = 0; i < len; i++) {579 stack.addFirst(Array.get(obj, i));580 }581 continue;582 }583 if (obj instanceof Collection) {584 stack.addAll(0, (Collection<?>) obj);585 continue;586 }587 if (obj instanceof Map) {588 stack.addAll(0, ((Map<?, ?>) obj).keySet());589 stack.addAll(0, ((Map<?, ?>) obj).values());590 continue;591 }592 if (obj instanceof Double || obj instanceof Float) {593 // just take the integral value for hashcode594 // equality tests things more comprehensively595 stack.add(Math.round(((Number) obj).doubleValue()));596 continue;597 }598 if (hasCustomHashCode(obj.getClass())) {599 // A real hashCode() method exists, call it.600 hash += obj.hashCode();601 continue;602 }603 Collection<Field> fields = getDeclaredFieldsIncludingInherited(obj.getClass());604 for (Field field : fields) {605 stack.addFirst(COMPARISON.getSimpleValue(field.getName(), obj));606 }607 }608 return hash;609 }610 /**611 * Determine if the passed in class has a non-Object.hashCode() method. This612 * method caches its results in static ConcurrentHashMap to benefit613 * execution performance.614 * 615 * @param c Class to check.616 * @return true, if the passed in Class has a .hashCode() method somewhere617 * between itself and just below Object in it's inheritance....
Source:EnhancedObjectAssert.java
...9import org.assertj.core.util.introspection.PropertySupport;10import java.lang.reflect.Field;11import java.util.*;12import static org.assertj.core.error.ShouldBeEqualToIgnoringFields.shouldBeEqualToIgnoringGivenFields;13import static org.assertj.core.internal.Objects.getDeclaredFieldsIncludingInherited;14import static org.assertj.core.internal.TypeComparators.defaultTypeComparators;15import static org.assertj.core.util.Sets.newLinkedHashSet;16/**17 * Enhanced object assert for <code>Assertj</code>18 * Created by nigel on 2020/3/15.19 *20 * @author nigel21 * @todo find a way to expose the class22 * @see org.assertj.core.api.ObjectAssert23 */24public abstract class EnhancedObjectAssert<SELF extends EnhancedObjectAssert<SELF, ACTUAL>, ACTUAL> extends AbstractAssert<SELF, ACTUAL> {25 public EnhancedObjectAssert(ACTUAL actual, Class<?> selfType) {26 super(actual, selfType);27 }28 @VisibleForTesting29 Objects objects = Objects.instance();30 @VisibleForTesting31 Failures failures = Failures.instance();32 @VisibleForTesting33 final PropertySupport propertySupport = PropertySupport.instance();34 @VisibleForTesting35 private final FieldSupport fieldSupport = FieldSupport.comparison();36 private Map<String, Comparator<?>> comparatorByPropertyOrField = new TreeMap<>();37 private TypeComparators comparatorByType = defaultTypeComparators();38 public SELF isEqualToIgnoringNullFieldsAndGivenFields(Object other, String... propertiesOrFieldsToIgnore) {39 objects.assertNotNull(info, actual);40 List<String> fieldsNames = new LinkedList<>();41 List<Object> rejectedValues = new LinkedList<>();42 List<Object> expectedValues = new LinkedList<>();43 List<String> nullFields = new LinkedList<>();44 for (Field field : getDeclaredFieldsIncludingInherited(actual.getClass())) {45 if (!canReadFieldValue(field, actual)) continue;46 String fieldName = field.getName();47 Object otherFieldValue = getPropertyOrFieldValue(other, fieldName);48 if (otherFieldValue == null) {49 nullFields.add(fieldName);50 } else {51 Object actualFieldValue = getPropertyOrFieldValue(actual, fieldName);52 if (!propertyOrFieldValuesAreEqual(actualFieldValue, otherFieldValue, fieldName,53 comparatorByPropertyOrField, comparatorByType)) {54 fieldsNames.add(fieldName);55 rejectedValues.add(actualFieldValue);56 expectedValues.add(otherFieldValue);57 }58 }...
Source:DefaultRecursiveAssertionIntrospectionStrategy.java
...13package org.assertj.core.api.recursive.assertion;14import static java.lang.String.format;15import static java.util.Arrays.stream;16import static java.util.stream.Collectors.toList;17import static org.assertj.core.internal.Objects.getDeclaredFieldsIncludingInherited;18import static org.assertj.core.util.introspection.PropertyOrFieldSupport.EXTRACTION;19import java.lang.reflect.Field;20import java.util.List;21import java.util.Optional;22public class DefaultRecursiveAssertionIntrospectionStrategy implements RecursiveAssertionIntrospectionStrategy {23 @Override24 public List<RecursiveAssertionNode> getChildNodesOf(Object node) {25 return getDeclaredFieldsIncludingInherited(node.getClass()).stream()26 .map(field -> toNode(field, node))27 .collect(toList());28 }29 @Override30 public String getDescription() {31 return "DefaultRecursiveAssertionIntrospectionStrategy which introspects all fields (including inherited ones)";32 }33 private static RecursiveAssertionNode toNode(Field field, Object node) {34 String fieldName = field.getName();35 Object fieldValue = EXTRACTION.getSimpleValue(fieldName, node);36 Class<?> fieldType = getFieldType(fieldValue, fieldName, node);37 return new RecursiveAssertionNode(fieldValue, fieldName, fieldType);38 }39 private static Class<?> getFieldType(Object fieldValue, String fieldName, Object targetObject) {...
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.api.Assertions;2import org.assertj.core.internal.Objects;3import java.lang.reflect.Field;4import java.util.Arrays;5import java.util.List;6public class 1 {7 public static void main(String[] args) {8 List<Field> fields = Arrays.asList(Objects.instance().getDeclaredFieldsIncludingInherited(ClassWithInheritedFields.class));9 Assertions.assertThat(fields).hasSize(4);10 }11 static class ClassWithInheritedFields extends ClassWithFields {12 }13 static class ClassWithFields {14 private String field1;15 private String field2;16 }17}18public static Field[] getDeclaredFieldsIncludingInherited(Class<?> clazz)19s.checkMemberAccess(this, Member.PUBLIC) fails20s.checkPackageAccess(this.getPackage().getName()) fails
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1package org.assertj.core.internal;2import static org.assertj.core.api.Assertions.assertThat;3import java.lang.reflect.Field;4import org.junit.Test;5public class Objects_getDeclaredFieldsIncludingInherited_Test {6 public void should_return_all_fields_including_inherited() {7 Field[] fields = Objects.instance().getDeclaredFieldsIncludingInherited(Child.class);8 assertThat(fields).hasSize(3);9 assertThat(fields[0].getName()).isEqualTo("parentField");10 assertThat(fields[1].getName()).isEqualTo("childField");11 assertThat(fields[2].getName()).isEqualTo("field");12 }13 private static class Parent {14 private String parentField;15 }16 private static class Child extends Parent {17 private String childField;18 }19 private static class GrandChild extends Child {20 private String field;21 }22}23package org.assertj.core.internal;24import static org.assertj.core.api.Assertions.assertThat;25import java.lang.reflect.Field;26import org.junit.Test;27public class Objects_getDeclaredFieldsIncludingInherited_Test {28 public void should_return_all_fields_including_inherited() {29 Field[] fields = Objects.instance().getDeclaredFieldsIncludingInherited(Child.class);30 assertThat(fields).hasSize(3);31 assertThat(fields[0].getName()).isEqualTo("parentField");32 assertThat(fields[1].getName()).isEqualTo("childField");33 assertThat(fields[2].getName()).isEqualTo("field");34 }35 private static class Parent {36 private String parentField;37 }38 private static class Child extends Parent {39 private String childField;40 }41 private static class GrandChild extends Child {42 private String field;43 }44}45package org.assertj.core.internal;46import static org.assertj.core.api.Assertions.assertThat;47import java.lang.reflect.Field;48import org.junit.Test;49public class Objects_getDeclaredFieldsIncludingInherited_Test {50 public void should_return_all_fields_including_inherited() {51 Field[] fields = Objects.instance().getDeclaredFieldsIncludingInherited(Child.class);52 assertThat(fields).hasSize(3);53 assertThat(fields[0].getName()).isEqualTo("parentField");54 assertThat(fields[1].getName()).isEqualTo("childField");55 assertThat(fields
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.api.Assertions;2import org.assertj.core.api.Condition;3import org.assertj.core.api.SoftAssertions;4import org.assertj.core.internal.Objects;5import org.junit.Test;6import java.lang.reflect.Field;7import java.util.Arrays;8import java.util.List;9import static org.assertj.core.api.Assertions.assertThat;10public class TestClass {11 public void test() throws Exception {12 final Objects objects = new Objects();13 final Field[] declaredFieldsIncludingInherited = objects.getDeclaredFieldsIncludingInherited(TestClass.class);14 final List<Field> fields = Arrays.asList(declaredFieldsIncludingInherited);15 assertThat(fields).hasSize(1);16 assertThat(fields).have(new Condition<Field>() {17 public boolean matches(Field value) {18 return value.getName().equals("objects");19 }20 });21 }22}23at org.assertj.core.api.AbstractListAssert.hasSize(AbstractListAssert.java:160)24at TestClass.test(TestClass.java:19)25import org.assertj.core.api.Assertions;26import org.assertj.core.api.SoftAssertions;27import org.assertj.core.internal.Classes;28import org.junit.Test;29import java.lang.reflect.Field;30import java.util.Arrays;31import java.util.List;32import static org.assertj.core.api.Assertions.assertThat;33public class TestClass {34 public void test() throws Exception {35 final Classes classes = new Classes();36 final Field[] declaredFieldsIncludingInherited = classes.getDeclaredFieldsIncludingInherited(TestClass.class);37 final List<Field> fields = Arrays.asList(declaredFieldsIncludingInherited);38 assertThat(fields).hasSize(1);39 assertThat(fields).have(new Condition<Field>() {40 public boolean matches(Field value) {41 return value.getName().equals("objects");42 }43 });44 }45}
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1package org.assertj.core.internal;2import java.lang.reflect.Field;3import java.util.ArrayList;4import java.util.List;5import org.assertj.core.util.Arrays;6import org.assertj.core.util.VisibleForTesting;7import org.assertj.core.util.introspection.IntrospectionError;8public class Objects_getDeclaredFieldsIncludingInherited_Test {9 public static void main(String[] args) {10 Objects objects = new Objects();11 List<Field> fields = objects.getDeclaredFieldsIncludingInherited(TestClass.class);12 for (Field field : fields) {13 System.out.println(field.getName());14 }15 }16}17class TestClass {18 private String field1;19 public String field2;20 protected String field3;21 String field4;22 private String[] field5;23 private List<String> field6;24 private List<String>[] field7;25 private List<String> field8 = new ArrayList<>();26 private List<String>[] field9 = new ArrayList[1];27 private List<String> field10 = new ArrayList<String>() {28 private static final long serialVersionUID = 1L;29 {30 add("field10");31 }32 };33 public List<String> field11 = new ArrayList<String>() {34 private static final long serialVersionUID = 1L;35 {36 add("field11");37 }38 };39 protected List<String> field12 = new ArrayList<String>() {40 private static final long serialVersionUID = 1L;41 {42 add("field12");43 }44 };45 List<String> field13 = new ArrayList<String>() {46 private static final long serialVersionUID = 1L;47 {48 add("field13");49 }50 };51 private List<String> field14 = new ArrayList<String>() {52 private static final long serialVersionUID = 1L;53 {54 add("field14");55 }56 };57 private List<String> field15 = new ArrayList<String>() {58 private static final long serialVersionUID = 1L;59 {60 add("field15");61 }62 };63 private List<String> field16 = new ArrayList<String>() {64 private static final long serialVersionUID = 1L;65 {66 add("field16");67 }68 };69 private List<String> field17 = new ArrayList<String>() {70 private static final long serialVersionUID = 1L;71 {72 add("field17");73 }74 };
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.internal.Objects;2import org.assertj.core.internal.FieldSupport;3import java.lang.reflect.Field;4import java.lang.reflect.Modifier;5import java.util.List;6import java.util.ArrayList;7import java.util.Arrays;8import java.util.Collections;9import java.lang.reflect.Type;10import java.lang.reflect.ParameterizedType;11import java.lang.reflect.GenericArrayType;12import java.lang.reflect.TypeVariable;13import java.lang.reflect.WildcardType;14import org.assertj.core.util.VisibleForTesting;15import org.assertj.core.util.Lists;16import org.assertj.core.util.Arrays;17import org.assertj.core.util.introspection.FieldSupport;18import org.assertj.core.util.introspection.IntrospectionError;19public class Test {20 public static void main(String[] args) {21 Objects objects = new Objects();22 FieldSupport fieldSupport = new FieldSupport();23 Field[] declaredFields = objects.getDeclaredFieldsIncludingInherited(fieldSupport, Test.class);24 for (Field field : declaredFields) {25 System.out.println(field.getName());26 }27 }28}29import org.assertj.core.internal.Objects;30import org.assertj.core.internal.FieldSupport;31import java.lang.reflect.Field;32import java.lang.reflect.Modifier;33import java.util.List;34import java.util.ArrayList;35import java.util.Arrays;36import java.util.Collections;37import java.lang.reflect.Type;38import java.lang.reflect.ParameterizedType;39import java.lang.reflect.GenericArrayType;40import java.lang.reflect.TypeVariable;41import java.lang.reflect.WildcardType;42import org.assertj.core.util.VisibleForTesting;43import org.assertj.core.util.Lists;44import org.assertj.core.util.Arrays;45import org.assertj.core.util.introspection.FieldSupport;46import org.assertj.core.util.introspection.IntrospectionError;47public class Test {48 public static void main(String[] args) {49 Objects objects = new Objects();50 FieldSupport fieldSupport = new FieldSupport();51 Field[] declaredFields = objects.getDeclaredFieldsIncludingInherited(fieldSupport, Test.class);52 for (Field field : declaredFields) {53 System.out.println(field.getName());54 }55 }56}57import org.assertj.core.internal.Objects;58import org.assertj.core.internal.FieldSupport;59import java.lang.reflect.Field;60import java.lang.reflect.Modifier;61import java.util.List;62import java.util.ArrayList;
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.internal.Objects;2import java.lang.reflect.Field;3import java.util.ArrayList;4import java.util.List;5public class 1 {6public static void main(String[] args) throws Exception {7Objects objects = new Objects();8List<Field> fields = new ArrayList<>();9fields = objects.getDeclaredFieldsIncludingInherited(Field.class);10System.out.println(fields);11}12}
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.internal.Objects;2import java.lang.reflect.Field;3import java.lang.reflect.Modifier;4public class Test {5 public static void main(String[] args) throws Exception {6 Objects objects = new Objects();7 Class<?> testClass = Class.forName("Test");8 Field[] fields = objects.getDeclaredFieldsIncludingInherited(testClass);9 for (Field field : fields) {10 System.out.println(field);11 }12 }13}14import org.assertj.core.internal.Objects;15import java.lang.reflect.Field;16import java.lang.reflect.Modifier;17public class Test {18 public static void main(String[] args) throws Exception {19 Objects objects = new Objects();20 Class<?> testClass = Class.forName("Test");21 Field[] fields = objects.getDeclaredFieldsIncludingInherited(testClass);22 for (Field field : fields) {23 System.out.println(field);24 }25 }26}27import org.assertj.core.internal.FieldSupport;28import java.lang.reflect.Field;29import java.lang.reflect.Modifier;30import java.util.List;31import java.util.ArrayList;32import java.util.Arrays;33import java.util.Collections;34import java.lang.reflect.Type;35import java.lang.reflect.ParameterizedType;36import java.lang.reflect.GenericArrayType;37import java.lang.reflect.TypeVariable;38import java.lang.reflect.WildcardType;39import org.assertj.core.util.VisibleForTesting;40import org.assertj.core.util.Lists;41import org.assertj.core.util.Arrays;42import org.assertj.core.util.introspection.FieldSupport;43import org.assertj.core.util.introspection.IntrospectionError;44public class Test {45 public static void main(String[] args) {46 Objects objects = new Objects();47 FieldSupport fieldSupport = new FieldSupport();48 Field[] declaredFields = objects.getDeclaredFieldsIncludingInherited(fieldSupport, Test.class);49 for (Field field : declaredFields) {50 System.out.println(field.getName());51 }52 }53}54import org.assertj.core.internal.Objects;55import org.assertj.core.internal.FieldSupport;56import java.lang.reflect.Field;57import java.lang.reflect.Modifier;58import java.util.List;59import java.util.ArrayList;60import java.util.Arrays;61import java.util.Collections;62import java.lang.reflect.Type;63import java.lang.reflect.ParameterizedType;64import java.lang.reflect.GenericArrayType;65import java.lang.reflect.TypeVariable;66import java.lang.reflect.WildcardType;67import org.assertj.core.util.VisibleForTesting;68import org.assertj.core.util.Lists;69import org.assertj.core.util.Arrays;70import org.assertj.core.util.introspection.FieldSupport;71import org.assertj.core.util.introspection.IntrospectionError;72public class Test {73 public static void main(String[] args) {74 Objects objects = new Objects();75 FieldSupport fieldSupport = new FieldSupport();76 Field[] declaredFields = objects.getDeclaredFieldsIncludingInherited(fieldSupport, Test.class);77 for (Field field : declaredFields) {78 System.out.println(field.getName());79 }80 }81}82import org.assertj.core.internal.Objects;83import org.assertj.core.internal.FieldSupport;84import java.lang.reflect.Field;85import java.lang.reflect.Modifier;86import java.util.List;87import java.util.ArrayList;
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.internal.Objects;2import java.lang.reflect.Field;3import java.util.ArrayList;4import java.util.List;5public class 1 {6public static void main(String[] args) throws Exception {7Objects objects = new Objects();8List<Field> fields = new ArrayList<>();9fields = objects.getDeclaredFieldsIncludingInherited(Field.class);10System.out.println(fields);11}12}
getDeclaredFieldsIncludingInherited
Using AI Code Generation
1import org.assertj.core.internal.Objects;2import java.lang.reflect.Field;3import java.lang.reflect.Modifier;4public class Test {5 public static void main(String[] args) throws Exception {6 Objects objects = new Objects();7 Class<?> testClass = Class.forName("Test");8 Field[] fields = objects.getDeclaredFieldsIncludingInherited(testClass);9 for (Field field : fields) {10 System.out.println(field);11 }12 }13}14import org.assertj.core.internal.Objects;15import java.lang.reflect.Field;16import java.lang.reflect.Modifier;17public class Test {18 public static void main(String[] args) throws Exception {19 Objects objects = new Objects();20 Class<?> testClass = Class.forName("Test");21 Field[] fields = objects.getDeclaredFieldsIncludingInherited(testClass);22 for (Field field : fields) {23 System.out.println(field);24 }25 }26}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!