Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_groupConcatFinalize.c183 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper provided in the module under test */7extern void test_groupConcatFinalize(sqlite3_context *context);8 9/* Unity fixtures */10void setUp(void) { }11void tearDown(void) { }12 13/* Helper: initialize sqlite3 Mems and context for finalize() */14static void init_context(sqlite3 *db, sqlite3_context *pCtx, Mem *pOut, Mem *pAgg){15  memset(pCtx, 0, sizeof(*pCtx));16  memset(pOut, 0, sizeof(*pOut));17  memset(pAgg, 0, sizeof(*pAgg));18  sqlite3VdbeMemInit(pOut, db, 0);19  sqlite3VdbeMemInit(pAgg, db, 0);20  pCtx->db = db;21  pCtx->pOut = pOut;22  pCtx->pMem = pAgg;23}24 25/* Helper: create and populate a GroupConcatCtx with given content */26static GroupConcatCtx* make_gcc_with_content(sqlite3 *db, const char *content27#ifndef SQLITE_OMIT_WINDOWFUNC28  , int withSepArray29#endif30){31  GroupConcatCtx *pGCC = (GroupConcatCtx*)sqlite3DbMallocZero(db, sizeof(GroupConcatCtx));32  TEST_ASSERT_NOT_NULL_MESSAGE(pGCC, "Failed to allocate GroupConcatCtx");33 34  /* Initialize StrAccum for dynamic accumulation with sane mxAlloc */35  sqlite3StrAccumInit(&pGCC->str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);36 37  if( content ){38    sqlite3_str_append(&pGCC->str, content, (int)strlen(content));39  }40 41#ifndef SQLITE_OMIT_WINDOWFUNC42  if( withSepArray ){43    /* Allocate a dummy pnSepLengths array to exercise free path in finalize */44    pGCC->pnSepLengths = (int*)sqlite3DbMallocZero(db, sizeof(int) * 3);45    TEST_ASSERT_NOT_NULL_MESSAGE(pGCC->pnSepLengths, "Failed to allocate pnSepLengths");46    pGCC->nAccum = 2;           /* arbitrary positive to represent some accumulation */47    pGCC->nFirstSepLength = 1;  /* arbitrary */48    pGCC->pnSepLengths[0] = 1;49    pGCC->pnSepLengths[1] = 2;50  }51#endif52 53  return pGCC;54}55 56/* Helper: attach an aggregate context (GroupConcatCtx*) to the context Mem */57static void attach_agg_context(sqlite3 *db, sqlite3_context *pCtx, Mem *pAgg, GroupConcatCtx *pGCC){58  (void)db;59  /* Mark the aggregate-context Mem as MEM_Agg and store pointer in z */60  pAgg->flags = MEM_Agg;61  pAgg->z = (char*)pGCC;62}63 64/* Helper: assert that Mem contains exactly expected string */65static void assert_mem_string_eq(Mem *pOut, const char *expected){66  TEST_ASSERT_TRUE_MESSAGE((pOut->flags & MEM_Str)!=0, "Output Mem does not contain a string");67  TEST_ASSERT_NOT_NULL_MESSAGE(pOut->z, "Output string pointer is NULL");68  TEST_ASSERT_EQUAL_INT((int)strlen(expected), pOut->n);69  TEST_ASSERT_EQUAL_STRING(expected, pOut->z);70}71 72/* Test: No aggregate context present -> finalize produces no result */73void test_groupConcatFinalize_no_agg_context_leaves_no_result(void){74  sqlite3 *db = 0;75  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));76 77  sqlite3_context ctx;78  Mem out, agg;79  init_context(db, &ctx, &out, &agg);80 81  /* Do NOT set MEM_Agg: simulates no aggregate-context allocation ever happened */82  test_groupConcatFinalize(&ctx);83 84  /* Expect no result set into pOut */85  TEST_ASSERT_EQUAL_UINT32(0, out.flags);86  TEST_ASSERT_NULL(out.z);87 88  sqlite3VdbeMemRelease(&out);89  sqlite3VdbeMemRelease(&agg);90  sqlite3_close(db);91}92 93/* Test: Aggregate context present with content "A,B" -> finalize returns "A,B" */94void test_groupConcatFinalize_returns_accumulated_text(void){95  sqlite3 *db = 0;96  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));97 98  sqlite3_context ctx;99  Mem out, agg;100  init_context(db, &ctx, &out, &agg);101 102  GroupConcatCtx *pGCC = make_gcc_with_content(db, "A,B"103#ifndef SQLITE_OMIT_WINDOWFUNC104    , 0105#endif106  );107  attach_agg_context(db, &ctx, &agg, pGCC);108 109  test_groupConcatFinalize(&ctx);110 111  assert_mem_string_eq(&out, "A,B");112 113  /* Cleanup: result string lives in out; release it, then free aggregate ctx */114  sqlite3VdbeMemRelease(&out);115  sqlite3VdbeMemRelease(&agg);116  sqlite3DbFree(db, pGCC);117  sqlite3_close(db);118}119 120/* Test: Aggregate context present, pnSepLengths allocated -> finalize still returns correct text */121void test_groupConcatFinalize_with_sep_lengths_allocated(void){122#ifndef SQLITE_OMIT_WINDOWFUNC123  sqlite3 *db = 0;124  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));125 126  sqlite3_context ctx;127  Mem out, agg;128  init_context(db, &ctx, &out, &agg);129 130  GroupConcatCtx *pGCC = make_gcc_with_content(db, "X,Y", 1);131  attach_agg_context(db, &ctx, &agg, pGCC);132 133  test_groupConcatFinalize(&ctx);134 135  assert_mem_string_eq(&out, "X,Y");136 137  /* Cleanup */138  sqlite3VdbeMemRelease(&out);139  sqlite3VdbeMemRelease(&agg);140  sqlite3DbFree(db, pGCC);141  sqlite3_close(db);142#else143  /* If window functions are omitted, just assert true to mark the test as pass */144  TEST_ASSERT_TRUE(1);145#endif146}147 148/* Optional: Aggregate context present but with empty accumulation -> finalize gives empty string */149void test_groupConcatFinalize_empty_accumulation_returns_empty_string(void){150  sqlite3 *db = 0;151  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));152 153  sqlite3_context ctx;154  Mem out, agg;155  init_context(db, &ctx, &out, &agg);156 157  GroupConcatCtx *pGCC = make_gcc_with_content(db, "", 158#ifndef SQLITE_OMIT_WINDOWFUNC159    0160#endif161  );162  attach_agg_context(db, &ctx, &agg, pGCC);163 164  test_groupConcatFinalize(&ctx);165 166  /* Expect an empty string as result (not NULL), since pGCC existed */167  assert_mem_string_eq(&out, "");168 169  sqlite3VdbeMemRelease(&out);170  sqlite3VdbeMemRelease(&agg);171  sqlite3DbFree(db, pGCC);172  sqlite3_close(db);173}174 175/* Unity main */176int main(void){177  UNITY_BEGIN();178  RUN_TEST(test_groupConcatFinalize_no_agg_context_leaves_no_result);179  RUN_TEST(test_groupConcatFinalize_returns_accumulated_text);180  RUN_TEST(test_groupConcatFinalize_with_sep_lengths_allocated);181  RUN_TEST(test_groupConcatFinalize_empty_accumulation_returns_empty_string);182  return UNITY_END();183}