diff --git a/pom.xml b/pom.xml
index 1f8b5dd..9bb5691 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,13 +14,19 @@
RELEASE
test
+
+ com.github.stefanbirkner
+ system-lambda
+ 1.2.1
+ test
+
11
11
UTF-8
- com.github.dtschust.zork.Zork
+ com.github.dtschust.zork.original.Zork
diff --git a/short.txt b/short.txt
deleted file mode 100644
index 4e2605d..0000000
--- a/short.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-You find yourself at the mouth of a cave and decide that in spite of common sense and any sense of self preservation that you're going to go exploring north into it. It's a little dark, but luckily there are some torches on the wall.
->e
-Can't go that way.
->N
-Error
->n
-*stumble* need some light...
->i
-Inventory: empty
diff --git a/src/test/java/com/github/dtschust/zork/ZorkTest.java b/src/test/java/com/github/dtschust/zork/ZorkTest.java
index 09e8e35..b11f745 100644
--- a/src/test/java/com/github/dtschust/zork/ZorkTest.java
+++ b/src/test/java/com/github/dtschust/zork/ZorkTest.java
@@ -1,138 +1,42 @@
package com.github.dtschust.zork;
+import com.github.dtschust.zork.utils.CommandReader;
+import com.github.dtschust.zork.utils.IOWrapper;
import org.junit.jupiter.api.Test;
-import java.io.*;
-import java.util.Scanner;
-
+import static com.github.stefanbirkner.systemlambda.SystemLambda.catchSystemExit;
import static org.junit.jupiter.api.Assertions.assertEquals;
-/**
- * Not really nice but works
- * TODO: The test result should be success instead of terminated ?WHY?
- * TODO: when looking at inventory (i) we are relying on the HashMap order, so the test may fail !UNSAFE!
- */
class ZorkTest {
+ /** Test the game interacting as a real player
+ * WARNING: when looking at inventory (i) we are relying on the HashMap order, so the test may be unsafe
+ */
@Test
- public void testRunThroughResults() {
- CommandReader run = new CommandReader("RunThroughResults.txt");
- GamePlayer game = new GamePlayer("sampleGame.xml", false);
+ public void testSampleGame() {
+ String gameConfig = "sampleGame.xml";
+ String gameExecution = "RunThroughResults.txt";
+
+ CommandReader run = new CommandReader(gameExecution);
+ IOWrapper io = new IOWrapper(false);
+ new Thread(() -> {
+ try {
+ catchSystemExit(() -> new Zork(gameConfig));
+ } catch (Exception ignored) {}
+ }).start();
while(true){
switch(run.getInstructionType()) {
case SEND:
- game.write(run.getInstruction());
+ io.write(run.getInstruction());
break;
case RECV:
- assertEquals(run.getInstruction(), game.read());
+ assertEquals(run.getInstruction(), io.read());
break;
default:
+ io.restore();
return;
}
}
}
-
- /**
- * CommandReader reads the .txt file containing expected input and output
- */
- static class CommandReader{
- private String instruction;
- private static Scanner scanner;
-
- public enum Type{ SEND, RECV, END }
-
- /** CommandReader Constructor
- * @param filename file containing command sent (with leading ">") and expected responses
- */
- CommandReader(String filename) {
- try {
- scanner = new Scanner(new File(filename));
- } catch (FileNotFoundException e){
- e.printStackTrace();
- }
- }
-
- /**
- * @return Type of the next instruction:
- * - END if the game ended
- * - SEND if it's th command to send
- * - RECV if it's a game output
- */
- public Type getInstructionType(){
- if(!scanner.hasNextLine())
- return Type.END;
- instruction = scanner.nextLine();
- if(instruction.startsWith(">")) {
- instruction = instruction.substring(1);
- return Type.SEND;
- }
-
- return Type.RECV;
- }
-
- /** Returns a text line (can be both an input or output depending on the Type)
- * @return The next text line
- */
- public String getInstruction() {
- return instruction;
- }
- }
-
- /**
- * GamePlayer start the game and holds a communication interface to interact to it
- */
- static class GamePlayer {
- public final PrintStream console;
- private PrintStream printer;
- private BufferedReader reader;
- private final boolean verbose;
-
-
- /** GamePlayer Constructor
- * @param filename name of the game configuration .xml file
- * @param verbose should log on the console all command sent to / received by the game
- */
- public GamePlayer(String filename, boolean verbose) {
- this.verbose = verbose;
- console = System.out;
- try{
- final PipedOutputStream testInput = new PipedOutputStream();
- final PipedOutputStream out = new PipedOutputStream();
- final PipedInputStream testOutput = new PipedInputStream(out);
- System.setIn(new PipedInputStream(testInput));
- System.setOut(new PrintStream(out));
- printer = new PrintStream(testInput);
- reader = new BufferedReader(new InputStreamReader(testOutput));
- } catch (IOException e) {
- e.printStackTrace(console);
- }
-
- new Thread(() -> new Zork(filename)).start();
- }
-
- /** Sends a command to the game (and print it if verbose)
- * @param line text to send to the game
- */
- public void write(String line) {
- printer.println(line);
- if(verbose)
- console.println("> " + line);
- }
-
- /** Receive a command from the game (and print it if verbose)
- * @return line of text sent by the game
- */
- public String read() {
- String line = null;
- try{
- line = reader.readLine();
- if(verbose)
- console.println("< " + line);
- } catch (IOException e) {
- e.printStackTrace(console);
- }
- return line;
- }
- }
}
\ No newline at end of file
diff --git a/src/test/java/com/github/dtschust/zork/utils/CommandReader.java b/src/test/java/com/github/dtschust/zork/utils/CommandReader.java
new file mode 100644
index 0000000..bc86d84
--- /dev/null
+++ b/src/test/java/com/github/dtschust/zork/utils/CommandReader.java
@@ -0,0 +1,51 @@
+package com.github.dtschust.zork.utils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+/**
+ * CommandReader reads the .txt file containing expected input and output
+ */
+public class CommandReader{
+ private String instruction;
+ private static Scanner scanner;
+
+ public enum Type{ SEND, RECV, END }
+
+ /** CommandReader Constructor
+ * @param filename file containing command sent (with leading ">") and expected responses
+ */
+ public CommandReader(String filename) {
+ try {
+ scanner = new Scanner(new File(filename));
+ } catch (FileNotFoundException e){
+ e.printStackTrace();
+ }
+ }
+
+ /** Load the next instruction (overwrite current instruction) and detect its type
+ * @return Type of the next instruction:
+ * - END if the game ended
+ * - SEND if it's th command to send
+ * - RECV if it's a game output
+ */
+ public Type getInstructionType(){
+ if(!scanner.hasNextLine())
+ return Type.END;
+ instruction = scanner.nextLine();
+ if(instruction.startsWith(">")) {
+ instruction = instruction.substring(1);
+ return Type.SEND;
+ }
+
+ return Type.RECV;
+ }
+
+ /** Returns a text line (can be both an input or output depending on the Type)
+ * @return The next text line
+ */
+ public String getInstruction() {
+ return instruction;
+ }
+}
diff --git a/src/test/java/com/github/dtschust/zork/utils/IOWrapper.java b/src/test/java/com/github/dtschust/zork/utils/IOWrapper.java
new file mode 100644
index 0000000..ee30bdb
--- /dev/null
+++ b/src/test/java/com/github/dtschust/zork/utils/IOWrapper.java
@@ -0,0 +1,67 @@
+package com.github.dtschust.zork.utils;
+
+
+import java.io.*;
+
+/**
+ * IOWrapper allows to automatize in/out communication
+ */
+public class IOWrapper {
+ public final PrintStream console;
+ public final InputStream input;
+ private PrintStream printer;
+ private BufferedReader reader;
+ private final boolean verbose;
+
+ /** IOWrapper Constructor
+ * @param verbose should log on the console all command sent to / received by the game
+ */
+ public IOWrapper(boolean verbose) {
+ this.verbose = verbose;
+ console = System.out;
+ input = System.in;
+ try{
+ final PipedOutputStream testInput = new PipedOutputStream();
+ final PipedOutputStream out = new PipedOutputStream();
+ final PipedInputStream testOutput = new PipedInputStream(out);
+ System.setIn(new PipedInputStream(testInput));
+ System.setOut(new PrintStream(out));
+ printer = new PrintStream(testInput);
+ reader = new BufferedReader(new InputStreamReader(testOutput));
+ } catch (IOException e) {
+ e.printStackTrace(console);
+ }
+ }
+
+ /** Sends a command to the game (and print it if verbose)
+ * @param line text to send to the game
+ */
+ public void write(String line) {
+ printer.println(line);
+ if(verbose)
+ console.println("> " + line);
+ }
+
+ /** Receive a command from the game (and print it if verbose)
+ * @return line of text sent by the game
+ */
+ public String read() {
+ String line = null;
+ try{
+ line = reader.readLine();
+ if(verbose)
+ console.println("< " + line);
+ } catch (IOException e) {
+ e.printStackTrace(console);
+ }
+ return line;
+ }
+
+ /** Restore the default System IO
+ *
+ */
+ public void restore(){
+ System.setIn(input);
+ System.setOut(console);
+ }
+}