com.fitbur.assertj.internal.Objects Maven / Gradle / Ivy
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2016 the original author or authors.
*/
package com.fitbur.assertj.internal;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static com.fitbur.assertj.error.ShouldBeEqual.shouldBeEqual;
import static com.fitbur.assertj.error.ShouldBeEqualByComparingFieldByFieldRecursively.shouldBeEqualByComparingFieldByFieldRecursive;
import static com.fitbur.assertj.error.ShouldBeEqualByComparingOnlyGivenFields.shouldBeEqualComparingOnlyGivenFields;
import static com.fitbur.assertj.error.ShouldBeEqualToIgnoringFields.shouldBeEqualToIgnoringGivenFields;
import static com.fitbur.assertj.error.ShouldBeExactlyInstanceOf.shouldBeExactlyInstance;
import static com.fitbur.assertj.error.ShouldBeIn.shouldBeIn;
import static com.fitbur.assertj.error.ShouldBeInstance.shouldBeInstance;
import static com.fitbur.assertj.error.ShouldBeInstanceOfAny.shouldBeInstanceOfAny;
import static com.fitbur.assertj.error.ShouldBeOfClassIn.shouldBeOfClassIn;
import static com.fitbur.assertj.error.ShouldBeSame.shouldBeSame;
import static com.fitbur.assertj.error.ShouldHavePropertyOrField.shouldHavePropertyOrField;
import static com.fitbur.assertj.error.ShouldHavePropertyOrFieldWithValue.shouldHavePropertyOrFieldWithValue;
import static com.fitbur.assertj.error.ShouldHaveSameClass.shouldHaveSameClass;
import static com.fitbur.assertj.error.ShouldHaveToString.shouldHaveToString;
import static com.fitbur.assertj.error.ShouldNotBeEqual.shouldNotBeEqual;
import static com.fitbur.assertj.error.ShouldNotBeExactlyInstanceOf.shouldNotBeExactlyInstance;
import static com.fitbur.assertj.error.ShouldNotBeIn.shouldNotBeIn;
import static com.fitbur.assertj.error.ShouldNotBeInstance.shouldNotBeInstance;
import static com.fitbur.assertj.error.ShouldNotBeInstanceOfAny.shouldNotBeInstanceOfAny;
import static com.fitbur.assertj.error.ShouldNotBeNull.shouldNotBeNull;
import static com.fitbur.assertj.error.ShouldNotBeOfClassIn.shouldNotBeOfClassIn;
import static com.fitbur.assertj.error.ShouldNotBeSame.shouldNotBeSame;
import static com.fitbur.assertj.error.ShouldNotHaveSameClass.shouldNotHaveSameClass;
import static com.fitbur.assertj.internal.CommonValidations.checkTypeIsNotNull;
import static com.fitbur.assertj.internal.DeepDifference.determineDifferences;
import static com.fitbur.assertj.util.Lists.newArrayList;
import static com.fitbur.assertj.util.Preconditions.checkNotNull;
import static com.fitbur.assertj.util.Sets.newLinkedHashSet;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.fitbur.assertj.api.AssertionInfo;
import com.fitbur.assertj.internal.DeepDifference.Difference;
import com.fitbur.assertj.util.VisibleForTesting;
import com.fitbur.assertj.util.introspection.FieldSupport;
import com.fitbur.assertj.util.introspection.IntrospectionError;
import com.fitbur.assertj.util.introspection.PropertyOrFieldSupport;
import com.fitbur.assertj.util.introspection.PropertySupport;
/**
* Reusable assertions for {@code Object}s.
*
* @author Yvonne Wang
* @author Alex Ruiz
* @author Nicolas François
* @author Mikhail Mazursky
*/
public class Objects {
private static final Objects INSTANCE = new Objects();
@VisibleForTesting
final PropertySupport propertySupport = PropertySupport.instance();
private final ComparisonStrategy comparisonStrategy;
@VisibleForTesting
Failures failures = Failures.instance();
private final FieldSupport fieldSupport = FieldSupport.comparison();
/**
* Returns the singleton instance of this class based on {@link StandardComparisonStrategy}.
*
* @return the singleton instance of this class based on {@link StandardComparisonStrategy}.
*/
public static Objects instance() {
return INSTANCE;
}
@VisibleForTesting
Objects() {
this(StandardComparisonStrategy.instance());
}
public Objects(ComparisonStrategy comparisonStrategy) {
this.comparisonStrategy = comparisonStrategy;
}
@VisibleForTesting
public Comparator> getComparator() {
return comparisonStrategy instanceof ComparatorBasedComparisonStrategy
? ((ComparatorBasedComparisonStrategy) comparisonStrategy).getComparator() : null;
}
@VisibleForTesting
public ComparisonStrategy getComparisonStrategy() {
return comparisonStrategy;
}
/**
* Verifies that the given object is an instance of the given type.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param type the type to check the given object against.
* @throws NullPointerException if the given type is {@code null}.
* @throws AssertionError if the given object is {@code null}.
* @throws AssertionError if the given object is not an instance of the given type.
*/
public void assertIsInstanceOf(AssertionInfo info, Object actual, Class> type) {
if (!isInstanceOfClass(actual, type, info)) throw failures.failure(info, shouldBeInstance(actual, type));
}
/**
* Verifies that the given object is an instance of any of the given types.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param types the types to check the given object against.
* @throws NullPointerException if the given array is {@code null}.
* @throws IllegalArgumentException if the given array is empty.
* @throws NullPointerException if the given array has {@code null} elements.
* @throws AssertionError if the given object is {@code null}.
* @throws AssertionError if the given object is not an instance of any of the given types.
*/
public void assertIsInstanceOfAny(AssertionInfo info, Object actual, Class>[] types) {
if (objectIsInstanceOfOneOfGivenClasses(actual, types, info)) return;
throw failures.failure(info, shouldBeInstanceOfAny(actual, types));
}
private boolean objectIsInstanceOfOneOfGivenClasses(Object actual, Class>[] types, AssertionInfo info) {
checkIsNotNullAndIsNotEmpty(types);
assertNotNull(info, actual);
for (Class> type : types) {
String format = "The given array of types:<%s> should not have null elements";
checkNotNull(type, format(format, info.representation().toStringOf(types)));
if (type.isInstance(actual)) {
return true;
}
}
return false;
}
/**
* Verifies that the given object is not an instance of the given type.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param type the type to check the given object against.
* @throws NullPointerException if the given type is {@code null}.
* @throws AssertionError if the given object is {@code null}.
* @throws AssertionError if the given object is an instance of the given type.
*/
public void assertIsNotInstanceOf(AssertionInfo info, Object actual, Class> type) {
if (isInstanceOfClass(actual, type, info)) throw failures.failure(info, shouldNotBeInstance(actual, type));
}
private boolean isInstanceOfClass(Object actual, Class> clazz, AssertionInfo info) {
assertNotNull(info, actual);
checkTypeIsNotNull(clazz);
return clazz.isInstance(actual);
}
/**
* Verifies that the given object is not an instance of any of the given types.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param types the types to check the given object against.
* @throws NullPointerException if the given array is {@code null}.
* @throws IllegalArgumentException if the given array is empty.
* @throws NullPointerException if the given array has {@code null} elements.
* @throws AssertionError if the given object is {@code null}.
* @throws AssertionError if the given object is an instance of any of the given types.
*/
public void assertIsNotInstanceOfAny(AssertionInfo info, Object actual, Class>[] types) {
if (!objectIsInstanceOfOneOfGivenClasses(actual, types, info)) return;
throw failures.failure(info, shouldNotBeInstanceOfAny(actual, types));
}
/**
* Verifies that the actual value has the same class as the given object.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @throws AssertionError if the actual has not the same type has the given object.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given object is null.
*/
public void assertHasSameClassAs(AssertionInfo info, Object actual, Object other) {
if (!haveSameClass(actual, other, info)) throw failures.failure(info, shouldHaveSameClass(actual, other));
}
private boolean haveSameClass(Object actual, Object other, AssertionInfo info) {
assertNotNull(info, actual);
checkNotNull(other, "The given object should not be null");
Class> actualClass = actual.getClass();
Class> otherClass = other.getClass();
return actualClass.equals(otherClass);
}
/**
* Verifies that the actual value does not have the same class as the given object.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to check type against.
* @throws AssertionError if the actual has the same type has the given object.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given object is null.
*/
public void assertDoesNotHaveSameClassAs(AssertionInfo info, Object actual, Object other) {
if (haveSameClass(actual, other, info)) throw failures.failure(info, shouldNotHaveSameClass(actual, other));
}
/**
* Verifies that the actual value is exactly an instance of given type.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param type the type to check the actual value against.
* @throws AssertionError if the actual is not exactly an instance of given type.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given object is null.
*/
public void assertIsExactlyInstanceOf(AssertionInfo info, Object actual, Class> type) {
if (!actualIsExactlyInstanceOfType(actual, type, info))
throw failures.failure(info, shouldBeExactlyInstance(actual, type));
}
private boolean actualIsExactlyInstanceOfType(Object actual, Class> expectedType, AssertionInfo info) {
assertNotNull(info, actual);
checkTypeIsNotNull(expectedType);
return expectedType.equals(actual.getClass());
}
/**
* Verifies that the actual value is not exactly an instance of given type.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param type the type to check the actual value against.
* @throws AssertionError if the actual is exactly an instance of given type.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given object is null.
*/
public void assertIsNotExactlyInstanceOf(AssertionInfo info, Object actual, Class> type) {
if (actualIsExactlyInstanceOfType(actual, type, info))
throw failures.failure(info, shouldNotBeExactlyInstance(actual, type));
}
/**
* Verifies that the actual value type is in given types.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param types the types to check the actual value against.
* @throws AssertionError if the actual value type is in given type.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given types is null.
*/
public void assertIsOfAnyClassIn(AssertionInfo info, Object actual, Class>[] types) {
boolean itemInArray = isOfOneOfGivenTypes(actual, types, info);
if (!itemInArray) throw failures.failure(info, shouldBeOfClassIn(actual, types));
}
private boolean isOfOneOfGivenTypes(Object actual, Class>[] types, AssertionInfo info) {
assertNotNull(info, actual);
checkNotNull(types, "The given types should not be null");
return isItemInArray(actual.getClass(), types);
}
/**
* Verifies that the actual value type is not in given types.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param types the types to check the actual value against.
* @throws AssertionError if the actual value type is in given type.
* @throws NullPointerException if the actual value is null.
* @throws NullPointerException if the given types is null.
*/
public void assertIsNotOfAnyClassIn(AssertionInfo info, Object actual, Class>[] types) {
boolean itemInArray = isOfOneOfGivenTypes(actual, types, info);
if (itemInArray) throw failures.failure(info, shouldNotBeOfClassIn(actual, types));
}
private void checkIsNotNullAndIsNotEmpty(Class>[] types) {
checkNotNull(types, "The given array of types should not be null");
if (types.length == 0) {
throw new IllegalArgumentException("The given array of types should not be empty");
}
}
/**
* Asserts that two objects are equal.
*
* @param info contains information about the assertion.
* @param actual the "actual" object.
* @param expected the "expected" object.
* @throws AssertionError if {@code actual} is not equal to {@code expected}. This method will throw a
* {@code org.junit.ComparisonFailure} instead if JUnit is in the classpath and the given objects are not
* equal.
*/
public void assertEqual(AssertionInfo info, Object actual, Object expected) {
if (areEqual(actual, expected)) {
return;
}
throw failures.failure(info, shouldBeEqual(actual, expected, comparisonStrategy, info.representation()));
}
/**
* Asserts that two objects are not equal.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to compare {@code actual} to.
* @throws AssertionError if {@code actual} is equal to {@code other}.
*/
public void assertNotEqual(AssertionInfo info, Object actual, Object other) {
if (!areEqual(actual, other)) {
return;
}
throw failures.failure(info, shouldNotBeEqual(actual, other, comparisonStrategy));
}
/**
* Compares actual and other with standard strategy (null safe equals check).
*
* @param actual the object to compare to other
* @param other the object to compare to actual
* @return true if actual and other are equal (null safe equals check), false otherwise.
*/
private boolean areEqual(Object actual, Object other) {
return comparisonStrategy.areEqual(actual, other);
}
/**
* Asserts that the given object is {@code null}.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @throws AssertionError if the given object is not {@code null}.
*/
public void assertNull(AssertionInfo info, Object actual) {
if (actual == null) {
return;
}
throw failures.failure(info, shouldBeEqual(actual, null, comparisonStrategy, info.representation()));
}
/**
* Asserts that the given object is not {@code null}.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @throws AssertionError if the given object is {@code null}.
*/
public void assertNotNull(AssertionInfo info, Object actual) {
if (actual != null) {
return;
}
throw failures.failure(info, shouldNotBeNull());
}
/**
* Asserts that two objects refer to the same object.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param expected the expected object.
* @throws AssertionError if the given objects do not refer to the same object.
*/
public void assertSame(AssertionInfo info, Object actual, Object expected) {
if (actual == expected) {
return;
}
throw failures.failure(info, shouldBeSame(actual, expected));
}
/**
* Asserts that two objects do not refer to the same object.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to compare {@code actual} to.
* @throws AssertionError if the given objects refer to the same object.
*/
public void assertNotSame(AssertionInfo info, Object actual, Object other) {
if (actual != other) {
return;
}
throw failures.failure(info, shouldNotBeSame(actual));
}
public void assertHasToString(AssertionInfo info, Object actual, String expectedToString) {
assertNotNull(info, actual);
if (!actual.toString().equals(expectedToString))
throw failures.failure(info, shouldHaveToString(actual, expectedToString));
}
/**
* Asserts that the given object is present in the given array.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given array.
* @throws NullPointerException if the given array is {@code null}.
* @throws IllegalArgumentException if the given array is empty.
* @throws AssertionError if the given object is not present in the given array.
*/
public void assertIsIn(AssertionInfo info, Object actual, Object[] values) {
checkIsNotNullAndNotEmpty(values);
assertIsIn(info, actual, asList(values));
}
/**
* Asserts that the given object is not present in the given array.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given array.
* @throws NullPointerException if the given array is {@code null}.
* @throws IllegalArgumentException if the given array is empty.
* @throws AssertionError if the given object is present in the given array.
*/
public void assertIsNotIn(AssertionInfo info, Object actual, Object[] values) {
checkIsNotNullAndNotEmpty(values);
assertIsNotIn(info, actual, asList(values));
}
private void checkIsNotNullAndNotEmpty(Object[] values) {
checkNotNull(values, "The given array should not be null");
if (values.length == 0) {
throw new IllegalArgumentException("The given array should not be empty");
}
}
/**
* Returns true
if given item is in given array, false
otherwise.
*
* @param item the object to look for in arrayOfValues
* @param arrayOfValues the array of values
* @return true
if given item is in given array, false
otherwise.
*/
private boolean isItemInArray(Object item, Object[] arrayOfValues) {
for (Object value : arrayOfValues) {
if (areEqual(value, item)) return true;
}
return false;
}
/**
* Asserts that the given object is present in the given collection.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given iterable.
* @throws NullPointerException if the given collection is {@code null}.
* @throws IllegalArgumentException if the given collection is empty.
* @throws AssertionError if the given object is not present in the given collection.
*/
public void assertIsIn(AssertionInfo info, Object actual, Iterable> values) {
checkIsNotNullAndNotEmpty(values);
if (!isActualIn(actual, values)) throw failures.failure(info, shouldBeIn(actual, values, comparisonStrategy));
}
/**
* Asserts that the given object is not present in the given collection.
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given collection.
* @throws NullPointerException if the given iterable is {@code null}.
* @throws IllegalArgumentException if the given collection is empty.
* @throws AssertionError if the given object is present in the given collection.
*/
public void assertIsNotIn(AssertionInfo info, Object actual, Iterable> values) {
checkIsNotNullAndNotEmpty(values);
if (isActualIn(actual, values)) throw failures.failure(info, shouldNotBeIn(actual, values, comparisonStrategy));
}
private void checkIsNotNullAndNotEmpty(Iterable> values) {
checkNotNull(values, "The given iterable should not be null");
if (!values.iterator().hasNext()) {
throw new IllegalArgumentException("The given iterable should not be empty");
}
}
private boolean isActualIn(Object actual, Iterable> values) {
for (Object value : values) {
if (areEqual(value, actual)) {
return true;
}
}
return false;
}
/**
* Assert that the given object is lenient equals by ignoring null fields value on other object (including inherited
* fields).
*
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to compare {@code actual} to.
* @throws NullPointerException if the actual type is {@code null}.
* @throws NullPointerException if the other type is {@code null}.
* @throws AssertionError if the actual and the given object are not lenient equals.
* @throws AssertionError if the other object is not an instance of the actual type.
*/
public void assertIsEqualToIgnoringNullFields(AssertionInfo info, A actual, A other,
Map> comparatorByPropertyOrField,
Map, Comparator>> comparatorByType) {
assertNotNull(info, actual);
List fieldsNames = new LinkedList<>();
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy