Best Assertj code snippet using org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.areDualValueEqual
Source:RecursiveComparisonDifferenceCalculator.java
...198 final Object actualFieldValue = dualValue.actual;199 final Object expectedFieldValue = dualValue.expected;200 // Custom comparators take precedence over all other types of comparison201 if (recursiveComparisonConfiguration.hasCustomComparator(dualValue)) {202 if (!areDualValueEqual(dualValue, recursiveComparisonConfiguration)) comparisonState.addDifference(dualValue);203 // since we used a custom comparator we don't need to inspect the nested fields any further204 continue;205 }206 if (actualFieldValue == expectedFieldValue) continue;207 if (actualFieldValue == null || expectedFieldValue == null) {208 // one of the value is null while the other is not as we already know that actualFieldValue != expectedFieldValue209 comparisonState.addDifference(dualValue);210 continue;211 }212 if (dualValue.isExpectedAnEnum()) {213 compareAsEnums(dualValue, comparisonState, recursiveComparisonConfiguration);214 continue;215 }216 // TODO move hasFieldTypesDifference check into each compareXXX217 if (dualValue.isExpectedFieldAnArray()) {218 compareArrays(dualValue, comparisonState);219 continue;220 }221 // we compare ordered collections specifically as to be matching, each pair of elements at a given index must match.222 // concretely we compare: (col1[0] vs col2[0]), (col1[1] vs col2[1])...(col1[n] vs col2[n])223 if (dualValue.isExpectedFieldAnOrderedCollection()224 && !recursiveComparisonConfiguration.shouldIgnoreCollectionOrder(dualValue.fieldLocation)) {225 compareOrderedCollections(dualValue, comparisonState);226 continue;227 }228 if (dualValue.isExpectedFieldAnIterable()) {229 compareUnorderedIterables(dualValue, comparisonState);230 continue;231 }232 if (dualValue.isExpectedFieldAnOptional()) {233 compareOptional(dualValue, comparisonState);234 continue;235 }236 // Compare two SortedMaps taking advantage of the fact that these Maps can be compared in O(N) time due to their ordering237 if (dualValue.isExpectedFieldASortedMap()) {238 compareSortedMap(dualValue, comparisonState);239 continue;240 }241 // Compare two Unordered Maps. This is a slightly more expensive comparison because order cannot be assumed, therefore a242 // temporary Map must be created, however the comparison still runs in O(N) time.243 if (dualValue.isExpectedFieldAMap()) {244 compareUnorderedMap(dualValue, comparisonState);245 continue;246 }247 // compare Atomic types by value manually as they are container type and we can't use introspection in java 17+248 if (dualValue.isExpectedFieldAnAtomicBoolean()) {249 compareAtomicBoolean(dualValue, comparisonState);250 continue;251 }252 if (dualValue.isExpectedFieldAnAtomicInteger()) {253 compareAtomicInteger(dualValue, comparisonState);254 continue;255 }256 if (dualValue.isExpectedFieldAnAtomicIntegerArray()) {257 compareAtomicIntegerArray(dualValue, comparisonState);258 continue;259 }260 if (dualValue.isExpectedFieldAnAtomicLong()) {261 compareAtomicLong(dualValue, comparisonState);262 continue;263 }264 if (dualValue.isExpectedFieldAnAtomicLongArray()) {265 compareAtomicLongArray(dualValue, comparisonState);266 continue;267 }268 if (dualValue.isExpectedFieldAnAtomicReference()) {269 compareAtomicReference(dualValue, comparisonState);270 continue;271 }272 if (dualValue.isExpectedFieldAnAtomicReferenceArray()) {273 compareAtomicReferenceArray(dualValue, comparisonState);274 continue;275 }276 if (shouldHonorEquals(dualValue, recursiveComparisonConfiguration)) {277 if (!actualFieldValue.equals(expectedFieldValue)) comparisonState.addDifference(dualValue);278 continue;279 }280 Class<?> actualFieldValueClass = actualFieldValue.getClass();281 Class<?> expectedFieldClass = expectedFieldValue.getClass();282 if (recursiveComparisonConfiguration.isInStrictTypeCheckingMode() && expectedTypeIsNotSubtypeOfActualType(dualValue)) {283 comparisonState.addDifference(dualValue,284 format(STRICT_TYPE_ERROR, expectedFieldClass.getName(), actualFieldValueClass.getName()));285 continue;286 }287 Set<String> actualNonIgnoredFieldsNames = recursiveComparisonConfiguration.getActualFieldNamesToCompare(dualValue);288 Set<String> expectedFieldsNames = getFieldsNames(expectedFieldClass);289 // Check if expected has more fields than actual, in that case the additional fields are reported as difference290 if (!expectedFieldsNames.containsAll(actualNonIgnoredFieldsNames)) {291 // report missing fields in actual292 Set<String> actualFieldsNamesNotInExpected = newHashSet(actualNonIgnoredFieldsNames);293 actualFieldsNamesNotInExpected.removeAll(expectedFieldsNames);294 String missingFields = actualFieldsNamesNotInExpected.toString();295 String expectedClassName = expectedFieldClass.getName();296 String actualClassName = actualFieldValueClass.getName();297 String missingFieldsDescription = format(MISSING_FIELDS, actualClassName, expectedClassName,298 expectedFieldClass.getSimpleName(), actualFieldValueClass.getSimpleName(),299 missingFields);300 comparisonState.addDifference(dualValue, missingFieldsDescription);301 } else { // TODO remove else to report more diff302 // compare actual's fields against expected :303 // - if actual has more fields than expected, the additional fields are ignored as expected is the reference304 for (String actualFieldName : actualNonIgnoredFieldsNames) {305 if (expectedFieldsNames.contains(actualFieldName)) {306 DualValue newDualValue = new DualValue(dualValue.fieldLocation.field(actualFieldName),307 COMPARISON.getSimpleValue(actualFieldName, actualFieldValue),308 COMPARISON.getSimpleValue(actualFieldName, expectedFieldValue));309 comparisonState.registerForComparison(newDualValue);310 }311 }312 }313 }314 return comparisonState.getDifferences();315 }316 // avoid comparing enum recursively since they contain static fields which are ignored in recursive comparison317 // this would make different field enum value to be considered the same!318 private static void compareAsEnums(final DualValue dualValue,319 ComparisonState comparisonState,320 RecursiveComparisonConfiguration recursiveComparisonConfiguration) {321 if (recursiveComparisonConfiguration.isInStrictTypeCheckingMode()) {322 // we can use == for comparison which checks both actual and expected values and types are the same323 if (dualValue.actual != dualValue.expected) comparisonState.addDifference(dualValue);324 return;325 }326 if (!dualValue.isActualAnEnum()) {327 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an enum"));328 return;329 }330 // both actual and expected are enums331 Enum<?> actualEnum = (Enum<?>) dualValue.actual;332 Enum<?> expectedEnum = (Enum<?>) dualValue.expected;333 // we must only compare actual and expected enum by value but not by type334 if (!actualEnum.name().equals(expectedEnum.name())) comparisonState.addDifference(dualValue);335 }336 private static boolean shouldHonorEquals(DualValue dualValue,337 RecursiveComparisonConfiguration recursiveComparisonConfiguration) {338 // since java 17 we can't introspect java types and get their fields so by default we compare them with equals339 // unless for some container like java types: iterables, array, optional, atomic values where we take the contained values340 // through accessors and register them in the recursive comparison.341 boolean shouldHonorJavaTypeEquals = dualValue.hasSomeJavaTypeValue() && !dualValue.isExpectedAContainer();342 return shouldHonorJavaTypeEquals || shouldHonorOverriddenEquals(dualValue, recursiveComparisonConfiguration);343 }344 private static boolean shouldHonorOverriddenEquals(DualValue dualValue,345 RecursiveComparisonConfiguration recursiveComparisonConfiguration) {346 boolean shouldNotIgnoreOverriddenEqualsIfAny = !recursiveComparisonConfiguration.shouldIgnoreOverriddenEqualsOf(dualValue);347 return shouldNotIgnoreOverriddenEqualsIfAny && dualValue.actual != null && hasOverriddenEquals(dualValue.actual.getClass());348 }349 private static void compareArrays(DualValue dualValue, ComparisonState comparisonState) {350 if (!dualValue.isActualFieldAnArray()) {351 // at the moment we only allow comparing arrays with arrays but we might allow comparing to collections later on352 // but only if we are not in strict type mode.353 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an array"));354 return;355 }356 // both values in dualValue are arrays357 int actualArrayLength = Array.getLength(dualValue.actual);358 int expectedArrayLength = Array.getLength(dualValue.expected);359 if (actualArrayLength != expectedArrayLength) {360 comparisonState.addDifference(dualValue, format(DIFFERENT_SIZE_ERROR, "arrays", actualArrayLength, expectedArrayLength));361 // no need to inspect elements, arrays are not equal as they don't have the same size362 return;363 }364 // register each pair of actual/expected elements for recursive comparison365 FieldLocation arrayFieldLocation = dualValue.fieldLocation;366 for (int i = 0; i < actualArrayLength; i++) {367 Object actualElement = Array.get(dualValue.actual, i);368 Object expectedElement = Array.get(dualValue.expected, i);369 FieldLocation elementFieldLocation = arrayFieldLocation.field(format("[%d]", i));370 comparisonState.registerForComparison(new DualValue(elementFieldLocation, actualElement, expectedElement));371 }372 }373 /*374 * Deeply compare two Collections that must be same length and in same order.375 */376 private static void compareOrderedCollections(DualValue dualValue, ComparisonState comparisonState) {377 if (!dualValue.isActualFieldAnOrderedCollection()) {378 // at the moment if expected is an ordered collection then actual should also be one379 comparisonState.addDifference(dualValue,380 format(ACTUAL_NOT_ORDERED_COLLECTION, dualValue.actual.getClass().getCanonicalName()));381 return;382 }383 Collection<?> actualCollection = (Collection<?>) dualValue.actual;384 Collection<?> expectedCollection = (Collection<?>) dualValue.expected;385 if (actualCollection.size() != expectedCollection.size()) {386 comparisonState.addDifference(dualValue, format(DIFFERENT_SIZE_ERROR, "collections", actualCollection.size(),387 expectedCollection.size()));388 // no need to inspect elements, arrays are not equal as they don't have the same size389 return;390 }391 // register pair of elements with same index for later comparison as we compare elements in order392 Iterator<?> expectedIterator = expectedCollection.iterator();393 int i = 0;394 for (Object element : actualCollection) {395 FieldLocation elementFielLocation = dualValue.fieldLocation.field(format("[%d]", i));396 DualValue elementDualValue = new DualValue(elementFielLocation, element, expectedIterator.next());397 comparisonState.registerForComparison(elementDualValue);398 i++;399 }400 }401 private static String differentTypeErrorMessage(DualValue dualValue, String actualTypeDescription) {402 return format(DIFFERENT_ACTUAL_AND_EXPECTED_FIELD_TYPES,403 actualTypeDescription, dualValue.actual.getClass().getCanonicalName());404 }405 private static void compareUnorderedIterables(DualValue dualValue, ComparisonState comparisonState) {406 if (!dualValue.isActualFieldAnIterable()) {407 // at the moment we only compare iterable with iterables (but we might allow arrays too)408 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an iterable"));409 return;410 }411 Iterable<?> actual = (Iterable<?>) dualValue.actual;412 Iterable<?> expected = (Iterable<?>) dualValue.expected;413 int actualSize = sizeOf(actual);414 int expectedSize = sizeOf(expected);415 if (actualSize != expectedSize) {416 comparisonState.addDifference(dualValue, format(DIFFERENT_SIZE_ERROR, "collections", actualSize, expectedSize));417 // no need to inspect elements, iterables are not equal as they don't have the same size418 return;419 }420 // copy actual as we will remove elements found in expected421 Collection<?> actualCopy = new LinkedList<>(toCollection(actual));422 List<Object> expectedElementsNotFound = list();423 for (Object expectedElement : expected) {424 boolean expectedElementMatched = false;425 // compare recursively expectedElement to all remaining actual elements426 Iterator<?> actualIterator = actualCopy.iterator();427 while (actualIterator.hasNext()) {428 Object actualElement = actualIterator.next();429 // we need to get the currently visited dual values otherwise a cycle would cause an infinite recursion.430 List<ComparisonDifference> differences = determineDifferences(actualElement, expectedElement, dualValue.fieldLocation,431 comparisonState.visitedDualValues,432 comparisonState.recursiveComparisonConfiguration);433 if (differences.isEmpty()) {434 // found an element in actual matching expectedElement, remove it as it can't be used to match other expected elements435 actualIterator.remove();436 expectedElementMatched = true;437 // jump to next actual element check438 break;439 }440 }441 if (!expectedElementMatched) {442 expectedElementsNotFound.add(expectedElement);443 }444 }445 if (!expectedElementsNotFound.isEmpty()) {446 String unmatched = format("The following expected elements were not matched in the actual %s:%n %s",447 actual.getClass().getSimpleName(), expectedElementsNotFound);448 comparisonState.addDifference(dualValue, unmatched);449 // TODO could improve the error by listing the actual elements not in expected but that would need450 // another double loop inverting actual and expected to find the actual elements not matched in expected451 }452 }453 // TODO replace by ordered map454 private static <K, V> void compareSortedMap(DualValue dualValue, ComparisonState comparisonState) {455 if (!dualValue.isActualFieldASortedMap()) {456 // at the moment we only compare iterable with iterables (but we might allow arrays too)457 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "a sorted map"));458 return;459 }460 Map<?, ?> actualMap = (Map<?, ?>) dualValue.actual;461 @SuppressWarnings("unchecked")462 Map<K, V> expectedMap = (Map<K, V>) dualValue.expected;463 if (actualMap.size() != expectedMap.size()) {464 comparisonState.addDifference(dualValue, format(DIFFERENT_SIZE_ERROR, "sorted maps", actualMap.size(), expectedMap.size()));465 // no need to inspect entries, maps are not equal as they don't have the same size466 return;467 }468 Iterator<Map.Entry<K, V>> expectedMapEntries = expectedMap.entrySet().iterator();469 for (Map.Entry<?, ?> actualEntry : actualMap.entrySet()) {470 Map.Entry<?, ?> expectedEntry = expectedMapEntries.next();471 // check keys are matched before comparing values as keys represents a field472 if (!java.util.Objects.equals(actualEntry.getKey(), expectedEntry.getKey())) {473 // report a missing key/field.474 comparisonState.addKeyDifference(dualValue, actualEntry.getKey(), expectedEntry.getKey());475 } else {476 // as the key/field match we can simply compare field/key values477 FieldLocation keyFieldLocation = keyFieldLocation(dualValue.fieldLocation, actualEntry.getKey());478 comparisonState.registerForComparison(new DualValue(keyFieldLocation, actualEntry.getValue(), expectedEntry.getValue()));479 }480 }481 }482 private static void compareUnorderedMap(DualValue dualValue, ComparisonState comparisonState) {483 if (!dualValue.isActualFieldAMap()) {484 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "a map"));485 return;486 }487 Map<?, ?> actualMap = (Map<?, ?>) dualValue.actual;488 Map<?, ?> expectedMap = (Map<?, ?>) dualValue.expected;489 if (actualMap.size() != expectedMap.size()) {490 comparisonState.addDifference(dualValue, format(DIFFERENT_SIZE_ERROR, "maps", actualMap.size(), expectedMap.size()));491 // no need to inspect entries, maps are not equal as they don't have the same size492 return;493 }494 // actual and expected maps same size but do they have the same keys?495 Set<?> expectedKeysNotFound = new LinkedHashSet<>(expectedMap.keySet());496 expectedKeysNotFound.removeAll(actualMap.keySet());497 if (!expectedKeysNotFound.isEmpty()) {498 comparisonState.addDifference(dualValue, format("The following keys were not found in the actual map value:%n %s",499 expectedKeysNotFound));500 return;501 }502 // actual and expected maps have the same keys, we need now to compare their values503 for (Object key : expectedMap.keySet()) {504 FieldLocation keyFieldLocation = keyFieldLocation(dualValue.fieldLocation, key);505 comparisonState.registerForComparison(new DualValue(keyFieldLocation, actualMap.get(key), expectedMap.get(key)));506 }507 }508 private static FieldLocation keyFieldLocation(FieldLocation parentFieldLocation, Object key) {509 return key == null ? parentFieldLocation : parentFieldLocation.field(key.toString());510 }511 private static void compareOptional(DualValue dualValue, ComparisonState comparisonState) {512 if (!dualValue.isActualFieldAnOptional()) {513 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an Optional"));514 return;515 }516 Optional<?> actual = (Optional<?>) dualValue.actual;517 Optional<?> expected = (Optional<?>) dualValue.expected;518 if (actual.isPresent() != expected.isPresent()) {519 comparisonState.addDifference(dualValue);520 return;521 }522 // either both are empty or present523 if (!actual.isPresent()) return; // both optional are empty => end of the comparison524 // both are present, we have to compare their values recursively525 Object value1 = actual.get();526 Object value2 = expected.get();527 // we add VALUE_FIELD_NAME to the path since we register Optional.value fields.528 comparisonState.registerForComparison(new DualValue(dualValue.fieldLocation.field(VALUE_FIELD_NAME), value1, value2));529 }530 private static void compareAtomicBoolean(DualValue dualValue, ComparisonState comparisonState) {531 if (!dualValue.isActualFieldAnAtomicBoolean()) {532 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicBoolean"));533 return;534 }535 AtomicBoolean actual = (AtomicBoolean) dualValue.actual;536 AtomicBoolean expected = (AtomicBoolean) dualValue.expected;537 Object value1 = actual.get();538 Object value2 = expected.get();539 // we add VALUE_FIELD_NAME to the path since we register AtomicBoolean.value fields.540 comparisonState.registerForComparison(new DualValue(dualValue.fieldLocation.field(VALUE_FIELD_NAME), value1, value2));541 }542 private static void compareAtomicInteger(DualValue dualValue, ComparisonState comparisonState) {543 if (!dualValue.isActualFieldAnAtomicInteger()) {544 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicInteger"));545 return;546 }547 AtomicInteger actual = (AtomicInteger) dualValue.actual;548 AtomicInteger expected = (AtomicInteger) dualValue.expected;549 Object value1 = actual.get();550 Object value2 = expected.get();551 // we add VALUE_FIELD_NAME to the path since we register AtomicInteger.value fields.552 comparisonState.registerForComparison(new DualValue(dualValue.fieldLocation.field(VALUE_FIELD_NAME), value1, value2));553 }554 private static void compareAtomicIntegerArray(DualValue dualValue, ComparisonState comparisonState) {555 if (!dualValue.isActualFieldAnAtomicIntegerArray()) {556 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicIntegerArray"));557 return;558 }559 AtomicIntegerArray actual = (AtomicIntegerArray) dualValue.actual;560 AtomicIntegerArray expected = (AtomicIntegerArray) dualValue.expected;561 // both values in dualValue are arrays562 int actualArrayLength = actual.length();563 int expectedArrayLength = expected.length();564 if (actualArrayLength != expectedArrayLength) {565 comparisonState.addDifference(dualValue,566 format(DIFFERENT_SIZE_ERROR, "AtomicIntegerArrays", actualArrayLength, expectedArrayLength));567 // no need to inspect elements, arrays are not equal as they don't have the same size568 return;569 }570 // register each pair of actual/expected elements for recursive comparison571 FieldLocation arrayFieldLocation = dualValue.fieldLocation;572 for (int i = 0; i < actualArrayLength; i++) {573 Object actualElement = actual.get(i);574 Object expectedElement = expected.get(i);575 FieldLocation elementFieldLocation = arrayFieldLocation.field(format(ARRAY_FIELD_NAME + "[%d]", i));576 comparisonState.registerForComparison(new DualValue(elementFieldLocation, actualElement, expectedElement));577 }578 }579 private static void compareAtomicLong(DualValue dualValue, ComparisonState comparisonState) {580 if (!dualValue.isActualFieldAnAtomicLong()) {581 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicLong"));582 return;583 }584 AtomicLong actual = (AtomicLong) dualValue.actual;585 AtomicLong expected = (AtomicLong) dualValue.expected;586 Object value1 = actual.get();587 Object value2 = expected.get();588 // we add VALUE_FIELD_NAME to the path since we register AtomicLong.value fields.589 comparisonState.registerForComparison(new DualValue(dualValue.fieldLocation.field(VALUE_FIELD_NAME), value1, value2));590 }591 private static void compareAtomicLongArray(DualValue dualValue, ComparisonState comparisonState) {592 if (!dualValue.isActualFieldAnAtomicLongArray()) {593 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicLongArray"));594 return;595 }596 AtomicLongArray actual = (AtomicLongArray) dualValue.actual;597 AtomicLongArray expected = (AtomicLongArray) dualValue.expected;598 // both values in dualValue are arrays599 int actualArrayLength = actual.length();600 int expectedArrayLength = expected.length();601 if (actualArrayLength != expectedArrayLength) {602 comparisonState.addDifference(dualValue,603 format(DIFFERENT_SIZE_ERROR, "AtomicLongArrays", actualArrayLength, expectedArrayLength));604 // no need to inspect elements, arrays are not equal as they don't have the same size605 return;606 }607 // register each pair of actual/expected elements for recursive comparison608 FieldLocation arrayFieldLocation = dualValue.fieldLocation;609 for (int i = 0; i < actualArrayLength; i++) {610 Object actualElement = actual.get(i);611 Object expectedElement = expected.get(i);612 FieldLocation elementFieldLocation = arrayFieldLocation.field(format(ARRAY_FIELD_NAME + "[%d]", i));613 comparisonState.registerForComparison(new DualValue(elementFieldLocation, actualElement, expectedElement));614 }615 }616 private static void compareAtomicReferenceArray(DualValue dualValue, ComparisonState comparisonState) {617 if (!dualValue.isActualFieldAnAtomicReferenceArray()) {618 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicReferenceArray"));619 return;620 }621 AtomicReferenceArray<?> actual = (AtomicReferenceArray<?>) dualValue.actual;622 AtomicReferenceArray<?> expected = (AtomicReferenceArray<?>) dualValue.expected;623 // both values in dualValue are arrays624 int actualArrayLength = actual.length();625 int expectedArrayLength = expected.length();626 if (actualArrayLength != expectedArrayLength) {627 comparisonState.addDifference(dualValue,628 format(DIFFERENT_SIZE_ERROR, "AtomicReferenceArrays", actualArrayLength,629 expectedArrayLength));630 // no need to inspect elements, arrays are not equal as they don't have the same size631 return;632 }633 // register each pair of actual/expected elements for recursive comparison634 FieldLocation arrayFieldLocation = dualValue.fieldLocation;635 for (int i = 0; i < actualArrayLength; i++) {636 Object actualElement = actual.get(i);637 Object expectedElement = expected.get(i);638 FieldLocation elementFieldLocation = arrayFieldLocation.field(format(ARRAY_FIELD_NAME + "[%d]", i));639 comparisonState.registerForComparison(new DualValue(elementFieldLocation, actualElement, expectedElement));640 }641 }642 private static void compareAtomicReference(DualValue dualValue, ComparisonState comparisonState) {643 if (!dualValue.isActualFieldAnAtomicReference()) {644 comparisonState.addDifference(dualValue, differentTypeErrorMessage(dualValue, "an AtomicReference"));645 return;646 }647 AtomicReference<?> actual = (AtomicReference<?>) dualValue.actual;648 AtomicReference<?> expected = (AtomicReference<?>) dualValue.expected;649 Object value1 = actual.get();650 Object value2 = expected.get();651 // we add VALUE_FIELD_NAME to the path since we register AtomicReference.value fields.652 comparisonState.registerForComparison(new DualValue(dualValue.fieldLocation.field(VALUE_FIELD_NAME), value1, value2));653 }654 /**655 * Determine if the passed in class has a non-Object.equals() method. This656 * method caches its results in static ConcurrentHashMap to benefit657 * execution performance.658 *659 * @param c Class to check.660 * @return true, if the passed in Class has a .equals() method somewhere661 * between itself and just below Object in it's inheritance.662 */663 static boolean hasOverriddenEquals(Class<?> c) {664 if (customEquals.containsKey(c)) {665 return customEquals.get(c);666 }667 Class<?> origClass = c;668 while (!Object.class.equals(c)) {669 try {670 c.getDeclaredMethod("equals", Object.class);671 customEquals.put(origClass, true);672 return true;673 } catch (Exception ignored) {}674 c = c.getSuperclass();675 }676 customEquals.put(origClass, false);677 return false;678 }679 @SuppressWarnings({ "rawtypes", "unchecked" })680 private static boolean areDualValueEqual(DualValue dualValue,681 RecursiveComparisonConfiguration recursiveComparisonConfiguration) {682 final String fieldName = dualValue.getConcatenatedPath();683 final Object actualFieldValue = dualValue.actual;684 final Object expectedFieldValue = dualValue.expected;685 // check field comparators as they take precedence over type comparators686 Comparator fieldComparator = recursiveComparisonConfiguration.getComparatorForField(fieldName);687 if (fieldComparator != null) return areEqualUsingComparator(actualFieldValue, expectedFieldValue, fieldComparator);688 // check if a type comparators exist for the field type689 Class fieldType = actualFieldValue != null ? actualFieldValue.getClass() : expectedFieldValue.getClass();690 Comparator typeComparator = recursiveComparisonConfiguration.getComparatorForType(fieldType);691 if (typeComparator != null) return areEqualUsingComparator(actualFieldValue, expectedFieldValue, typeComparator);692 // default comparison using equals693 return deepEquals(actualFieldValue, expectedFieldValue);694 }...
areDualValueEqual
Using AI Code Generation
1package com.baeldung;2import static org.assertj.core.api.Assertions.assertThat;3import java.util.Arrays;4import java.util.List;5import org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator;6import org.junit.Test;7public class AssertJRecursionComparisonUnitTest {8 public void givenTwoListsWithDifferentOrder_whenAssertingEquality_thenFails() {9 List<String> list1 = Arrays.asList("A", "B", "C");10 List<String> list2 = Arrays.asList("A", "C", "B");11 assertThat(list1).usingRecursiveComparison().isEqualTo(list2);12 }13 public void givenTwoListsWithDifferentOrder_whenAssertingEqualityWithCustomComparator_thenPasses() {14 List<String> list1 = Arrays.asList("A", "B", "C");15 List<String> list2 = Arrays.asList("A", "C", "B");16 assertThat(list1).usingRecursiveComparison().usingComparatorForType(new ListComparator(), List.class)17 .isEqualTo(list2);18 }19 public void givenTwoListsWithDifferentOrder_whenAssertingEqualityWithCustomComparatorUsingAssertJMethod_thenPasses() {20 List<String> list1 = Arrays.asList("A", "B", "C");21 List<String> list2 = Arrays.asList("A", "C", "B");22 assertThat(areDualValueEqual(list1, list2)).isTrue();23 }24 private boolean areDualValueEqual(Object actual, Object other) {25 RecursiveComparisonDifferenceCalculator calculator = new RecursiveComparisonDifferenceCalculator();26 return calculator.calculateDifferences(actual, other)27 .isEmpty();28 }29}30package com.baeldung;31import java.util.List;32import org.assertj.core.api.recursive.comparison.DualValue;33public class ListComparator {34 public boolean compare(DualValue<List<String>> dualValue) {35 List<String> actual = dualValue.getActual();36 List<String> other = dualValue.getOther();37 return actual.containsAll(other) && other.containsAll(actual);38 }39}
areDualValueEqual
Using AI Code Generation
1import org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator;2import org.assertj.core.api.recursive.comparison.RecursiveComparisonDifference;3class Test {4 public static void main(String[] args) {5 RecursiveComparisonDifferenceCalculator calculator = new RecursiveComparisonDifferenceCalculator();6 RecursiveComparisonDifference difference = calculator.calculateDifferences("Hello", "Hello");7 System.out.println(difference);8 }9}10System.out.println(difference.getValue());11System.out.println(difference.getValue());12public class Test { public static void main(String[] args) { RecursiveComparisonDifferenceCalculator calculator = new RecursiveComparisonDifferenceCalculator(); RecursiveComparisonDifference difference = calculator.calculateDifferences("Hello", "Hello"); System.out.println(difference.getValue()); } }
areDualValueEqual
Using AI Code Generation
1import org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator;2import org.assertj.core.api.recursive.comparison.DualValue;3import org.assertj.core.api.recursive.comparison.DualValue.DualValueDifference;4import org.assertj.core.api.recursive.comparison.DualValue.DualValueDifference.DualValueDifferenceType;5public class AssertJExample {6 public static void main(String[] args) {7 DualValueDifference dualValueDifference = new DualValueDifference(new DualValue("a", "b"), DualValueDifferenceType.NOT_EQUAL);8 System.out.println(RecursiveComparisonDifferenceCalculator.areDualValueEqual(dualValueDifference));9 }10}
areDualValueEqual
Using AI Code Generation
1List<DualValue> dualValueList = new ArrayList<>();2DualValue dualValue1 = new DualValue("1", "1");3DualValue dualValue2 = new DualValue("2", "2");4DualValue dualValue3 = new DualValue("3", "3");5DualValue dualValue4 = new DualValue("4", "4");6DualValue dualValue5 = new DualValue("5", "5");7DualValue dualValue6 = new DualValue("6", "6");8DualValue dualValue7 = new DualValue("7", "7");9DualValue dualValue8 = new DualValue("8", "8");10DualValue dualValue9 = new DualValue("9", "9");11DualValue dualValue10 = new DualValue("10", "10");12DualValue dualValue11 = new DualValue("11", "11");13DualValue dualValue12 = new DualValue("12", "12");14DualValue dualValue13 = new DualValue("13", "13");15DualValue dualValue14 = new DualValue("14", "14");16DualValue dualValue15 = new DualValue("15", "15");17DualValue dualValue16 = new DualValue("16", "16");18DualValue dualValue17 = new DualValue("17", "17");19DualValue dualValue18 = new DualValue("18", "18");20DualValue dualValue19 = new DualValue("19", "19");21DualValue dualValue20 = new DualValue("20", "20");22DualValue dualValue21 = new DualValue("21", "21");23DualValue dualValue22 = new DualValue("22", "22");24DualValue dualValue23 = new DualValue("23", "23");25DualValue dualValue24 = new DualValue("24", "24");26DualValue dualValue25 = new DualValue("25", "25");27DualValue dualValue26 = new DualValue("26", "26");28DualValue dualValue27 = new DualValue("27", "27");29DualValue dualValue28 = new DualValue("28", "28");30DualValue dualValue29 = new DualValue("29", "29");31DualValue dualValue30 = new DualValue("30", "30");32DualValue dualValue31 = new DualValue("31", "31");33DualValue dualValue32 = new DualValue("32", "
areDualValueEqual
Using AI Code Generation
1RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();2boolean result = areDualValueEqual.areDualValueEqual(100,100);3System.out.println("Result = " + result);4RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();5boolean result = areDualValueEqual.areDualValueEqual(100,200);6System.out.println("Result = " + result);7RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();8boolean result = areDualValueEqual.areDualValueEqual("100","100");9System.out.println("Result = " + result);10RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();11boolean result = areDualValueEqual.areDualValueEqual("100","200");12System.out.println("Result = " + result);13RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();14boolean result = areDualValueEqual.areDualValueEqual("100",100);15System.out.println("Result = " + result);16RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();17boolean result = areDualValueEqual.areDualValueEqual("100",null);18System.out.println("Result = " + result);19RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();20boolean result = areDualValueEqual.areDualValueEqual(null,null);21System.out.println("Result = " + result);22RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();23boolean result = areDualValueEqual.areDualValueEqual(null,100);24System.out.println("Result = " + result);25RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();26boolean result = areDualValueEqual.areDualValueEqual(100,null);27System.out.println("Result = " + result);28RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();29boolean result = areDualValueEqual.areDualValueEqual(null,"100");30System.out.println("Result = " + result);31RecursiveComparisonDifferenceCalculator areDualValueEqual = new RecursiveComparisonDifferenceCalculator();32boolean result = areDualValueEqual.areDualValueEqual(null,"100");
areDualValueEqual
Using AI Code Generation
1public class AssertJTest {2 public void test() {3 String expected = "John";4 String actual = "John";5 boolean result = areDualValueEqual(expected, actual);6 assertThat(result).isTrue();7 }8 private boolean areDualValueEqual(Object expected, Object actual) {9 RecursiveComparisonDifferenceCalculator recursiveComparisonDifferenceCalculator = new RecursiveComparisonDifferenceCalculator();10 List<DualValueDifference> dualValueDifferences = recursiveComparisonDifferenceCalculator.calculateDifferences(expected, actual);11 return dualValueDifferences.isEmpty();12 }13}14public void test() {15 String expected = "John";16 String actual = "John1";17 boolean result = areDualValueEqual(expected, actual);18 assertThat(result).isTrue();19}
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!!