| #include "sqliteInt.h" |
| #include "unity.h" |
| #include <string.h> |
| #include <stdio.h> |
|
|
| |
| extern int test_isRealTable(Parse *pParse, Table *pTab, int iOp); |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| static sqlite3* open_mem_db(void){ |
| sqlite3 *db = 0; |
| int rc = sqlite3_open(":memory:", &db); |
| TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed"); |
| TEST_ASSERT_NOT_NULL_MESSAGE(db, "db is NULL after sqlite3_open"); |
| return db; |
| } |
|
|
| static void clear_parse_err(sqlite3 *db, Parse *pParse){ |
| if( pParse->zErrMsg ){ |
| sqlite3DbFree(db, pParse->zErrMsg); |
| pParse->zErrMsg = 0; |
| } |
| } |
|
|
| |
| static void init_parse(Parse *pParse, sqlite3 *db){ |
| memset(pParse, 0, sizeof(*pParse)); |
| pParse->db = db; |
| } |
|
|
| |
| static void make_real_table(Table *pTab, const char *zName){ |
| memset(pTab, 0, sizeof(*pTab)); |
| pTab->zName = (char*)zName; |
| } |
|
|
| |
| static void make_view_table(Table *pTab, const char *zName){ |
| memset(pTab, 0, sizeof(*pTab)); |
| pTab->zName = (char*)zName; |
| |
| static Select dummySelect; |
| memset(&dummySelect, 0, sizeof(dummySelect)); |
| pTab->pSelect = &dummySelect; |
| #ifdef TF_View |
| pTab->tabFlags |= TF_View; |
| #endif |
| } |
|
|
| |
| static void make_virtual_table(Table *pTab, const char *zName){ |
| memset(pTab, 0, sizeof(*pTab)); |
| pTab->zName = (char*)zName; |
| #ifdef TF_Virtual |
| pTab->tabFlags |= TF_Virtual; |
| #else |
| |
| pTab->tabFlags = 0xFFFFFFFF; |
| #endif |
| } |
|
|
| void test_isRealTable_returns_zero_for_real_table(void){ |
| sqlite3 *db = open_mem_db(); |
| Parse parse; |
| init_parse(&parse, db); |
|
|
| Table tab; |
| make_real_table(&tab, "t_real"); |
|
|
| int rc = test_isRealTable(&parse, &tab, 0); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
| TEST_ASSERT_NULL(parse.zErrMsg); |
|
|
| sqlite3_close(db); |
| } |
|
|
| void test_isRealTable_view_rename_columns_sets_error(void){ |
| sqlite3 *db = open_mem_db(); |
| Parse parse; |
| init_parse(&parse, db); |
|
|
| Table tab; |
| make_view_table(&tab, "v1"); |
|
|
| int rc = test_isRealTable(&parse, &tab, 0); |
| TEST_ASSERT_EQUAL_INT(1, rc); |
| TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
| |
| const char *msg = parse.zErrMsg; |
| TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "rename columns of")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "view")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "\"v1\"")); |
|
|
| clear_parse_err(db, &parse); |
| sqlite3_close(db); |
| } |
|
|
| void test_isRealTable_view_drop_column_sets_error(void){ |
| sqlite3 *db = open_mem_db(); |
| Parse parse; |
| init_parse(&parse, db); |
|
|
| Table tab; |
| make_view_table(&tab, "v_drop"); |
|
|
| int rc = test_isRealTable(&parse, &tab, 1); |
| TEST_ASSERT_EQUAL_INT(1, rc); |
| TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
| const char *msg = parse.zErrMsg; |
| TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "drop column from")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "view")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "\"v_drop\"")); |
|
|
| clear_parse_err(db, &parse); |
| sqlite3_close(db); |
| } |
|
|
| void test_isRealTable_virtual_edit_constraints_sets_error(void){ |
| sqlite3 *db = open_mem_db(); |
| Parse parse; |
| init_parse(&parse, db); |
|
|
| Table tab; |
| make_virtual_table(&tab, "vt1"); |
|
|
| int rc = test_isRealTable(&parse, &tab, 2); |
| TEST_ASSERT_EQUAL_INT(1, rc); |
| TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
| const char *msg = parse.zErrMsg; |
| TEST_ASSERT_NOT_NULL(strstr(msg, "cannot ")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "edit constraints of")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "\"vt1\"")); |
|
|
| clear_parse_err(db, &parse); |
| sqlite3_close(db); |
| } |
|
|
| void test_isRealTable_both_view_and_virtual_prefers_virtual_in_message(void){ |
| sqlite3 *db = open_mem_db(); |
| Parse parse; |
| init_parse(&parse, db); |
|
|
| Table tab; |
| make_view_table(&tab, "bothy"); |
| |
| #ifdef TF_Virtual |
| tab.tabFlags |= TF_Virtual; |
| #endif |
|
|
| int rc = test_isRealTable(&parse, &tab, 0); |
| TEST_ASSERT_EQUAL_INT(1, rc); |
| TEST_ASSERT_NOT_NULL(parse.zErrMsg); |
|
|
| const char *msg = parse.zErrMsg; |
| |
| TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table")); |
| TEST_ASSERT_NOT_NULL(strstr(msg, "\"bothy\"")); |
|
|
| clear_parse_err(db, &parse); |
| sqlite3_close(db); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_isRealTable_returns_zero_for_real_table); |
| RUN_TEST(test_isRealTable_view_rename_columns_sets_error); |
| RUN_TEST(test_isRealTable_view_drop_column_sets_error); |
| RUN_TEST(test_isRealTable_virtual_edit_constraints_sets_error); |
| RUN_TEST(test_isRealTable_both_view_and_virtual_prefers_virtual_in_message); |
| return UNITY_END(); |
| } |