Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_countInverse.c154 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <stdlib.h>6#include <string.h>7 8/*9  Test suite for: static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv)10  Wrapper provided in module: void test_countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv);11*/12extern void test_countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv);13 14/* Globals to steer the aggregate step behavior for each test */15static int gMode = 0; /* 1: argc=0, 2: argc=1 NULL, 3: argc=1 non-NULL */16static sqlite3_int64 gInitial = 3;17 18/* Aggregate step callback that sets up aggregate context and invokes test_countInverse */19static void invtestStep(sqlite3_context *ctx, int argc, sqlite3_value **argv){20  (void)argc; (void)argv;21 22  /* Allocate/obtain the aggregate context and initialize the first 8 bytes (CountCtx.n) */23  void *p = sqlite3_aggregate_context(ctx, 16); /* >= sizeof(CountCtx) across builds */24  TEST_ASSERT_NOT_NULL_MESSAGE(p, "sqlite3_aggregate_context returned NULL in step");25 26  /* Initialize starting count to gInitial */27  ((sqlite3_int64*)p)[0] = gInitial;28 29  sqlite3_int64 expectedAfter = gInitial;30 31  if( gMode==1 ){32    /* argc==0 case: should decrement */33    test_countInverse(ctx, 0, NULL);34    expectedAfter = gInitial - 1;35  }else if( gMode==2 ){36    /* argc==1 with NULL argument: should NOT decrement */37    Mem m; memset(&m, 0, sizeof(m));38    m.flags = MEM_Null; /* Represents a NULL sqlite3_value */39    sqlite3_value *localArgv[1];40    localArgv[0] = (sqlite3_value*)&m;41    test_countInverse(ctx, 1, localArgv);42    expectedAfter = gInitial;43  }else if( gMode==3 ){44    /* argc==1 with non-NULL integer argument: should decrement */45    Mem m; memset(&m, 0, sizeof(m));46    m.flags = MEM_Int;47#if defined(SQLITE_OMIT_FLOATING_POINT)48    m.u.i = 123; /* integer path */49#else50    m.u.i = 123;51#endif52    sqlite3_value *localArgv[1];53    localArgv[0] = (sqlite3_value*)&m;54    test_countInverse(ctx, 1, localArgv);55    expectedAfter = gInitial - 1;56  }else{57    TEST_FAIL_MESSAGE("Invalid gMode in invtestStep");58  }59 60  /* Verify the same aggregate context pointer and expected count value */61  void *p2 = sqlite3_aggregate_context(ctx, 0);62  TEST_ASSERT_EQUAL_PTR(p, p2);63 64  sqlite3_int64 after = ((sqlite3_int64*)p2)[0];65  TEST_ASSERT_EQUAL_INT64(expectedAfter, after);66}67 68/* Aggregate final callback - nothing required for these tests */69static void invtestFinal(sqlite3_context *ctx){70  /* No-op: The test assertions are performed in the step function */71  (void)ctx;72}73 74void setUp(void) {75  /* No global setup needed */76}77 78void tearDown(void) {79  /* No global teardown needed */80}81 82/* Helper to execute a single-row aggregate to trigger one step invocation */83static void run_single_row_aggregate(sqlite3 *db){84  int rc;85  char *zErrMsg = NULL;86  /* Single row to ensure exactly one xStep() call */87  rc = sqlite3_exec(db, "SELECT invtest(1);", 0, 0, &zErrMsg);88  if( zErrMsg ){89    /* Ensure no leaked error message */90    TEST_MESSAGE(zErrMsg);91    sqlite3_free(zErrMsg);92  }93  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);94}95 96/* Register the aggregate function used for testing */97static void register_invtest(sqlite3 *db){98  int rc = sqlite3_create_function_v2(99    db,100    "invtest",          /* name */101    1,                  /* nArg: we pass 1 arg in SQL, but internal tests ignore it */102    SQLITE_UTF8,        /* encoding */103    NULL,               /* pApp */104    NULL,               /* xFunc (scalar) */105    invtestStep,        /* xStep (aggregate) */106    invtestFinal,       /* xFinal */107    NULL                /* xDestroy */108  );109  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);110}111 112void test_countInverse_decrements_when_no_args(void){113  sqlite3 *db = NULL;114  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));115  register_invtest(db);116 117  gMode = 1;   /* argc==0 path */118  gInitial = 3;119  run_single_row_aggregate(db);120 121  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));122}123 124void test_countInverse_no_decrement_when_arg_is_NULL(void){125  sqlite3 *db = NULL;126  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));127  register_invtest(db);128 129  gMode = 2;   /* argc==1 with NULL argument */130  gInitial = 5; /* Use different initial to ensure independence */131  run_single_row_aggregate(db);132 133  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));134}135 136void test_countInverse_decrements_when_arg_not_NULL(void){137  sqlite3 *db = NULL;138  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));139  register_invtest(db);140 141  gMode = 3;   /* argc==1 with non-NULL argument */142  gInitial = 10;143  run_single_row_aggregate(db);144 145  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));146}147 148int main(void) {149  UNITY_BEGIN();150  RUN_TEST(test_countInverse_decrements_when_no_args);151  RUN_TEST(test_countInverse_no_decrement_when_arg_is_NULL);152  RUN_TEST(test_countInverse_decrements_when_arg_not_NULL);153  return UNITY_END();154}