File size: 6,705 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Wrapper provided by the SQLite build for static function renameTableTest */
extern void test_renameTableTest(sqlite3_context*, int, sqlite3_value**);
static sqlite3 *gDb = NULL;
/* Bridge function to invoke the wrapper from SQL */
static void unit_rename_table_test(sqlite3_context *ctx, int argc, sqlite3_value **argv){
/* Directly forward to the provided test_ wrapper */
test_renameTableTest(ctx, argc, argv);
}
static void exec_ok(const char *sql){
char *errmsg = NULL;
int rc = sqlite3_exec(gDb, sql, 0, 0, &errmsg);
if( rc!=SQLITE_OK ){
const char *msg = errmsg ? errmsg : "exec failed";
TEST_FAIL_MESSAGE(msg);
}
sqlite3_free(errmsg);
}
/* Helper to call the unit function; returns the sqlite3_step rc.
** If SQLITE_ROW, *pColType is set to the type of column 0. */
static int call_unit_fn(
const char *zDb,
const char *zInput,
const char *zType,
const char *zName,
int isTemp,
const char *zWhen,
int bNoDQS,
sqlite3_stmt **ppStmt,
int *pColType
){
char *sql = sqlite3_mprintf(
"SELECT unit_rename_table_test(%Q,%Q,%Q,%Q,%d,%Q,%d)",
zDb, zInput, zType, zName, isTemp, zWhen, bNoDQS
);
TEST_ASSERT_NOT_NULL(sql);
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2(gDb, sql, -1, &stmt, 0);
sqlite3_free(sql);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
rc = sqlite3_step(stmt);
if( rc==SQLITE_ROW ){
if( pColType ) *pColType = sqlite3_column_type(stmt, 0);
}
if( ppStmt ) *ppStmt = stmt; else sqlite3_finalize(stmt);
return rc;
}
void setUp(void) {
int rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Register the 7-arg unit test SQL function */
rc = sqlite3_create_function(gDb, "unit_rename_table_test", 7, SQLITE_UTF8,
NULL, unit_rename_table_test, NULL, NULL);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
void tearDown(void) {
if( gDb ){
sqlite3_close(gDb);
gDb = NULL;
}
}
/* 1) Valid CREATE TABLE -> returns NULL */
void test_renameTableTest_create_table_returns_null(void){
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", "CREATE TABLE t1(a)", "table", "t1", 0, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_NULL, colType);
sqlite3_finalize(stmt);
}
/* 2) Invalid SQL with writable_schema OFF -> raises error with contextual message */
void test_renameTableTest_invalid_sql_raises_error_without_writable_schema(void){
/* Missing closing parenthesis */
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", "CREATE TABLE t1(a", "table", "t1", 0, "when", 0, &stmt, NULL);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
sqlite3_finalize(stmt);
const char *errmsg = sqlite3_errmsg(gDb);
TEST_ASSERT_NOT_NULL(errmsg);
TEST_ASSERT_NOT_NULL(strstr(errmsg, "error in table t1 when:"));
}
/* 3) Invalid SQL with writable_schema ON -> returns NULL instead of error */
void test_renameTableTest_invalid_sql_returns_null_with_writable_schema(void){
exec_ok("PRAGMA writable_schema=ON");
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", "CREATE TABLE t1(a", "table", "t1", 0, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_NULL, colType);
sqlite3_finalize(stmt);
exec_ok("PRAGMA writable_schema=OFF");
}
/* 4) Trigger on main.t1, zDb='main' -> returns 1 */
void test_renameTableTest_trigger_on_main_returns_1_in_main_db(void){
exec_ok("CREATE TABLE t1(x)");
const char *trigSql = "CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END";
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", trigSql, "trigger", "tr1", 0, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_INTEGER, colType);
TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(stmt, 0));
sqlite3_finalize(stmt);
}
/* 5) Trigger on main.t1, zDb='temp' -> returns NULL (no match) */
void test_renameTableTest_trigger_on_main_returns_null_in_temp_db(void){
exec_ok("CREATE TABLE t1(x)");
const char *trigSql = "CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END";
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("temp", trigSql, "trigger", "tr1", 1, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_NULL, colType);
sqlite3_finalize(stmt);
}
/* 6) Trigger on temp.t2, zDb='temp' -> returns 1 */
void test_renameTableTest_trigger_on_temp_returns_1_in_temp_db(void){
exec_ok("CREATE TEMP TABLE t2(y)");
const char *trigSql = "CREATE TRIGGER tr2 AFTER INSERT ON t2 BEGIN SELECT 1; END";
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("temp", trigSql, "trigger", "tr2", 1, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_INTEGER, colType);
TEST_ASSERT_EQUAL_INT(1, sqlite3_column_int(stmt, 0));
sqlite3_finalize(stmt);
}
/* 7) View with double-quoted string: with DQS enabled (bNoDQS=0) -> returns NULL */
void test_renameTableTest_view_dqs_enabled_returns_null(void){
const char *viewSql = "CREATE VIEW v1 AS SELECT \"string\"";
int colType = -1;
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", viewSql, "view", "v1", 0, "when", 0, &stmt, &colType);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_NULL, colType);
sqlite3_finalize(stmt);
}
/* 8) Same view with DQS disabled (bNoDQS=1) -> unresolved identifier error */
void test_renameTableTest_view_dqs_disabled_raises_error(void){
const char *viewSql = "CREATE VIEW v1 AS SELECT \"string\"";
sqlite3_stmt *stmt = NULL;
int rc = call_unit_fn("main", viewSql, "view", "v1", 0, "when", 1, &stmt, NULL);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
sqlite3_finalize(stmt);
const char *errmsg = sqlite3_errmsg(gDb);
TEST_ASSERT_NOT_NULL(errmsg);
TEST_ASSERT_NOT_NULL(strstr(errmsg, "error in view v1 when:"));
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_renameTableTest_create_table_returns_null);
RUN_TEST(test_renameTableTest_invalid_sql_raises_error_without_writable_schema);
RUN_TEST(test_renameTableTest_invalid_sql_returns_null_with_writable_schema);
RUN_TEST(test_renameTableTest_trigger_on_main_returns_1_in_main_db);
RUN_TEST(test_renameTableTest_trigger_on_main_returns_null_in_temp_db);
RUN_TEST(test_renameTableTest_trigger_on_temp_returns_1_in_temp_db);
RUN_TEST(test_renameTableTest_view_dqs_enabled_returns_null);
RUN_TEST(test_renameTableTest_view_dqs_disabled_raises_error);
return UNITY_END();
} |