/** Test Exprs. * See http://www.radford.edu/itec380/2009fall/Hw06/hw06.html * * Meant to cover most syntax situations for N0-N3. * HOWEVER, the testing approach has some systemic flaws -- * we never test against the expected internal representation. * (For example, testParseToString just checks that parse and * 'toString' are inverses of each other; if they are both * the identity function, it would pass all tests.) * * Compiling this function will generate a warning * ('unchecked generic array creation', due to using Arrays.asList * and varargs). * * @author Ian Barland * @version 2008.Dec.06 */ public class ExprTest extends junit.framework.TestCase { static final double TOLERANCE = 0.000001; java.util.List> allTests; /* allTests should be a list of pairs: * an L0 Expr, and what that expression evaluates to. * Use a Double, for Num values. */ /** * Sets up the test fixture. * * Called before every test case method. */ protected void setUp() { /* allTests should be a list of pairs: * an L0 Expr, and what that expression evaluates to. * Use a Double, for Num values. */ allTests = java.util.Arrays.asList( /* N0 tests: */ new Pair( "7", 7 ) // ,new Pair( "7.0", 7 ) // parseString("7.0").toString() return "7", not "7.0". ,new Pair( "(3 plus 4)", 7 ) ,new Pair( "(3 times 4)", 12 ) ,new Pair( "((3 plus 4) plus( 3 times 4 ))", 19) ,new Pair( "if 0 is0 then 1 else 2;", 1 ) ,new Pair( "if 1 is0 then 1 else 2;", 2 ) ,new Pair( "if (3 plus -3) is0 then 1 else 2;", 1 ) ,new Pair( "if (if if -1 is0 then 1 else 2; is0 then 3 else 4 ; plus -3) is0 then 1 else 2;", 2 ) /**** N1 tests: ****/ /**** YOU NEED TO UPDATE THESE TO THE N1 SYNTAX (infix, not prefix): ,new Pair( "(3.0 mod 4.0)", 3) ,new Pair( "((5.0 plus 6.0) mod 3.0)", 2) ,new Pair( "(8.1 mod 3.0)", 2.1) ,new Pair( "(8.0 mod 3.1)", 1.8) ,new Pair( "(-8.1 mod 3.0)", 0.9) ,new Pair( "(-8.0 mod 3.1)", 1.3) ,new Pair( "(8.1 mod -3)", -0.9) ,new Pair( "(8.0 mod -3.1)", -1.3) ,new Pair( "(-8.1 mod -3.0)", -2.1) ,new Pair( "(-8.0 mod -3.1)", -1.8) ,new Pair( "(8.0 mod 2.0)", 0) ,new Pair( "(-8.0 mod 2.0)", 0) ,new Pair( "(8.0 mod -2.0)", 0) ,new Pair( "(-8.0 mod -2.0)", 0) ,new Pair( "(8.0 mod 3.0)", 2) ,new Pair( "(-8.0 mod 3.0)", 1) ,new Pair( "(8.0 mod -3.0)", -1) ,new Pair( "(-8.0 mod -3.0)", -2) YOU MUST CREATE SOME TESTS FOR isNegExprs ****/ ); } /** For every element in allTests, * parse the string, and then call toString on the result, * checking that we get back exactly the input string * (up to whitespace). */ public void testParseToString() { for ( Pair t : allTests ) { String expected = t.getFirst(); String actual = Expr.parse( t.getFirst() ).toString(); if (! UtilIan.equalsIgnoreWhitespace(expected, actual, Expr.PUNCTUATION)) { // This assert will fail; just present it to the user: assertEquals( expected, actual ); } } } /** For every element in allTests, * parse the string and eval the result, * checking that we get back the second item in the pair. * If the second item is a number, we check within {@value TOLERANCE}. * If it's not a number (as in L2, once function-values are introduced), * this code doesn't actually test anything, and asserts an error saying so. */ public void testEval() { for ( Pair t : allTests ) { if (Number.class.isInstance( t.getSecond() )) { assertEquals( ((Number)t.getSecond()).doubleValue(), ((Num)(Expr.parse( t.getFirst() ).eval())).doubleValue(), TOLERANCE ); } else { // I guess Java expects us to implement .equals for every single Expr. // Should we do that, or hack some other way of doing our tests? assertEquals( t.getFirst() + " didn't evaluate to a double", "How to express the expected Fun value?" ); } } } /** * Tears down the test fixture. * * Called after every test case method. */ protected void tearDown() { } }