/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "dusktest.h" #include "util/sort.h" #include "util/memory.h" typedef struct { int_t key; char value; } teststruct_t; void testSortMethod( void (*sortMethod)( void *array, const size_t count, const size_t size, const sortcompare_t compare ), const char *methodName ) { // Create an array of integers size_t count = 5; int_t *array = (int_t*)memoryAllocate(count * sizeof(int_t)); assert_non_null(array); // Initialize with unsorted data array[0] = 5; array[1] = 3; array[2] = 4; array[3] = 1; array[4] = 2; // Comparator function int_t compareInts(const void *a, const void *b) { int_t intA = *(const int_t*)a; int_t intB = *(const int_t*)b; return (intA > intB) - (intA < intB); } // Sort the array sortMethod(array, count, sizeof(int_t), compareInts); // Check that the array is sorted for(size_t i = 0; i < count; i++) { assert_int_equal(array[i], (int_t)(i + 1)); } // Test with custom struct comparator teststruct_t unsortedStructs[4] = { {3, 'b'}, {1, 'd'}, {4, 'a'}, {2, 'c'} }; teststruct_t structArray[4]; // Test with number comparator memoryCopy(structArray, unsortedStructs, sizeof(unsortedStructs)); int_t compareStructsKeys(const void *a, const void *b) { const teststruct_t *structA = (const teststruct_t*)a; const teststruct_t *structB = (const teststruct_t*)b; return (structA->key > structB->key) - (structA->key < structB->key); } sortMethod(structArray, 4, sizeof(teststruct_t), compareStructsKeys); for(size_t i = 0; i < 4; i++) { assert_int_equal(structArray[i].key, (int_t)(i + 1)); } // Test with char comparator memoryCopy(structArray, unsortedStructs, sizeof(unsortedStructs)); int_t compareStructsValues(const void *a, const void *b) { const teststruct_t *structA = (const teststruct_t*)a; const teststruct_t *structB = (const teststruct_t*)b; return (structA->value > structB->value) - (structA->value < structB->value); } sortMethod(structArray, 4, sizeof(teststruct_t), compareStructsValues); char expectedValues[4] = {'a', 'b', 'c', 'd'}; for(size_t i = 0; i < 4; i++) { assert_int_equal(structArray[i].value, expectedValues[i]); } // Cannot sort NULL base expect_assert_failure(sortMethod(NULL, count, sizeof(int_t), compareInts)); // Cannot sort 0 elements expect_assert_failure(sortMethod(array, 0, sizeof(int_t), compareInts)); // Cannot sort with size 0 expect_assert_failure(sortMethod(array, count, 0, compareInts)); // Cannot sort with NULL comparator expect_assert_failure(sortMethod(array, count, sizeof(int_t), NULL)); memoryFree(array); // Expect no leaks assert_int_equal(memoryGetAllocatedCount(), 0); } static void test_sortBubble(void **state) { (void)state; testSortMethod(sortBubble, "sortBubble"); } static void test_sortQuick(void **state) { (void)state; testSortMethod(sortQuick, "sortQuick"); } static void test_sortArrayU8(void **state) { (void)state; // Create an array of uint8_t size_t count = 6; uint8_t array[6] = {5, 2, 4, 1, 3, 0}; // Sort the array sortArrayU8(array, count); // Check that the array is sorted for(size_t i = 0; i < count; i++) { assert_int_equal(array[i], (uint8_t)i); } // Cannot sort NULL array expect_assert_failure(sortArrayU8(NULL, count)); // Cannot sort 0 elements expect_assert_failure(sortArrayU8(array, 0)); // Expect no leaks assert_int_equal(memoryGetAllocatedCount(), 0); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_sortBubble), cmocka_unit_test(test_sortQuick), cmocka_unit_test(test_sortArrayU8), }; return cmocka_run_group_tests(tests, NULL, NULL); }