You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
12 KiB

package de.tims.tictactoe;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Component;
import java.util.stream.Stream;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestInstance(Lifecycle.PER_CLASS)
class GameLogicTest {
private final int SIZE = 3;
private GameLogic game;
@BeforeAll
void setUpBeforeClass() throws Exception {
this.game = new GameLogic(SIZE);
}
@Test
void createGameLogicTest() {
GameLogic expectedResult = this.game;
GameLogic realResult = new GameLogic(SIZE);
assertEquals(expectedResult.getClass(), realResult.getClass());
}
@Test
void getBoardTest() {
// @formatter:off
char[][] expectedResult = new char[][]{{'-', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}};
// @formatter:on
char[][] realResult = this.game.getBoard();
assertArrayEquals(expectedResult, realResult);
}
@Test
void createGameLogicWithGivenBoardTest() {
// @formatter:off
char[][] expectedResult = new char[][]{{'x', '-', '-'},
{'-', 'o', '-'},
{'x', '-', '-'}};
// @formatter:on
char[][] givenBoard = expectedResult;
char[][] realResult = new GameLogic(givenBoard).getBoard();
assertArrayEquals(expectedResult, realResult);
}
@Test
void generateGUITest() {
JPanel expectedResult = new JPanel();
JPanel realResult = this.game.generateGUI();
assertEquals(expectedResult.getClass(), realResult.getClass());
}
@Test
void numberOfGUIFieldsTest() {
int expectedResult = (int) Math.pow(SIZE, 2);
int realResult = 0;
JPanel gui = this.game.generateGUI();
Component[] components = gui.getComponents();
for (Component component : components) {
if (component instanceof JButton)
realResult++;
}
assertEquals(expectedResult, realResult);
}
@Test
void getCurrentPlayerTest() {
GameLogic game = new GameLogic(SIZE);
char expectedResult = 'x';
char realResult = game.getCurrentPlayer();
assertEquals(expectedResult, realResult);
}
@Test
void switchPlayerTest() {
GameLogic game = new GameLogic(SIZE);
game.switchPlayer();
char expectedResult = 'o';
char realResult = game.getCurrentPlayer();
assertEquals(expectedResult, realResult);
}
@Test
void resetBoardTest() {
GameLogic game = new GameLogic(SIZE);
game.setField(1, 2, 'x');
// @formatter:off
char[][] expectedResult = new char[][]{{'-', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}};
// @formatter:on
game.resetBoard();
char[][] realResult = game.getBoard();
assertArrayEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0} -> {2} fields")
@MethodSource("testCasesForCountPlayfields")
void fieldCountTest(String testName, int size, int expectedResult) {
GameLogic game = new GameLogic(size);
int realResult = game.countFields();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForSetField")
void setFieldTest(String testName, int column, int row, char player, char[][] expectedResult) {
this.game.setField(column, row, player);
char[][] realResult = this.game.getBoard();
assertArrayEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("testCasesForCheckEmptyField")
void fieldIsEmptyTest(String testName, int columnToCheck, int rowToCheck, boolean expectedResult, char[][] board) {
GameLogic game = new GameLogic(board);
boolean realResult = game.fieldIsEmpty(columnToCheck, rowToCheck);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {2}")
@MethodSource("testCasesForCheckForWin")
void checkForWinTest(String testName, char player, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkForWin(player);
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckEndOfGame")
void checkEndOfGameTest(String testName, boolean expectedResult, char[][] boardToCheck) {
boolean realResult = new GameLogic(boardToCheck).checkEndOfGame();
assertEquals(expectedResult, realResult);
}
@ParameterizedTest(name = "[{index}] {0}: should be {1}")
@MethodSource("testCasesForCheckButtonState")
void buttonStateTest(String testName, boolean expectedResult, boolean doClick, int column, int row) throws InterruptedException {
GameLogic game = new GameLogic(SIZE);
game.generateGUI();
JButton currentField = game.getGUIField(0, 0);
if (doClick)
currentField.doClick();
boolean realResult = !currentField.getText().isEmpty();
assertEquals(expectedResult, realResult);
}
// @formatter:off
private static Stream<Arguments> testCasesForCountPlayfields() {
return Stream.of(Arguments.of("1x1 board with too few fields", 1, 9),
Arguments.of("2x2 board with too few fields", 2, 9),
Arguments.of("3x3 board with 9 playfields", 3, 9),
Arguments.of("4x4 board with 16 playfields", 4, 16),
Arguments.of("5x5 board with 25 playfields", 5, 25));
}
private static Stream<Arguments> testCasesForSetField() {
return Stream.of(
Arguments.of("set field [0][0] for player 1", 0, 0, 'x', new char[][]
{{'x', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("set field [1][0] for player 2", 1, 0, 'o', new char[][]
{{'x', '-', '-'},
{'o', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("try to set occupied field [1][0] for player 1", 1, 0, 'x', new char[][]
{{'x', '-', '-'},
{'o', '-', '-'},
{'-', '-', '-'}})
);
}
private static Stream<Arguments> testCasesForCheckEmptyField() {
return Stream.of(
Arguments.of("check an empty field", 0, 0, true, new char[][]
{{'-', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("check a field set by player 1", 0, 0, false, new char[][]
{{'x', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("check a field set by player 2", 0, 0, false, new char[][]
{{'o', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}})
);
}
private static Stream<Arguments> testCasesForCheckForWin() {
return Stream.of(
Arguments.of("check win in column 0 for player 1", 'x', true, new char[][]
{{'x', '-', '-'},
{'x', '-', '-'},
{'x', '-', '-'}}),
Arguments.of("check win in column 1 for player 1", 'x', true, new char[][]
{{'-', 'x', '-'},
{'-', 'x', '-'},
{'-', 'x', '-'}}),
Arguments.of("check win in column 2 for player 1", 'x', true, new char[][]
{{'-', '-', 'x'},
{'-', '-', 'x'},
{'-', '-', 'x'}}),
Arguments.of("check win in column 0 for player 2", 'o', true, new char[][]
{{'o', '-', '-'},
{'o', '-', '-'},
{'o', '-', '-'}}),
Arguments.of("check win in row 0 for player 1", 'x', true, new char[][]
{{'x', 'x', 'x'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("check win in row 0 for player 2", 'o', true, new char[][]
{{'o', 'o', 'o'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("check win in row 1 for player 2", 'o', true, new char[][]
{{'-', '-', '-'},
{'o', 'o', 'o'},
{'-', '-', '-'}}),
Arguments.of("check win in row 2 for player 2", 'o', true, new char[][]
{{'-', '-', '-'},
{'-', '-', '-'},
{'o', 'o', 'o'}}),
Arguments.of("check win in column 0 for player 1 with full board", 'x', true, new char[][]
{{'x', 'o', 'o'},
{'x', 'o', 'x'},
{'x', 'x', 'o'}}),
Arguments.of("check win in column 1 for player 2 with full board", 'o', true, new char[][]
{{'x', 'o', 'o'},
{'x', 'o', 'x'},
{'o', 'o', 'x'}}),
Arguments.of("check win in column 2 for player 2 with full board", 'o', true, new char[][]
{{'x', 'o', 'o'},
{'x', 'x', 'o'},
{'o', 'o', 'o'}}),
Arguments.of("check win in row 0 for player 1 with full board", 'x', true, new char[][]
{{'x', 'x', 'x'},
{'x', 'o', 'o'},
{'o', 'o', 'x'}}),
Arguments.of("check win in row 1 for player 1 with full board", 'x', true, new char[][]
{{'x', 'x', 'o'},
{'x', 'x', 'x'},
{'o', 'o', 'x'}}),
Arguments.of("check win in row 2 for player 2 with full board", 'o', true, new char[][]
{{'x', 'x', 'o'},
{'o', 'x', 'x'},
{'o', 'o', 'o'}}),
Arguments.of("check win in column 0 for player 2", 'o', false, new char[][]
{{'o', '-', '-'},
{'o', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("check a draw for player 2", 'o', false, new char[][]
{{'o', 'o', 'x'},
{'o', 'x', 'x'},
{'x', 'x', 'o'}}),
Arguments.of("check a draw for player 1", 'x', false, new char[][]
{{'o', 'o', 'x'},
{'o', 'o', 'x'},
{'x', 'x', 'o'}}),
Arguments.of("check diagonal left win for player 1", 'x', true, new char[][]
{{'x', 'o', 'x'},
{'x', 'x', 'o'},
{'o', 'o', 'x'}}),
Arguments.of("check diagonal right win for player 2", 'o', true, new char[][]
{{'x', 'x', 'o'},
{'x', 'o', 'o'},
{'o', 'x', 'x'}})
);
}
private static Stream<Arguments> testCasesForCheckEndOfGame() {
return Stream.of(
Arguments.of("check empty board", false, new char[][]
{{'-', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}}),
Arguments.of("end of game with win for player 1", true, new char[][]
{{'x', 'o', 'x'},
{'x', 'x', 'o'},
{'x', 'o', 'o'}}),
Arguments.of("end of game with win for player 2", true, new char[][]
{{'x', 'x', 'o'},
{'o', 'o', 'o'},
{'x', 'o', 'x'}}),
Arguments.of("check tied game", true, new char[][]
{{'x', 'x', 'o'},
{'o', 'x', 'o'},
{'x', 'o', 'x'}}),
Arguments.of("check not yet finished game", false, new char[][]
{{'x', 'x', '-'},
{'o', 'o', '-'},
{'x', 'o', 'x'}})
);
}
private static Stream<Arguments> testCasesForCheckButtonState() {
return Stream.of(
Arguments.of("trigger gui field [0][0]", true, true, 0, 0),
Arguments.of("dont't trigger gui field [1][1]", false, false, 1, 1)
);
}
// @formatter:on
}