149 lines
3.8 KiB
C
149 lines
3.8 KiB
C
/**
|
|
* 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);
|
|
} |