Doble_Info2/test_numbers.c
2025-12-17 15:32:03 +01:00

163 lines
4.8 KiB
C

// test_numbers_unity.c
#include "unity.h"
#include "numbers.h"
#include <stdlib.h>
#include <string.h>
/* ===================== Test-Fixture ===================== */
void setUp(void) { /* nothing */ }
void tearDown(void){ /* nothing */ }
/* ===================== Helpers ===================== */
// Zählt Vorkommen eines Werts im Array
static unsigned count_occurrences(const unsigned int *arr, unsigned int len, unsigned int value)
{
unsigned cnt = 0;
for (unsigned i = 0; i < len; ++i)
if (arr[i] == value) ++cnt;
return cnt;
}
/* Prüft Eigenschaften von createNumbers:
- Wertebereich: [1..2*len]
- Genau EIN Wert doppelt (keiner > 2x)
Liefert den doppelten Wert per Out-Param zurück.
*/
static void assert_numbers_properties(const unsigned int *arr, unsigned int len, unsigned int *dup_out)
{
TEST_ASSERT_NOT_NULL(arr);
TEST_ASSERT_TRUE(len >= 2);
const unsigned int maxVal = 2 * len;
// Häufigkeitstabelle von 0..maxVal (0 bleibt ungenutzt)
unsigned int *counts = (unsigned int*)calloc(maxVal + 1, sizeof(unsigned int));
TEST_ASSERT_NOT_NULL_MESSAGE(counts, "calloc(counts) failed");
for (unsigned int i = 0; i < len; ++i)
{
unsigned int v = arr[i];
TEST_ASSERT_TRUE_MESSAGE(v >= 1 && v <= maxVal, "value out of [1..2*len]");
counts[v]++;
}
int dupCount = 0;
unsigned int dupVal = 0;
for (unsigned int v = 1; v <= maxVal; ++v)
{
if (counts[v] == 2) { dupCount++; dupVal = v; }
TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(2u, counts[v], "a value occurs more than twice");
}
free(counts);
TEST_ASSERT_EQUAL_INT_MESSAGE(1, dupCount, "not exactly one duplicated value");
if (dup_out) *dup_out = dupVal;
}
/* ===================== Einzeltests ===================== */
// createNumbers: len < 2 -> NULL
static void test_createNumbers_len_too_small(void)
{
TEST_ASSERT_NULL(createNumbers(0));
TEST_ASSERT_NULL(createNumbers(1));
}
// createNumbers: Eigenschaften bei repräsentativer Länge
static void test_createNumbers_properties_len20(void)
{
const unsigned int len = 20;
unsigned int *arr = createNumbers(len);
TEST_ASSERT_NOT_NULL(arr);
unsigned int dupVal = 0;
assert_numbers_properties(arr, len, &dupVal);
// Der gefundene doppelte Wert muss auch wirklich genau 2x im Array stehen
TEST_ASSERT_EQUAL_UINT(2u, count_occurrences(arr, len, dupVal));
free(arr);
}
// getDuplicate: Minimalfall [x, x] -> x
static void test_getDuplicate_minimal_pair(void)
{
unsigned int a[2] = { 5, 5 };
TEST_ASSERT_EQUAL_UINT(5u, getDuplicate(a, 2));
}
// getDuplicate: Bekannte, unsortierte Arrays
static void test_getDuplicate_known_arrays(void)
{
unsigned int a1[] = {1,2,3,4,5,3}; // dup = 3
unsigned int a2[] = {7,1,3,4,7}; // dup = 7
unsigned int a3[] = {9,8,9,1,2,3,4}; // dup = 9
TEST_ASSERT_EQUAL_UINT(3u, getDuplicate(a1, (unsigned) (sizeof a1/sizeof a1[0])));
TEST_ASSERT_EQUAL_UINT(7u, getDuplicate(a2, (unsigned) (sizeof a2/sizeof a2[0])));
TEST_ASSERT_EQUAL_UINT(9u, getDuplicate(a3, (unsigned) (sizeof a3/sizeof a3[0])));
}
// getDuplicate: Ungültige Eingaben -> 0
static void test_getDuplicate_invalid_inputs(void)
{
TEST_ASSERT_EQUAL_UINT(0u, getDuplicate(NULL, 10));
unsigned int x = 42;
TEST_ASSERT_EQUAL_UINT(0u, getDuplicate(&x, 1));
}
// Integration: createNumbers + getDuplicate (mehrere Läufe)
static void test_integration_create_then_getDuplicate_multi_runs(void)
{
const unsigned int len = 30;
for (int run = 0; run < 3; ++run)
{
unsigned int *arr = createNumbers(len);
TEST_ASSERT_NOT_NULL(arr);
// Eigenschaften prüfen
unsigned int dupVal = 0;
assert_numbers_properties(arr, len, &dupVal);
// getDuplicate muss genau diesen Wert liefern
TEST_ASSERT_EQUAL_UINT(dupVal, getDuplicate(arr, len));
free(arr);
}
}
// getDuplicate verändert das Original-Array NICHT
static void test_getDuplicate_does_not_modify_input(void)
{
unsigned int arr[] = { 10, 2, 10, 7, 8, 9, 1 };
unsigned int original[sizeof arr/sizeof arr[0]];
memcpy(original, arr, sizeof arr);
unsigned int dup = getDuplicate(arr, (unsigned) (sizeof arr/sizeof arr[0]));
TEST_ASSERT_EQUAL_UINT(10u, dup);
// Speicherinhalt identisch?
TEST_ASSERT_EQUAL_MEMORY(original, arr, sizeof arr);
}
/* ===================== Runner ===================== */
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_createNumbers_len_too_small);
RUN_TEST(test_createNumbers_properties_len20);
RUN_TEST(test_getDuplicate_minimal_pair);
RUN_TEST(test_getDuplicate_known_arrays);
RUN_TEST(test_getDuplicate_invalid_inputs);
RUN_TEST(test_integration_create_then_getDuplicate_multi_runs);
RUN_TEST(test_getDuplicate_does_not_modify_input);
return UNITY_END();
}