AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <math.h>6 7/* Declaration for the auto-generated test wrapper we must call */8extern void test_fpdecodeFunc(sqlite3_context *context, int argc, sqlite3_value **argv);9 10/* Helpers */11 12static sqlite3* open_db_or_fail(void){13 sqlite3 *db = 0;14 int rc = sqlite3_open(":memory:", &db);15 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");16 TEST_ASSERT_NOT_NULL_MESSAGE(db, "db is NULL");17 return db;18}19 20/* Run the wrapper function and return a heap-allocated copy of the result text.21 Caller must sqlite3_free() the returned string. */22static char* run_wrapper_and_get_result(sqlite3 *db, double x, int y, int z){23 sqlite3_context ctx;24 memset(&ctx, 0, sizeof(ctx));25 26 Mem out;27 sqlite3VdbeMemInit(db, &out, 0, 0);28 ctx.pOut = &out;29 30 Mem *a0 = sqlite3ValueNew(db);31 Mem *a1 = sqlite3ValueNew(db);32 Mem *a2 = sqlite3ValueNew(db);33 TEST_ASSERT_NOT_NULL(a0);34 TEST_ASSERT_NOT_NULL(a1);35 TEST_ASSERT_NOT_NULL(a2);36 37 sqlite3VdbeMemSetDouble(a0, x);38 sqlite3VdbeMemSetInt64(a1, (i64)y);39 sqlite3VdbeMemSetInt64(a2, (i64)z);40 41 sqlite3_value *argv[3];42 argv[0] = (sqlite3_value*)a0;43 argv[1] = (sqlite3_value*)a1;44 argv[2] = (sqlite3_value*)a2;45 46 test_fpdecodeFunc(&ctx, 3, argv);47 48 const unsigned char *zRes = sqlite3_value_text((sqlite3_value*)&out);49 TEST_ASSERT_NOT_NULL_MESSAGE(zRes, "Result text is NULL");50 char *ret = sqlite3_mprintf("%s", (const char*)zRes);51 52 sqlite3ValueFree(a0);53 sqlite3ValueFree(a1);54 sqlite3ValueFree(a2);55 sqlite3VdbeMemRelease(&out);56 57 return ret;58}59 60/* Build the expected string using sqlite3FpDecode directly.61 Mirrors the exact formatting in fpdecodeFunc, including z<=0 clamp. */62static char* expected_decode_string(double x, int y, int z){63 FpDecode s;64 int zclamp = z<=0 ? 1 : z;65 sqlite3FpDecode(&s, x, y, zclamp);66 if( s.isSpecial==2 ){67 return sqlite3_mprintf("NaN");68 }else{69 /* Format: "%c%.*s/%d" */70 return sqlite3_mprintf("%c%.*s/%d", s.sign, s.n, s.z, s.iDP);71 }72}73 74/* Unity fixtures */75void setUp(void) {76 /* No global setup needed for these tests */77}78void tearDown(void) {79 /* No global teardown needed */80}81 82/* Tests */83 84void test_fpdecodeFunc_nan(void){85 sqlite3 *db = open_db_or_fail();86 87 double x = NAN;88 int y = 6;89 int z = 10;90 91 char *actual = run_wrapper_and_get_result(db, x, y, z);92 /* For NaN, wrapper always returns "NaN" */93 TEST_ASSERT_EQUAL_STRING("NaN", actual);94 95 sqlite3_free(actual);96 sqlite3_close(db);97}98 99void test_fpdecodeFunc_zero_value(void){100 sqlite3 *db = open_db_or_fail();101 102 double x = 0.0;103 int y = 8;104 int z = 10;105 106 char *actual = run_wrapper_and_get_result(db, x, y, z);107 char *expected = expected_decode_string(x, y, z);108 109 TEST_ASSERT_EQUAL_STRING(expected, actual);110 111 sqlite3_free(expected);112 sqlite3_free(actual);113 sqlite3_close(db);114}115 116void test_fpdecodeFunc_positive_simple(void){117 sqlite3 *db = open_db_or_fail();118 119 double x = 1.0;120 int y = 6;121 int z = 12;122 123 char *actual = run_wrapper_and_get_result(db, x, y, z);124 char *expected = expected_decode_string(x, y, z);125 126 TEST_ASSERT_EQUAL_STRING(expected, actual);127 128 sqlite3_free(expected);129 sqlite3_free(actual);130 sqlite3_close(db);131}132 133void test_fpdecodeFunc_negative_value(void){134 sqlite3 *db = open_db_or_fail();135 136 double x = -123.45;137 int y = 10;138 int z = 20;139 140 char *actual = run_wrapper_and_get_result(db, x, y, z);141 char *expected = expected_decode_string(x, y, z);142 143 TEST_ASSERT_EQUAL_STRING(expected, actual);144 145 sqlite3_free(expected);146 sqlite3_free(actual);147 sqlite3_close(db);148}149 150void test_fpdecodeFunc_clamps_z_to_one_when_nonpositive(void){151 sqlite3 *db = open_db_or_fail();152 153 double x = 3.141592653589793;154 int y = 8;155 int z_nonpos = 0; /* This should be clamped to 1 by fpdecodeFunc */156 int z_one = 1;157 158 char *actual = run_wrapper_and_get_result(db, x, y, z_nonpos);159 160 /* Expected uses z clamped to 1 */161 char *expected = expected_decode_string(x, y, z_one);162 163 TEST_ASSERT_EQUAL_STRING(expected, actual);164 165 sqlite3_free(expected);166 sqlite3_free(actual);167 sqlite3_close(db);168}169 170void test_fpdecodeFunc_very_large_and_very_small(void){171 sqlite3 *db = open_db_or_fail();172 173 /* Very large */174 {175 double x = 1.0e300;176 int y = 12;177 int z = 24;178 char *actual = run_wrapper_and_get_result(db, x, y, z);179 char *expected = expected_decode_string(x, y, z);180 TEST_ASSERT_EQUAL_STRING(expected, actual);181 sqlite3_free(expected);182 sqlite3_free(actual);183 }184 185 /* Very small */186 {187 double x = 1.0e-300;188 int y = 12;189 int z = 24;190 char *actual = run_wrapper_and_get_result(db, x, y, z);191 char *expected = expected_decode_string(x, y, z);192 TEST_ASSERT_EQUAL_STRING(expected, actual);193 sqlite3_free(expected);194 sqlite3_free(actual);195 }196 197 sqlite3_close(db);198}199 200void test_fpdecodeFunc_precision_variation(void){201 sqlite3 *db = open_db_or_fail();202 203 double x = 2.718281828459045;204 int z = 16;205 206 /* y small */207 {208 int y = 3;209 char *actual = run_wrapper_and_get_result(db, x, y, z);210 char *expected = expected_decode_string(x, y, z);211 TEST_ASSERT_EQUAL_STRING(expected, actual);212 sqlite3_free(expected);213 sqlite3_free(actual);214 }215 216 /* y larger */217 {218 int y = 12;219 char *actual = run_wrapper_and_get_result(db, x, y, z);220 char *expected = expected_decode_string(x, y, z);221 TEST_ASSERT_EQUAL_STRING(expected, actual);222 sqlite3_free(expected);223 sqlite3_free(actual);224 }225 226 sqlite3_close(db);227}228 229/* Main */230int main(void){231 UNITY_BEGIN();232 RUN_TEST(test_fpdecodeFunc_nan);233 RUN_TEST(test_fpdecodeFunc_zero_value);234 RUN_TEST(test_fpdecodeFunc_positive_simple);235 RUN_TEST(test_fpdecodeFunc_negative_value);236 RUN_TEST(test_fpdecodeFunc_clamps_z_to_one_when_nonpositive);237 RUN_TEST(test_fpdecodeFunc_very_large_and_very_small);238 RUN_TEST(test_fpdecodeFunc_precision_variation);239 return UNITY_END();240}