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 // getResource() cannot be null: this file itself is ScriptFileTests
132 // getParentFile() cannot be null: ScriptFileTests has a package
133 @SuppressWarnings("nullness")
134 File myDirectory = new File(ScriptFileTests.class.getResource("ScriptFileTests.class").toURI()).getParentFile();
135 for (File f : myDirectory.listFiles()) {
136 if (f.getName().endsWith(".test")) {
137 suite.addTest(new ScriptFileTests(f));
138 }
139 }
140 return suite;
141 } catch (URISyntaxException e) {
142 throw new RuntimeException(e);
143 }
144 }
145 }