add pages
This commit is contained in:
@@ -0,0 +1,445 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* -- _____ ______ _____ -
|
||||
* -- |_ _| | ____|/ ____| -
|
||||
* -- | | _ __ | |__ | (___ Institute of Embedded Systems -
|
||||
* -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur -
|
||||
* -- _| |_| | | | |____ ____) | (University of Applied Sciences) -
|
||||
* -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland -
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief Test suite for the given package.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <CUnit/Basic.h>
|
||||
#include "test_utils.h"
|
||||
#include "model.h"
|
||||
|
||||
#ifndef TARGET // must be given by the make file --> see test target
|
||||
#error missing TARGET define
|
||||
#endif
|
||||
|
||||
/// @brief alias for EXIT_SUCCESS
|
||||
#define OK EXIT_SUCCESS
|
||||
/// @brief alias for EXIT_FAILURE
|
||||
#define FAIL EXIT_FAILURE
|
||||
|
||||
/// @brief The name of the STDOUT text file.
|
||||
#define OUTFILE "stdout.txt"
|
||||
/// @brief The name of the STDERR text file.
|
||||
#define ERRFILE "stderr.txt"
|
||||
|
||||
#define TRACE_INDENT "\n " ///< allow for better stdout formatting in case of error
|
||||
|
||||
// setup & cleanup
|
||||
static int setup(void)
|
||||
{
|
||||
remove_file_if_exists(OUTFILE);
|
||||
remove_file_if_exists(ERRFILE);
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
static int teardown(void)
|
||||
{
|
||||
// Do nothing.
|
||||
// Especially: do not remove result files - they are removed in int setup(void) *before* running a test.
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
// test utils
|
||||
static void init_model(model_t *instance, int act)
|
||||
{
|
||||
if (act) printf(TRACE_INDENT "init_model:... ");
|
||||
model_init(instance);
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
if (act) printf("%zd/%zd ", row, col);
|
||||
CU_ASSERT_EQUAL_FATAL(instance->board[row][col], model_state_none);
|
||||
}
|
||||
}
|
||||
if (act) printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
static void print_board(model_state_t board[MODEL_SIZE][MODEL_SIZE])
|
||||
{
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
printf("{ ");
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
printf("%d ", board[row][col]);
|
||||
}
|
||||
printf("} ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// tests
|
||||
static void test_model_init(void)
|
||||
{
|
||||
// check void model_init(model_t *instance);
|
||||
|
||||
// arrange
|
||||
model_t model;
|
||||
// act & assert
|
||||
init_model(&model, 1);
|
||||
}
|
||||
|
||||
static void test_model_get_state(void)
|
||||
{
|
||||
// check: model_state_t model_get_state(model_t *instance, model_pos_t pos);
|
||||
|
||||
{
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "initial state:... ");
|
||||
print_board(model.board);
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
printf("%zd/%zd ", row, col);
|
||||
CU_ASSERT_EQUAL_FATAL(model_get_state(&model, model_pos(row, col)), model_state_none);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_b },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "modified state:... ");
|
||||
print_board(model.board);
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
printf("%zd/%zd ", row, col);
|
||||
CU_ASSERT_EQUAL_FATAL(model_get_state(&model, model_pos(row, col)), board[row][col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
static void test_model_get_winner(void)
|
||||
{
|
||||
// check: model_state_t model_get_winner(model_t *instance);
|
||||
|
||||
{
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "initial no winner:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_get_winner(&model), model_state_none);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_b },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "winner:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_get_winner(&model), model_state_b);
|
||||
}
|
||||
printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
static void test_model_can_move(void)
|
||||
{
|
||||
// check: int model_can_move(model_t *instance);
|
||||
|
||||
{
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "initial can move:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 1);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_b },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "can move while not yet done nor win:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 1);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_b },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "cannot move after win:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_b },
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "cannot move when all done:... ");
|
||||
print_board(model.board);
|
||||
CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0);
|
||||
}
|
||||
printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
static void test_model_move(void)
|
||||
{
|
||||
// check: int model_move(model_t *instance, model_pos_t pos, model_state_t state);
|
||||
|
||||
{
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "initial move:... ");
|
||||
print_board(model.board);
|
||||
model_pos_t pos_a = model_pos(0, 0);
|
||||
printf("%zd/%zd ", pos_a.row, pos_a.col);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_a), 1);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_a), 0);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_a, model_state_b), 0);
|
||||
model_pos_t pos_b = model_pos(2, 2);
|
||||
printf("%zd/%zd ", pos_b.row, pos_b.col);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_b), 1);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_b), 0);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos_b, model_state_a), 0);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_b },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "can move while not yet done nor win:... ");
|
||||
print_board(model.board);
|
||||
model_pos_t pos = model_pos(2, 1);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 1);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_b },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "cannot move after win:... ");
|
||||
print_board(model.board);
|
||||
model_pos_t pos = model_pos(2, 1);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_b },
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "cannot move when all done:... ");
|
||||
print_board(model.board);
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
model_pos_t pos = model_pos(row, col);
|
||||
printf("%zd/%zd ", row, col);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_a), 0);
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, pos, model_state_b), 0);
|
||||
}
|
||||
}
|
||||
CU_ASSERT_EQUAL_FATAL(model_can_move(&model), 0);
|
||||
}
|
||||
printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
static void test_model_get_win_line(void)
|
||||
{
|
||||
// check: model_line_t model_get_win_line(model_t *instance);
|
||||
|
||||
{
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "initial no winner:... ");
|
||||
print_board(model.board);
|
||||
model_line_t no_win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_none, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_none },
|
||||
{ model_state_b, model_state_none, model_state_b },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "no winner while not yet done nor win:... ");
|
||||
print_board(model.board);
|
||||
model_line_t no_win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none);
|
||||
}
|
||||
{
|
||||
// arrange
|
||||
static const model_state_t board[MODEL_SIZE][MODEL_SIZE] = {
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
{ model_state_a, model_state_b, model_state_b },
|
||||
{ model_state_b, model_state_a, model_state_a },
|
||||
};
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
memcpy(model.board, board, sizeof(board));
|
||||
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "no winner when all done:... ");
|
||||
print_board(model.board);
|
||||
model_line_t no_win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(no_win.dir, model_dir_none);
|
||||
}
|
||||
{
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(row, col), model_state_a), 1);
|
||||
}
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "row winner:... ");
|
||||
print_board(model.board);
|
||||
model_line_t win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_h);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.row, row);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.col, 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
for(size_t col = 0; col < MODEL_SIZE; col++) {
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
for(size_t row = 0; row < MODEL_SIZE; row++) {
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(row, col), model_state_a), 1);
|
||||
}
|
||||
// act & assert
|
||||
printf(TRACE_INDENT "column winner:... ");
|
||||
print_board(model.board);
|
||||
model_line_t win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_v);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.row, 0);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.col, col);
|
||||
}
|
||||
}
|
||||
{
|
||||
printf(TRACE_INDENT "diagonal left-right winner:... ");
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
for(size_t i = 0; i < MODEL_SIZE; i++) {
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(i, i), model_state_a), 1);
|
||||
}
|
||||
// act & assert
|
||||
print_board(model.board);
|
||||
model_line_t win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_d);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.row, 0);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.col, 0);
|
||||
}
|
||||
{
|
||||
printf(TRACE_INDENT "diagonal right-left winner:... ");
|
||||
// arrange
|
||||
model_t model;
|
||||
init_model(&model, 0);
|
||||
for(size_t i = 0; i < MODEL_SIZE; i++) {
|
||||
CU_ASSERT_EQUAL_FATAL(model_move(&model, model_pos(MODEL_SIZE - 1 - i, i), model_state_a), 1);
|
||||
}
|
||||
// act & assert
|
||||
print_board(model.board);
|
||||
model_line_t win = model_get_win_line(&model);
|
||||
CU_ASSERT_EQUAL_FATAL(win.dir, model_dir_d);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.row, 0);
|
||||
CU_ASSERT_EQUAL_FATAL(win.start.col, MODEL_SIZE - 1);
|
||||
}
|
||||
printf(TRACE_INDENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers and runs the tests.
|
||||
* @returns success (0) or one of the CU_ErrorCode (>0)
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
// setup, run, teardown
|
||||
TestMainBasic("lab test", setup, teardown
|
||||
, test_model_init
|
||||
, test_model_get_state
|
||||
, test_model_get_winner
|
||||
, test_model_can_move
|
||||
, test_model_move
|
||||
, test_model_get_win_line
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user