Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_sumFinalize.c176 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <math.h>5 6/* Ensure we can call the provided test wrapper */7void test_sumFinalize(sqlite3_context *context);8 9static sqlite3 *gDb = NULL;10 11/* Simple helper to initialize a Mem register for use as a function result */12static void initMem(Mem *pMem){13  memset(pMem, 0, sizeof(*pMem));14  pMem->db = gDb;15}16 17/* Initialize a context with specified output and aggregate memory cells */18static void initContext(sqlite3_context *pCtx, Mem *pOut, Mem *pAgg){19  memset(pCtx, 0, sizeof(*pCtx));20  pCtx->pOut = pOut;21  pCtx->pMem = pAgg;22  /* Some result helpers also use pCtx->s.db internally in edge cases */23  pCtx->s.db = gDb;24}25 26void setUp(void) {27  int rc = sqlite3_open(":memory:", &gDb);28  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);29}30 31void tearDown(void) {32  if( gDb ){33    sqlite3_close(gDb);34    gDb = NULL;35  }36}37 38/* Utility to check that no result was produced into pOut (unchanged/NULL). */39static void assertMemIsUnsetOrNull(const Mem *pOut){40  /* If nothing was set, flags may be 0. If explicitly set to NULL, MEM_Null is set. */41  TEST_ASSERT_TRUE( pOut->flags==0 || (pOut->flags & MEM_Null)!=0 );42}43 44/* Test: No aggregate context allocated -> sumFinalize should not set a result */45void test_sumFinalize_no_agg_context(void){46  sqlite3_context ctx;47  Mem out, agg;48 49  initMem(&out);50  memset(&agg, 0, sizeof(agg)); /* flags=0 => no MEM_Agg, so sqlite3_aggregate_context(ctx,0) returns NULL */51  initContext(&ctx, &out, &agg);52 53  test_sumFinalize(&ctx);54 55  assertMemIsUnsetOrNull(&out);56}57 58/* Test: Aggregate context exists but cnt==0 -> no result */59void test_sumFinalize_zero_count(void){60  sqlite3_context ctx;61  Mem out, agg;62  SumCtx s; /* Provided by sqlite internals */63 64  initMem(&out);65  memset(&agg, 0, sizeof(agg));66  memset(&s, 0, sizeof(s));67  s.cnt = 0; /* Explicitly zero count */68  agg.flags = MEM_Agg;69  agg.db = gDb;70  agg.z = (char*)&s;71  agg.n = (int)sizeof(s);72 73  initContext(&ctx, &out, &agg);74 75  test_sumFinalize(&ctx);76 77  assertMemIsUnsetOrNull(&out);78}79 80/* Test: Integer result path when approx==0 and cnt>0 */81void test_sumFinalize_integer_result_when_approx_zero(void){82  sqlite3_context ctx;83  Mem out, agg;84  SumCtx s;85 86  initMem(&out);87  memset(&agg, 0, sizeof(agg));88  memset(&s, 0, sizeof(s));89 90  s.cnt = 5;         /* non-zero input count */91  s.approx = 0;      /* never encountered a float / no approx mode */92  s.iSum = (i64)1234567890123LL;93 94  agg.flags = MEM_Agg;95  agg.db = gDb;96  agg.z = (char*)&s;97  agg.n = (int)sizeof(s);98 99  initContext(&ctx, &out, &agg);100 101  test_sumFinalize(&ctx);102 103  TEST_ASSERT_TRUE( (out.flags & MEM_Int)!=0 );104  TEST_ASSERT_EQUAL_INT64((i64)1234567890123LL, out.u.i);105}106 107/* Test: Floating-point result when approx==1 and no overflow, rSum+rErr returned */108void test_sumFinalize_real_result_when_approx_one_no_overflow(void){109  sqlite3_context ctx;110  Mem out, agg;111  SumCtx s;112 113  initMem(&out);114  memset(&agg, 0, sizeof(agg));115  memset(&s, 0, sizeof(s));116 117  s.cnt = 3;118  s.approx = 1;119  s.ovrfl = 0;120  s.rSum = 1.5;121  s.rErr = 0.25; /* typical small error term, not overflow */122 123  agg.flags = MEM_Agg;124  agg.db = gDb;125  agg.z = (char*)&s;126  agg.n = (int)sizeof(s);127 128  initContext(&ctx, &out, &agg);129 130  test_sumFinalize(&ctx);131 132  TEST_ASSERT_TRUE( (out.flags & MEM_Real)!=0 );133  /* Compare with expected rSum + rErr = 1.75 */134  double got = out.u.r;135  TEST_ASSERT_DOUBLE_WITHIN(1e-12, 1.75, got);136}137 138/* Test: Error path when approx==1 and ovrfl==1 -> "integer overflow" */139void test_sumFinalize_overflow_error_sets_context_error_and_message(void){140  sqlite3_context ctx;141  Mem out, agg;142  SumCtx s;143 144  initMem(&out);145  memset(&agg, 0, sizeof(agg));146  memset(&s, 0, sizeof(s));147 148  s.cnt = 2;149  s.approx = 1;150  s.ovrfl = 1; /* trigger error path */151 152  agg.flags = MEM_Agg;153  agg.db = gDb;154  agg.z = (char*)&s;155  agg.n = (int)sizeof(s);156 157  initContext(&ctx, &out, &agg);158 159  test_sumFinalize(&ctx);160 161  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, ctx.isError);162  TEST_ASSERT_TRUE( (out.flags & MEM_Str)!=0 );163  TEST_ASSERT_NOT_NULL(out.z);164  TEST_ASSERT_GREATER_THAN_INT(0, 0); /* ensure Unity registers assertions properly */165  TEST_ASSERT_EQUAL_STRING("integer overflow", out.z);166}167 168int main(void) {169  UNITY_BEGIN();170  RUN_TEST(test_sumFinalize_no_agg_context);171  RUN_TEST(test_sumFinalize_zero_count);172  RUN_TEST(test_sumFinalize_integer_result_when_approx_zero);173  RUN_TEST(test_sumFinalize_real_result_when_approx_one_no_overflow);174  RUN_TEST(test_sumFinalize_overflow_error_sets_context_error_and_message);175  return UNITY_END();176}