From aa7d07e6f669c0b2562a8db0348feac1d9b36ba8 Mon Sep 17 00:00:00 2001
From: Matthew Hague <matthew.hague@rhul.ac.uk>
Date: Thu, 11 Nov 2021 12:08:29 +0000
Subject: [PATCH] SubmissionWrapper (almost) always expects finished

Add parameter flag to indicate if a scriptedInteraction should finish
the program. Make the flag default to true.

Also make expectFinished account for remaining output with no end of
line.
---
 .../uk/ac/rhul/cs/javatester/BaseTester.java  |  7 ----
 .../rhul/cs/javatester/SubmissionWrapper.java | 37 +++++++++++++++++--
 .../uk/ac/rhul/cs/javatester/UnitTests.java   | 30 +++++++--------
 3 files changed, 47 insertions(+), 27 deletions(-)

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 d19933f..660090e 100644
--- a/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java
+++ b/src/main/java/uk/ac/rhul/cs/javatester/BaseTester.java
@@ -218,13 +218,6 @@ 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 4560d11..eba0894 100644
--- a/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java
+++ b/src/main/java/uk/ac/rhul/cs/javatester/SubmissionWrapper.java
@@ -427,12 +427,16 @@ public class SubmissionWrapper implements AutoCloseable {
      *
      * The interaction is stored in the interaction buffer.
      *
+     * @param full true if expectFinished should be checked at end
+     * @param interaction the interaction as described above
      * @return null if passed, or the sequence of messages from the
      * failure. These are returned in reverse order with the real
      * failure first, following by any optional lines that were not
      * previously matched.
      */
-    public List<String> scriptedInteraction(String... interaction) {
+    public List<String> scriptedInteraction(
+        boolean full, String... interaction
+    ) {
         int pos = 0;
         List<String> failureMsgs = new LinkedList<String>();
 
@@ -487,9 +491,32 @@ public class SubmissionWrapper implements AutoCloseable {
                 break;
             }
         }
+
+        if (full) {
+            String finishedErr = expectFinished();
+            if (finishedErr != null) {
+                failureMsgs.add(finishedErr);
+                return failureMsgs;
+            }
+        }
+
         return null;
     }
 
+    /**
+     * Convenience for a scriptedInteraction with full set to true
+     */
+    public List<String> scriptedInteraction(String... interaction) {
+        return scriptedInteraction(true, interaction);
+    }
+
+    /**
+     * Convenience for a scriptedInteraction with full set to false
+     */
+    public List<String> scriptedInteractionPart(String... interaction) {
+        return scriptedInteraction(false, interaction);
+    }
+
     /**
      * The program is expected to have finished with no further output
      *
@@ -497,9 +524,11 @@ public class SubmissionWrapper implements AutoCloseable {
      */
     public String expectFinished() {
         try {
-            String line = getLine();
-            if (line == null)
-                return line;
+            String line = getRemainingOutput();
+            if (line.isEmpty())
+                line = getLine();
+            if (line == null || line.isEmpty())
+                return null;
             else
                 return String.format(
                     "Expected the end of the program, but received the ouput '%s'",
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 8606639..66db034 100644
--- a/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java
+++ b/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java
@@ -101,7 +101,7 @@ public class UnitTests {
         try (SubmissionWrapper wrapper
                 = new SubmissionWrapper(ASSIGNMENT)) {
 
-            assertNull(wrapper.scriptedInteraction(
+            assertNull(wrapper.scriptedInteractionPart(
                 "? Here is an optional line",
                     "There was an optional line that was not there",
                 OUT_THING_RE, THING_FAIL_MSG
@@ -146,21 +146,19 @@ 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());
+    public void testUnfinishedInteractionFail() throws IOException {
+        try (SubmissionWrapper wrapper
+                = new SubmissionWrapper(SIMPLE_IN_OUT)) {
+            List<String> failureMsgs = wrapper.scriptedInteraction(
+                "> .*Hello.*", "Expected Hello",
+                "< Matt",
+                "> .*Matt.*", "Expected Matt",
+                "! .*band.*",
+                    "< High Rise",
+                    "The band question was malformed."
+            );
+            assertNotNull(failureMsgs);
+        }
     }
 
     @Test
-- 
GitLab