/* Gregory M. Lobdell, CS& 145, Winter 2010 Test code for Homework #5, Due March 5, 2010 AnagramsTest.java */ import java.io.*; import java.util.*; import java.util.zip.*; /** AnagramsTest Class Test the Anagrams class */ public class AnagramsTest { // dictionary file to use for input (change to dict2, dict3) //private static final String DICTIONARY_FILE = "dict1.txt"; private static final String DICTIONARY_FILE1 = "dict1.txt"; private static final String DICTIONARY_FILE2 = "dict2.txt"; private static final String DICTIONARY_FILE3 = "dict3.txt"; public static final int TEST_COUNT = 20; public static void main ( String [] args ) { test(); } public static void test ( ) { System.out.println ( "Testing Anagrams: " + TEST_COUNT + " tests..." ); PrintStream origOut = null; PrintStream origError = null; // initialize pass and fail counters, [0] is pass, [1] is fail int[] counts = {0, 0}; try { // Capture the streams so we can listen // @throws java.lang.Exception ByteArrayOutputStream testOutput = new ByteArrayOutputStream(); origOut = System.out; origError = System.err; testOutput = new ByteArrayOutputStream(); PrintStream err = new PrintStream(testOutput); PrintStream out = new PrintStream(testOutput); // set the output streams to the byte array System.setErr(err); System.setOut(out); // get the char(s) produced by "\n" String cr = getCRLF( testOutput, origOut ); // test constructor Anagrams solver1; Anagrams solver2; Anagrams solver3; solver1 = test_constructor ( "Testing constructor with null dictionary...", origOut, null, false, true, counts ); Set dict1 = getDict ( DICTIONARY_FILE1, origOut, 60, 93624319L ); solver1 = test_constructor ( "Testing constructor with dict1...", origOut, dict1, true, false, counts ); Set dict2 = getDict ( DICTIONARY_FILE2, origOut, 3927, 3036045834L ); solver2 = test_constructor ( "Testing constructor with dict2...", origOut, dict2, true, false, counts ); Set dict3 = getDict ( DICTIONARY_FILE3, origOut, 19911, 1690958084L ); solver3 = test_constructor ( "Testing constructor with dict3...", origOut, dict3, true, false, counts ); // test getWords Set result = new TreeSet(); test_getWords ( "Testing getWords with null phrase...", origOut, solver1, null, result, cr, false, true, counts ); String[] strArr1 = {"abash", "aura", "bar", "barb", "brush", "bus", "hub", "rub", "shrub", "sub"}; result = new TreeSet( Arrays.asList( strArr1 ) ); test_getWords ( "Testing getWords(\"Barbara Bush\") with dict1...", origOut, solver1, "Barbara Bush", result, cr, true, false, counts ); // test print one argument test_print1 ( "Testing print(phrase) with null argument...", origOut, testOutput, solver1, null, "", cr, false, true, counts ); String resultString = ( "[abash, bar, rub]" + cr + "[bar, abash, rub]" + cr + "[abash, rub, bar]" + cr + "[bar, rub, abash]" + cr + "[rub, abash, bar]" + cr + "[rub, bar, abash]" ); test_print1 ( "Testing print(\"Barbara Bush\") with dict1...", origOut, testOutput, solver1, "Barbara Bush", resultString, cr, true, false, counts ); resultString = ( "[bee, bee, sir, sir]" + cr + "[bee, sir, bee, sir]" + cr + "[sir, bee, bee, sir]" + cr + "[bee, sir, sir, bee]" + cr + "[sir, bee, sir, bee]" + cr + "[sir, sir, bee, bee]" ); test_print1 ( "Testing print(\"sir bee sir bee\") with dict1 [this is a hard test]...", origOut, testOutput, solver1, "sir bee sir bee", resultString, cr, true, false, counts ); // test print two arguments test_print2 ( "Testing print(phrase, max) with null phrase...", origOut, testOutput, solver1, null, 0, "", cr, false, true, counts ); test_print2 ( "Testing print(phrase, max) with max < 0...", origOut, testOutput, solver1, "George Bush", -1, "", cr, false, true, counts ); String[] strArr2 = {"bar", "briar", "brush", "bus", "hub", "huh", "hush", "rub", "shrub", "sir", "sub"}; result = new TreeSet( Arrays.asList( strArr2 ) ); test_getWords ( "Testing getWords(\"hairbrush\") with dict1...", origOut, solver1, "hairbrush", result, cr, true, false, counts ); resultString = ( "[briar, hush]" + cr + "[hush, briar]" ); test_print2 ( "Testing print(\"hairbrush\", 2) with dict1...", origOut, testOutput, solver1, "hairbrush", 2, resultString, cr, true, false, counts ); resultString = ( "[abash, bar, rub]" + cr + "[bar, abash, rub]" + cr + "[abash, rub, bar]" + cr + "[bar, rub, abash]" + cr + "[rub, abash, bar]" + cr + "[rub, bar, abash]" ); test_print1 ( "Re-testing print(\"Barbara Bush\") after other print...", origOut, testOutput, solver1, "Barbara Bush", resultString, cr, true, false, counts ); // run tests with dict2 String[] strArr3 = {"a", "all", "also", "art", "as", "at", "fall", "falls", "far", "fast", "flash", "flat", "float", "floats", "fly", "for", "forth", "fry", "half", "hall", "has", "hat", "host", "hot", "last", "lay", "lost", "lot", "lots", "of", "oh", "or", "roll", "sat", "say", "shall", "short", "shortly", "so", "soft", "sort", "stay", "to", "trash", "try" }; result = new TreeSet( Arrays.asList( strArr3 ) ); test_getWords ( "Testing getWords(\"sally forth\") with dict2...", origOut, solver2, "sally forth", result, cr, true, false, counts ); resultString = ( "[all, fry, host]" + cr + "[all, host, fry]" + cr + "[falls, oh, try]" + cr + "[falls, try, oh]" + cr + "[fry, all, host]" + cr + "[fry, host, all]" + cr + "[fry, shall, to]" + cr + "[fry, to, shall]" + cr + "[host, all, fry]" + cr + "[host, fry, all]" + cr + "[of, shall, try]" + cr + "[of, try, shall]" + cr + "[oh, falls, try]" + cr + "[oh, try, falls]" + cr + "[shall, fry, to]" + cr + "[shall, of, try]" + cr + "[shall, to, fry]" + cr + "[shall, try, of]" + cr + "[to, fry, shall]" + cr + "[to, shall, fry]" + cr + "[try, falls, oh]" + cr + "[try, of, shall]" + cr + "[try, oh, falls]" + cr + "[try, shall, of]" ); test_print1 ( "Testing print(\"sally forth\") with dict2...", origOut, testOutput, solver2, "sally forth", resultString, cr, true, false, counts ); // run tests with dict3 String[] strArr4 = {"act", "ash", "ashy", "ask", "ass", "assay", "cash", "cask", "cast", "cat", "chat", "cyst", "hack", "hast", "hasty", "hat", "hay", "haystack", "sac", "sack", "sash", "sashay", "sat", "say", "scat", "shack", "shaky", "shay", "shy", "skat", "sky", "stack", "stash", "stay", "tack", "tacky", "task", "thy", "yacht", "yah", "yak"}; result = new TreeSet( Arrays.asList( strArr4 ) ); test_getWords ( "Testing getWords(\"haystacks\") with dict3...", origOut, solver3, "haystacks", result, cr, true, false, counts ); resultString = ( "[ashy, stack]" + cr + "[cask, hasty]" + cr + "[cast, shaky]" + cr + "[hasty, cask]" + cr + "[hasty, sack]" + cr + "[sack, hasty]" + cr + "[sash, tacky]" + cr + "[scat, shaky]" + cr + "[shack, stay]" + cr + "[shaky, cast]" + cr + "[shaky, scat]" + cr + "[shay, stack]" + cr + "[stack, ashy]" + cr + "[stack, shay]" + cr + "[stay, shack]" + cr + "[tacky, sash]" ); test_print2 ( "Testing print(\"haystacks\", 2) with dict3...", origOut, testOutput, solver3, "haystacks", 2, resultString, cr, true, false, counts ); resultString = ( resultString + cr + "[act, ash, sky]" + cr + "[act, ask, shy]" + cr + "[act, shy, ask]" + cr + "[act, sky, ash]" + cr + "[ash, act, sky]" + cr + "[ash, cat, sky]" + cr + "[ash, sky, act]" + cr + "[ash, sky, cat]" + cr + "[ask, act, shy]" + cr + "[ask, cat, shy]" + cr + "[ask, sac, thy]" + cr + "[ask, shy, act]" + cr + "[ask, shy, cat]" + cr + "[ask, thy, sac]" + cr + "[cat, ash, sky]" + cr + "[cat, ask, shy]" + cr + "[cat, shy, ask]" + cr + "[cat, sky, ash]" + cr + "[hat, sac, sky]" + cr + "[hat, sky, sac]" + cr + "[sac, ask, thy]" + cr + "[sac, hat, sky]" + cr + "[sac, sky, hat]" + cr + "[sac, thy, ask]" + cr + "[shy, act, ask]" + cr + "[shy, ask, act]" + cr + "[shy, ask, cat]" + cr + "[shy, cat, ask]" + cr + "[sky, act, ash]" + cr + "[sky, ash, act]" + cr + "[sky, ash, cat]" + cr + "[sky, cat, ash]" + cr + "[sky, hat, sac]" + cr + "[sky, sac, hat]" + cr + "[thy, ask, sac]" + cr + "[thy, sac, ask]" ); test_print1 ( "Testing print(\"haystacks\") with dict3...", origOut, testOutput, solver3, "haystacks", resultString, cr, true, false, counts ); test_print2 ( "Testing print(\"haystacks\", 0) with dict3...", origOut, testOutput, solver3, "haystacks", 0, resultString, cr, true, false, counts ); printReport ( origOut, counts ); } catch (Exception e) { if ( origOut == null ) origOut = System.out; origOut.println ( "\nUnhandled exception: " + e ); counts[1]++; printReport ( origOut, counts ); } } // test constructor private static Anagrams test_constructor ( String message, PrintStream stdout, Set arg, boolean success, boolean exception, int[] counts ) { Anagrams theAG; try { stdout.print ( message ); theAG = new Anagrams(arg); if ( success ) { stdout.println ( "PASS" ); counts[0]++; } else { stdout.println ( "expecting exception - FAIL" ); stdout.println ( " Anagrams object may be invalid" ); counts[1]++; } } catch ( IllegalArgumentException e ) { if ( exception ) { stdout.println ( " -> IllegalArgumentException PASS" ); counts[0]++; } else { stdout.println ( "FAIL - IllegalArgumentException: " + e ); counts[1]++; stdout.println ( " Contructor failed, returning null" ); } theAG = null; } catch ( Exception e ) { stdout.println ( "FAIL - exception: " + e ); counts[1]++; stdout.println ( " Contructor failed, returning null" ); theAG = null; } return theAG; } // test getWords private static Set test_getWords ( String message, PrintStream stdout, Anagrams theAG, String arg, Set result, String cr, boolean success, boolean exception, int[] counts ) { stdout.print ( message ); Set value; try { value = theAG.getWords( arg ); handleSuccess ( stdout, cr, value.equals(result), value.toString(), result.toString(), success, exception, counts ); } catch ( Exception e ) { handleException ( stdout, cr, e, result.toString(), exception, counts ); value = null; } return value; } // test print one argument public static void test_print1 ( String message, PrintStream stdout, ByteArrayOutputStream testout, Anagrams theAG, String arg, String result, String cr, boolean success, boolean exception, int[] counts ) { stdout.print ( message ); try { theAG.print(arg); String value = testout.toString(); handleSuccess ( stdout, cr, compareStrings ( value, result, cr ), value, result, success, exception, counts ); testout.reset(); } catch ( Exception e ) { handleException ( stdout, cr, e, result, exception, counts ); } } // test print two arguments public static void test_print2 ( String message, PrintStream stdout, ByteArrayOutputStream testout, Anagrams theAG, String arg1, int arg2, String result, String cr, boolean success, boolean exception, int[] counts ) { stdout.print ( message ); try { theAG.print(arg1, arg2); String value = testout.toString(); handleSuccess ( stdout, cr, compareStrings ( value, result, cr ), value, result, success, exception, counts ); testout.reset(); } catch ( Exception e ) { handleException ( stdout, cr, e, result, exception, counts ); } } public static void handleSuccess ( PrintStream stdout, String cr, boolean test, String value, String result, boolean success, boolean exception, int[] counts ) { if ( test && success ) { stdout.println ( "PASS" ); counts[0]++; } else if ( exception ) { stdout.println ( "FAIL - should throw exception" ); counts[1]++; stdout.print ( " Instead method returned value: "); printIndent ( stdout, value, cr, " " ); } else { stdout.println ( "FAIL - wrong return value" ); counts[1]++; stdout.print ( " Expecting: " ); printIndent ( stdout, result, cr, " " ); stdout.print ( " Actual return value: " ); printIndent ( stdout, value, cr, " "); } } public static void handleException ( PrintStream stdout, String cr, Exception e, String result, boolean exception, int[] counts ) { if ( e instanceof IllegalArgumentException ) { if ( exception ) { stdout.println ( " -> IllegalArgumentException PASS" ); counts[0]++; } else { stdout.println ( "FAIL = IllegalArgumentException: " + e ); counts[1]++; stdout.print ( " Expecting return value: " ); printIndent ( stdout, result, cr, " "); } } else { stdout.println ( "FAIL = exception: " + e ); counts[1]++; if ( exception ) { stdout.println ( " Expecting IllegalArgumentException" ); } else { stdout.print ( " Expecting return value: " ); printIndent ( stdout, result, cr, " "); } } } // print the report 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"); } } public static String getCRLF ( ByteArrayOutputStream testOutput, PrintStream stdout) { String cr; try { System.out.println ( ); cr = testOutput.toString(); testOutput.reset(); } catch ( Exception e ) { stdout.println ( " Error getting printed output" ); stdout.println ( " Printing tests may fail" ); cr = "\n"; } return cr; } public static Set getDict ( String filename, PrintStream stdout, int length, long checksum ) { // stdout.println("Using dictionary file " + filename + "."); // read dictionary into a set Set dictionary = new TreeSet(); try { Scanner input = new Scanner(new File(filename)); while (input.hasNextLine()) { dictionary.add(input.nextLine()); } dictionary = Collections.unmodifiableSet(dictionary); // read-only CRC32 crc = new CRC32(); for ( String word : dictionary ) crc.update ( word.getBytes() ); if ( dictionary.size() != length ) { stdout.println ( "Dictionary " + filename + " length not correct." ); stdout.println ( " Expecting " + length + " actual length " + dictionary.size() + ". This may cause problems later." ); } if ( crc.getValue() != checksum ) { stdout.println ( "Dictionary " + filename + " has different checksum." ); stdout.println ( " Expecting " + checksum + " actual checksum " + crc.getValue() + ". This may cause problems later." ); } } catch ( FileNotFoundException e ) { stdout.println ( "Dictionary file not found, " + filename + ", may cause problems with later tests." ); dictionary = null; } catch ( Exception e ) { stdout.println ( "Error reading dictionary file " + filename + ", may cause problems with later tests." ); stdout.println ( " Error: " + e ); dictionary = null; } return dictionary; } public static boolean compareStrings ( String value, String result, String cr ) { if ( value.equals(result) ) return true; String[] valueArr = value.split( cr ); String[] resultArr = result.split( cr ); if ( Arrays.equals ( valueArr, resultArr ) ) return true; Set valueSet = new HashSet(Arrays.asList(valueArr)); Set resultSet = new HashSet(Arrays.asList(resultArr)); if ( valueArr.length == valueSet.size() && valueSet.equals(resultSet) ) return true; return false; } public static void printIndent ( PrintStream stdout, String str, String cr, String indent ) { if ( str == null ) stdout.println ( str ); else { String[] strArr = str.split(cr); stdout.println ( strArr[0] ); for ( int i = 1 ; i < strArr.length ; i++ ) stdout.println ( indent + strArr[i] ); } } }