generated from freudenreichan/info2Praktikum-DobleSpiel
Unity-Tests numbers
This commit is contained in:
parent
e34f06850b
commit
461562b59b
162
test_numbers.c
Normal file
162
test_numbers.c
Normal file
@ -0,0 +1,162 @@
|
||||
|
||||
// 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();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user