/*
* RHQ Management Platform
* Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.test;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class AssertUtils {
/**
* Verifies that all public, accessible properties of the two objects are equal. This method might be used when you
* want to compare two objects without using their <code>equals()</code> methods or when they do not implement <code>
* equals()</code>.
*
* @param expected The expected object to compare against. Should be non-null.
* @param actual The actual object to be compared. Should be non-null.
* @param msg An error message
* @param <T> The type of the objects to be compared
*/
public static <T> void assertPropertiesMatch(T expected, T actual, String msg) {
assertPropertiesMatch(msg, expected, actual, null, Collections.<String> emptyList());
}
/**
* @param msg An error message
* @param expected The expected object to compare against. Should be non-null.
* @param actual The actual object to be compared. Should be non-null.
* @param ignoredProperties A list of property names to exclude from comparison.
* @param <T> The type of the objects to be compared.
*/
public static <T> void assertPropertiesMatch(String msg, T expected, T actual, String... ignoredProperties) {
assertPropertiesMatch(msg, expected, actual, null, Arrays.asList(ignoredProperties));
}
/**
* @param msg An error message
* @param expected The expected object to compare against. Should be non-null.
* @param actual The actual object to be compared. Should be non-null.
* @param ignoredProperties A list of property names to exclude from comparison.
* @param maxDifference When matching doubles, the max roundoff difference still considered equal. If null Double.equals() is used.
* @param <T> The type of the objects to be compared.
*/
public static <T> void assertPropertiesMatch(String msg, T expected, T actual, Double maxDifference,
String... ignoredProperties) {
assertPropertiesMatch(msg, expected, actual, maxDifference, Arrays.asList(ignoredProperties));
}
/**
* Verifies that all public, accessible properties of the two objects are equal, excluding those specified in the
* <code>ignoredProperties</code> argument. This method might be used when you want to compare two objects without
* using their <code>equals()</code> methods or when they do not implement <code>equals</code>.
*
* @param msg An error message
* @param expected The expected object to compare against. Should be non-null.
* @param actual The actual object to be compared. Should be non-null.
* @param ignoredProperties A list of property names to exclude from comparison.
* @param <T> The type of the objects to be compared.
*/
public static <T> void assertPropertiesMatch(String msg, T expected, T actual, List<String> ignoredProperties) {
assertPropertiesMatch(msg, expected, actual, null, ignoredProperties);
}
/**
* Verifies that all public, accessible properties of the two objects are equal, excluding those specified in the
* <code>ignoredProperties</code> argument. This method might be used when you want to compare two objects without
* using their <code>equals()</code> methods or when they do not implement <code>equals</code>.
*
* @param msg An error message
* @param expected The expected object to compare against. Should be non-null.
* @param actual The actual object to be compared. Should be non-null.
* @param maxDifference When matching doubles, the max roundoff difference still considered equal. If null Double.equals() is used.
* @param ignoredProperties A list of property names to exclude from comparison.
* @param <T> The type of the objects to be compared.
*/
public static <T> void assertPropertiesMatch(String msg, T expected, T actual, Double maxDifference,
List<String> ignoredProperties) {
assertNotNull(expected, "Expected object should not be null");
assertNotNull(actual, "Actual object should not be null");
PropertyMatcher<T> matcher = new PropertyMatcher<T>();
matcher.setExpected(expected);
matcher.setActual(actual);
matcher.setMaxDifference(maxDifference);
matcher.setIgnoredProperties(ignoredProperties);
MatchResult result = matcher.execute();
assertTrue(result.isMatch(), msg + " -- " + result.getDetails());
}
/**
* Verifies that two collections are equal, according to the definition of <code>equals()</code> of the contained
* elements. Order is ignored as well as the runtime type of the collections.
*
* @param expected The expected collection to compare against
* @param actual The actual collection to compare against
* @param msg An error message
* @param <T> The type of the elements in the collections
*/
public static <T> void assertCollectionEqualsNoOrder(Collection<T> expected, Collection<T> actual, String msg) {
CollectionEqualsChecker<T> checker = new CollectionEqualsChecker<T>();
checker.setExpected(expected);
checker.setActual(actual);
EqualsResult result = checker.execute();
assertTrue(result.isEqual(), msg + " -- " + result.getDetails());
}
/**
* Verifies that the two collections contain the same number of matching elements as is
* done in {@link #assertPropertiesMatch(String, Object, Object, String...)}. If the
* collections differ in size, an assertion error will be thrown; otherwise, elements
* are compared, ignoring order. Note that all element properties are are compared in
* this method.
*
* @param expected The expected collection to compare against
* @param actual The actual collection under test
* @param msg An error message
* @param <T> The type of the elements in the collections
*/
public static <T> void assertCollectionMatchesNoOrder(Collection<T> expected, Collection<T> actual, String msg) {
CollectionMatchesChecker<T> checker = new CollectionMatchesChecker<T>();
checker.setExpected(expected);
checker.setActual(actual);
MatchResult result = checker.execute();
assertTrue(result.isMatch(), msg + " -- " + result.getDetails());
}
public static <T> void assertCollectionMatchesNoOrder(String msg, Collection<T> expected, Collection<T> actual,
String... ignoredProperties) {
CollectionMatchesChecker<T> checker = new CollectionMatchesChecker<T>();
checker.setExpected(expected);
checker.setActual(actual);
checker.setIgnoredProperties(ignoredProperties);
MatchResult result = checker.execute();
assertTrue(result.isMatch(), msg + " -- " + result.getDetails());
}
/**
* <p>
* Verifies that the two collections contain the same number of matching elements as is
* done in {@link #assertPropertiesMatch(String, Object, Object, String...)}. If the
* collections differ in size, an assertion error will be thrown; otherwise, elements
* are compared, ignoring order. Note that all element properties are are compared in
* this method.
* </p>
* <p>
* This version takes an additional argument that specifies a tolerance for comparing
* doubles. When the expected and actual property is a double the absolute difference
* between the values has to be within the tolerance.
* </p>
*
* @param msg An error message
* @param expected The expected collection to compare against
* @param actual The actual collection under test
* @param tolerance The absolute tolerance between the expected and actual value of
* properties that are of type double.
* @param ignoredProperties Properties to exclude from comparison
* @param <T> The type of elements in the collection
*/
public static <T> void assertCollectionMatchesNoOrder(String msg, Collection<T> expected, Collection<T> actual,
Double tolerance, String... ignoredProperties) {
CollectionMatchesChecker<T> checker = new CollectionMatchesChecker<T>();
checker.setExpected(expected);
checker.setActual(actual);
checker.setTolerance(tolerance);
checker.setIgnoredProperties(ignoredProperties);
MatchResult result = checker.execute();
assertTrue(result.isMatch(), msg + " -- " + result.getDetails());
}
/**
* Asserts a condition evaluates to true before a timeout is reached.
*
* @param booleanCondition the condition to evaluare
* @param message the message to show if this assertion fails
* @param maxWait the maximum amount of time to wait before the condition evaluates to true
* @param maxWaitUnit the time unit for <code>maxWait</code>
* @param step the amount of time to make the executing thread sleep between condition evaluations
* @param stepUnit the time unit for <code>step</code>
*
* @throws AssertionError if the conditions does not evaluate to true before the timeout is reached
* @throws InterruptedException if the current thread is interrupted while waiting
*/
public static void timedAssertion(BooleanCondition booleanCondition, String message, long maxWait,
TimeUnit maxWaitUnit, long step, TimeUnit stepUnit) throws InterruptedException {
assertNotNull(booleanCondition, "booleanCondition is null");
assertTrue(maxWait > 0, "maxWait must be positive");
assertNotNull(maxWaitUnit, "maxWaitUnit is null");
assertTrue(step > 0, "step must be positive");
assertNotNull(stepUnit, "stepUnit is null");
long start = System.currentTimeMillis();
long limit = start + maxWaitUnit.toMillis(maxWait);
for (;;) {
if (booleanCondition.eval()) {
return;
}
if (System.currentTimeMillis() >= limit) {
fail(message);
}
Thread.sleep(stepUnit.toMillis(step));
}
}
/**
* A condition which must evaluate to true or false.
*/
public interface BooleanCondition {
boolean eval();
}
}