/* Gregory M. Lobdell, CS& 145, Winter 2010 In class: 09 Feb 2010 GrammarTest.java */ import java.util.*; import java.io.*; /** GrammarTest Class Test code for GrammarSover */ public class GrammarTest { private static final int TEST_COUNT = 42; public static void main ( String [] args ) { test(); } public static void test () { System.out.println ( "Testing Grammar Solver: " + TEST_COUNT + " tests..." ); // initialize pass and fail counters, [0] is pass, [1] is fail int[] counts = {0, 0}; // no printout tests, so no need to divert System.out // declarations GrammarSolver theGS; List list; Set set; // wrap everything in a try just in case an unhandled error is thrown try { // test constructor theGS = test_constructor ( "Testing null list to constructor...", null, false, true, counts ); list = new LinkedList(); theGS = test_constructor ( "Testing empty list to constructor...", list, false, true, counts ); String[] array = {"S::=Hello World"}; list = Arrays.asList(array); theGS = test_constructor ( "Testing constructor with one rule...", list, true, false, counts ); // test getSymbols() String[] oneSymbolsArray = {"S"}; set = new HashSet(Arrays.asList(oneSymbolsArray)); test_getSymbols ( "Testing getSymbols method...", theGS, set, counts ); // test contains(String) test_contains ( "Testing contains method on null string -> exception...", theGS, null, false, true, counts ); test_contains ( "Testing contains method on zero length string -> exception...", theGS, "", false, true, counts ); test_contains ( "Testing contains method on one rule 'S'...", theGS, "S", true, false, counts ); test_contains ( "Testing contains method on non-existent rule...", theGS, "B", false, false, counts ); // test generate() test_generate ( "Testing generate method...", theGS, "S", "Hello World", false, counts ); test_generate ( "Testing generate method on null string...", theGS, null, "", true, counts ); test_generate ( "Testing generate method on zero length string...", theGS, null, "", true, counts ); String[] threearray = {"Error ::= A B", "A ::= Apple", "Error ::= A B C"}; list = Arrays.asList(threearray); theGS = test_constructor ( "Testing constructor with duplicate rules...", list, false, true, counts ); String[] fivearray = {"AS ::= A2 B2 C2 D2", "A2 ::= a | A | 1 | !", "B2 ::= b | B | 2 | @", "C2 ::= c | C | 3 | #", "D2 ::= d | D | 4 | $"}; list = Arrays.asList(fivearray); theGS = test_constructor ( "Testing constructor with multiple rules...", list, true, false, counts ); // test getSymbols() String[] fiveSymbolsArray = {"AS", "A2", "B2", "C2", "D2"}; set = new HashSet(Arrays.asList(fiveSymbolsArray)); test_getSymbols ( "Testing getSymbols method...", theGS, set, counts ); // test contains(String) test_contains ( "Testing contains method on multi-rule grammar 'A2'...", theGS, "A2", true, false, counts ); test_contains ( "Testing contains method on multi-rule grammar 'D2'...", theGS, "D2", true, false, counts ); test_contains ( "Testing contains method on non-existent rule...", theGS, "A1", false, false, counts ); test_generate ( "Testing generate method on multi-rule grammar...", theGS, "A2", "[aA1!]", false, counts); test_generate ( "Testing generate method on multi-rule grammar...", theGS, "B2", "[bB2@]", false, counts); test_generate ( "Testing generate method on multi-rule grammar...", theGS, "AS", "[aA1!] [bB2@] [cC3#] [dD4$]", false, 5, counts); String[] tenarray = {"AS ::= start A1 B1 C1 D1 E1 end", "A1 ::= A2 | A1 A2", "A2 ::= a | A | 1 | !", "B1 ::= B2 | B1 B2", "B2 ::= b | B | 2 | @", "C1 ::= C2 | C1 C2", "C2 ::= c | C | 3 | #", "D1 ::= D2 | D1 D2", "D2 ::= d | D | 4 | $", "E1 ::= e | E | 5 | %"}; list = Arrays.asList(tenarray); theGS = test_constructor ( "Testing constructor with recursive rule grammar...", list, true, false, counts ); String pattern = "start ([aA1!] )+([bB2@] )+([cC3#] )+([dD4$] )+[eE5%] end"; test_generate ( "Testing generate method on recursive rule grammar...", theGS, "AS", pattern, false, 5, counts); String[] weirdarray = {" Pattern \t ::= rule \t\t one | \t rule\ttwo |\trule three \t \t \t", " \t rule ::=\t st\t| ts |\t ss\t|\ttt\t", "\tone\t::= 1 | 11 | 111 ", "two::=2|22|222", " three ::=\t3\t| \t33\t |\t 333 \t \t", "otherwise::= Fruit flies like a banana "}; list = Arrays.asList(weirdarray); theGS = test_constructor ( "Testing constructor with extra whitespace rules...", list, true, false, counts ); String[] weirdSymbolsArray = {"Pattern", "rule", "one", "two", "three", "otherwise"}; set = new HashSet(Arrays.asList(weirdSymbolsArray)); test_getSymbols ( "Testing getSymbols method...", theGS, set, counts ); test_generate ( "Testing generate with extra whitespace grammar...", theGS, "Pattern", "[st][st] [123]+", false, 5, counts); test_generate ( "Testing 'one' terminal...", theGS, "one", "1{1,3}", false, 1, counts); test_generate ( "Testing 'two' terminal...", theGS, "two", "2{1,3}", false, 1, counts); test_generate ( "Testing 'three' terminal...", theGS, "three", "3{1,3}", false, 1, counts); test_generate ( "Testing 'otherwise' terminal...", theGS, "otherwise", "Fruit flies like a banana", false, 1, counts); String[] blankarray = {"SeattleSonics ::= "}; list = Arrays.asList(blankarray); System.out.println ( "The blank rule test should throw an exception, either in the" ); System.out.println ( " constructor or in the generate method." ); theGS = test_constructor ( "Testing constructor with blank rule...", list, true, true, counts ); if ( theGS != null ) { counts[0]--; test_generate ( "Testing generate with blank rule grammar...", theGS, "SeattleSonics", null, true, 1, counts ); } printReport ( System.out, counts ); } catch (Exception e) { System.out.println ( "\nUnhandled exception: " + e ); counts[1]++; printReport ( System.out, counts ); } } public static void printlist ( List list, String indent ) { for ( String str : list ) System.out.println ( indent + str ); } public static GrammarSolver test_constructor ( String message, List arg, boolean success, boolean exception, int[] counts ) { GrammarSolver theGS; try { System.out.print ( message ); theGS = new GrammarSolver(arg); if ( success ) { System.out.println ( "PASS" ); counts[0]++; System.out.println ( "Grammar:" ); printlist(arg, " " ); } else { System.out.println ( " expecting exception - FAIL" ); System.out.println ( "GrammarSolver object may be invalid" ); counts[1]++; } } catch ( IllegalArgumentException e ) { if ( exception ) { System.out.println ( " -> exception PASS" ); counts[0]++; } else { System.out.println ( "FAIL - IllegalArgumentException: " + e ); counts[1]++; System.out.println ( "Contructor failed, returning null" ); } theGS = null; } catch ( Exception e ) { System.out.println ( "FAIL - exception: " + e ); counts[1]++; if ( exception ) System.out.println ( " Expecting exception: IllegalArgumentException" ); System.out.println ( " Contructor failed, returning null" ); theGS = null; } return theGS; } public static String printSet ( Set set ) { String value = ""; if ( set == null || set.size() == 0 ) return "[]"; for ( String str : set ) value += ", " + printStr(str); return "[" + value.substring(2) + "]"; } public static String printStr ( String str ) { return ( "\"" + str + "\"" ); } public static void test_contains ( String message, GrammarSolver theGS, String arg, boolean result, boolean exception, int[] counts ) { System.out.print ( message ); try { boolean value = theGS.contains( arg ); if ( value == result && !exception ) { System.out.println ( "PASS" ); counts[0]++; } else if ( !exception ) { System.out.println ( "FAIL - wrong return value" ); counts[1]++; System.out.println ( " Expecting: " + result + " actual return value: " + value ); } else { System.out.println ( "FAIL - should throw exception" ); counts[1]++; System.out.println ( " Instead method returned value: " + value ); } } catch ( IllegalArgumentException e ) { if ( exception ) { System.out.println ( "PASS" ); counts[0]++; } else { System.out.println ( "FAIL = IllegalArgumentException: " + e ); counts[1]++; System.out.println ( " Expecting return value: " + result ); } } catch ( Exception e ) { System.out.println ( "FAIL = exception: " + e ); counts[1]++; if ( exception ) System.out.println ( " Expecting exception: IllegalArgumentException" ); else System.out.println ( " Expecting return value: " + result ); } } public static void test_getSymbols ( String message, GrammarSolver theGS, Set result, int[] counts ) { System.out.print ( message ); boolean exception = false; try { Set value = theGS.getSymbols(); if ( value.equals(result) && !exception ) { System.out.println ( "PASS" ); counts[0]++; } else if ( !exception ) { System.out.println ( "FAIL - wrong return value" ); counts[1]++; System.out.println ( " Expecting set: " + printSet(result)); System.out.println ( " Actual return value: " + printSet(value) ); } else { System.out.println ( "FAIL - should throw exception" ); counts[1]++; System.out.println ( " Instead method returned value: " + printSet(value) ); } } catch ( Exception e ) { System.out.println ( "FAIL = exception: " + e ); counts[1]++; System.out.println ( " Expecting return value: " + printSet(result) ); } } public static void test_generate ( String message, GrammarSolver theGS, String arg, String pattern, boolean exception, int[] counts ) { test_generate ( message, theGS, arg, pattern, exception, 1, counts ); } public static void test_generate ( String message, GrammarSolver theGS, String arg, String pattern, boolean exception, int repeat, int[] counts ) { System.out.print ( message ); boolean multi = repeat > 1; if ( multi ) System.out.println (); try { do { String value = theGS.generate( arg ); if ( multi ) System.out.print ( " " + arg + " -> " + value + " " ); else System.out.print ( " " + arg + " -> " + value + " " ); if ( value.matches(pattern) && !exception ) { System.out.println ( "PASS" ); counts[0]++; } else if ( !exception ) { System.out.println ( "FAIL - wrong return value" ); counts[1]++; System.out.println ( " Expecting a match to " + printStr(pattern) ); System.out.println ( " Generated string: " + printStr(value) ); } else { System.out.println ( "FAIL - should throw exception" ); counts[1]++; System.out.println ( " Instead method returned value: " + printStr(value) ); } repeat--; } while ( repeat > 0 ); } catch ( IllegalArgumentException e ) { if ( exception ) { System.out.println ( "-> exception PASS" ); counts[0]++; } else { System.out.println ( "FAIL = IllegalArgumentException: " + e ); counts[1]++; System.out.println ( " Expecting return value that matches: " + printStr(pattern) ); } } catch ( Exception e ) { System.out.println ( "FAIL = exception: " + e ); counts[1]++; if ( exception ) System.out.println ( " Expecting exception: IllegalArgumentException" ); else System.out.println ( " Expecting return value that matches: " + printStr(pattern) ); } } public static void printReport ( PrintStream stdout, int[] counts ) { if ( stdout == null ) stdout = System.out; stdout.println (); if ( counts[0] + counts[1] == TEST_COUNT ) { stdout.println ( "Testing Complete - PASS: " + counts[0] + "/" + TEST_COUNT + " FAIL: " + counts[1] ); } else { stdout.println ( "Test Score - PASS: " + counts[0] + "/" + TEST_COUNT + " FAIL: " + counts[1] ); } if ( counts[0] == TEST_COUNT && counts[1] == 0 ) { stdout.println ( "Congratulations! All tests passed." ); } else if ( counts[0] != TEST_COUNT && counts[1] == 0 ) { stdout.println ( "Not all tests complete" ); } else { stdout.println ( "Test FAIL"); } } } /* // test case for empty rules String[] blankarray = {"sports ::= city sport", "city ::= Seattle | Kent | Everett", "sport ::= baseball | basketball | hockey | football ", "baseball ::= Mariners | | Aquasox", "basketball ::= ", "hockey ::= | Thunderbirds | Silvertips", "football ::= Seahawks | Falcons | " }; list = Arrays.asList(blankarray); theGS = test_constructor ( "Testing constructor with blank rules...", list, true, false, counts ); pattern = "(Seattle)*(Kent)*(Everett)*" + "( Mariners)*( Aquasox)*( Thunderbirds)*( Silvertips)*( Seahawks)*( Falcons)*"; theGS.generate ( "sports" ); test_generate ( "Testing generate with blank rule grammar...", theGS, "sports", pattern, false, 5, counts ); */