Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_concatFuncCore.c220 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper function provided in the source module */7extern void test_concatFuncCore(sqlite3_context *context, int argc, sqlite3_value **argv, int nSep, const char *zSep);8 9static sqlite3 *gDb = NULL;10static sqlite3_context gCtx;11static Mem gOut; /* Output Mem for sqlite3_context */12 13/* Helper: reset the sqlite3_context and output Mem before each call */14static void reset_context(void){15  memset(&gOut, 0, sizeof(gOut));16  gOut.db = gDb;       /* Important so sqlite3_result_* can allocate/free */17  memset(&gCtx, 0, sizeof(gCtx));18  gCtx.pOut = &gOut;19}20 21/* Helper: create a sqlite3_value* with a UTF-8 string. If s==NULL, returns a NULL value */22static sqlite3_value* makeTextVal(const char *s){23  sqlite3_value *v = sqlite3ValueNew(gDb);24  TEST_ASSERT_NOT_NULL_MESSAGE(v, "sqlite3ValueNew returned NULL");25  if( s!=NULL ){26    sqlite3ValueSetStr(v, -1, (const void*)s, SQLITE_UTF8, SQLITE_STATIC);27  }28  return v;29}30 31/* Helper: verify the output equals expected string exactly */32static void assert_out_eq(const char *expected){33  size_t nExp = strlen(expected);34  TEST_ASSERT_EQUAL_UINT64_MESSAGE(nExp, (unsigned long long)gOut.n, "Output length mismatch");35  TEST_ASSERT_NOT_NULL_MESSAGE(gOut.z, "Output string pointer is NULL");36  /* Ensure NUL-terminated */37  TEST_ASSERT_EQUAL_INT8_MESSAGE(0, gOut.z[gOut.n], "Output string not NUL-terminated");38  /* Compare exact bytes (including potential embedded NULs if any) */39  TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, gOut.z, nExp, "Output content mismatch");40}41 42/* Unity setup/teardown */43void setUp(void) {44  if( gDb==NULL ){45    int rc = sqlite3_open(":memory:", &gDb);46    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory sqlite3 db");47  }48  reset_context();49}50void tearDown(void) {51  /* Release any memory held by output Mem */52  sqlite3VdbeMemRelease(&gOut);53  memset(&gOut, 0, sizeof(gOut));54}55 56/* Tests */57 58void test_concatFuncCore_simple_no_separator(void){59  sqlite3_value *argv[3];60  argv[0] = makeTextVal("a");61  argv[1] = makeTextVal("b");62  argv[2] = makeTextVal("c");63 64  test_concatFuncCore(&gCtx, 3, argv, 0, NULL);65 66  assert_out_eq("abc");67 68  sqlite3ValueFree(argv[0]);69  sqlite3ValueFree(argv[1]);70  sqlite3ValueFree(argv[2]);71}72 73void test_concatFuncCore_with_separator_all_non_null(void){74  sqlite3_value *argv[3];75  argv[0] = makeTextVal("apple");76  argv[1] = makeTextVal("banana");77  argv[2] = makeTextVal("cherry");78 79  const char *sep = "-";80  test_concatFuncCore(&gCtx, 3, argv, (int)strlen(sep), sep);81 82  assert_out_eq("apple-banana-cherry");83 84  sqlite3ValueFree(argv[0]);85  sqlite3ValueFree(argv[1]);86  sqlite3ValueFree(argv[2]);87}88 89void test_concatFuncCore_with_nulls_ignored_and_separators_only_between_nonnull(void){90  sqlite3_value *argv[4];91  argv[0] = makeTextVal("a");92  argv[1] = makeTextVal(NULL);  /* NULL */93  argv[2] = makeTextVal("b");94  argv[3] = makeTextVal(NULL);  /* NULL */95 96  const char *sep = ":";97  test_concatFuncCore(&gCtx, 4, argv, (int)strlen(sep), sep);98 99  assert_out_eq("a:b");100 101  sqlite3ValueFree(argv[0]);102  sqlite3ValueFree(argv[1]);103  sqlite3ValueFree(argv[2]);104  sqlite3ValueFree(argv[3]);105}106 107void test_concatFuncCore_all_nulls_returns_empty_string(void){108  sqlite3_value *argv[3];109  argv[0] = makeTextVal(NULL);110  argv[1] = makeTextVal(NULL);111  argv[2] = makeTextVal(NULL);112 113  const char *sep = "/";114  test_concatFuncCore(&gCtx, 3, argv, (int)strlen(sep), sep);115 116  assert_out_eq("");117 118  sqlite3ValueFree(argv[0]);119  sqlite3ValueFree(argv[1]);120  sqlite3ValueFree(argv[2]);121}122 123void test_concatFuncCore_empty_strings_are_nonnull_and_produce_separators(void){124  sqlite3_value *argv[2];125  argv[0] = makeTextVal("");126  argv[1] = makeTextVal("");127 128  const char *sep = ",";129  test_concatFuncCore(&gCtx, 2, argv, (int)strlen(sep), sep);130 131  /* Two empty but non-NULL strings -> separator appears between them */132  assert_out_eq(",");133 134  sqlite3ValueFree(argv[0]);135  sqlite3ValueFree(argv[1]);136}137 138void test_concatFuncCore_utf8_multibyte_inputs_and_separator(void){139  /* Use multibyte UTF-8 characters */140  const char *s1 = "éclair";          /* 'é' is multibyte in UTF-8 */141  const char *s2 = "你";              /* Chinese character */142  const char *s3 = "🙂";              /* Emoji */143  const char *sep = "—";              /* em dash, multibyte */144 145  sqlite3_value *argv[3];146  argv[0] = makeTextVal(s1);147  argv[1] = makeTextVal(s2);148  argv[2] = makeTextVal(s3);149 150  test_concatFuncCore(&gCtx, 3, argv, (int)strlen(sep), sep);151 152  char expected[256];153  memset(expected, 0, sizeof(expected));154  /* Build expected using standard C string concatenation */155  strcpy(expected, s1);156  strcat(expected, sep);157  strcat(expected, s2);158  strcat(expected, sep);159  strcat(expected, s3);160 161  assert_out_eq(expected);162 163  sqlite3ValueFree(argv[0]);164  sqlite3ValueFree(argv[1]);165  sqlite3ValueFree(argv[2]);166}167 168void test_concatFuncCore_zero_length_separator(void){169  sqlite3_value *argv[3];170  argv[0] = makeTextVal("x");171  argv[1] = makeTextVal("y");172  argv[2] = makeTextVal("z");173 174  const char *sep = ""; /* zero-length separator */175  test_concatFuncCore(&gCtx, 3, argv, 0, sep);176 177  assert_out_eq("xyz");178 179  sqlite3ValueFree(argv[0]);180  sqlite3ValueFree(argv[1]);181  sqlite3ValueFree(argv[2]);182}183 184void test_concatFuncCore_mixed_empty_and_null(void){185  sqlite3_value *argv[3];186  argv[0] = makeTextVal("");187  argv[1] = makeTextVal(NULL);188  argv[2] = makeTextVal("");189 190  const char *sep = ":";191  test_concatFuncCore(&gCtx, 3, argv, (int)strlen(sep), sep);192 193  /* Two non-NULL empties with a NULL in the middle -> just the separator */194  assert_out_eq(":");195 196  sqlite3ValueFree(argv[0]);197  sqlite3ValueFree(argv[1]);198  sqlite3ValueFree(argv[2]);199}200 201int main(void) {202  UNITY_BEGIN();203 204  RUN_TEST(test_concatFuncCore_simple_no_separator);205  RUN_TEST(test_concatFuncCore_with_separator_all_non_null);206  RUN_TEST(test_concatFuncCore_with_nulls_ignored_and_separators_only_between_nonnull);207  RUN_TEST(test_concatFuncCore_all_nulls_returns_empty_string);208  RUN_TEST(test_concatFuncCore_empty_strings_are_nonnull_and_produce_separators);209  RUN_TEST(test_concatFuncCore_utf8_multibyte_inputs_and_separator);210  RUN_TEST(test_concatFuncCore_zero_length_separator);211  RUN_TEST(test_concatFuncCore_mixed_empty_and_null);212 213  /* Clean up global DB */214  if( gDb ){215    sqlite3_close(gDb);216    gDb = NULL;217  }218 219  return UNITY_END();220}