// test_numbers_unity.c #include "unity.h" #include "numbers.h" #include #include void setUp(void) { /* nothing */ } void tearDown(void){ /* nothing */ } // 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(); }