AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <math.h>6#include <float.h>7 8/* The function under test is static in the module; call the provided wrapper */9extern void test_percentSort(double *a, unsigned int n);10 11/* Helper: comparator for qsort on doubles (no NaN in test data) */12static int cmp_double_asc(const void *pa, const void *pb){13 double a = *(const double*)pa;14 double b = *(const double*)pb;15 if( a < b ) return -1;16 if( a > b ) return 1;17 return 0;18}19 20/* Helper: assert array is non-decreasing */21static void assert_non_decreasing(const double *a, unsigned int n){22 for(unsigned int i=0; i+1<n; i++){23 TEST_ASSERT_TRUE_MESSAGE(!(a[i] > a[i+1]), "Array is not sorted non-decreasing");24 }25}26 27/* Helper: sort with qsort to build expected result, then compare element-wise */28static void assert_sorted_matches_qsort(const double *input, unsigned int n){29 double *work = (double*)sqlite3_malloc64(n*sizeof(double));30 double *expd = (double*)sqlite3_malloc64(n*sizeof(double));31 TEST_ASSERT_NOT_NULL(work);32 TEST_ASSERT_NOT_NULL(expd);33 34 memcpy(work, input, n*sizeof(double));35 memcpy(expd, input, n*sizeof(double));36 37 /* Sort using the function under test */38 test_percentSort(work, n);39 /* Reference sort */40 qsort(expd, n, sizeof(double), cmp_double_asc);41 42 /* Verify non-decreasing and equality to reference */43 assert_non_decreasing(work, n);44 for(unsigned int i=0; i<n; i++){45 /* Exact equality is expected for finite numbers including infinities and +/-0.0 */46 TEST_ASSERT_TRUE(work[i] == expd[i]);47 }48 49 sqlite3_free(work);50 sqlite3_free(expd);51}52 53void setUp(void) {54 /* No global setup needed */55}56void tearDown(void) {57 /* No global teardown needed */58}59 60void test_percentSort_two_elements_already_sorted(void){61 double a[2] = {-1.0, 5.5};62 test_percentSort(a, 2);63 TEST_ASSERT_TRUE(a[0] <= a[1]);64 TEST_ASSERT_EQUAL_DOUBLE(-1.0, a[0]);65 TEST_ASSERT_EQUAL_DOUBLE(5.5, a[1]);66}67 68void test_percentSort_two_elements_reverse_order(void){69 double a[2] = {5.5, -1.0};70 test_percentSort(a, 2);71 TEST_ASSERT_TRUE(a[0] <= a[1]);72 TEST_ASSERT_EQUAL_DOUBLE(-1.0, a[0]);73 TEST_ASSERT_EQUAL_DOUBLE(5.5, a[1]);74}75 76void test_percentSort_three_elements_various_permutations(void){77 /* Test a representative set of 3-element permutations */78 const double cases[][3] = {79 {1.0, 2.0, 3.0},80 {1.0, 3.0, 2.0},81 {2.0, 1.0, 3.0},82 {2.0, 3.0, 1.0},83 {3.0, 1.0, 2.0},84 {3.0, 2.0, 1.0}85 };86 for(size_t i=0; i<sizeof(cases)/sizeof(cases[0]); i++){87 assert_sorted_matches_qsort(cases[i], 3);88 }89}90 91void test_percentSort_reverse_sorted_sequence(void){92 double a[10];93 for(int i=0; i<10; i++){94 a[i] = (double)(10 - i); /* 10,9,8,...,1 */95 }96 assert_sorted_matches_qsort(a, 10);97}98 99void test_percentSort_with_duplicates_and_negatives(void){100 double a[] = {3.0, -1.0, 2.0, 3.0, 0.0, -1.0, 2.0, 2.0, -5.0, 3.0};101 assert_sorted_matches_qsort(a, (unsigned int)(sizeof(a)/sizeof(a[0])));102}103 104void test_percentSort_all_equal_values(void){105 double a[12];106 for(int i=0; i<12; i++) a[i] = 7.25;107 test_percentSort(a, 12);108 assert_non_decreasing(a, 12);109 for(int i=0; i<12; i++){110 TEST_ASSERT_EQUAL_DOUBLE(7.25, a[i]);111 }112}113 114void test_percentSort_extremes_and_infinities(void){115 double a[] = {116 -HUGE_VAL,117 -DBL_MAX,118 -1.0e308,119 -DBL_MIN,120 -0.0,121 0.0,122 DBL_MIN,123 1.0e-308,124 1.0,125 DBL_MAX,126 HUGE_VAL127 };128 assert_sorted_matches_qsort(a, (unsigned int)(sizeof(a)/sizeof(a[0])));129}130 131static unsigned int lcg_u32(unsigned int *state){132 /* Deterministic LCG: Numerical Recipes parameters */133 *state = (*state)*1664525u + 1013904223u;134 return *state;135}136 137void test_percentSort_large_deterministic_dataset(void){138 const unsigned int n = 256;139 double *a = (double*)sqlite3_malloc64(n*sizeof(double));140 TEST_ASSERT_NOT_NULL(a);141 142 unsigned int s = 0x12345678u;143 for(unsigned int i=0; i<n; i++){144 /* Spread values across positive/negative range deterministically */145 unsigned int r = lcg_u32(&s);146 int sign = (r & 1u) ? 1 : -1;147 double mag = (double)(r >> 1); /* use upper bits for magnitude */148 a[i] = sign * (mag / 1000.0);149 }150 151 assert_sorted_matches_qsort(a, n);152 153 /* Idempotence: sorting again keeps order */154 test_percentSort(a, n);155 assert_non_decreasing(a, n);156 157 sqlite3_free(a);158}159 160int main(void){161 UNITY_BEGIN();162 RUN_TEST(test_percentSort_two_elements_already_sorted);163 RUN_TEST(test_percentSort_two_elements_reverse_order);164 RUN_TEST(test_percentSort_three_elements_various_permutations);165 RUN_TEST(test_percentSort_reverse_sorted_sequence);166 RUN_TEST(test_percentSort_with_duplicates_and_negatives);167 RUN_TEST(test_percentSort_all_equal_values);168 RUN_TEST(test_percentSort_extremes_and_infinities);169 RUN_TEST(test_percentSort_large_deterministic_dataset);170 return UNITY_END();171}