2025-12-12 14:33:45 +01:00

276 lines
7.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "stack.h"
// ANSI Farben für bessere Lesbarkeit
#define GREEN "\033[0;32m"
#define RED "\033[0;31m"
#define RESET "\033[0m"
#define BLUE "\033[0;34m"
int testsPassed = 0;
int testsFailed = 0;
void printTestResult(const char *testName, int passed)
{
if (passed)
{
printf(GREEN "[PASS]" RESET " %s\n", testName);
testsPassed++;
}
else
{
printf(RED "[FAIL]" RESET " %s\n", testName);
testsFailed++;
}
}
// Test 1: Push und Top
void test_push_and_top()
{
printf(BLUE "\n--- Test 1: Push und Top ---" RESET "\n");
StackNode *stack = NULL;
int value1 = 42;
int value2 = 17;
// Erstes Element pushen
stack = push(stack, &value1);
int *topValue = (int *)top(stack);
printTestResult("Push eines Elements", stack != NULL);
printTestResult("Top gibt korrekten Wert zurueck", topValue != NULL && *topValue == 42);
// Zweites Element pushen
stack = push(stack, &value2);
topValue = (int *)top(stack);
printTestResult("Push eines zweiten Elements", stack != NULL);
printTestResult("Top gibt neuesten Wert zurueck (LIFO)", topValue != NULL && *topValue == 17);
// Aufräumen
clearStack(stack);
}
// Test 2: Pop
void test_pop()
{
printf(BLUE "\n--- Test 2: Pop ---" RESET "\n");
StackNode *stack = NULL;
int value1 = 100;
int value2 = 200;
int value3 = 300;
// Drei Elemente pushen
stack = push(stack, &value1);
stack = push(stack, &value2);
stack = push(stack, &value3);
// Erstes Pop
int *topBefore = (int *)top(stack);
stack = pop(stack);
int *topAfter = (int *)top(stack);
printTestResult("Pop entfernt oberstes Element", topBefore != NULL && *topBefore == 300);
printTestResult("Nach Pop ist naechstes Element oben", topAfter != NULL && *topAfter == 200);
// Zweites Pop
stack = pop(stack);
topAfter = (int *)top(stack);
printTestResult("Nach zweitem Pop ist letztes Element oben", topAfter != NULL && *topAfter == 100);
// Letztes Pop
stack = pop(stack);
printTestResult("Nach letztem Pop ist Stack leer", stack == NULL);
// Pop auf leerem Stack
stack = pop(stack);
printTestResult("Pop auf leerem Stack gibt NULL zurueck", stack == NULL);
}
// Test 3: Top auf leerem Stack
void test_top_empty_stack()
{
printf(BLUE "\n--- Test 3: Top auf leerem Stack ---" RESET "\n");
StackNode *stack = NULL;
void *result = top(stack);
printTestResult("Top auf leerem Stack gibt NULL zurueck", result == NULL);
}
// Test 4: ClearStack
void test_clear_stack()
{
printf(BLUE "\n--- Test 4: ClearStack ---" RESET "\n");
StackNode *stack = NULL;
int values[5] = {10, 20, 30, 40, 50};
// Mehrere Elemente pushen
for (int i = 0; i < 5; i++)
{
stack = push(stack, &values[i]);
}
printTestResult("Stack wurde mit 5 Elementen gefuellt", stack != NULL);
// Stack löschen
clearStack(stack);
stack = NULL;
printTestResult("ClearStack wurde ausgefuehrt (manuell pruefen mit valgrind)", 1);
// Neuer Push nach Clear
int newValue = 999;
stack = push(stack, &newValue);
int *topValue = (int *)top(stack);
printTestResult("Nach Clear kann neuer Stack aufgebaut werden", topValue != NULL && *topValue == 999);
clearStack(stack);
}
// Test 5: LIFO-Prinzip mit mehreren Elementen
void test_lifo_principle()
{
printf(BLUE "\n--- Test 5: LIFO-Prinzip ---" RESET "\n");
StackNode *stack = NULL;
int values[10];
// 10 Elemente in aufsteigender Reihenfolge pushen
for (int i = 0; i < 10; i++)
{
values[i] = i;
stack = push(stack, &values[i]);
}
// In umgekehrter Reihenfolge poppen und prüfen
int allCorrect = 1;
for (int i = 9; i >= 0; i--)
{
int *topValue = (int *)top(stack);
if (topValue == NULL || *topValue != i)
{
allCorrect = 0;
break;
}
stack = pop(stack);
}
printTestResult("LIFO-Prinzip: Elemente kommen in umgekehrter Reihenfolge zurueck", allCorrect);
printTestResult("Nach allen Pops ist Stack leer", stack == NULL);
}
// Test 6: Push mit verschiedenen Datentypen
void test_different_data_types()
{
printf(BLUE "\n--- Test 6: Verschiedene Datentypen ---" RESET "\n");
StackNode *stack = NULL;
// Integer
int intVal = 42;
stack = push(stack, &intVal);
// Double
double doubleVal = 3.14159;
stack = push(stack, &doubleVal);
// String
char *stringVal = "Hello Stack!";
stack = push(stack, &stringVal);
// Rückwärts prüfen
char **topString = (char **)top(stack);
stack = pop(stack);
double *topDouble = (double *)top(stack);
stack = pop(stack);
int *topInt = (int *)top(stack);
stack = pop(stack);
int stringCorrect = (topString != NULL && strcmp(*topString, "Hello Stack!") == 0);
int doubleCorrect = (topDouble != NULL && *topDouble > 3.14 && *topDouble < 3.15);
int intCorrect = (topInt != NULL && *topInt == 42);
printTestResult("Stack funktioniert mit String", stringCorrect);
printTestResult("Stack funktioniert mit Double", doubleCorrect);
printTestResult("Stack funktioniert mit Integer", intCorrect);
clearStack(stack);
}
// Test 7: Stress-Test mit vielen Elementen
void test_large_stack()
{
printf(BLUE "\n--- Test 7: Stress-Test (1000 Elemente) ---" RESET "\n");
StackNode *stack = NULL;
int *values = malloc(1000 * sizeof(int));
// 1000 Elemente pushen
for (int i = 0; i < 1000; i++)
{
values[i] = i;
stack = push(stack, &values[i]);
}
// Prüfe Top
int *topValue = (int *)top(stack);
printTestResult("1000 Elemente gepusht, Top ist korrekt", topValue != NULL && *topValue == 999);
// Alle wieder poppen
int count = 0;
while (stack != NULL)
{
stack = pop(stack);
count++;
}
printTestResult("Alle 1000 Elemente erfolgreich gepoppt", count == 1000);
free(values);
}
int main()
{
printf("\n");
printf("+----------------------------------------------+\n");
printf("| STACK UNIT TESTS |\n");
printf("+----------------------------------------------+\n");
test_push_and_top();
test_pop();
test_top_empty_stack();
test_clear_stack();
test_lifo_principle();
test_different_data_types();
test_large_stack();
printf("\n");
printf("+----------------------------------------------+\n");
printf("| TEST ZUSAMMENFASSUNG |\n");
printf("+----------------------------------------------+\n");
printf(GREEN "Tests bestanden: %d" RESET "\n", testsPassed);
printf(RED "Tests fehlgeschlagen: %d" RESET "\n", testsFailed);
printf("Gesamt: %d\n", testsPassed + testsFailed);
if (testsFailed == 0)
{
printf(GREEN "\n==> Alle Tests erfolgreich!\n" RESET);
return EXIT_SUCCESS;
}
else
{
printf(RED "\n==> Einige Tests sind fehlgeschlagen!\n" RESET);
return EXIT_FAILURE;
}
}