Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_printf_sqlite3ResultStrAccum.c189 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global snapshot of StrAccum state after calling sqlite3ResultStrAccum */7static StrAccum gSnap;8static int gSnapValid;9 10/* Helper to reset snapshot */11static void resetSnapshot(void){12  memset(&gSnap, 0, sizeof(gSnap));13  gSnapValid = 0;14}15 16static void snapshotAccum(StrAccum *p){17  gSnap = *p;   /* Shallow copy is sufficient for field checks */18  gSnapValid = 1;19}20 21/* UDF: triggers error path (accError set), also ensures malloced buffer is present */22static void udf_accum_error(sqlite3_context *ctx, int argc, sqlite3_value **argv){23  (void)argc; (void)argv;24  StrAccum a;25  memset(&a, 0, sizeof(a));26  a.db = sqlite3_context_db_handle(ctx);27  a.accError = SQLITE_TOOBIG;               /* Non-zero error */28  a.printfFlags = SQLITE_PRINTF_MALLOCED;   /* Pretend we have malloced text to be cleaned */29  a.zText = sqlite3DbStrDup(a.db, "ShouldBeFreed");30  a.nChar = (int)strlen("ShouldBeFreed");31  /* Call target function */32  sqlite3ResultStrAccum(ctx, &a);33  /* Capture state after call */34  snapshotAccum(&a);35}36 37/* UDF: triggers malloced path (isMalloced true) and returns "Hello" */38static void udf_accum_malloced(sqlite3_context *ctx, int argc, sqlite3_value **argv){39  (void)argc; (void)argv;40  StrAccum a;41  memset(&a, 0, sizeof(a));42  a.db = sqlite3_context_db_handle(ctx);43  a.printfFlags = SQLITE_PRINTF_MALLOCED;44  a.zText = sqlite3DbStrDup(a.db, "Hello");45  a.nChar = 5;46  /* Call target function */47  sqlite3ResultStrAccum(ctx, &a);48  /* Capture state after call (should not be reset) */49  snapshotAccum(&a);50}51 52/* UDF: triggers non-malloced/no-error path -> empty string result + reset */53static void udf_accum_nomalloc(sqlite3_context *ctx, int argc, sqlite3_value **argv){54  (void)argc; (void)argv;55  StrAccum a;56  memset(&a, 0, sizeof(a));57  a.db = sqlite3_context_db_handle(ctx);58  /* Not malloced; even if we place some text here, function should ignore and reset */59  a.zText = (char*)"World";   /* Not malloced (string literal) */60  a.nChar = 5;61  a.printfFlags = 0;          /* Not malloced */62  /* Call target function */63  sqlite3ResultStrAccum(ctx, &a);64  /* Capture state after call (should be reset) */65  snapshotAccum(&a);66}67 68void setUp(void) {69  /* Setup code here, or leave empty */70}71 72void tearDown(void) {73  /* Cleanup code here, or leave empty */74}75 76/* Utility: open in-memory DB */77static sqlite3* open_memory_db(void){78  sqlite3 *db = NULL;79  int rc = sqlite3_open(":memory:", &db);80  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");81  return db;82}83 84/* Utility: finalize and ensure rc is OK */85static void finalize_and_check(sqlite3_stmt *pStmt){86  int rc = sqlite3_finalize(pStmt);87  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_finalize failed");88}89 90/* Test 1: accError path results in SQLITE_ERROR with specific code and StrAccum reset */91void test_sqlite3ResultStrAccum_error_sets_error_and_resets(void){92  resetSnapshot();93  sqlite3 *db = open_memory_db();94 95  int rc = sqlite3_create_function_v2(db, "unit_err", 0, SQLITE_UTF8, NULL,96                                      udf_accum_error, NULL, NULL, NULL);97  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);98 99  sqlite3_stmt *pStmt = NULL;100  rc = sqlite3_prepare_v2(db, "SELECT unit_err()", -1, &pStmt, NULL);101  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);102 103  rc = sqlite3_step(pStmt);104  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);105  TEST_ASSERT_EQUAL_INT(SQLITE_TOOBIG, sqlite3_errcode(db));106 107  /* Snapshot should be valid and reflect reset state after call */108  TEST_ASSERT_TRUE(gSnapValid);109  TEST_ASSERT_EQUAL_PTR(NULL, gSnap.zText);110  TEST_ASSERT_EQUAL_INT(0, gSnap.nChar);111  TEST_ASSERT_EQUAL_INT(0, gSnap.nAlloc);112  TEST_ASSERT_EQUAL_INT(0, (gSnap.printfFlags & SQLITE_PRINTF_MALLOCED));113 114  finalize_and_check(pStmt);115  sqlite3_close(db);116}117 118/* Test 2: malloced path returns the text and does not reset StrAccum immediately */119void test_sqlite3ResultStrAccum_malloced_returns_text_dynamic(void){120  resetSnapshot();121  sqlite3 *db = open_memory_db();122 123  int rc = sqlite3_create_function_v2(db, "unit_malloc", 0, SQLITE_UTF8, NULL,124                                      udf_accum_malloced, NULL, NULL, NULL);125  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);126 127  sqlite3_stmt *pStmt = NULL;128  rc = sqlite3_prepare_v2(db, "SELECT unit_malloc()", -1, &pStmt, NULL);129  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);130 131  rc = sqlite3_step(pStmt);132  TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);133 134  const unsigned char *txt = sqlite3_column_text(pStmt, 0);135  int n = sqlite3_column_bytes(pStmt, 0);136  TEST_ASSERT_NOT_NULL(txt);137  TEST_ASSERT_EQUAL_INT(5, n);138  TEST_ASSERT_EQUAL_STRING("Hello", (const char*)txt);139 140  /* StrAccum should NOT be reset in this branch; fields remain set */141  TEST_ASSERT_TRUE(gSnapValid);142  TEST_ASSERT_NOT_NULL(gSnap.zText);143  TEST_ASSERT_EQUAL_INT(5, gSnap.nChar);144  TEST_ASSERT_NOT_EQUAL(0, (gSnap.printfFlags & SQLITE_PRINTF_MALLOCED));145 146  finalize_and_check(pStmt);147  sqlite3_close(db);148}149 150/* Test 3: non-malloced/no-error path returns empty string and resets StrAccum */151void test_sqlite3ResultStrAccum_nonmalloced_returns_empty_and_resets(void){152  resetSnapshot();153  sqlite3 *db = open_memory_db();154 155  int rc = sqlite3_create_function_v2(db, "unit_nomalloc", 0, SQLITE_UTF8, NULL,156                                      udf_accum_nomalloc, NULL, NULL, NULL);157  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);158 159  sqlite3_stmt *pStmt = NULL;160  rc = sqlite3_prepare_v2(db, "SELECT unit_nomalloc()", -1, &pStmt, NULL);161  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);162 163  rc = sqlite3_step(pStmt);164  TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);165 166  const unsigned char *txt = sqlite3_column_text(pStmt, 0);167  int n = sqlite3_column_bytes(pStmt, 0);168  TEST_ASSERT_NOT_NULL(txt);169  TEST_ASSERT_EQUAL_INT(0, n);170  TEST_ASSERT_EQUAL_STRING("", (const char*)txt);171 172  /* StrAccum should be reset */173  TEST_ASSERT_TRUE(gSnapValid);174  TEST_ASSERT_EQUAL_PTR(NULL, gSnap.zText);175  TEST_ASSERT_EQUAL_INT(0, gSnap.nChar);176  TEST_ASSERT_EQUAL_INT(0, gSnap.nAlloc);177  TEST_ASSERT_EQUAL_INT(0, (gSnap.printfFlags & SQLITE_PRINTF_MALLOCED));178 179  finalize_and_check(pStmt);180  sqlite3_close(db);181}182 183int main(void) {184  UNITY_BEGIN();185  RUN_TEST(test_sqlite3ResultStrAccum_error_sets_error_and_resets);186  RUN_TEST(test_sqlite3ResultStrAccum_malloced_returns_text_dynamic);187  RUN_TEST(test_sqlite3ResultStrAccum_nonmalloced_returns_empty_and_resets);188  return UNITY_END();189}