From db32be75edfa2105a7dd1ca3fc9220d7676e28be Mon Sep 17 00:00:00 2001 From: Sebastian Bazley Date: Fri, 21 Jan 2011 19:57:06 +0000 Subject: [PATCH] Make Special test methods generic Add tests for two parameters Add checks for missing or extra methods git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_X@1061985 13f79535-47bb-0310-9956-ffa450edef68 --- .../commons/math/util/FastMathTest.java | 135 ++++++++++++------ 1 file changed, 93 insertions(+), 42 deletions(-) diff --git a/src/test/java/org/apache/commons/math/util/FastMathTest.java b/src/test/java/org/apache/commons/math/util/FastMathTest.java index 4c2258474..d92ac0728 100644 --- a/src/test/java/org/apache/commons/math/util/FastMathTest.java +++ b/src/test/java/org/apache/commons/math/util/FastMathTest.java @@ -16,9 +16,11 @@ */ package org.apache.commons.math.util; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.util.Arrays; import org.apache.commons.math.dfp.Dfp; import org.apache.commons.math.dfp.DfpField; @@ -36,7 +38,7 @@ public class FastMathTest { private static final int NUMBER_OF_TRIALS = 1000; // Values which often need special handling - private static final double [] DOUBLE_SPECIAL_VALUES = { + private static final Double[] DOUBLE_SPECIAL_VALUES = { -0.0, +0.0, // 1,2 Double.NaN, // 3 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, // 4,5 @@ -47,7 +49,7 @@ public class FastMathTest { -Double.MIN_VALUE, Double.MIN_VALUE, // 12,13 }; - private static final float [] FLOAT_SPECIAL_VALUES = { + private static final Float [] FLOAT_SPECIAL_VALUES = { -0.0f, +0.0f, // 1,2 Float.NaN, // 3 Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, // 4,5 @@ -975,7 +977,7 @@ public class FastMathTest { } private static void reportError(String message) { - final boolean fatal = true; + final boolean fatal = false; if (fatal) { Assert.fail(message); } else { @@ -983,59 +985,80 @@ public class FastMathTest { } } - private static abstract class SpecialComparer { - abstract void compareSpecials(Method mathMethod, Method fastMethod) throws Exception; - void check(Method mathMethod, float f, Object expected, Object actual, int entry){ - if (!expected.equals(actual)){ - reportError(mathMethod.getName()+"(float "+f+") expected "+expected+" actual "+actual+ " entry "+entry); - } - } - void check(Method mathMethod, double d, Object expected, Object actual, int entry){ - if (!expected.equals(actual)){ - reportError(mathMethod.getName()+"(double "+d+") expected "+expected+" actual "+actual+ " entry "+entry); - } - } + private static void check(Method mathMethod, Object[] params, Object expected, Object actual, int[] entries){ + if (!expected.equals(actual)){ + StringBuilder sb = new StringBuilder(); + sb.append(mathMethod.getName()); + sb.append("("); + String sep = ""; + for(Object o : params){ + sb.append(sep); + sb.append(o.getClass().getSimpleName().toLowerCase()); // Hack: assume only Float/Double are used + sb.append(" "); + sb.append(o); + sep=", "; + } + sb.append(") expected "); + sb.append(expected); + sb.append(" actual "); + sb.append(actual); + sb.append(" entries "); + sb.append(Arrays.toString(entries)); + reportError(sb.toString()); + } } - private static class CompareFloatSpecials extends SpecialComparer { - @Override - public void compareSpecials(Method mathMethod, Method fastMethod) throws Exception { - int entry = 0; - for(float f : FLOAT_SPECIAL_VALUES) { - entry++; - Object expected = mathMethod.invoke(mathMethod, new Object[]{f}); - Object actual = fastMethod.invoke(mathMethod, new Object[]{f}); - check(mathMethod, f, expected, actual, entry); + private static class CompareSpecials { + private final Object[] specialvalues; + CompareSpecials(Object[] values){ + specialvalues=values; + } + void compareSpecials(Method mathMethod, Method fastMethod, Type[] types) throws Exception { + Object[] params = new Object[types.length]; + int entry1 = 0; + int[] entries = new int[types.length]; + for(Object d : specialvalues) { + entry1++; + params[0] = d; + entries[0] = entry1; + if (params.length > 1){ + int entry2 = 0; + for(Object d1 : specialvalues) { + entry2++; + params[1] = d1; + entries[1] = entry2; + compare(mathMethod, fastMethod, params, entries); + } + } else { + compare(mathMethod, fastMethod, params, entries); + } } } - } - - private static class CompareDoubleSpecials extends SpecialComparer { - @Override - public void compareSpecials(Method mathMethod, Method fastMethod) throws Exception { - int entry = 0; - for(double d : DOUBLE_SPECIAL_VALUES) { - entry++; - Object expected = mathMethod.invoke(mathMethod, new Object[]{d}); - Object actual = fastMethod.invoke(mathMethod, new Object[]{d}); - check(mathMethod, d, expected, actual, entry); + private void compare(Method mathMethod, Method fastMethod, + Object[] params, int[] entries) throws IllegalAccessException, + InvocationTargetException { + try { + Object expected = mathMethod.invoke(mathMethod, params); + Object actual = fastMethod.invoke(mathMethod, params); + check(mathMethod, params, expected, actual, entries); + } catch (IllegalArgumentException e) { + Assert.fail(mathMethod+" "+e); } } } - private void testSpecialCases(Class type, SpecialComparer comparer) throws Exception { - Class param[] = new Class [] {type}; + private void testSpecialCases(Class type, CompareSpecials comparer) throws Exception { Method math[] = StrictMath.class.getDeclaredMethods(); for(Method mathMethod : math) { Type ret = mathMethod.getGenericReturnType(); if (ret.equals(type) && Modifier.isPublic(mathMethod.getModifiers())){ Type []params = mathMethod.getGenericParameterTypes(); - if (params.length ==1 && params[0].equals(type)) { + if (params.length >=1 && params[0].equals(type)) { Method fastMethod = null; String name = mathMethod.getName(); try { - fastMethod = FastMath.class.getDeclaredMethod(name, param); - comparer.compareSpecials(mathMethod, fastMethod); + fastMethod = FastMath.class.getDeclaredMethod(name, (Class[]) params); + comparer.compareSpecials(mathMethod, fastMethod, params); } catch (NoSuchMethodException e) { System.out.println("Cannot find FastMath method corresponding to: "+mathMethod); } @@ -1046,12 +1069,40 @@ public class FastMathTest { @Test public void testFloatSpecialCases() throws Exception { - testSpecialCases(float.class, new CompareFloatSpecials()); + testSpecialCases(float.class, new CompareSpecials(FLOAT_SPECIAL_VALUES)); } @Test public void testDoubleSpecialCases() throws Exception { - testSpecialCases(double.class, new CompareDoubleSpecials()); + testSpecialCases(double.class, new CompareSpecials(DOUBLE_SPECIAL_VALUES)); + } + + private boolean compareClassMethods(Class class1, Class class2){ + boolean allfound = true; + for(Method method1 : class1.getDeclaredMethods()){ + if (Modifier.isPublic(method1.getModifiers())){ + Type []params = method1.getGenericParameterTypes(); + try { + class2.getDeclaredMethod(method1.getName(), (Class[]) params); + } catch (NoSuchMethodException e) { + allfound = false; + System.out.println(class2.getSimpleName()+" does not implement: "+method1); + } + } + } + return allfound; + } + + @Test + public void checkMissingFastMathClasses() { + boolean ok = compareClassMethods(StrictMath.class, FastMath.class); + // TODO Assert.assertTrue("FastMath should implement all StrictMath methods", ok); + } + + @Ignore + @Test + public void checkExtraFastMathClasses() { + compareClassMethods( FastMath.class, StrictMath.class); } @Ignore