001    package ps3.test;
002    
003    import java.io.BufferedReader;
004    import java.io.File;
005    import java.io.FileNotFoundException;
006    import java.io.FileReader;
007    import java.io.FileWriter;
008    import java.io.IOException;
009    import java.io.Reader;
010    import java.io.Writer;
011    import java.net.URISyntaxException;
012    
013    import junit.framework.Test;
014    import junit.framework.TestCase;
015    import junit.framework.TestSuite;
016    
017    import ps3.test.PS3TestDriver;
018    
019    /**
020     * This class, along with a complete PS4TestDriver implementation,
021     * can be used to test the your implementations of Graph and the
022     * path finding algorithm using the script file format described
023     * in the problem set.  It is assumed that the files are
024     * located in the same directory as this class.
025    */
026    public class ScriptFileTests extends TestCase {
027        private final File testDriver;
028            
029        /**
030         * Creates a new ScriptFileTests case, which runs the given test file.
031         * @param testDriver
032         */
033        public ScriptFileTests(File testDriver) {
034            super("testWithScriptFile");
035            //TWS: if only we could make the test name the name of the script :(
036            //super(testDriver.getName());
037            this.testDriver = testDriver;
038        }
039    
040        /**
041         * Reads in the contents of a file; changes the line
042         * separator to System.getProperty("line.separator")
043         * @throws FileNotFoundException, IOException
044         * @requires that the specified File exists && File ends with a newline
045         * @returns the contents of that file
046         */
047        private String fileContents(File f) throws IOException {
048            if (f == null) {
049                throw new IllegalArgumentException("No file specified");
050            }
051            
052            BufferedReader br = new BufferedReader(new FileReader(f));
053            
054            StringBuilder result = new StringBuilder();
055            String line = null;
056            
057            //read line reads up to *any* newline character
058            while( (line = br.readLine()) != null){
059                    result.append(line);
060                    result.append(System.getProperty("line.separator"));
061            }
062                   
063            br.close();
064            return result.toString();
065        }
066    
067        /**
068         * @throws IOException 
069         * @requires there exists a test file indicated by testDriver
070         *
071         * @effects runs the test in filename, and output its results to a file in
072         * the same directory with name filename+".actual"; if that file already
073         * exists, it will be overwritten.     
074         * @returns the contents of the output file
075         */
076        private String runScriptFile() throws IOException {
077            if (testDriver == null) {
078                throw new RuntimeException("No file specified");
079            }
080            
081            File actual = fileWithSuffix("actual");
082            
083            Reader r = new FileReader(testDriver);
084            Writer w = new FileWriter(actual);
085            
086            PS3TestDriver td = new PS3TestDriver(r, w);
087            td.runTests();
088            
089            return fileContents(actual);
090        }
091        
092        /**
093         * @param newSuffix
094         * @return a File with the same name as testDriver, except that the test
095         *         suffix is replaced by the given suffix
096         */
097        private File fileWithSuffix(String newSuffix) {
098            File parent = testDriver.getParentFile();
099            String driverName = testDriver.getName();
100            String baseName = driverName.substring(0, driverName.length() - "test".length());
101            
102            return new File(parent, baseName + newSuffix);
103        }
104        
105        /**
106         * The only test that is run: run a script file and test its output.
107         * @throws IOException
108         */
109        public void testWithScriptFile() throws IOException {
110            File expected = fileWithSuffix("expected");
111            
112            //TWS: Hack to differentiate tests based on script name
113            setName(testDriver.getName().substring(0, testDriver.getName().lastIndexOf('.')) );
114            
115            assertEquals(testDriver.getName(), fileContents(expected), runScriptFile());
116        
117        }
118        
119        /**
120         * Build a test suite of all of the script files in the directory.
121         * @return the test suite
122         * @throws URISyntaxException
123         */
124        public static Test suite()
125        { 
126            TestSuite suite = new TestSuite(); 
127            
128            // Hack to get at the directory where the files are: they are in the
129            // same directory as the compiled ScriptFileTests class,
130            try {
131                File myDirectory = new File(ScriptFileTests.class.getResource("ScriptFileTests.class").toURI()).getParentFile();
132                for (File f : myDirectory.listFiles()) {
133                    if (f.getName().endsWith(".test")) {
134                        suite.addTest(new ScriptFileTests(f));
135                    }
136                }
137                return suite;
138            } catch (URISyntaxException e) {
139                throw new RuntimeException(e);
140            }
141        }
142    }