diff --git a/I2_Dobble/makefile b/I2_Dobble/makefile index f2acc1f..b60440c 100644 --- a/I2_Dobble/makefile +++ b/I2_Dobble/makefile @@ -36,11 +36,15 @@ $(program_obj_filesobj_files): %.o: %.c # -------------------------- # Unit Tests # -------------------------- -unitTests: numbersTest +unitTests: numbersTest stackTest ./runNumbersTest + ./runStackTest -numbersTest: numbers.o bintree.o numbersTest.o $($(unityfolder)/unity.c) - $(CC) $(FLAGS) $(LDFLAGS) $^ -o $@ +numbersTest: numbers.o bintree.o numbersTest.o $(unityfolder)/unity.c + $(CC) $(FLAGS) $(LDFLAGS) $^ -o runNumbersTest + +stackTest: stack.o stackTest.o $(unityfolder)/unity.c + $(CC) $(FLAGS) $(LDFLAGS) $^ -o runStackTest %.o: %.c $(CC) -c $(FLAGS) $< -o $@ @@ -50,7 +54,7 @@ numbersTest: numbers.o bintree.o numbersTest.o $($(unityfolder)/unity.c) # -------------------------- clean: ifeq ($(OS),Windows_NT) - del /f *.o doble runNumbersTest + del /f *.o doble runNumbersTest runStackTest else - rm -f *.o doble runNumbersTest + rm -f *.o doble runNumbersTest runStackTest endif \ No newline at end of file diff --git a/I2_Dobble/stack.c b/I2_Dobble/stack.c index e3a90d4..2bc5825 100644 --- a/I2_Dobble/stack.c +++ b/I2_Dobble/stack.c @@ -1,7 +1,7 @@ #include #include "stack.h" -//TODO: grundlegende Stackfunktionen implementieren: +//DONE: grundlegende Stackfunktionen implementieren: /* * `push`: legt ein Element oben auf den Stack, * `pop`: entfernt das oberste Element, * `top`: liefert das oberste Element zurück, @@ -10,24 +10,52 @@ // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data) { - + // ,-→ Wenn keine Daten angegeben wird die Liste unverändert zurückgegeben + if (data != NULL) + { + StackNode *newNode; + newNode = (StackNode *)malloc(sizeof(StackNode)); + newNode->data = data; + + // ,-→ bedeutet Liste war leer - das neue Element hat keinen Nachfolger (next = NULL) + if (stack == NULL) { + newNode->next = NULL; + } else { + newNode->next = stack; + } + stack = newNode; + } + + return stack; } -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) +// Deletes the top element of the stack (latest added element) and releases its memory. +// (Pointer to data has to be freed by caller.) StackNode *pop(StackNode *stack) { - + if(stack != NULL) + { + StackNode *nextNode = stack->next; + free(stack); + stack = nextNode; + } + return stack; } // Returns the data of the top element. void *top(StackNode *stack) { - + if (stack != NULL) { + return stack->data; + } else { + return NULL; + } } // Clears stack and releases all memory. void clearStack(StackNode *stack) { - -} \ No newline at end of file + while (stack != NULL) { + stack = pop(stack); + } +} diff --git a/I2_Dobble/stack.h b/I2_Dobble/stack.h index f7d542d..641b400 100644 --- a/I2_Dobble/stack.h +++ b/I2_Dobble/stack.h @@ -7,7 +7,12 @@ The latest element is taken from the stack. */ #include -//TODO: passenden Datentyp als struct anlegen +//DONE: passenden Datentyp als struct anlegen +typedef struct Node +{ + void *data; + struct Node* next; +} StackNode; // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data); diff --git a/I2_Dobble/stackTest.c b/I2_Dobble/stackTest.c new file mode 100644 index 0000000..76173dc --- /dev/null +++ b/I2_Dobble/stackTest.c @@ -0,0 +1,167 @@ +#include "stack.h" +#include "unity/unity.h" +#include "unity/unity_internals.h" + +/* wird nicht mehr gebraucht + +// Ein Blick in den Stack - listet den Stack-Inhalt der Reihe nach auf +void inspectStack(StackNode *stack) +{ + if (stack != NULL) + { + printf("Der Stack enthält die folgenden Elemente: %d", *(int*)stack->data); + while (stack->next != NULL) + { + printf(" %d", *(int*)stack->next->data); + stack = stack->next; + } + putchar('\n'); + } + else + { + printf("Der Stack ist leer\n"); + } +} +*/ + +// Setup-Funktionen von Unity, die zumindest als Platzhalter definiert sein müssen +void setUp(void) {}; +void tearDown(void) {}; + +void test_createNodeAbortsOnZeroData(void) +{ + void *data = NULL; + StackNode *stack = NULL; + stack = push(stack, data); + TEST_ASSERT_EQUAL_PTR(stack, NULL); + + clearStack(stack); +} + +void test_createdNodeIsFirstInList(void) +{ + int data = 42; + StackNode *stack = NULL; + stack = push(stack, &data); + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_PTR(&data, stack->data); + TEST_ASSERT_NULL(stack->next); + + clearStack(stack); +} + +void test_createNodeCorrectOrder(void) +{ + int data[3] = {0, 1, 2}; + StackNode *stack = NULL; + stack = push(stack, &data[2]); + stack = push(stack, &data[1]); + stack = push(stack, &data[0]); + + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_PTR(&data[0], stack->data); + TEST_ASSERT_EQUAL_PTR(&data[1], stack->next->data); + TEST_ASSERT_EQUAL_PTR(&data[2], stack->next->next->data); + TEST_ASSERT_NULL(stack->next->next->next); + + clearStack(stack); +} + +void test_removeNodeAbortsOnZero(void) +{ + StackNode *stack = NULL; + TEST_ASSERT_NULL(pop(stack)); + + clearStack(stack); +} + +void test_removeOnlyNodeEmptysList(void) +{ + int data = 42; + StackNode *stack = NULL; + stack = pop(push(stack, &data)); + + TEST_ASSERT_NULL(stack); + + clearStack(stack); +} + +void test_removeNodeRemovesFirst(void) +{ + int data[2] = {0, 1}; + StackNode *stack = NULL; + stack = push(stack, &data[1]); + stack = push(stack, &data[0]); + stack = pop(stack); + + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_PTR(&data[1], stack->data); + TEST_ASSERT_NULL(stack->next); + + clearStack(stack); +} + +void test_outputTopFailsOnZero(void) +{ + StackNode *stack = NULL; + + TEST_ASSERT_NULL(top(stack)); + + clearStack(stack); +} + +void test_outputTopCorrect(void) +{ + int data[2] = {0, 1}; + StackNode *stack = NULL; + stack = push(stack, &data[1]); + stack = push(stack, &data[0]); + + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_PTR(top(stack), stack->data); + + clearStack(stack); +} + + +/* Speicher freigabe lässt sich nicht mit Unity testen, am besten Programm mit valgrind ausführen +void test_clearStackFreesMemory(void) +{ + int data[2] = {22, 17}; + StackNode *lowNode = (StackNode *)malloc(sizeof(StackNode)); + lowNode->next = NULL; + lowNode->data = &data[0]; + StackNode *highNode = (StackNode *)malloc(sizeof(StackNode)); + highNode->next = lowNode; + highNode->data = &data[1]; + StackNode *stack = highNode; + + clearStack(stack); + + TEST_ASSERT_NULL(lowNode); + TEST_ASSERT_NULL(highNode); + TEST_ASSERT_NULL(stack); +} +*/ + +int main() +{ + UNITY_BEGIN(); + + printf("\n============================\n Stack tests\n============================\n"); + printf("-> Create Nodes (push)\n"); + RUN_TEST(test_createNodeAbortsOnZeroData); + RUN_TEST(test_createdNodeIsFirstInList); + RUN_TEST(test_createNodeCorrectOrder); + + printf("\n-> Remove Nodes (pop)\n"); + RUN_TEST(test_removeNodeAbortsOnZero); + RUN_TEST(test_removeOnlyNodeEmptysList); + RUN_TEST(test_removeNodeRemovesFirst); + + printf("\n-> Output Top (top)\n"); + RUN_TEST(test_outputTopFailsOnZero); + RUN_TEST(test_outputTopCorrect); + + return UNITY_END(); +} \ No newline at end of file diff --git a/I2_Dobble/test_stack.c b/I2_Dobble/test_stack.c new file mode 100644 index 0000000..60fabd8 --- /dev/null +++ b/I2_Dobble/test_stack.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include "stack.h" + +void inspectStack(StackNode *stack) +{ + if (stack != NULL) + { + printf("Der Stack enthält die folgenden Elemente: %d", *(int*)stack->value); + while (stack->next != NULL) + { + printf(" %d", *(int*)stack->next->value); + stack = stack->next; + } + putchar('\n'); + } + else + { + printf("Der Stack ist leer\n"); + } +} + +int main() +{ + StackNode *stack; + stack = NULL; // initialisierung mit NULL -> leere Liste + + printf("...ein Element wird eingefügt...\n"); + int toBeRemoved = 42; + stack = push(stack, &toBeRemoved); + + inspectStack(stack); + + printf("...das Element wird wieder entfernt...\n"); + stack = pop(stack); + + inspectStack(stack); + + printf("...pop auf leeren Stack...\n"); + stack = pop(stack); + + inspectStack(stack); + putchar('\n'); + + int data[5] = {1, 2, 3, 4, 5}; + + // alle 5 werte der reihe nach auf den Satck legen - 1 unten ... 5 oben + for (int i = 0; i < 5; i++) + { + stack = push(stack, &data[i]); + } + + + //alle Elemente mit Test-Funktion ausgeben + inspectStack(stack); + + // Elemente stück für Stück ausgeben und entfernen + printf("1. Element war: %d\n", *(int*)top(stack)); + stack = pop(stack); + printf("2. Element war: %d\n", *(int*)top(stack)); + stack = pop(stack); + printf("3. Element war: %d\n", *(int*)top(stack)); + stack = pop(stack); + printf("4. Element war: %d\n", *(int*)top(stack)); + stack = pop(stack); + printf("5. Element war: %d\n", *(int*)top(stack)); +} + +/* +int main() +{ + UNITY_BEGIN(); + + printf("============================\n Stack tests\n============================\n"); + RUN_TEST(test_createNodeFailsOnZeroData); + + return UNITY_END(); +} +*/