#include "unity.h" #include "numbers.h" #include "stdlib.h" #include "string.h" static int compareInt(const void *ptr1, const void *ptr2); void setUp(void) { // set stuff up here } void tearDown(void) { // set stuff up here } // getDuplicate on array without duplicats // expects 0/error void test_get_duplicate_without_duplicates(void) { unsigned int input[] = {1, 5, 9, 2, 4}; unsigned int len = sizeof(input) / sizeof(input[0]); TEST_ASSERT_EQUAL_UINT(0, getDuplicate(input, len)); } // getDuplicate() on some arrays with 1 duplicate void test_get_duplicate(void) { unsigned int arr1[] = {4, 15, 32, 5, 3, 8, 8}; unsigned int len1 = sizeof(arr1) / sizeof(arr1[0]); unsigned int arr2[] = {1, 3, 3, 7}; unsigned int len2 = sizeof(arr2) / sizeof(arr2[0]); unsigned int arr3[] = {7, 7, 8, 4, 9, 1}; unsigned int len3 = sizeof(arr3) / sizeof(arr3[0]); TEST_ASSERT_EQUAL_UINT(8, getDuplicate(arr1, len1)); TEST_ASSERT_EQUAL_UINT(3, getDuplicate(arr2, len2)); TEST_ASSERT_EQUAL_UINT(7, getDuplicate(arr3, len3)); } // this tries to brute force a triple void test_for_triple(void) { // this test is less effective if srand is called inside createNumbers() for (int i = 0; i < 100000; i++) { unsigned int *numbers = createNumbers(3); if (numbers[0] == numbers[1] && numbers[1] == numbers[2]) { TEST_FAIL_MESSAGE("triple generated"); } free(numbers); } } // check if getDuplicate() modifies the original array (it should not) void test_get_duplicate_does_modify() { unsigned int arr1[] = {1, 2, 3, 4, 5, 4, 3, 2, 1}; // sorting would change this size_t len1 = sizeof(arr1) / sizeof(arr1[0]); unsigned int arr1Copy[9]; memcpy(arr1Copy, arr1, len1 * sizeof(unsigned int)); getDuplicate(arr1, len1); // return value does not matter // check if the arrays are still the same if (memcmp(arr1, arr1Copy, len1 * sizeof(unsigned int))) { TEST_FAIL_MESSAGE("Arrays have diverged"); } } // checks if there is exactly 1 duplicate number at varying array sizes void test_exactly_one_duplicate() { const size_t MAX_LIST_SIZE = 20; // max tested array len const size_t ITERATIONS_PER_LEN = 20; // number of iterations for each tested array len for (size_t len = 2; len < MAX_LIST_SIZE; len++) // start with smallest sensible size 2 { for (size_t i = 0; i < ITERATIONS_PER_LEN; i++) { unsigned int *randTestList = createNumbers((unsigned int)len); qsort(randTestList, len, sizeof(unsigned int), compareInt); int cntDuplicate = 0; for (size_t j = 0; j < len - 1; j++) { if (randTestList[j] == randTestList[j + 1]) { cntDuplicate++; } } // there should be exactly 1 duplicate TEST_ASSERT_EQUAL_INT(1, cntDuplicate); free(randTestList); } } } static int compareInt(const void *ptr1, const void *ptr2) { unsigned int num1 = *(int *)ptr1; unsigned int num2 = *(int *)ptr2; if (num1 < num2) return -1; if (num1 > num2) return 1; return 0; } int main(void) { printf("============================\nNumbers tests\n============================\n"); UNITY_BEGIN(); RUN_TEST(test_get_duplicate_without_duplicates); RUN_TEST(test_for_triple); RUN_TEST(test_exactly_one_duplicate); RUN_TEST(test_get_duplicate); RUN_TEST(test_get_duplicate_does_modify); return UNITY_END(); }