197 lines
6.6 KiB
C
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;
|
|
}
|
|
}
|