#include #include #include #include "numbers.h" /* * Unit-Tests für createNumbers und getDuplicate: * - createNumbers liefert ein gültiges Array * - alle Zahlen liegen im Bereich [1, 2*len] * - genau eine Zahl kommt doppelt vor * - getDuplicate findet genau diese doppelte Zahl * - Fehlerfälle (NULL-Pointer, zu kleine Länge) */ /* * Prüft ein Zahlenarray auf Korrektheit: * - Array darf nicht NULL sein * - Wertebereich muss stimmen * - genau eine Zahl darf doppelt vorkommen */ static void check_numbers_array(unsigned int *numbers, unsigned int len) { unsigned int maxValue = 2 * len; // Maximal erlaubter Zahlenwert unsigned int *counts; // Array zum Zählen der Vorkommen unsigned int i; unsigned int duplicatesCount = 0; // Zähler für doppelte Werte assert(numbers != NULL); // Sicherstellen, dass das Array existiert // Speicher für Zähler-Array reservieren und mit 0 initialisieren counts = (unsigned int *)calloc(maxValue + 1, sizeof(unsigned int)); assert(counts != NULL); // Prüfen, ob Speicher erfolgreich reserviert wurde // Schleife über alle Elemente des numbers-Arrays // Zählt die Werte und prüft gleichzeitig den gültigen Wertebereich for (i = 0; i < len; ++i) { unsigned int v = numbers[i]; // Aktueller Wert assert(v >= 1 && v <= maxValue); // Wertebereich prüfen counts[v]++; // Anzahl dieses Wertes erhöhen } // Schleife über alle möglichen Werte // Prüft, dass genau ein Wert doppelt vorkommt for (i = 1; i <= maxValue; ++i) { if (counts[i] == 2) duplicatesCount++; // Ein doppelter Wert gefunden else assert(counts[i] == 0 || counts[i] == 1); // Alle anderen max. einmal } assert(duplicatesCount == 1); // Es darf genau ein Duplikat geben free(counts); // Speicher freigeben } /* * Testet createNumbers und getDuplicate für eine gegebene Länge */ static void test_createNumbers_and_getDuplicate(unsigned int len) { printf("test_createNumbers_and_getDuplicate(len=%u)...\n", len); // Zahlenarray erzeugen unsigned int *numbers = createNumbers(len); assert(numbers != NULL); // Rückgabewert prüfen // Struktur und Inhalt des Arrays überprüfen check_numbers_array(numbers, len); // Erneutes Zählen, um das erwartete Duplikat zu ermitteln unsigned int maxValue = 2 * len; unsigned int *counts = (unsigned int *)calloc(maxValue + 1, sizeof(unsigned int)); assert(counts != NULL); // Schleife zum Zählen aller Werte for (unsigned int i = 0; i < len; ++i) { unsigned int v = numbers[i]; counts[v]++; } // Schleife zur Bestimmung des doppelten Wertes unsigned int expectedDuplicate = 0; for (unsigned int v = 1; v <= maxValue; ++v) { if (counts[v] == 2) { expectedDuplicate = v; // Doppelten Wert merken break; } } assert(expectedDuplicate != 0); // Es muss ein Duplikat existieren // getDuplicate-Funktion testen unsigned int found = getDuplicate(numbers, len); assert(found == expectedDuplicate); // Ergebnis vergleichen free(counts); // Speicher freigeben free(numbers); printf("...OK\n"); } /* * Testet Fehlerfälle für getDuplicate */ static void test_getDuplicate_error_cases(void) { printf("test_getDuplicate_error_cases...\n"); // Test mit NULL-Pointer unsigned int dup = getDuplicate(NULL, 10); assert(dup == 0); // Test mit zu kleiner Länge (< 2) unsigned int dummy[1] = {42}; dup = getDuplicate(dummy, 1); assert(dup == 0); printf("...OK\n"); } /* * Hauptfunktion: startet alle Unit-Tests */ int main(void) { printf("Running numbers unit tests...\n\n"); // Typische Testfälle mit unterschiedlichen Array-Längen test_createNumbers_and_getDuplicate(5); test_createNumbers_and_getDuplicate(10); test_createNumbers_and_getDuplicate(20); // Test der Fehlerfälle test_getDuplicate_error_cases(); printf("\nAll numbers tests passed.\n"); return 0; }