blob: cf6a7af5196bcec664cdbe58fd3b0c60eed492da [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.commons.math;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import org.apache.commons.math.complex.Complex;
import org.apache.commons.math.complex.ComplexFormat;
/**
* @version $Revision$ $Date$
*/
public class TestUtils {
/**
* Collection of static methods used in math unit tests.
*/
private TestUtils() {
super();
}
/**
* Verifies that expected and actual are within delta, or are both NaN or
* infinities of the same sign.
*/
public static void assertEquals(double expected, double actual, double delta) {
assertEquals(null, expected, actual, delta);
}
/**
* Verifies that expected and actual are within delta, or are both NaN or
* infinities of the same sign.
*/
public static void assertEquals(String msg, double expected, double actual, double delta) {
// check for NaN
if(Double.isNaN(expected)){
Assert.assertTrue("" + actual + " is not NaN.",
Double.isNaN(actual));
} else {
Assert.assertEquals(msg, expected, actual, delta);
}
}
/**
* Verifies that the two arguments are exactly the same, either
* both NaN or infinities of same sign, or identical floating point values.
*/
public static void assertSame(double expected, double actual) {
assertEquals(expected, actual, 0);
}
/**
* Verifies that real and imaginary parts of the two complex arguments
* are exactly the same. Also ensures that NaN / infinite components match.
*/
public static void assertSame(Complex expected, Complex actual) {
assertSame(expected.getReal(), actual.getReal());
assertSame(expected.getImaginary(), actual.getImaginary());
}
/**
* Verifies that real and imaginary parts of the two complex arguments
* differ by at most delta. Also ensures that NaN / infinite components match.
*/
public static void assertEquals(Complex expected, Complex actual, double delta) {
assertEquals(expected.getReal(), actual.getReal(), delta);
assertEquals(expected.getImaginary(), actual.getImaginary(), delta);
}
/**
* Verifies that two double arrays have equal entries, up to tolerance
*/
public static void assertEquals(double a[], double b[], double tolerance) {
Assert.assertEquals(a.length, b.length);
for (int i = 0; i < a.length; i++) {
Assert.assertEquals(a[i], b[i], tolerance);
}
}
/**
* Serializes an object to a bytes array and then recovers the object from the bytes array.
* Returns the deserialized object.
*
* @param o object to serialize and recover
* @return the recovered, deserialized object
*/
public static Object serializeAndRecover(Object o) {
try {
// serialize the Object
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bos);
so.writeObject(o);
// deserialize the Object
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream si = new ObjectInputStream(bis);
return si.readObject();
} catch (IOException ioe) {
return null;
} catch (ClassNotFoundException cnfe) {
return null;
}
}
/**
* Verifies that serialization preserves equals and hashCode.
* Serializes the object, then recovers it and checks equals and hash code.
*
* @param object the object to serialize and recover
*/
public static void checkSerializedEquality(Object object) {
Object object2 = serializeAndRecover(object);
Assert.assertEquals("Equals check", object, object2);
Assert.assertEquals("HashCode check", object.hashCode(), object2.hashCode());
}
/**
* Verifies that the relative error in actual vs. expected is less than or
* equal to relativeError. If expected is infinite or NaN, actual must be
* the same (NaN or infinity of the same sign).
*
* @param expected expected value
* @param actual observed value
* @param relativeError maximum allowable relative error
*/
public static void assertRelativelyEquals(double expected, double actual,
double relativeError) {
assertRelativelyEquals(null, expected, actual, relativeError);
}
/**
* Verifies that the relative error in actual vs. expected is less than or
* equal to relativeError. If expected is infinite or NaN, actual must be
* the same (NaN or infinity of the same sign).
*
* @param msg message to return with failure
* @param expected expected value
* @param actual observed value
* @param relativeError maximum allowable relative error
*/
public static void assertRelativelyEquals(String msg, double expected,
double actual, double relativeError) {
if (Double.isNaN(expected)) {
Assert.assertTrue(msg, Double.isNaN(actual));
} else if (Double.isNaN(actual)) {
Assert.assertTrue(msg, Double.isNaN(expected));
} else if (Double.isInfinite(actual) || Double.isInfinite(expected)) {
Assert.assertEquals(expected, actual, relativeError);
} else if (expected == 0.0) {
Assert.assertEquals(msg, actual, expected, relativeError);
} else {
double x = Math.abs((expected - actual) / expected);
Assert.assertEquals(msg, 0.0, x, relativeError);
}
}
/**
* Fails iff values does not contain a number within epsilon of z.
*
* @param msg message to return with failure
* @param values complex array to search
* @param z value sought
* @param epsilon tolerance
*/
public static void assertContains(String msg, Complex[] values,
Complex z, double epsilon) {
int i = 0;
boolean found = false;
while (!found && i < values.length) {
try {
assertEquals(values[i], z, epsilon);
found = true;
} catch (AssertionFailedError er) {
// no match
}
i++;
}
if (!found) {
Assert.fail(msg +
" Unable to find " + ComplexFormat.formatComplex(z));
}
}
/**
* Fails iff values does not contain a number within epsilon of z.
*
* @param values complex array to search
* @param z value sought
* @param epsilon tolerance
*/
public static void assertContains(Complex[] values,
Complex z, double epsilon) {
assertContains(null, values, z, epsilon);
}
/**
* Fails iff values does not contain a number within epsilon of x.
*
* @param msg message to return with failure
* @param values double array to search
* @param x value sought
* @param epsilon tolerance
*/
public static void assertContains(String msg, double[] values,
double x, double epsilon) {
int i = 0;
boolean found = false;
while (!found && i < values.length) {
try {
assertEquals(values[i], x, epsilon);
found = true;
} catch (AssertionFailedError er) {
// no match
}
i++;
}
if (!found) {
Assert.fail(msg + " Unable to find" + x);
}
}
/**
* Fails iff values does not contain a number within epsilon of x.
*
* @param values double array to search
* @param x value sought
* @param epsilon tolerance
*/
public static void assertContains(double[] values, double x,
double epsilon) {
assertContains(null, values, x, epsilon);
}
}