Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_json_jsonGroupInverse.c175 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Forward declaration of the wrapper added in the module */7void test_jsonGroupInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv);8 9static sqlite3 *gDb = NULL;10 11/* Aggregate context structure is JsonString, which is defined in SQLite core.12   We only need to set zBuf and nUsed for jsonGroupInverse to work. */13 14/* Aggregate step: initialize aggregate context with provided JSON text */15static void do_inv_step(sqlite3_context *ctx, int argc, sqlite3_value **argv){16  const unsigned char *zIn;17  int nIn;18  JsonString *pStr;19 20  if( argc<1 || sqlite3_value_type(argv[0])==SQLITE_NULL ){21    /* Create an empty buffer if NULL passed */22    zIn = (const unsigned char *)"[]";23    nIn = 2;24  }else{25    zIn = sqlite3_value_text(argv[0]);26    nIn = sqlite3_value_bytes(argv[0]);27  }28 29  pStr = (JsonString*)sqlite3_aggregate_context(ctx, (int)sizeof(JsonString));30  if( pStr==0 ) return; /* Out of memory or mis-use; let SQLite signal error later */31  memset(pStr, 0, sizeof(*pStr));32 33  /* Allocate buffer and copy input JSON text */34  pStr->zBuf = (char*)sqlite3_malloc64((sqlite3_uint64)nIn + 1);35  if( pStr->zBuf==0 ){36    sqlite3_result_error_nomem(ctx);37    return;38  }39  memcpy(pStr->zBuf, zIn, (size_t)nIn);40  pStr->zBuf[nIn] = 0;41  pStr->nUsed = (u32)nIn;42}43 44/* Aggregate final: call the inverse function, then return the mutated JSON text */45static void do_inv_final(sqlite3_context *ctx){46  JsonString *pStr;47  /* Invoke the target under test */48  test_jsonGroupInverse(ctx, 0, 0);49 50  /* Retrieve the aggregate context and return the resulting buffer */51  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);52  if( pStr && pStr->zBuf ){53    sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);54    sqlite3_free(pStr->zBuf);55    pStr->zBuf = 0;56  }else{57    sqlite3_result_null(ctx);58  }59}60 61/* Helper to register the aggregate that will drive jsonGroupInverse */62static void register_do_inv(sqlite3 *db){63  int rc = sqlite3_create_function_v2(db, "do_inv", 1, SQLITE_UTF8, 0,64                                      0, do_inv_step, do_inv_final, 0);65  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to register do_inv()");66}67 68/* Helper to run SELECT do_inv(?) and return heap-allocated result string */69static char *run_do_inv(sqlite3 *db, const char *input){70  sqlite3_stmt *pStmt = 0;71  int rc;72  const unsigned char *zRes;73  int nRes;74  char *zOut = NULL;75 76  rc = sqlite3_prepare_v2(db, "SELECT do_inv(?)", -1, &pStmt, 0);77  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");78 79  rc = sqlite3_bind_text(pStmt, 1, input, -1, SQLITE_TRANSIENT);80  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "bind failed");81 82  rc = sqlite3_step(pStmt);83  TEST_ASSERT_TRUE_MESSAGE(rc==SQLITE_ROW, "step did not return a row");84 85  zRes = sqlite3_column_text(pStmt, 0);86  nRes = sqlite3_column_bytes(pStmt, 0);87 88  if( zRes ){89    zOut = (char*)sqlite3_malloc64((sqlite3_uint64)nRes + 1);90    TEST_ASSERT_NOT_NULL_MESSAGE(zOut, "malloc for result failed");91    memcpy(zOut, zRes, (size_t)nRes);92    zOut[nRes] = 0;93  }94 95  rc = sqlite3_finalize(pStmt);96  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "finalize failed");97  return zOut;98}99 100void setUp(void) {101  int rc = sqlite3_open(":memory:", &gDb);102  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");103  register_do_inv(gDb);104}105 106void tearDown(void) {107  if( gDb ){108    int rc = sqlite3_close(gDb);109    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");110    gDb = NULL;111  }112}113 114/* Tests */115 116void test_jsonGroupInverse_array_simple(void) {117  const char *input = "[1,2,3]";118  char *out = run_do_inv(gDb, input);119  TEST_ASSERT_NOT_NULL(out);120  TEST_ASSERT_EQUAL_STRING("[2,3]", out);121  sqlite3_free(out);122}123 124void test_jsonGroupInverse_array_string_with_comma(void) {125  const char *input = "[\"a,b\",\"c\"]";126  char *out = run_do_inv(gDb, input);127  TEST_ASSERT_NOT_NULL(out);128  TEST_ASSERT_EQUAL_STRING("[\"c\"]", out);129  sqlite3_free(out);130}131 132void test_jsonGroupInverse_array_nested(void) {133  const char *input = "[{\"x\":1,\"y\":[2,3]},4,5]";134  char *out = run_do_inv(gDb, input);135  TEST_ASSERT_NOT_NULL(out);136  TEST_ASSERT_EQUAL_STRING("[4,5]", out);137  sqlite3_free(out);138}139 140void test_jsonGroupInverse_object_simple(void) {141  const char *input = "{\"a\":1,\"b\":2}";142  char *out = run_do_inv(gDb, input);143  TEST_ASSERT_NOT_NULL(out);144  TEST_ASSERT_EQUAL_STRING("{\"b\":2}", out);145  sqlite3_free(out);146}147 148void test_jsonGroupInverse_single_element_array(void) {149  const char *input = "[1]";150  char *out = run_do_inv(gDb, input);151  TEST_ASSERT_NOT_NULL(out);152  /* With no comma found, nUsed is set to 1, leaving just the opening bracket */153  TEST_ASSERT_EQUAL_STRING("[", out);154  sqlite3_free(out);155}156 157void test_jsonGroupInverse_escapes_and_commas_inside_string(void) {158  /* First element contains an escaped quote and a comma; it should be skipped correctly */159  const char *input = "[\"ab\\\"cd,ef\",\"Z\"]";160  char *out = run_do_inv(gDb, input);161  TEST_ASSERT_NOT_NULL(out);162  TEST_ASSERT_EQUAL_STRING("[\"Z\"]", out);163  sqlite3_free(out);164}165 166int main(void) {167  UNITY_BEGIN();168  RUN_TEST(test_jsonGroupInverse_array_simple);169  RUN_TEST(test_jsonGroupInverse_array_string_with_comma);170  RUN_TEST(test_jsonGroupInverse_array_nested);171  RUN_TEST(test_jsonGroupInverse_object_simple);172  RUN_TEST(test_jsonGroupInverse_single_element_array);173  RUN_TEST(test_jsonGroupInverse_escapes_and_commas_inside_string);174  return UNITY_END();175}