Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_math1Func.c217 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <math.h>5 6/* We will call the provided wrapper for the static function */7void test_math1Func(sqlite3_context *context, int argc, sqlite3_value **argv);8 9/* Global DB handle for tests */10static sqlite3 *gDb = NULL;11 12/* Simple math functions to use as sqlite3_user_data(context) */13static double identity_func(double x){ return x; }14static double square_func(double x){ return x*x; }15 16/* Helper: invoke math1Func with given input value and user function pointer */17static void invoke_math1(sqlite3 *db, double (*fptr)(double),18                         sqlite3_value *in, Mem *out){19    sqlite3_context ctx;20    FuncDef def;21    memset(&ctx, 0, sizeof(ctx));22    memset(&def, 0, sizeof(def));23    def.pUserData = (void*)fptr;24    def.nArg = 1;25    ctx.pFunc = &def;26    ctx.pOut = out;27    ctx.db = db;28 29    sqlite3_value *argv[1];30    argv[0] = in;31    test_math1Func(&ctx, 1, argv);32}33 34void setUp(void) {35    int rc = sqlite3_open(":memory:", &gDb);36    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory DB");37}38 39void tearDown(void) {40    if( gDb ){41        sqlite3_close(gDb);42        gDb = NULL;43    }44}45 46/* Utility to allocate a fresh sqlite3_value (Mem) initialized as NULL */47static Mem* newMem(void){48    sqlite3_value *v = sqlite3ValueNew(gDb);49    TEST_ASSERT_NOT_NULL(v);50    return (Mem*)v;51}52 53static void freeMem(Mem *m){54    sqlite3ValueFree((sqlite3_value*)m);55}56 57/* Create various input Mem values */58static Mem* newIntVal(sqlite3_int64 x){59    Mem *m = newMem();60    int rc = sqlite3VdbeMemSetInt64(m, x);61    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);62    return m;63}64 65static Mem* newDoubleVal(double x){66    Mem *m = newMem();67    int rc = sqlite3VdbeMemSetDouble(m, x);68    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);69    return m;70}71 72static Mem* newTextVal(const char *z){73    Mem *m = newMem();74    int rc = sqlite3VdbeMemSetStr(m, z, (int)strlen(z), SQLITE_UTF8, SQLITE_TRANSIENT);75    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);76    return m;77}78 79static Mem* newBlobVal(const void *p, int n){80    Mem *m = newMem();81    int rc = sqlite3VdbeMemSetStr(m, (const char*)p, n, 0 /* enc=0 => BLOB */, SQLITE_TRANSIENT);82    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);83    return m;84}85 86static Mem* newNullVal(void){87    return newMem(); /* Already NULL by sqlite3ValueNew */88}89 90/* Extract double from output Mem */91static double outAsDouble(Mem *out){92    return sqlite3_value_double((sqlite3_value*)out);93}94 95static int outType(Mem *out){96    return sqlite3_value_type((sqlite3_value*)out);97}98 99/* Tests */100 101void test_math1Func_integer_identity(void){102    Mem *in = newIntVal(7);103    Mem *out = newMem(); /* initialize result holder as NULL */104 105    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);106 107    TEST_ASSERT_EQUAL_INT(SQLITE_FLOAT, outType(out));108    TEST_ASSERT_DOUBLE_WITHIN(1e-12, 7.0, outAsDouble(out));109 110    freeMem(in);111    freeMem(out);112}113 114void test_math1Func_float_square(void){115    Mem *in = newDoubleVal(1.5);116    Mem *out = newMem();117 118    invoke_math1(gDb, square_func, (sqlite3_value*)in, out);119 120    TEST_ASSERT_EQUAL_INT(SQLITE_FLOAT, outType(out));121    TEST_ASSERT_DOUBLE_WITHIN(1e-12, 2.25, outAsDouble(out));122 123    freeMem(in);124    freeMem(out);125}126 127void test_math1Func_numeric_text_float_identity(void){128    Mem *in = newTextVal("2.5"); /* numeric text */129    Mem *out = newMem();130 131    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);132 133    TEST_ASSERT_EQUAL_INT(SQLITE_FLOAT, outType(out));134    TEST_ASSERT_DOUBLE_WITHIN(1e-12, 2.5, outAsDouble(out));135 136    freeMem(in);137    freeMem(out);138}139 140void test_math1Func_numeric_text_integer_identity(void){141    Mem *in = newTextVal("42"); /* numeric integer text */142    Mem *out = newMem();143 144    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);145 146    TEST_ASSERT_EQUAL_INT(SQLITE_FLOAT, outType(out));147    TEST_ASSERT_DOUBLE_WITHIN(1e-12, 42.0, outAsDouble(out));148 149    freeMem(in);150    freeMem(out);151}152 153void test_math1Func_non_numeric_text_leaves_null(void){154    Mem *in = newTextVal("abc"); /* non-numeric text */155    Mem *out = newNullVal();     /* remains NULL if function returns early */156 157    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);158 159    TEST_ASSERT_EQUAL_INT(SQLITE_NULL, outType(out));160 161    freeMem(in);162    freeMem(out);163}164 165void test_math1Func_blob_leaves_null(void){166    const unsigned char blobData[3] = {0x01, 0x02, 0x03};167    Mem *in = newBlobVal(blobData, 3);168    Mem *out = newNullVal();169 170    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);171 172    TEST_ASSERT_EQUAL_INT(SQLITE_NULL, outType(out));173 174    freeMem(in);175    freeMem(out);176}177 178void test_math1Func_null_leaves_null(void){179    Mem *in = newNullVal();180    Mem *out = newNullVal();181 182    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);183 184    TEST_ASSERT_EQUAL_INT(SQLITE_NULL, outType(out));185 186    freeMem(in);187    freeMem(out);188}189 190void test_math1Func_nan_propagation_identity(void){191    /* Create a NaN value and ensure it propagates through */192    double nanv = NAN;193    Mem *in = newDoubleVal(nanv);194    Mem *out = newMem();195 196    invoke_math1(gDb, identity_func, (sqlite3_value*)in, out);197 198    TEST_ASSERT_EQUAL_INT(SQLITE_FLOAT, outType(out));199    double got = outAsDouble(out);200    TEST_ASSERT_TRUE(isnan(got));201 202    freeMem(in);203    freeMem(out);204}205 206int main(void) {207    UNITY_BEGIN();208    RUN_TEST(test_math1Func_integer_identity);209    RUN_TEST(test_math1Func_float_square);210    RUN_TEST(test_math1Func_numeric_text_float_identity);211    RUN_TEST(test_math1Func_numeric_text_integer_identity);212    RUN_TEST(test_math1Func_non_numeric_text_leaves_null);213    RUN_TEST(test_math1Func_blob_leaves_null);214    RUN_TEST(test_math1Func_null_leaves_null);215    RUN_TEST(test_math1Func_nan_propagation_identity);216    return UNITY_END();217}