142 lines
4.3 KiB
C
142 lines
4.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#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;
|
|
} |