Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_sqlite3IsLikeFunction.c230 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global database handle for tests */7static sqlite3 *gDb = NULL;8 9/* Helper: allocate and zero memory tied to db */10static void *dbMalloc(sqlite3 *db, int n){11  void *p = sqlite3DbMallocZero(db, n);12  TEST_ASSERT_MESSAGE(p != NULL, "sqlite3DbMallocZero returned NULL");13  return p;14}15 16/* Helper: create a basic Expr with given op and zToken */17static Expr *makeExprOpToken(sqlite3 *db, int op, const char *zToken){18  Expr *p = (Expr*)dbMalloc(db, sizeof(Expr));19  memset(p, 0, sizeof(Expr));20  p->op = (u8)op;21  p->u.zToken = (char*)zToken; /* zToken is only read; test uses string literals */22  return p;23}24 25/* Helper: create a TK_STRING Expr with given content (no quotes) */26static Expr *makeStringExpr(sqlite3 *db, const char *z){27  return makeExprOpToken(db, TK_STRING, z);28}29 30/* Helper: create a TK_NULL Expr (content unused) */31static Expr *makeNullExpr(sqlite3 *db){32  return makeExprOpToken(db, TK_NULL, NULL);33}34 35/* Helper: free an Expr recursively if it contains an ExprList */36static void freeExpr(sqlite3 *db, Expr *p){37  if( p==NULL ) return;38  if( p->op==TK_FUNCTION && ExprUseXList(p) && p->x.pList ){39    ExprList *pList = p->x.pList;40    int i;41    for(i=0; i<pList->nExpr; i++){42      if( pList->a[i].pExpr ){43        freeExpr(db, pList->a[i].pExpr);44        pList->a[i].pExpr = NULL;45      }46    }47    sqlite3DbFree(db, pList);48    p->x.pList = NULL;49  }50  sqlite3DbFree(db, p);51}52 53/* Helper: build an ExprList with n arguments.54   If n>=1 the first two args are TK_NULL (unused by target function).55   If n==3 and escapeZ!=NULL, the third arg is TK_STRING with escapeZ;56   otherwise the third arg is TK_NULL. */57static ExprList *makeArgList(sqlite3 *db, int n, const char *escapeZ){58  if( n<=0 ){59    return NULL;60  }61  int sz = sizeof(ExprList) + (n-1) * (int)sizeof(((ExprList*)0)->a[0]);62  ExprList *pList = (ExprList*)dbMalloc(db, sz);63  memset(pList, 0, sz);64  pList->nExpr = n;65  pList->nAlloc = n;66  for(int i=0; i<n; i++){67    if( i==2 && escapeZ!=NULL ){68      pList->a[i].pExpr = makeStringExpr(db, escapeZ);69    }else{70      pList->a[i].pExpr = makeNullExpr(db);71    }72  }73  return pList;74}75 76/* Helper: construct a TK_FUNCTION Expr for a given function name with nArg args and optional escape */77static Expr *makeFuncExpr(sqlite3 *db, const char *zFunc, int nArg, const char *escapeZ){78  Expr *p = makeExprOpToken(db, TK_FUNCTION, zFunc);79  /* Ensure ExprUseXList(p) condition: op==TK_FUNCTION suffices */80  p->x.pList = makeArgList(db, nArg, escapeZ);81  return p;82}83 84void setUp(void) {85  int rc = sqlite3_open(":memory:", &gDb);86  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);87  TEST_ASSERT_NOT_NULL(gDb);88}89 90void tearDown(void) {91  if( gDb ){92    sqlite3_close(gDb);93    gDb = NULL;94  }95}96 97/* Test: LIKE with 2 arguments (no ESCAPE) */98void test_sqlite3IsLikeFunction_like_two_args_basic(void){99  Expr *p = makeFuncExpr(gDb, "like", 2, NULL);100  int isNoCase = -1;101  char aWc[4] = {0,0,0,0};102 103  int rc = sqlite3IsLikeFunction(gDb, p, &isNoCase, aWc);104  TEST_ASSERT_EQUAL_INT(1, rc);105  /* Expected wildcards for LIKE are '%' and '_' and no set */106  TEST_ASSERT_EQUAL_CHAR('%', aWc[0]);107  TEST_ASSERT_EQUAL_CHAR('_', aWc[1]);108  TEST_ASSERT_EQUAL_CHAR(0,  aWc[2]);109  TEST_ASSERT_EQUAL_CHAR(0,  aWc[3]);110  /* LIKE is case-insensitive by default */111  TEST_ASSERT_TRUE(isNoCase!=0);112 113  freeExpr(gDb, p);114}115 116/* Test: LIKE with 3 arguments and valid ESCAPE '\' */117void test_sqlite3IsLikeFunction_like_three_args_with_valid_escape(void){118  Expr *p = makeFuncExpr(gDb, "like", 3, "\\");119  int isNoCase = -1;120  char aWc[4] = {0,0,0,0};121 122  int rc = sqlite3IsLikeFunction(gDb, p, &isNoCase, aWc);123  TEST_ASSERT_EQUAL_INT(1, rc);124  TEST_ASSERT_EQUAL_CHAR('%', aWc[0]);125  TEST_ASSERT_EQUAL_CHAR('_', aWc[1]);126  TEST_ASSERT_EQUAL_CHAR(0,  aWc[2]);127  TEST_ASSERT_EQUAL_CHAR('\\', aWc[3]);128  TEST_ASSERT_TRUE(isNoCase!=0);129 130  freeExpr(gDb, p);131}132 133/* Test: LIKE with 3 args but ESCAPE equals matchAll ('%') or matchOne ('_') -> should fail */134void test_sqlite3IsLikeFunction_like_three_args_invalid_escape_same_as_wildcards(void){135  /* Escape as '%' */136  Expr *p1 = makeFuncExpr(gDb, "like", 3, "%");137  int isNoCase = -1;138  char aWc[4] = {0,0,0,0};139  int rc = sqlite3IsLikeFunction(gDb, p1, &isNoCase, aWc);140  TEST_ASSERT_EQUAL_INT(0, rc);141  freeExpr(gDb, p1);142 143  /* Escape as '_' */144  Expr *p2 = makeFuncExpr(gDb, "like", 3, "_");145  memset(aWc, 0, sizeof(aWc));146  rc = sqlite3IsLikeFunction(gDb, p2, &isNoCase, aWc);147  TEST_ASSERT_EQUAL_INT(0, rc);148  freeExpr(gDb, p2);149}150 151/* Test: LIKE with invalid ESCAPE: multi-character, empty string, or non-string token */152void test_sqlite3IsLikeFunction_like_three_args_invalid_escape_length_or_type(void){153  /* Multi-character escape "ab" */154  Expr *p1 = makeFuncExpr(gDb, "like", 3, "ab");155  int isNoCase = -1;156  char aWc[4] = {0,0,0,0};157  int rc = sqlite3IsLikeFunction(gDb, p1, &isNoCase, aWc);158  TEST_ASSERT_EQUAL_INT(0, rc);159  freeExpr(gDb, p1);160 161  /* Empty-string escape "" */162  Expr *p2 = makeFuncExpr(gDb, "like", 3, "");163  memset(aWc, 0, sizeof(aWc));164  rc = sqlite3IsLikeFunction(gDb, p2, &isNoCase, aWc);165  TEST_ASSERT_EQUAL_INT(0, rc);166  freeExpr(gDb, p2);167 168  /* Non-string token in 3rd arg: build list manually with TK_NULL as 3rd */169  Expr *p3 = makeFuncExpr(gDb, "like", 3, NULL); /* third defaults to TK_NULL in our helper */170  memset(aWc, 0, sizeof(aWc));171  rc = sqlite3IsLikeFunction(gDb, p3, &isNoCase, aWc);172  TEST_ASSERT_EQUAL_INT(0, rc);173  freeExpr(gDb, p3);174}175 176/* Test: x.pList is NULL -> should return 0 */177void test_sqlite3IsLikeFunction_null_arglist_returns_false(void){178  Expr *p = makeExprOpToken(gDb, TK_FUNCTION, "like");179  /* Intentionally leave x.pList NULL */180  int isNoCase = -1;181  char aWc[4] = {0,0,0,0};182 183  int rc = sqlite3IsLikeFunction(gDb, p, &isNoCase, aWc);184  TEST_ASSERT_EQUAL_INT(0, rc);185 186  freeExpr(gDb, p);187}188 189/* Test: Non-LIKE-style function (substr) -> should return 0 */190void test_sqlite3IsLikeFunction_non_like_function_returns_false(void){191  Expr *p = makeFuncExpr(gDb, "substr", 2, NULL);192  int isNoCase = -1;193  char aWc[4] = {0,0,0,0};194 195  int rc = sqlite3IsLikeFunction(gDb, p, &isNoCase, aWc);196  TEST_ASSERT_EQUAL_INT(0, rc);197 198  freeExpr(gDb, p);199}200 201/* Test: GLOB with 2 arguments -> should return 1, case-sensitive, and expected wildcards */202void test_sqlite3IsLikeFunction_glob_two_args_casesensitive(void){203  Expr *p = makeFuncExpr(gDb, "glob", 2, NULL);204  int isNoCase = -1;205  char aWc[4] = {0,0,0,0};206 207  int rc = sqlite3IsLikeFunction(gDb, p, &isNoCase, aWc);208  TEST_ASSERT_EQUAL_INT(1, rc);209  /* Expected glob wildcards: '*', '?', '[' */210  TEST_ASSERT_EQUAL_CHAR('*', aWc[0]);211  TEST_ASSERT_EQUAL_CHAR('?', aWc[1]);212  TEST_ASSERT_EQUAL_CHAR('[', aWc[2]);213  TEST_ASSERT_EQUAL_CHAR(0,  aWc[3]);214  /* GLOB is case-sensitive */215  TEST_ASSERT_FALSE(isNoCase!=0);216 217  freeExpr(gDb, p);218}219 220int main(void) {221  UNITY_BEGIN();222  RUN_TEST(test_sqlite3IsLikeFunction_like_two_args_basic);223  RUN_TEST(test_sqlite3IsLikeFunction_like_three_args_with_valid_escape);224  RUN_TEST(test_sqlite3IsLikeFunction_like_three_args_invalid_escape_same_as_wildcards);225  RUN_TEST(test_sqlite3IsLikeFunction_like_three_args_invalid_escape_length_or_type);226  RUN_TEST(test_sqlite3IsLikeFunction_null_arglist_returns_false);227  RUN_TEST(test_sqlite3IsLikeFunction_non_like_function_returns_false);228  RUN_TEST(test_sqlite3IsLikeFunction_glob_two_args_casesensitive);229  return UNITY_END();230}