diff --git a/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java b/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java index 7a2ec7021cf3a3008d4a6aecf16dc8f54f67b64e..d19933f00e313fb109561f22ea36f7e0567403c1 100644 --- a/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java +++ b/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java @@ -14,6 +14,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; @@ -206,7 +207,8 @@ public abstract class BaseTester { * Create a wrapper and run wrapper.scriptedInteraction then output * the result to the user * - * Convenience method + * Convenience method. Will error if more output occurs than is + * expected. * * @return true if the test passed */ @@ -216,6 +218,13 @@ public abstract class BaseTester { SubmissionWrapper wrapper = getNewSubmissionWrapper(); try { msgs = wrapper.scriptedInteraction(interaction); + String closedError = wrapper.expectFinished(); + if (closedError != null) { + if (msgs == null) { + msgs = new ArrayList<String>(); + msgs.add(closedError); + } + } } finally { wrapper.close(); } diff --git a/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java b/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java index f62ad6bb6e8e680126b14d029ac3e4821a648e2b..4560d115338d6c51a8067307af474b4e31e1984a 100644 --- a/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java +++ b/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java @@ -358,7 +358,8 @@ public class SubmissionWrapper implements AutoCloseable { } /** - * Get any output that has not been used in an interaction + * Get any output that has been read but has not been used in an + * interaction */ public String getRemainingOutput() { return lineBuilder.toString(); @@ -415,6 +416,9 @@ public class SubmissionWrapper implements AutoCloseable { * the program then outputs "You like music?" the input "Yep" will * be provided. Else the input is not provided. * + * Note: does not care if there is output after the script finishes. + * Calls to scriptedInteraction may be chained together. + * * After each expected output, a message is given to identify the * failure. * @@ -486,6 +490,26 @@ public class SubmissionWrapper implements AutoCloseable { return null; } + /** + * The program is expected to have finished with no further output + * + * @return null if no problem, a failure message if failed + */ + public String expectFinished() { + try { + String line = getLine(); + if (line == null) + return line; + else + return String.format( + "Expected the end of the program, but received the ouput '%s'", + line + ); + } catch (TimeoutException e) { + return "Expected the end of the program, but it continued to run without producing any standard output."; + } + } + /** * Concatenates the given string arrays * diff --git a/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java b/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java index ea885a362ed70990ad64dc38c7deff9663bef1cb..8606639e5cb70b17b01c0e058fefc42cfa78b50d 100644 --- a/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java +++ b/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java @@ -145,6 +145,24 @@ public class UnitTests { } } + @Test + public void testUnfinishedInteractionFail() { + BaseTester tester = new BaseTester(SIMPLE_IN_OUT) { + @SuppressWarnings("unused") + public boolean testUnfinished() throws IOException { + return scriptedInteraction( + "> .*Hello.*", "Expected Hello", + "< Matt", + "> .*Matt.*", "Expected Matt", + "! .*band.*", + "< High Rise", + "The band question was malformed." + ); + } + }; + assertFalse(tester.runTests()); + } + @Test public void testLoadClass() { BaseTester tester = new BaseTester(STORAGE) {