#include #include #include #include #include "unity.h" #include "numbers.h" // Externe Deklaration der Vergleichsfunktion aus numbers.c (für den Test) extern int compareNumbers(const void *arg1, const void *arg2); // ========================================================================= // HILFSFUNKTIONEN // ========================================================================= /** * Zählt in einem Array, wie oft jedes Element vorkommt und stellt sicher, * dass genau ein Element zweimal (Duplikat) und der Rest einmal vorkommt. * Dies ist die vollständige Validierung, die der Test 'test_createNumbersGeneratesCorrectDuplicate' nutzt. * @param numbers Das zu prüfende Array. * @param len Die Länge des Arrays. */ static int validateArrayHasSingleDuplicate(const unsigned int *numbers, unsigned int len) { if (len < 3) return 0; int duplicateCount = 0; int uniqueCount = 0; for (unsigned int i = 0; i < len; i++) { int occurrences = 0; // Zähle, wie oft numbers[i] im gesamten Array vorkommt for (unsigned int j = 0; j < len; j++) { if (numbers[i] == numbers[j]) { occurrences++; } } if (occurrences == 2) { duplicateCount++; } else if (occurrences == 1) { uniqueCount++; } else { // Eine Zahl kommt 0, 3 oder mehr Male vor -> Fehler return 0; } } // Wenn genau ein Duplikat vorhanden ist, dann: // duplicateCount muss 2 sein (da 2 Instanzen der doppelten Zahl gezählt werden) // uniqueCount muss len - 2 sein (alle anderen Zahlen sind eindeutig) if (duplicateCount == 2 && uniqueCount == (int)len - 2) { return 1; // Korrekte Duplikat-Struktur gefunden } // Ansonsten ist die Struktur fehlerhaft. return 0; } // ========================================================================= // TESTFALL GRUPPE 1: createNumbers (KERNFUNKTION) // ========================================================================= // Prüft die wichtigste Anforderung: Korrekte Allokation, Länge, Duplikat-Struktur und Wertebereich. void test_createNumbersCoreFunctionality(void) { const unsigned int len = 10; unsigned int *numbers = createNumbers(len); TEST_ASSERT_NOT_NULL(numbers); // Muss Speicher allokieren // 1. Prüfe, ob genau ein Duplikat vorhanden ist (mit Helper-Funktion) TEST_ASSERT_TRUE(validateArrayHasSingleDuplicate(numbers, len)); // 2. Prüfe, ob die Duplikat-Findung funktioniert (Test der Integration von getDuplicate) unsigned int duplicate = getDuplicate(numbers, len); TEST_ASSERT_TRUE(duplicate != 0); // Muss eine doppelte Zahl finden // 3. Prüfe, ob die Zahlen im erwarteten Bereich [1, 2 * len] liegen const unsigned int max_val = 2 * len; for (unsigned int i = 0; i < len; i++) { TEST_ASSERT_TRUE(numbers[i] >= 1); TEST_ASSERT_TRUE(numbers[i] <= max_val); } // Speicher freigeben free(numbers); } // ========================================================================= // TESTFALL GRUPPE 2: getDuplicate (KERNFUNKTION) // ========================================================================= // Prüft die Duplikaterkennung über qsort auf einem unsortierten Array. void test_getDuplicateFindsDuplicatedNumber(void) { // Testfall: Duplikat in der Mitte eines unsortierten Arrays unsigned int testArray[] = {10, 5, 20, 30, 5}; TEST_ASSERT_EQUAL_UINT(5, getDuplicate(testArray, 5)); } // ========================================================================= // TESTFALL GRUPPE 3: compareNumbers (HILFSFUNKTION FÜR qsort) // ========================================================================= // Prüft die korrekte Funktionalität der Vergleichsfunktion für alle 3 Fälle. void test_compareNumbersCheckAllCases(void) { unsigned int a = 10, b = 5, c = 10; // Fall 1: a > b (muss positiv sein) TEST_ASSERT_TRUE(compareNumbers(&a, &b) > 0); // Fall 2: b < a (muss negativ sein) TEST_ASSERT_TRUE(compareNumbers(&b, &a) < 0); // Fall 3: a = c (muss null sein) TEST_ASSERT_EQUAL_INT(0, compareNumbers(&a, &c)); } // ========================================================================= // MAIN // ========================================================================= void setUp(void) { // Wird vor jedem Test aufgerufen } void tearDown(void) { // Wird nach jedem Test aufgerufen } int main(void) { UNITY_BEGIN(); printf("\n============================\nNumbers Module Tests\n============================\n"); // Die essentiellen Tests RUN_TEST(test_createNumbersCoreFunctionality); RUN_TEST(test_getDuplicateFindsDuplicatedNumber); RUN_TEST(test_compareNumbersCheckAllCases); return UNITY_END(); }