AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Forward declaration of the auto-generated wrapper provided in the module */7int test_sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr);8 9/* Unity setup/teardown */10void setUp(void) {11 /* No-op */12}13void tearDown(void) {14 /* No-op */15}16 17/* Helper: create TK_INTEGER Expr with immediate value */18static Expr* makeInteger(sqlite3 *db, int v){19 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));20 TEST_ASSERT_NOT_NULL(p);21 p->op = TK_INTEGER;22 p->flags = EP_IntValue;23 p->u.iValue = v;24 return p;25}26 27/* Helper: create TK_NULL Expr */28static Expr* makeNull(sqlite3 *db){29 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));30 TEST_ASSERT_NOT_NULL(p);31 p->op = TK_NULL;32 return p;33}34 35/* Helper: create an ExprList from an array of Expr* */36static ExprList* makeExprList(sqlite3 *db, int nArg, Expr **args){37 ExprList *pList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));38 TEST_ASSERT_NOT_NULL(pList);39 if( nArg>0 ){40 pList->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item)*nArg);41 TEST_ASSERT_NOT_NULL(pList->a);42 for(int i=0; i<nArg; i++){43 pList->a[i].pExpr = args[i];44 }45 }46 pList->nExpr = nArg;47 pList->nAlloc = nArg;48 return pList;49}50 51/* Helper: create TK_FUNCTION Expr for given name and args.52 If nArg==0 and args==NULL, x.pList will be NULL to test that path. */53static Expr* makeFunction(sqlite3 *db, const char *zName, int nArg, Expr **args){54 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));55 TEST_ASSERT_NOT_NULL(p);56 p->op = TK_FUNCTION;57 p->u.zToken = (char*)zName; /* Only read by sqlite3FindFunction; safe for tests */58 if( nArg>0 ){59 p->x.pList = makeExprList(db, nArg, args);60 }else{61 p->x.pList = 0;62 }63 return p;64}65 66/* Helper: create TK_CASE Expr with optional pLeft.67 nExpr is number of items in x.pList (2 or 3 in our tests). */68static Expr* makeCase(sqlite3 *db, int nExpr, Expr **args, int withLeft){69 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));70 TEST_ASSERT_NOT_NULL(p);71 p->op = TK_CASE;72 p->x.pList = makeExprList(db, nExpr, args);73 if( withLeft ){74 p->pLeft = makeInteger(db, 0);75 }76 return p;77}78 79/* Tests for TK_FUNCTION path: iif(...) */80 81/* iif(x,y) -> true */82void test_sqlite3ExprIsIIF_function_two_args_returns_true(void){83 sqlite3 *db = 0;84 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));85 Expr *args[2];86 args[0] = makeInteger(db, 1);87 args[1] = makeInteger(db, 42);88 Expr *pFunc = makeFunction(db, "iif", 2, args);89 90 int rc = test_sqlite3ExprIsIIF(db, pFunc);91 TEST_ASSERT_EQUAL(1, rc);92 93 sqlite3ExprDelete(db, pFunc);94 sqlite3_close(db);95}96 97/* iif(x,y,NULL) -> true */98void test_sqlite3ExprIsIIF_function_three_args_third_null_returns_true(void){99 sqlite3 *db = 0;100 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));101 Expr *args[3];102 args[0] = makeInteger(db, 0);103 args[1] = makeInteger(db, 7);104 args[2] = makeNull(db);105 Expr *pFunc = makeFunction(db, "iif", 3, args);106 107 int rc = test_sqlite3ExprIsIIF(db, pFunc);108 TEST_ASSERT_EQUAL(1, rc);109 110 sqlite3ExprDelete(db, pFunc);111 sqlite3_close(db);112}113 114/* iif(x,y,0) -> true because 3rd arg is not true */115void test_sqlite3ExprIsIIF_function_three_args_third_zero_returns_true(void){116 sqlite3 *db = 0;117 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));118 Expr *args[3];119 args[0] = makeInteger(db, 0);120 args[1] = makeInteger(db, 7);121 args[2] = makeInteger(db, 0);122 Expr *pFunc = makeFunction(db, "iif", 3, args);123 124 int rc = test_sqlite3ExprIsIIF(db, pFunc);125 TEST_ASSERT_EQUAL(1, rc);126 127 sqlite3ExprDelete(db, pFunc);128 sqlite3_close(db);129}130 131/* iif(x,y,1) -> false because 3rd arg is true */132void test_sqlite3ExprIsIIF_function_three_args_third_one_returns_false(void){133 sqlite3 *db = 0;134 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));135 Expr *args[3];136 args[0] = makeInteger(db, 0);137 args[1] = makeInteger(db, 7);138 args[2] = makeInteger(db, 1);139 Expr *pFunc = makeFunction(db, "iif", 3, args);140 141 int rc = test_sqlite3ExprIsIIF(db, pFunc);142 TEST_ASSERT_EQUAL(0, rc);143 144 sqlite3ExprDelete(db, pFunc);145 sqlite3_close(db);146}147 148/* Non-iif name starting with 'i' (e.g., instr) -> false */149void test_sqlite3ExprIsIIF_function_name_instr_returns_false(void){150 sqlite3 *db = 0;151 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));152 Expr *args[2];153 args[0] = makeInteger(db, 1);154 args[1] = makeInteger(db, 2);155 Expr *pFunc = makeFunction(db, "instr", 2, args);156 157 int rc = test_sqlite3ExprIsIIF(db, pFunc);158 TEST_ASSERT_EQUAL(0, rc);159 160 sqlite3ExprDelete(db, pFunc);161 sqlite3_close(db);162}163 164/* Function name not starting with 'i'/'I' -> false */165void test_sqlite3ExprIsIIF_function_name_not_i_start_returns_false(void){166 sqlite3 *db = 0;167 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));168 Expr *args[2];169 args[0] = makeInteger(db, 1);170 args[1] = makeInteger(db, 2);171 Expr *pFunc = makeFunction(db, "jif", 2, args);172 173 int rc = test_sqlite3ExprIsIIF(db, pFunc);174 TEST_ASSERT_EQUAL(0, rc);175 176 sqlite3ExprDelete(db, pFunc);177 sqlite3_close(db);178}179 180/* iif with 4 args -> false (no such builtin with 4 args) */181void test_sqlite3ExprIsIIF_function_iif_four_args_returns_false(void){182 sqlite3 *db = 0;183 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));184 Expr *args[4];185 args[0] = makeInteger(db, 1);186 args[1] = makeInteger(db, 2);187 args[2] = makeInteger(db, 3);188 args[3] = makeInteger(db, 4);189 Expr *pFunc = makeFunction(db, "iif", 4, args);190 191 int rc = test_sqlite3ExprIsIIF(db, pFunc);192 TEST_ASSERT_EQUAL(0, rc);193 194 sqlite3ExprDelete(db, pFunc);195 sqlite3_close(db);196}197 198/* iif with NULL arglist (x.pList==0) -> false */199void test_sqlite3ExprIsIIF_function_no_arglist_returns_false(void){200 sqlite3 *db = 0;201 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));202 Expr *pFunc = makeFunction(db, "iif", 0, NULL);203 204 int rc = test_sqlite3ExprIsIIF(db, pFunc);205 TEST_ASSERT_EQUAL(0, rc);206 207 sqlite3ExprDelete(db, pFunc);208 sqlite3_close(db);209}210 211/* Tests for TK_CASE path */212 213/* CASE WHEN x THEN y END -> true (nExpr==2, pLeft==0) */214void test_sqlite3ExprIsIIF_case_two_exprs_returns_true(void){215 sqlite3 *db = 0;216 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));217 Expr *args[2];218 args[0] = makeInteger(db, 0); /* WHEN x */219 args[1] = makeInteger(db, 7); /* THEN y */220 Expr *pCase = makeCase(db, 2, args, 0);221 222 int rc = test_sqlite3ExprIsIIF(db, pCase);223 TEST_ASSERT_EQUAL(1, rc);224 225 sqlite3ExprDelete(db, pCase);226 sqlite3_close(db);227}228 229/* CASE WHEN x THEN y ELSE NULL END -> true (nExpr==3, 3rd not true) */230void test_sqlite3ExprIsIIF_case_three_exprs_third_null_returns_true(void){231 sqlite3 *db = 0;232 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));233 Expr *args[3];234 args[0] = makeInteger(db, 0);235 args[1] = makeInteger(db, 7);236 args[2] = makeNull(db); /* ELSE NULL */237 Expr *pCase = makeCase(db, 3, args, 0);238 239 int rc = test_sqlite3ExprIsIIF(db, pCase);240 TEST_ASSERT_EQUAL(1, rc);241 242 sqlite3ExprDelete(db, pCase);243 sqlite3_close(db);244}245 246/* CASE WHEN x THEN y ELSE 1 END -> false (3rd is true) */247void test_sqlite3ExprIsIIF_case_three_exprs_third_one_returns_false(void){248 sqlite3 *db = 0;249 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));250 Expr *args[3];251 args[0] = makeInteger(db, 0);252 args[1] = makeInteger(db, 7);253 args[2] = makeInteger(db, 1); /* ELSE 1 => true */254 Expr *pCase = makeCase(db, 3, args, 0);255 256 int rc = test_sqlite3ExprIsIIF(db, pCase);257 TEST_ASSERT_EQUAL(0, rc);258 259 sqlite3ExprDelete(db, pCase);260 sqlite3_close(db);261}262 263/* CASE with pLeft non-NULL -> false */264void test_sqlite3ExprIsIIF_case_with_pLeft_returns_false(void){265 sqlite3 *db = 0;266 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));267 Expr *args[2];268 args[0] = makeInteger(db, 1);269 args[1] = makeInteger(db, 2);270 Expr *pCase = makeCase(db, 2, args, 1); /* withLeft = 1 */271 272 int rc = test_sqlite3ExprIsIIF(db, pCase);273 TEST_ASSERT_EQUAL(0, rc);274 275 sqlite3ExprDelete(db, pCase);276 sqlite3_close(db);277}278 279/* Non-FUNCTION/CASE op should return false */280void test_sqlite3ExprIsIIF_non_function_non_case_returns_false(void){281 sqlite3 *db = 0;282 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));283 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));284 TEST_ASSERT_NOT_NULL(p);285 p->op = TK_INTEGER;286 p->flags = EP_IntValue;287 p->u.iValue = 5;288 289 int rc = test_sqlite3ExprIsIIF(db, p);290 TEST_ASSERT_EQUAL(0, rc);291 292 sqlite3ExprDelete(db, p);293 sqlite3_close(db);294}295 296/* Unity main */297int main(void) {298 UNITY_BEGIN();299 RUN_TEST(test_sqlite3ExprIsIIF_function_two_args_returns_true);300 RUN_TEST(test_sqlite3ExprIsIIF_function_three_args_third_null_returns_true);301 RUN_TEST(test_sqlite3ExprIsIIF_function_three_args_third_zero_returns_true);302 RUN_TEST(test_sqlite3ExprIsIIF_function_three_args_third_one_returns_false);303 RUN_TEST(test_sqlite3ExprIsIIF_function_name_instr_returns_false);304 RUN_TEST(test_sqlite3ExprIsIIF_function_name_not_i_start_returns_false);305 RUN_TEST(test_sqlite3ExprIsIIF_function_iif_four_args_returns_false);306 RUN_TEST(test_sqlite3ExprIsIIF_function_no_arglist_returns_false);307 RUN_TEST(test_sqlite3ExprIsIIF_case_two_exprs_returns_true);308 RUN_TEST(test_sqlite3ExprIsIIF_case_three_exprs_third_null_returns_true);309 RUN_TEST(test_sqlite3ExprIsIIF_case_three_exprs_third_one_returns_false);310 RUN_TEST(test_sqlite3ExprIsIIF_case_with_pLeft_returns_false);311 RUN_TEST(test_sqlite3ExprIsIIF_non_function_non_case_returns_false);312 return UNITY_END();313}