Info2-Pr-Doble-Spiel/test_stack.c
2025-12-02 17:42:33 +01:00

197 lines
6.6 KiB
C

#include <stdio.h> // Für printf
#include <stdlib.h> // Für malloc, free
#include "stack.h" // Für die Stack-Funktionen und -Strukturen
// Globale Zähler für die Testergebnisse
int test_count = 0;
int test_failed = 0;
// Hilfsfunktion für Assertionen
void assert_equals_int(int expected, int actual, const char *test_name) {
test_count++;
if (expected == actual) {
printf(" [PASS] %s\n", test_name);
} else {
printf(" [FAIL] %s - Erwartet: %d, Tatsächlich: %d\n", test_name, expected, actual);
test_failed++;
}
}
void assert_equals_ptr(void *expected, void *actual, const char *test_name) {
test_count++;
if (expected == actual) {
printf(" [PASS] %s\n", test_name);
} else {
printf(" [FAIL] %s - Erwartet: %p, Tatsächlich: %p\n", test_name, expected, actual);
test_failed++;
}
}
// Hilfsfunktion zum Freigeben der Daten im Stack, bevor der Stack selbst geleert wird
void free_stack_data(StackNode *stack) {
StackNode *current = stack;
while (current != NULL) {
if (current->data != NULL) {
free(current->data); // Freigabe der Integer-Daten
current->data = NULL; // Optional: Pointer auf NULL setzen
}
current = current->next;
}
}
// --- Testfälle ---
void test_push_single_element() {
printf("--- Test: push_single_element ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 10;
stack = push(stack, data1);
assert_equals_ptr(data1, stack->data, "Top should be 10");
assert_equals_ptr(NULL, stack->next, "Next element should be NULL");
// Aufräumen
free_stack_data(stack); // Daten freigeben
clearStack(stack); // StackNodes freigeben
}
void test_push_multiple_elements() {
printf("--- Test: push_multiple_elements ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 10;
int *data2 = (int *)malloc(sizeof(int)); *data2 = 20;
int *data3 = (int *)malloc(sizeof(int)); *data3 = 30;
stack = push(stack, data1); // Stack: [10]
stack = push(stack, data2); // Stack: [20, 10]
stack = push(stack, data3); // Stack: [30, 20, 10]
assert_equals_int(30, *(int*)stack->data, "Top should be 30");
assert_equals_int(20, *(int*)stack->next->data, "Second element should be 20");
assert_equals_int(10, *(int*)stack->next->next->data, "Third element should be 10");
assert_equals_ptr(NULL, stack->next->next->next, "Fourth element should be NULL");
// Aufräumen
free_stack_data(stack);
clearStack(stack);
}
void test_pop_from_empty_stack() {
printf("--- Test: pop_from_empty_stack ---\n");
StackNode *stack = NULL;
StackNode *result = pop(stack);
assert_equals_ptr(NULL, result, "Pop from empty stack should return NULL");
assert_equals_ptr(NULL, stack, "Stack should remain NULL"); // stack pointer passed by value, so it's still NULL
}
void test_pop_single_element() {
printf("--- Test: pop_single_element ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 10;
stack = push(stack, data1); // Stack: [10]
assert_equals_int(10, *(int*)stack->data, "Top should be 10 before pop");
// Daten freigeben, bevor der Knoten freigegeben wird
free(top(stack)); // Freigabe von data1
stack = pop(stack); // Stack: []
assert_equals_ptr(NULL, stack, "Stack should be empty after popping last element");
assert_equals_ptr(NULL, stack->data, "Top should be NULL after popping last element");
}
void test_pop_multiple_elements() {
printf("--- Test: pop_multiple_elements ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 10;
int *data2 = (int *)malloc(sizeof(int)); *data2 = 20;
int *data3 = (int *)malloc(sizeof(int)); *data3 = 30;
stack = push(stack, data1);
stack = push(stack, data2);
stack = push(stack, data3); // Stack: [30, 20, 10]
// Pop 1 (30)
free(top(stack)); // Freigabe von data3
stack = pop(stack); // Stack: [20, 10]
assert_equals_int(20, *(int*)top(stack), "Top should be 20 after first pop");
// Pop 2 (20)
free(top(stack)); // Freigabe von data2
stack = pop(stack); // Stack: [10]
assert_equals_int(10, *(int*)top(stack), "Top should be 10 after second pop");
// Pop 3 (10)
free(top(stack)); // Freigabe von data1
stack = pop(stack); // Stack: []
assert_equals_ptr(NULL, stack, "Stack should be empty after third pop");
assert_equals_ptr(NULL, top(stack), "Top should be NULL after third pop");
}
void test_top_function() {
printf("--- Test: top_function ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 100;
int *data2 = (int *)malloc(sizeof(int)); *data2 = 200;
assert_equals_ptr(NULL, top(stack), "Top of empty stack should be NULL");
stack = push(stack, data1);
assert_equals_int(100, *(int*)top(stack), "Top should be 100");
stack = push(stack, data2);
assert_equals_int(200, *(int*)top(stack), "Top should be 200");
// Aufräumen
free_stack_data(stack);
clearStack(stack);
}
void test_clear_stack_function() {
printf("--- Test: clear_stack_function ---\n");
StackNode *stack = NULL;
int *data1 = (int *)malloc(sizeof(int)); *data1 = 1;
int *data2 = (int *)malloc(sizeof(int)); *data2 = 2;
int *data3 = (int *)malloc(sizeof(int)); *data3 = 3;
stack = push(stack, data1);
stack = push(stack, data2);
stack = push(stack, data3); // Stack: [3, 2, 1]
// Zuerst die Daten freigeben
free_stack_data(stack);
// Dann die StackNodes freigeben
clearStack(stack);
// WICHTIG: Der lokale 'stack'-Zeiger muss manuell auf NULL gesetzt werden,
// da clearStack ihn nicht ändern kann (pass-by-value).
stack = NULL;
assert_equals_ptr(NULL, stack, "Stack should be NULL after clearStack");
assert_equals_ptr(NULL, top(stack), "Top of cleared stack should be NULL");
}
int main() {
printf("Starte Stack Unit-Tests...\n");
test_push_single_element();
test_push_multiple_elements();
test_pop_from_empty_stack();
test_pop_single_element();
test_pop_multiple_elements();
test_top_function();
test_clear_stack_function();
printf("\n--- Testergebnisse ---\n");
printf("Gesamtzahl der Tests: %d\n", test_count);
printf("Fehlgeschlagene Tests: %d\n", test_failed);
if (test_failed == 0) {
printf("Alle Tests erfolgreich bestanden! 🎉\n");
return EXIT_SUCCESS;
} else {
printf("Einige Tests sind fehlgeschlagen. 😟\n");
return EXIT_FAILURE;
}
}