package gov.sandia.cognition.testutil;
import gov.sandia.cognition.math.matrix.Vector;
import java.util.Collection;
import static org.junit.Assert.*;
/**
* Class contains helper methods for tests
*/
public class AssertUtil
{
/**
* Returns the position of the most significant digit of d.
*
* @param d The number to test for position of most significant digit
* @return the position of the most significant digit
*/
public static long mostSignificantDigitPosition(double d)
{
double nDigits = Math.log10(Math.abs(d));
if ((nDigits == (int) nDigits) && (nDigits >= 0))
{
nDigits += 1;
}
return (d == 0) ? 0 : (nDigits > 0) ? (long) Math.ceil(nDigits)
: (long) Math.floor(nDigits);
}
/**
* Rounds the input double to n significant digits. This code started from
* an example on
* http://stackoverflow.com/questions/202302/rounding-to-an-arbitrary-number-of-significant-digits
*
* @param d The number to round
* @param n The number of digits to round to
* @return d rounded to n digits
*/
public static double roundToNumDigits(double d,
int n)
{
if (d == 0)
{
return 0;
}
final long numDs = mostSignificantDigitPosition(d);
final long power = n - ((numDs > 0) ? numDs : (numDs + 1));
final double mag = Math.pow(10, power);
final long shifted = Math.round(d * mag);
return shifted / mag;
}
/**
* Tests that d1 and d2 are the same number to numDigits significant digits.
* This is different from junit's assertEquals that includes the precision
* required in that this requires a certain number of digits be the same
* instead of specifying the exact precision required (1 digit of precision
* between 12,000 and 11,000 is different from equal to the 1's position).
*
* @param d1 The first number to test
* @param d2 The second number to test
* @param numDigits The number of significant digits that d1 and d2 must be
* equal for the assert to pass
*/
public static void equalToNumDigits(double d1,
double d2,
int numDigits)
{
assertEquals(roundToNumDigits(d1, numDigits), roundToNumDigits(d2,
numDigits), 1e-15);
}
/**
* Tests that d1 and d2 are the same number to numDigits significant digits.
* This is different from junit's assertEquals that includes the precision
* required in that this requires a certain number of digits be the same
* instead of specifying the exact precision required (1 digit of precision
* between 12,000 and 11,000 is different from equal to the 1's position).
*
* @param errString The string to print on an error
* @param d1 The first number to test
* @param d2 The second number to test
* @param numDigits The number of significant digits that d1 and d2 must be
* equal for the assert to pass
*/
public static void equalToNumDigits(String errString,
double d1,
double d2,
int numDigits)
{
assertEquals(errString, roundToNumDigits(d1, numDigits),
roundToNumDigits(d2, numDigits), 1e-15);
}
/**
* Checks that all elements in c1 are in c2 and all elements in c2 are in
* c1. Optionally tests that they are the same size. NOTE: If these are
* lists with repeated elements, there is no guarantee that they have the
* same number of each element. There are no order checks.
*
* @param c1 First collection
* @param c2 Second collection
* @param sameSize If true, tests that the two inputs are the same size
*/
public static <Type> void equalContents(Collection<Type> c1,
Collection<Type> c2,
boolean sameSize)
{
if (sameSize)
{
assertEquals(c1.size(), c2.size());
}
for (Type t : c1)
{
assertTrue(c2.contains(t));
}
for (Type t : c2)
{
assertTrue(c1.contains(t));
}
}
}