diff options
| author | Cliff Click <cliffc@acm.org> | 2026-11-08 14:10:02 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-11-08 14:10:02 -0800 |
| commit | 06fb5aceeb65a75b1cd643debd667c52fdcafcb9 (patch) | |
| tree | c99813eaf27d98f840245302c4d6e923c964307e /chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java | |
| parent | 6560a92433a38825fd1d44d9c66ffba9f26990ff (diff) | |
| download | Simple-ch30.tar.gz Simple-ch30.zip | |
Better error messagesch30
Better error messages.
Buffs to the std lib; getch() to fetch a single character; streaming I/O handles retries, and large sizes, with better error reporting.
Formatted strings.
Default int moved to i32.
TicTacToe, the game.
Diffstat (limited to 'chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java')
| -rw-r--r-- | chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java b/chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java new file mode 100644 index 00000000..1d267935 --- /dev/null +++ b/chapter30/src/test/java/com/seaofnodes/simple/TicTacToeTest.java @@ -0,0 +1,92 @@ +package com.seaofnodes.simple; + +import com.seaofnodes.simple.util.Ary; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +public class TicTacToeTest { + private static String exe; + + @BeforeClass public static void compileGame() throws Exception { + exe=TestC.compile(Files.readString(Path.of("docs/examples/TicTacToe.smp")), + "ticTacToeGames",new Ary<>(new String[]{TestC.RELEASE_SYS_DIR}), + TestC.CALL_CONVENTION,null,null,-1); + } + + private static String play(String keys) throws Exception { + Process child=new ProcessBuilder(exe).redirectErrorStream(true).start(); + try { + child.getOutputStream().write(keys.getBytes(StandardCharsets.US_ASCII)); + child.getOutputStream().close(); + assertTrue("Game did not finish",child.waitFor(10,TimeUnit.SECONDS)); + String text=new String(child.getInputStream().readAllBytes(),StandardCharsets.UTF_8); + assertEquals(text,0,child.exitValue()); + return text; + } finally { + child.destroyForcibly(); + } + } + + private static String board(String squares) { + StringBuilder out=new StringBuilder(); + for(int row=0;row<3;row++) { + if(row>0) out.append("---+---+---\n"); + for(int col=0;col<3;col++) { + if(col>0) out.append('|'); + out.append(' ').append(squares.charAt(row*3+col)).append(' '); + } + out.append('\n'); + } + return out.toString(); + } + + @Test public void testPlayerWin() throws Exception { + String text=play("1879"); + assertTrue(text,text.endsWith(board("X OOO XXX")+"You win!\n")); + assertEquals(3,text.split("CPU plays ",-1).length-1); + } + + @Test public void testCPUWinsEveryLine() throws Exception { + // Three rows, three columns, and both diagonals in complete games. + String[][] games={ + {"4697","OOOXOXX X"}, {"1278","XXOOOOXX "}, {"5234","OXXXX OOO"}, + {"2893","OXXOO OXX"}, {"134","XOXXO O "}, {"5472","OXOXXOX O"}, + {"234","OXXXO O"}, {"124","XXOXO O "} + }; + for(String[] game:games) { + String text=play(game[0]); + assertTrue(game[0]+"\n"+text,text.endsWith(board(game[1])+"CPU wins!\n")); + } + } + + @Test public void testDraw() throws Exception { + String text=play("12768"); + assertTrue(text,text.endsWith(board("XXOOOXXXO")+"It's a draw!\n")); + assertEquals(4,text.split("CPU plays ",-1).length-1); + } + + @Test public void testBusySquaresAndInvalidInputDoNotTakeATurn() throws Exception { + // X takes 5 and O takes 1; neither occupied square can be overwritten. + String text=play("x\r\n551q"); + assertEquals(text,1,text.split("Choose a square",-1).length-1); + assertEquals(text,2,text.split("That square is occupied",-1).length-1); + assertEquals(text,1,text.split("CPU plays ",-1).length-1); + assertTrue(text,text.contains("Your move (1-9): \nChoose a square from 1 to 9: 5\n" + +board(" X "))); + assertTrue(text,text.contains(board("O X "))); + assertTrue(text,text.endsWith("Your move (1-9): " + +"\nThat square is occupied. Your move (1-9): " + +"\nThat square is occupied. Your move (1-9): \nGoodbye!\n")); + } + + @Test public void testCPUBlocksAndEOFQuits() throws Exception { + String text=play("12"); + assertTrue(text,text.contains("CPU plays 3.\n"+board("XXO O "))); + assertTrue(text,text.endsWith("Goodbye!\n")); + } +} |
