276 lines
7.0 KiB
C
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;
|
|
}
|
|
} |