Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_ceilingFunc.c254 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <math.h>6 7/* Prototype for the provided test wrapper of the static function */8void test_ceilingFunc(sqlite3_context *context, int argc, sqlite3_value **argv);9 10static sqlite3 *gDb = NULL;11 12/* Simple user functions to attach via pUserData */13static double stub_double(double x){ return x * 2.0; }14static double stub_negate(double x){ return -x; }15static double stub_nan(double x){ (void)x; return NAN; }16 17/* Helper to initialize a Mem as output */18static void initOutMem(Mem *pOut){19  sqlite3VdbeMemInit(pOut, gDb, 0);20  sqlite3VdbeMemSetNull(pOut);21}22 23/* Helper to prepare a sqlite3_context with given user-data function pointer and output Mem */24static void initContext(sqlite3_context *pCtx, FuncDef *pDef, void *pUserData, Mem *pOut){25  memset(pCtx, 0, sizeof(*pCtx));26  memset(pDef, 0, sizeof(*pDef));27  pDef->pUserData = pUserData;28  pCtx->pFunc = pDef;29  pCtx->pOut = pOut;30}31 32/* Helpers to prepare input values */33static void makeArgInt64(Mem *pMem, sqlite3_int64 v){34  sqlite3VdbeMemInit(pMem, gDb, 0);35  sqlite3VdbeMemSetInt64(pMem, v);36}37static void makeArgDouble(Mem *pMem, double v){38  sqlite3VdbeMemInit(pMem, gDb, 0);39  sqlite3VdbeMemSetDouble(pMem, v);40}41static void makeArgText(Mem *pMem, const char *z){42  sqlite3VdbeMemInit(pMem, gDb, 0);43  /* Use SQLITE_STATIC for string literal storage */44  sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, SQLITE_STATIC);45}46static void makeArgNull(Mem *pMem){47  sqlite3VdbeMemInit(pMem, gDb, 0);48  sqlite3VdbeMemSetNull(pMem);49}50 51void setUp(void){52  int rc = sqlite3_open(":memory:", &gDb);53  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory SQLite DB");54}55void tearDown(void){56  if( gDb ){57    sqlite3_close(gDb);58    gDb = NULL;59  }60}61 62/* Integer input should pass through unchanged and not use the user function */63void test_ceilingFunc_integer_passthrough(void){64  sqlite3_context ctx;65  FuncDef def;66  Mem out, arg;67  sqlite3_value *argv[1];68 69  initOutMem(&out);70  initContext(&ctx, &def, (void*)stub_double, &out);71 72  sqlite3_int64 in = (sqlite3_int64)1234567890123456LL;73  makeArgInt64(&arg, in);74  argv[0] = (sqlite3_value*)&arg;75 76  test_ceilingFunc(&ctx, 1, argv);77 78  TEST_ASSERT_TRUE(out.flags & MEM_Int);79  TEST_ASSERT_EQUAL_INT64(in, out.u.i);80 81  sqlite3VdbeMemRelease(&arg);82  sqlite3VdbeMemRelease(&out);83}84 85/* Large int64 edge value passthrough */86void test_ceilingFunc_large_int64_passthrough(void){87  sqlite3_context ctx;88  FuncDef def;89  Mem out, arg;90  sqlite3_value *argv[1];91 92  initOutMem(&out);93  initContext(&ctx, &def, (void*)stub_double, &out);94 95  sqlite3_int64 in = ((sqlite3_int64)0x7fffffffffffffffLL) - 1; /* avoid INT64_MAX if any corner handling */96  makeArgInt64(&arg, in);97  argv[0] = (sqlite3_value*)&arg;98 99  test_ceilingFunc(&ctx, 1, argv);100 101  TEST_ASSERT_TRUE(out.flags & MEM_Int);102  TEST_ASSERT_EQUAL_INT64(in, out.u.i);103 104  sqlite3VdbeMemRelease(&arg);105  sqlite3VdbeMemRelease(&out);106}107 108/* Float input should apply the user function (double) and return a double */109void test_ceilingFunc_float_applies_user_function(void){110  sqlite3_context ctx;111  FuncDef def;112  Mem out, arg;113  sqlite3_value *argv[1];114 115  initOutMem(&out);116  initContext(&ctx, &def, (void*)stub_double, &out);117 118  double in = 1.25;119  makeArgDouble(&arg, in);120  argv[0] = (sqlite3_value*)&arg;121 122  test_ceilingFunc(&ctx, 1, argv);123 124  TEST_ASSERT_TRUE(out.flags & MEM_Real);125  TEST_ASSERT_DOUBLE_WITHIN(1e-12, in*2.0, out.u.r);126 127  sqlite3VdbeMemRelease(&arg);128  sqlite3VdbeMemRelease(&out);129}130 131/* Negative float input with a different user function */132void test_ceilingFunc_float_with_negate_user_function(void){133  sqlite3_context ctx;134  FuncDef def;135  Mem out, arg;136  sqlite3_value *argv[1];137 138  initOutMem(&out);139  initContext(&ctx, &def, (void*)stub_negate, &out);140 141  double in = -2.75;142  makeArgDouble(&arg, in);143  argv[0] = (sqlite3_value*)&arg;144 145  test_ceilingFunc(&ctx, 1, argv);146 147  TEST_ASSERT_TRUE(out.flags & MEM_Real);148  TEST_ASSERT_DOUBLE_WITHIN(1e-12, -in, out.u.r);149 150  sqlite3VdbeMemRelease(&arg);151  sqlite3VdbeMemRelease(&out);152}153 154/* Numeric text should be converted to FLOAT and user function applied */155void test_ceilingFunc_numeric_text_is_converted_and_applied(void){156  sqlite3_context ctx;157  FuncDef def;158  Mem out, arg;159  sqlite3_value *argv[1];160 161  initOutMem(&out);162  initContext(&ctx, &def, (void*)stub_double, &out);163 164  const char *zNum = "123.75";165  makeArgText(&arg, zNum);166  argv[0] = (sqlite3_value*)&arg;167 168  test_ceilingFunc(&ctx, 1, argv);169 170  TEST_ASSERT_TRUE(out.flags & MEM_Real);171  TEST_ASSERT_DOUBLE_WITHIN(1e-12, 123.75 * 2.0, out.u.r);172 173  sqlite3VdbeMemRelease(&arg);174  sqlite3VdbeMemRelease(&out);175}176 177/* Non-numeric text should produce no result (remain NULL) */178void test_ceilingFunc_non_numeric_text_no_result(void){179  sqlite3_context ctx;180  FuncDef def;181  Mem out, arg;182  sqlite3_value *argv[1];183 184  initOutMem(&out);185  initContext(&ctx, &def, (void*)stub_double, &out);186 187  const char *zText = "not-a-number";188  makeArgText(&arg, zText);189  argv[0] = (sqlite3_value*)&arg;190 191  test_ceilingFunc(&ctx, 1, argv);192 193  TEST_ASSERT_TRUE(out.flags & MEM_Null);194 195  sqlite3VdbeMemRelease(&arg);196  sqlite3VdbeMemRelease(&out);197}198 199/* NULL input should produce no result (remain NULL) */200void test_ceilingFunc_null_input_no_result(void){201  sqlite3_context ctx;202  FuncDef def;203  Mem out, arg;204  sqlite3_value *argv[1];205 206  initOutMem(&out);207  initContext(&ctx, &def, (void*)stub_double, &out);208 209  makeArgNull(&arg);210  argv[0] = (sqlite3_value*)&arg;211 212  test_ceilingFunc(&ctx, 1, argv);213 214  TEST_ASSERT_TRUE(out.flags & MEM_Null);215 216  sqlite3VdbeMemRelease(&arg);217  sqlite3VdbeMemRelease(&out);218}219 220/* User function returning NaN should propagate NaN in result */221void test_ceilingFunc_user_function_nan_propagates(void){222  sqlite3_context ctx;223  FuncDef def;224  Mem out, arg;225  sqlite3_value *argv[1];226 227  initOutMem(&out);228  initContext(&ctx, &def, (void*)stub_nan, &out);229 230  double in = 3.14159;231  makeArgDouble(&arg, in);232  argv[0] = (sqlite3_value*)&arg;233 234  test_ceilingFunc(&ctx, 1, argv);235 236  TEST_ASSERT_TRUE(out.flags & MEM_Real);237  TEST_ASSERT_TRUE(isnan(out.u.r));238 239  sqlite3VdbeMemRelease(&arg);240  sqlite3VdbeMemRelease(&out);241}242 243int main(void){244  UNITY_BEGIN();245  RUN_TEST(test_ceilingFunc_integer_passthrough);246  RUN_TEST(test_ceilingFunc_large_int64_passthrough);247  RUN_TEST(test_ceilingFunc_float_applies_user_function);248  RUN_TEST(test_ceilingFunc_float_with_negate_user_function);249  RUN_TEST(test_ceilingFunc_numeric_text_is_converted_and_applied);250  RUN_TEST(test_ceilingFunc_non_numeric_text_no_result);251  RUN_TEST(test_ceilingFunc_null_input_no_result);252  RUN_TEST(test_ceilingFunc_user_function_nan_propagates);253  return UNITY_END();254}