diff options
Diffstat (limited to 'luni/src/test/java/libcore')
3 files changed, 259 insertions, 0 deletions
diff --git a/luni/src/test/java/libcore/java/math/CSVTest.java b/luni/src/test/java/libcore/java/math/CSVTest.java new file mode 100644 index 0000000..9e151c3 --- /dev/null +++ b/luni/src/test/java/libcore/java/math/CSVTest.java @@ -0,0 +1,88 @@ +package libcore.java.math; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Standard single-input test framework for csv math tests + */ +public abstract class CSVTest extends junit.framework.TestCase { + /* + * csv file should have the following format: + * function,expected_output,input,extra_info + * e.g. cos,-0x1.0000000000000p+0,0x1.921fb54442d18p+1,cos(pi) + * for two input: function,expected_output,input1,input2,extra + * vogar classpath: obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar + */ + + /** + * This is a set of functions in java.Math/StrictMath that take two inputs. + * These functions will call run2InputTest; others will call runTest. + */ + protected static final Set<String> twoInputFunctions; + static { + Set<String> twoInFunc = new HashSet<String>(); + twoInFunc.add("atan2"); + twoInFunc.add("copySign"); + twoInFunc.add("hypot"); + twoInFunc.add("IEEEremainder"); + twoInFunc.add("max"); + twoInFunc.add("min"); + twoInFunc.add("nextAfter"); + twoInFunc.add("pow"); + twoInFunc.add("scalb"); + twoInputFunctions = Collections.unmodifiableSet(twoInFunc); + } + + void TestCSVInputs(String[] csvFileNames) throws Exception { + int totalTests = 0; + for (String csvFileName : csvFileNames) { + String line = ""; + BufferedReader br = null; + + try { + br = new BufferedReader(new InputStreamReader( + getClass().getResourceAsStream(csvFileName))); + while ((line = br.readLine()) != null) { + if (line.charAt(0) != '#') { + String[] testCase = line.split(","); + runTest(testCase); + totalTests++; + } + } + } finally { + if (br != null) { + br.close(); + } + } + } + System.out.println("Completed running " + totalTests + " tests"); + } + + protected void runTest(String[] testCase) throws Exception { + String function = testCase[0]; + double expectedOutput = Double.parseDouble(testCase[1]); + double input = Double.parseDouble(testCase[2]); + String extra = ""; + if (twoInputFunctions.contains(function)) { + double input2 = Double.parseDouble(testCase[3]); + if (testCase.length > 4) { + extra = testCase[4]; + } + run2InputTest(function, expectedOutput, input, input2, extra); + } else { + if (testCase.length > 3) { + extra = testCase[3]; + } + runTest(function, expectedOutput, input, extra); + } + } + + abstract void runTest(String func, double expectedOutput, double input, + String extra) throws Exception; + + abstract void run2InputTest(String func, double expectedOutput, double input1, double input2, String extra) throws Exception; +}
\ No newline at end of file diff --git a/luni/src/test/java/libcore/java/math/RunCSVTests.java b/luni/src/test/java/libcore/java/math/RunCSVTests.java new file mode 100644 index 0000000..0c107f1 --- /dev/null +++ b/luni/src/test/java/libcore/java/math/RunCSVTests.java @@ -0,0 +1,109 @@ +package libcore.java.math; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Tests functions in java.lang.Math + * Looks for the filenames in csvFileNames in tests/resources + * Tests functions and numbers found in those files. + * Run: vogar --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar + * libcore/luni/src/test/java/libcore/java/math/RunCSVTests.java + */ +public class RunCSVTests extends CSVTest { + /** Stores ulps of error allowed for each function, if not 1 ulp.*/ + private static final Map<String, Double> UlpMap; + static { + final HashMap<String, Double> funcUlps = new HashMap<String, Double>(); + funcUlps.put("sinh", 2.5); + funcUlps.put("cosh", 2.5); + funcUlps.put("tanh", 2.5); + funcUlps.put("abs", 0.0); + funcUlps.put("signum", 0.0); + funcUlps.put("getExponent", 0.0); + funcUlps.put("toRadians", 0.0); + funcUlps.put("toDegrees", 0.0); + funcUlps.put("sqrt", 0.0); + funcUlps.put("ceil", 0.0); + funcUlps.put("floor", 0.0); + funcUlps.put("rint", 0.0); + funcUlps.put("atan2", 2.0); + funcUlps.put("round", 0.0); + funcUlps.put("max", 0.0); + funcUlps.put("min", 0.0); + funcUlps.put("copySign", 0.0); + funcUlps.put("nextAfter", 0.0); + funcUlps.put("scalb", 0.0); + UlpMap = Collections.unmodifiableMap(funcUlps); + } + + public static final String[] csvFileNames = { "/math_tests.csv", + "/math_important_numbers.csv", "/math_java_only.csv" }; + + public void test_csv() throws Exception { + this.TestCSVInputs(csvFileNames); + } + + /** + * Runs a standard single-input test using assertEquals. + * Allows error based on UlpMap, but defaults to 1 ulp. + */ + @Override + void runTest(String func, double expectedOutput, double input, String extra) + throws Exception { + Class<Math> mathClass = Math.class; + Method m = mathClass.getMethod(func, new Class[] { Double.TYPE }); + Object returnValue = m.invoke(null, input); + + double allowedError; + if (UlpMap.containsKey(func)) { + allowedError = UlpMap.get(func)*Math.ulp(expectedOutput); + } else { + allowedError = Math.ulp(expectedOutput); + } + + try { + assertEquals(extra + ": " + m + ": " + input + ": ", expectedOutput, + (double) returnValue, allowedError); + } catch (ClassCastException e) { + assertEquals(extra + ": " + m + ": " + input + ": ", (int) expectedOutput, + (int) returnValue, allowedError); + } + } + + /** + * Runs a 2-input test using assertEquals. + * Allows error based on UlpMap, but defaults to 1 ulp. + */ + @Override + void run2InputTest(String func, double expectedOutput, double input1, + double input2, String extra) throws Exception { + Class<Math> mathClass = Math.class; + Method m; + Object returnValue; + if (func.equals("scalb")) { + m = mathClass.getMethod(func, new Class[] { Double.TYPE, Integer.TYPE }); + returnValue = m.invoke(null, input1, (int) input2); + } else { + m = mathClass.getMethod(func, new Class[] { Double.TYPE, Double.TYPE }); + returnValue = m.invoke(null, input1, input2); + } + + double allowedError; + if (UlpMap.containsKey(func)) { + allowedError = UlpMap.get(func)*Math.ulp(expectedOutput); + } else { + allowedError = Math.ulp(expectedOutput); + } + + try { + assertEquals(extra + ": " + m + ": ", expectedOutput, (double) returnValue, + allowedError); + } catch (ClassCastException e) { + assertEquals(extra + ": " + m + ": ", (int) expectedOutput, (int) returnValue, + allowedError); + } + } +} diff --git a/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java b/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java new file mode 100644 index 0000000..0443eb0 --- /dev/null +++ b/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java @@ -0,0 +1,62 @@ +package libcore.java.math; + +import java.lang.reflect.Method; + +/** + * Tests java.lang.StrictMath + * Looks for the filenames in csvFileNames in tests/resources + * Tests functions and numbers found in those files. + * Run: vogar --classpath out/target/common/obj/JAVA_LIBRARIES/core-tests-support_intermediates/javalib.jar + * libcore/luni/src/test/java/libcore/java/math/RunCSVTestsStrict.java + */ +public class RunCSVTestsStrict extends CSVTest { + public static final String[] csvFileNames = { "/math_tests.csv", + "/math_important_numbers.csv", "/math_java_only.csv" }; + + public void test_csv() throws Exception { + this.TestCSVInputs(csvFileNames); + } + + /** + * Runs single-input test using assertEquals. + */ + @Override + void runTest(String func, double expectedOutput, double input, String extra) + throws Exception { + Class<StrictMath> mathClass = StrictMath.class; + Method m = mathClass.getMethod(func, new Class[] { Double.TYPE }); + Object returnValue = m.invoke(null, input); + + try { + assertEquals(extra + ": " + m + ": " + input + ": ", expectedOutput, + (double) returnValue, 0D); + } catch (ClassCastException e) { + assertEquals(extra + ": " + m + ": " + input + ": ", (int) expectedOutput, + (int) returnValue, 0D); + } + } + + /** + * Runs 2-input test using assertEquals. + */ + @Override + void run2InputTest(String func, double expectedOutput, double input1, + double input2, String extra) throws Exception { + Class<StrictMath> mathClass = StrictMath.class; + Method m; + Object returnValue; + if (func.equals("scalb")) { + m = mathClass.getMethod(func, new Class[] { Double.TYPE, Integer.TYPE }); + returnValue = m.invoke(null, input1, (int) input2); + } else { + m = mathClass.getMethod(func, new Class[] { Double.TYPE, Double.TYPE }); + returnValue = m.invoke(null, input1, input2); + } + + try { + assertEquals(extra + ": " + m + ": " , expectedOutput, (double) returnValue, 0D); + } catch (ClassCastException e) { + assertEquals(extra + ": " + m + ": ", (int) expectedOutput, (int) returnValue, 0D); + } + } +} |