fixed test

This commit is contained in:
RaffaeleMorganti 2022-11-17 21:58:02 +01:00
parent 4b01c0a85c
commit f4dc0fac73
5 changed files with 145 additions and 126 deletions

View file

@ -14,13 +14,19 @@
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mainClass>com.github.dtschust.zork.Zork</mainClass>
<mainClass>com.github.dtschust.zork.original.Zork</mainClass>
</properties>
<build>

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}