From 099a5c5cc56205d18c351dd833accb54c0eaa697 Mon Sep 17 00:00:00 2001 From: Basti Date: Tue, 16 Dec 2025 02:29:34 +0100 Subject: [PATCH] BinTree fertig gemacht inclusive unity tests --- bintree.c | 72 ++++++++++++++++++++++++++++- bintreeTests.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 27 +++++++---- stackTests.c | 104 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 bintreeTests.c diff --git a/bintree.c b/bintree.c index 5cf82a9..ffbd4bf 100644 --- a/bintree.c +++ b/bintree.c @@ -12,7 +12,36 @@ // if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate) { + if(root == NULL) + { + TreeNode *newNode = malloc(sizeof(TreeNode)); + newNode->data = malloc(dataSize); + memcpy(newNode->data, data, dataSize); + newNode->left = NULL; + newNode->right = NULL; + if(isDuplicate != NULL) + *isDuplicate = 0; + + return newNode; + } + else + { + int cmpResult = compareFct(data, root->data); + + if(cmpResult < 0) + root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); + else if(cmpResult > 0) + root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); + else + { + // Duplicate found + if(isDuplicate != NULL) + *isDuplicate = 1; + } + + return root; + } } // Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction. @@ -20,17 +49,56 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc // push the top node and push all its left nodes. void *nextTreeData(TreeNode *root) { + static StackNode *stack = NULL; + if (root != NULL) + { + clearStack(stack); + stack = NULL; + + TreeNode *current = root; + while (current != NULL) + { + stack = push(stack, current); + current = current->left; + } + } + + if (stack == NULL) + return NULL; + + TreeNode *node = (TreeNode *)top(stack); + stack = pop(stack); + + void *data = node->data; + + TreeNode *current = node->right; + while (current != NULL) + { + stack = push(stack, current); + current = current->left; + } + + return data; } + // Releases all memory resources (including data copies). void clearTree(TreeNode *root) { - + if(root != NULL) + { + clearTree(root->left); + clearTree(root->right); + free(root->data); + free(root); + } } // Returns the number of entries in the tree given by root. unsigned int treeSize(const TreeNode *root) { - + if(root == NULL) + return 0; + return 1 + treeSize(root->left) + treeSize(root->right); } \ No newline at end of file diff --git a/bintreeTests.c b/bintreeTests.c new file mode 100644 index 0000000..b31c807 --- /dev/null +++ b/bintreeTests.c @@ -0,0 +1,122 @@ +#include +#include +#include "unity.h" +#include "bintree.h" + +/* ---------- Helper ---------- */ + +int compareInt(const void *a, const void *b) +{ + int ia = *(const int *)a; + int ib = *(const int *)b; + return ia - ib; +} + +void setUp(void){} +void tearDown(void){} + +/* ---------- addToTree ---------- */ + +void test_addToTree_adds_first_element(void) +{ + TreeNode *root = NULL; + int value = 5; + int isDup = -1; + + root = addToTree(root, &value, sizeof(int), compareInt, &isDup); + + TEST_ASSERT_NOT_NULL(root); + TEST_ASSERT_EQUAL_INT(0, isDup); + TEST_ASSERT_EQUAL_INT(1, treeSize(root)); + + clearTree(root); +} + +void test_addToTree_detects_duplicate(void) +{ + TreeNode *root = NULL; + int value = 5; + int isDup = -1; + + root = addToTree(root, &value, sizeof(int), compareInt, &isDup); + root = addToTree(root, &value, sizeof(int), compareInt, &isDup); + + TEST_ASSERT_EQUAL_INT(1, isDup); + TEST_ASSERT_EQUAL_INT(1, treeSize(root)); + + clearTree(root); +} + +/* ---------- treeSize ---------- */ + +void test_treeSize_counts_multiple_elements(void) +{ + TreeNode *root = NULL; + int values[] = {5, 2, 8, 1, 3}; + + for (int i = 0; i < 5; i++) + root = addToTree(root, &values[i], sizeof(int), compareInt, NULL); + + TEST_ASSERT_EQUAL_UINT(5, treeSize(root)); + + clearTree(root); +} + +/* ---------- nextTreeData ---------- */ + +void test_nextTreeData_returns_sorted_order(void) +{ + TreeNode *root = NULL; + int values[] = {5, 2, 8, 1, 3}; + + for (int i = 0; i < 5; i++) + root = addToTree(root, &values[i], sizeof(int), compareInt, NULL); + + int expected[] = {1, 2, 3, 5, 8}; + + int *val; + + /* erster Aufruf initialisiert den Iterator */ + val = (int *)nextTreeData(root); + TEST_ASSERT_NOT_NULL(val); + TEST_ASSERT_EQUAL_INT(expected[0], *val); + + /* weitere Aufrufe liefern die nächsten Elemente */ + for (int i = 1; i < 5; i++) + { + val = (int *)nextTreeData(NULL); + TEST_ASSERT_NOT_NULL(val); + TEST_ASSERT_EQUAL_INT(expected[i], *val); + } + + /* danach muss NULL kommen */ + TEST_ASSERT_NULL(nextTreeData(NULL)); + + clearTree(root); +} + +/* ---------- clearTree ---------- */ + +void test_clearTree_on_empty_tree_does_not_crash(void) +{ + clearTree(NULL); + TEST_PASS(); +} + +/* ---------- MAIN ---------- */ + +int main(void) +{ + UNITY_BEGIN(); + + RUN_TEST(test_addToTree_adds_first_element); + RUN_TEST(test_addToTree_detects_duplicate); + + RUN_TEST(test_treeSize_counts_multiple_elements); + + RUN_TEST(test_nextTreeData_returns_sorted_order); + + RUN_TEST(test_clearTree_on_empty_tree_does_not_crash); + + return UNITY_END(); +} \ No newline at end of file diff --git a/makefile b/makefile index 0b03bab..69f012c 100644 --- a/makefile +++ b/makefile @@ -29,21 +29,30 @@ program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o doble : main.o $(program_obj_files) $(CC) $(FLAGS) $^ -o doble -$(program_obj_filesobj_files): %.o: %.c - $(CC) -c $(FLAGS) $^ -o $@ - -numbers.o: numbers.c - $(CC) -c $(CFLAGS) numbers.c +# -------------------------- +# Objektdateien kompilieren +# -------------------------- +%.o: %.c + $(CC) -c $(FLAGS) $< -o $@ # -------------------------- # Unit Tests # -------------------------- numbersTests: numbers.o numbersTests.c $(unityfolder)/unity.c - $(CC) $(CFLAGS) -I$(unityfolder) -o runNumbersTests numbersTests.c numbers.o $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) \ + -o runNumbersTests \ + numbersTests.c numbers.o $(unityfolder)/unity.c stackTests: stack.o stackTests.c $(unityfolder)/unity.c - $(CC) $(CFLAGS) -I$(unityfolder) -o runStackTests stackTests.c stack.o $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) \ + -o runStackTests \ + stackTests.c stack.o $(unityfolder)/unity.c + +bintreeTests: bintree.o stack.o bintreeTests.c $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) \ + -o runBintreeTests \ + bintreeTests.c bintree.o stack.o $(unityfolder)/unity.c # -------------------------- # Clean @@ -52,5 +61,5 @@ clean: ifeq ($(OS),!Windows_NT) del /f *.o doble *.exe else - rm -f *.o doble *runNumbersTests -endif \ No newline at end of file + rm -f *.o doble run*Tests* +endif diff --git a/stackTests.c b/stackTests.c index a70ff14..59cec50 100644 --- a/stackTests.c +++ b/stackTests.c @@ -1,4 +1,4 @@ -#include +/*#include #include #include "stack.h" #include "unity.h" @@ -24,5 +24,107 @@ int main(void) UNITY_BEGIN(); RUN_TEST(test_push_created_new_stacknode); + return UNITY_END(); +}*/ +#include +#include +#include "stack.h" +#include "unity.h" + +void setUp(void){} +void tearDown(void){} + +/* ---------------- PUSH ---------------- */ + +void test_push_created_new_stacknode(void) +{ + int testdata1 = 111; + StackNode test = {&testdata1,NULL}; + int testdata2 = 222; + + StackNode *test1 = push(&test,&testdata2); + TEST_ASSERT_NOT_NULL(test1); + TEST_ASSERT_EQUAL_PTR(&testdata2,test1->data); + TEST_ASSERT_EQUAL_PTR(&test,test1->next); +} + +/* ---------------- TOP ---------------- */ + +void test_top_on_empty_stack_returns_null(void) +{ + TEST_ASSERT_NULL(top(NULL)); +} + +void test_top_returns_top_element(void) +{ + int data = 42; + StackNode node = {&data, NULL}; + + TEST_ASSERT_EQUAL_PTR(&data, top(&node)); +} + +/* ---------------- POP ---------------- */ + +void test_pop_on_empty_stack_returns_null(void) +{ + TEST_ASSERT_NULL(pop(NULL)); +} + +void test_pop_removes_top_element(void) +{ + int d1 = 1; + int d2 = 2; + + StackNode *s = NULL; + s = push(s, &d1); + s = push(s, &d2); + + StackNode *newTop = pop(s); + + TEST_ASSERT_NOT_NULL(newTop); + TEST_ASSERT_EQUAL_PTR(&d1, newTop->data); + + clearStack(newTop); // Speicher aufräumen +} + +/* ---------------- CLEAR ---------------- */ + +void test_clearStack_on_empty_stack_does_not_crash(void) +{ + clearStack(NULL); + TEST_PASS(); // Test besteht, wenn kein Crash +} + +void test_clearStack_clears_multiple_elements(void) +{ + int d1 = 1, d2 = 2, d3 = 3; + + StackNode *s = NULL; + s = push(s, &d1); + s = push(s, &d2); + s = push(s, &d3); + + clearStack(s); + + TEST_PASS(); // kein Crash = bestanden +} + +/* ---------------- MAIN ---------------- */ + +int main(void) +{ + UNITY_BEGIN(); + + RUN_TEST(test_push_created_new_stacknode); + + RUN_TEST(test_top_on_empty_stack_returns_null); + RUN_TEST(test_top_returns_top_element); + + RUN_TEST(test_pop_on_empty_stack_returns_null); + RUN_TEST(test_pop_removes_top_element); + + RUN_TEST(test_clearStack_on_empty_stack_does_not_crash); + RUN_TEST(test_clearStack_clears_multiple_elements); + return UNITY_END(); } \ No newline at end of file