generated from freudenreichan/info2Praktikum-DobleSpiel
147 lines
5.0 KiB
C
147 lines
5.0 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <limits.h>
|
|
#include "unity.h"
|
|
#include "stack.h"
|
|
|
|
// =========================================================================
|
|
// HILFSFUNKTIONEN FÜR DIE TESTS
|
|
// =========================================================================
|
|
|
|
/**
|
|
* Erstellt eine Kopie eines Integer-Wertes auf dem Heap.
|
|
* Dies ist notwendig, da der Stack void* Pointer speichert.
|
|
*/
|
|
static int *createIntPointer(int value)
|
|
{
|
|
int *ptr = (int *)malloc(sizeof(int));
|
|
TEST_ASSERT_NOT_NULL(ptr); // Stelle sicher, dass malloc erfolgreich war
|
|
*ptr = value;
|
|
return ptr;
|
|
}
|
|
|
|
/**
|
|
* Räumt den Stack und die darauf gespeicherten Datenpointer auf (spezifisch für Integer-Tests).
|
|
* Im Gegensatz zu clearStack() befreit diese Funktion auch die Daten, da sie im Test hier allokiert wurden.
|
|
*/
|
|
static void clearStackWithData(StackNode *stack)
|
|
{
|
|
while (stack != NULL)
|
|
{
|
|
StackNode *next = stack->next;
|
|
if (stack->data != NULL)
|
|
{
|
|
free(stack->data); // Gib die Daten (Integer-Pointer) frei
|
|
}
|
|
free(stack); // Gib den Knoten selbst frei
|
|
stack = next;
|
|
}
|
|
}
|
|
|
|
// =========================================================================
|
|
// DIE WICHTIGSTEN TESTFÄLLE (REDUZIERT)
|
|
// =========================================================================
|
|
|
|
// Testet ob das oberste Element (top) korrekt das zuletzt hinzugefügte Element (push) ist
|
|
void test_pushAndTop(void)
|
|
{
|
|
StackNode *stack = NULL; // Initialisiert den Stack als leeren Pointer.
|
|
int *data = createIntPointer(42); // Erzeugt Integer-Wert (42) auf dem Heap
|
|
|
|
// 1. Push
|
|
stack = push(stack, data); //Ruft push-Funktion auf; neuer Knoten oben auf den stack
|
|
TEST_ASSERT_NOT_NULL(stack); // Prüfung -> Stack-Pointer darf nach dem Pushen nicht NULL sein (siehe unity.h)
|
|
|
|
// 2. Top
|
|
int *top_data = (int *)top(stack); // Ruft top-Funktion auf; Holt void* Pointer von oben und castet ihn zurück zu int*
|
|
TEST_ASSERT_EQUAL_INT(42, *top_data);// Prüft, ob der Wert an der Spitze tatsächlich 42 ist
|
|
|
|
//clean-up
|
|
stack = pop(stack); // pop-Funktion: Entfernt den obersten Knoten und gibt seinen Speicher frei.
|
|
free(data); // Gibt den Datenpointer (42) frei
|
|
TEST_ASSERT_NULL(stack); // Prüft ob stack jetzt wieder NULL ist
|
|
}
|
|
|
|
// Testet die korrekte LIFO-Reihenfolge mit mehreren Elementen und die Pop-Funktion.
|
|
void test_popMultipleElements(void)
|
|
{
|
|
StackNode *stack = NULL;
|
|
|
|
// Erzeugt drei separate Integer-Werte (1, 2, 3) auf dem Heap
|
|
int *data1 = createIntPointer(1);
|
|
int *data2 = createIntPointer(2);
|
|
int *data3 = createIntPointer(3);
|
|
|
|
// stack befüllen mit push-Funktion
|
|
stack = push(NULL, data1); // Stack: [1] (1 ist unten)
|
|
stack = push(stack, data2); // Stack: [2, 1]
|
|
stack = push(stack, data3); // Stack: [3, 2, 1] (3 ist oben, LIFO).
|
|
|
|
// 1. Pop: Prüfe ob 3 oben liegt
|
|
TEST_ASSERT_EQUAL_INT(3, *(int *)top(stack)); // vergleicht 3 mit top-fkt ausgabe (siehe unity.h)
|
|
free(data3); //Gibt den Heap-Speicher frei
|
|
stack = pop(stack); //Entfernt den Knoten 3; Stack ist jetzt [2, 1]
|
|
|
|
// 2. Pop: Prüfe 2
|
|
TEST_ASSERT_EQUAL_INT(2, *(int *)top(stack)); //vergleicht 2 mit top-fkt ausgabe (siehe unity.h)
|
|
free(data2);
|
|
stack = pop(stack); //Entfernt den Knoten 2; Stack ist jetzt [1]
|
|
|
|
// 3. Pop: Prüfe 1
|
|
TEST_ASSERT_EQUAL_INT(1, *(int *)top(stack)); //vergleicht 1 mit top-fkt ausgabe (siehe unity.h)
|
|
free(data1);
|
|
stack = pop(stack); //Entfernt den Knoten 2; Stack ist jetzt NULL
|
|
|
|
TEST_ASSERT_NULL(stack); //Prüft ob Stack NULL ist
|
|
}
|
|
|
|
// Testet den Grenzfall: Pop auf einem leeren Stack -> soll NULL zurückgeben
|
|
void test_popOnEmptyStack(void)
|
|
{
|
|
StackNode *stack = NULL; //Initialisiert leeren Stack
|
|
|
|
TEST_ASSERT_NULL(pop(stack));// Pop sollte NULL zurückgeben, wenn der Stack leer ist
|
|
}
|
|
|
|
// Testet die Speicherfreigabe
|
|
void test_clearStackFunctionality(void)
|
|
{
|
|
StackNode *stack = NULL;
|
|
|
|
// Allokiere Daten und pushe sie auf den Stack
|
|
stack = push(stack, createIntPointer(10)); //Knoten mit zugehörigem Pointer mit Hilfsfkt
|
|
stack = push(stack, createIntPointer(20));
|
|
stack = push(stack, createIntPointer(30));
|
|
|
|
clearStackWithData(stack); // gibt iterativ alle Daten und Knoten frei
|
|
stack = NULL;
|
|
// Wenn der Test ohne Speicherzugriffsverletzung durchläuft, war clearStack erfolgreich.
|
|
}
|
|
|
|
|
|
// =========================================================================
|
|
// MAIN SETUP / RUNNER
|
|
// =========================================================================
|
|
|
|
void setUp(void) {
|
|
// Wird vor jedem Test aufgerufen
|
|
}
|
|
|
|
void tearDown(void) {
|
|
// Wird nach jedem Test aufgerufen
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
UNITY_BEGIN();
|
|
|
|
printf("\n============================\nStack Module Tests\n============================\n");
|
|
|
|
// Die essentiellen Tests
|
|
RUN_TEST(test_pushAndTop);
|
|
RUN_TEST(test_popMultipleElements);
|
|
RUN_TEST(test_popOnEmptyStack);
|
|
RUN_TEST(test_clearStackFunctionality);
|
|
|
|
return UNITY_END();
|
|
} |