| #include "sqliteInt.h" |
| #include "unity.h" |
| #include <string.h> |
|
|
| |
| static sqlite3 *gDb = NULL; |
|
|
| static Expr* make_id_expr(Parse *pParse, const char *zId){ |
| Token t; |
| t.z = (char*)zId; |
| t.n = (int)strlen(zId); |
| return sqlite3ExprAlloc(pParse->db, TK_ID, &t, 0); |
| } |
|
|
| static Expr* make_int_expr(Parse *pParse, const char *zNum){ |
| Token t; |
| t.z = (char*)zNum; |
| t.n = (int)strlen(zNum); |
| return sqlite3ExprAlloc(pParse->db, TK_INTEGER, &t, 0); |
| } |
|
|
| void setUp(void) { |
| if (!gDb) { |
| int rc = sqlite3_open(":memory:", &gDb); |
| TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory DB"); |
| } |
| } |
|
|
| void tearDown(void) { |
| if (gDb) { |
| int rc = sqlite3_close(gDb); |
| TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to close in-memory DB"); |
| gDb = NULL; |
| } |
| } |
|
|
| |
| static void initParse(Parse *pParse){ |
| memset(pParse, 0, sizeof(Parse)); |
| pParse->db = gDb; |
| |
| pParse->eParseMode = PARSE_MODE_RENAME; |
| } |
|
|
| |
| void test_sqlite3RenameExprUnmap_restores_mode_when_expr_null(void){ |
| Parse sParse; |
| initParse(&sParse); |
| u8 orig = sParse.eParseMode; |
|
|
| sqlite3RenameExprUnmap(&sParse, NULL); |
|
|
| TEST_ASSERT_EQUAL_UINT8(orig, sParse.eParseMode); |
| TEST_ASSERT_EQUAL_INT(0, sParse.nErr); |
| } |
|
|
| |
| void test_sqlite3RenameExprUnmap_restores_mode_when_expr_simple(void){ |
| Parse sParse; |
| initParse(&sParse); |
|
|
| Expr *pInt = make_int_expr(&sParse, "123"); |
| TEST_ASSERT_NOT_NULL(pInt); |
|
|
| u8 orig = sParse.eParseMode; |
| sqlite3RenameExprUnmap(&sParse, pInt); |
|
|
| TEST_ASSERT_EQUAL_UINT8(orig, sParse.eParseMode); |
| TEST_ASSERT_EQUAL_INT(0, sParse.nErr); |
|
|
| sqlite3ExprDelete(sParse.db, pInt); |
| } |
|
|
| |
| void test_sqlite3RenameExprUnmap_does_not_modify_tree(void){ |
| Parse sParse; |
| initParse(&sParse); |
|
|
| Expr *pA = make_id_expr(&sParse, "a"); |
| Expr *pB = make_id_expr(&sParse, "b"); |
| TEST_ASSERT_NOT_NULL(pA); |
| TEST_ASSERT_NOT_NULL(pB); |
|
|
| Expr *pPlus = sqlite3PExpr(&sParse, TK_PLUS, pA, pB); |
| TEST_ASSERT_NOT_NULL(pPlus); |
|
|
| Expr *pLeftBefore = pPlus->pLeft; |
| Expr *pRightBefore = pPlus->pRight; |
|
|
| sqlite3RenameExprUnmap(&sParse, pPlus); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(pLeftBefore, pPlus->pLeft); |
| TEST_ASSERT_EQUAL_PTR(pRightBefore, pPlus->pRight); |
| TEST_ASSERT_EQUAL_INT(0, sParse.nErr); |
|
|
| sqlite3ExprDelete(sParse.db, pPlus); |
| } |
|
|
| |
| void test_sqlite3RenameExprUnmap_handles_nested_tree_no_side_effects(void){ |
| Parse sParse; |
| initParse(&sParse); |
|
|
| |
| Expr *pA = make_id_expr(&sParse, "a"); |
| Expr *pB = make_id_expr(&sParse, "b"); |
| Expr *pPlus = sqlite3PExpr(&sParse, TK_PLUS, pA, pB); |
| TEST_ASSERT_NOT_NULL(pA); |
| TEST_ASSERT_NOT_NULL(pB); |
| TEST_ASSERT_NOT_NULL(pPlus); |
|
|
| Expr *pThree = make_int_expr(&sParse, "3"); |
| TEST_ASSERT_NOT_NULL(pThree); |
|
|
| |
| Expr *pMul = sqlite3PExpr(&sParse, TK_STAR, pPlus, pThree); |
| TEST_ASSERT_NOT_NULL(pMul); |
|
|
| u8 orig = sParse.eParseMode; |
| sqlite3RenameExprUnmap(&sParse, pMul); |
|
|
| |
| TEST_ASSERT_EQUAL_UINT8(orig, sParse.eParseMode); |
| TEST_ASSERT_EQUAL_INT(0, sParse.nErr); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(pPlus, pMul->pLeft); |
| TEST_ASSERT_EQUAL_PTR(pThree, pMul->pRight); |
|
|
| sqlite3ExprDelete(sParse.db, pMul); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_sqlite3RenameExprUnmap_restores_mode_when_expr_null); |
| RUN_TEST(test_sqlite3RenameExprUnmap_restores_mode_when_expr_simple); |
| RUN_TEST(test_sqlite3RenameExprUnmap_does_not_modify_tree); |
| RUN_TEST(test_sqlite3RenameExprUnmap_handles_nested_tree_no_side_effects); |
| return UNITY_END(); |
| } |