generated from freudenreichan/info2Praktikum-DobleSpiel
161 lines
5.5 KiB
C
161 lines
5.5 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#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.
|
|
*/
|
|
|
|
//Das Array enthält exakt (len-2) Unikate und 1 Duplikat
|
|
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: Zufallsgenerierung, Duplikatprüfung (via BST) und korrekte Array-Struktur
|
|
void test_createNumbersCoreFunctionality(void)
|
|
{
|
|
const unsigned int len = 10; // Definiert Array-Größe (10) für den Test
|
|
unsigned int *numbers = createNumbers(len); // Ruft createNumbers-Fkt auf
|
|
|
|
TEST_ASSERT_NOT_NULL(numbers); // prüft ob Speicher allokiert worden ist
|
|
|
|
// 1. Prüfe, ob genau ein Duplikat und sonst unikate vorhanden ist (mit Hilffunktion)
|
|
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); // getDuplicate-Fkt sucht das Duplikat aus dem gerade erzeugtem array mit qsort
|
|
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; //maximale größe der zahlen ist 2*len = hier 20
|
|
for (unsigned int i = 0; i < len; i++) // Geht dasss array (len=10) durch und prüft ob die zahlen zwischen 1 und 20 liegen
|
|
{
|
|
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)
|
|
{
|
|
|
|
unsigned int testArray[] = {10, 5, 20, 30, 5}; //Definiert ein unsortiertes Array mit dem Duplikat 5
|
|
TEST_ASSERT_EQUAL_UINT(5, getDuplicate(testArray, 5)); //Ruft getDuplicate auf, die intern qsort aufruft; Der Test erwartet die Zahl 5 und vergleicht
|
|
}
|
|
|
|
|
|
// =========================================================================
|
|
// 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;
|
|
|
|
//Aufrufen der compareNumbers-fkt
|
|
// Fall 1: a > b (muss positiv sein)
|
|
TEST_ASSERT_TRUE(compareNumbers(&a, &b) > 0); // (10 > 5) -> return 1 > 0 -> positiver Wert -> True
|
|
|
|
// Fall 2: b < a (muss negativ sein)
|
|
TEST_ASSERT_TRUE(compareNumbers(&b, &a) < 0); // (5 < 10) -> return -1 < 0 -> negativer Wert -> True
|
|
|
|
// Fall 3: a = c (muss null sein)
|
|
TEST_ASSERT_EQUAL_INT(0, compareNumbers(&a, &c)); // (10 = 10) -> return 0 == 0 -> True
|
|
}
|
|
|
|
|
|
// =========================================================================
|
|
// 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();
|
|
} |