#include "sqliteInt.h" #include "unity.h" #include #include static sqlite3 *gDb = NULL; static FuncDef* mustFindFunc(const char *zName, int nArg){ FuncDef *pDef = sqlite3FindFunction(gDb, zName, nArg, SQLITE_UTF8, 0); TEST_ASSERT_MESSAGE(pDef != NULL, "Expected function not found"); TEST_ASSERT_EQUAL_INT_MESSAGE(nArg, pDef->nArg, "Function arity mismatch"); return pDef; } void setUp(void) { int rc; /* Ensure the ALTER functions are registered before a connection is opened */ sqlite3AlterFunctions(); rc = sqlite3_open(":memory:", &gDb); TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed"); } void tearDown(void) { if( gDb ){ sqlite3_close(gDb); gDb = NULL; } } void test_sqlite3AlterFunctions_registers_all_expected_functions(void){ struct { const char *zName; int nArg; } aFuncs[] = { { "sqlite_rename_column", 9 }, { "sqlite_rename_table", 7 }, { "sqlite_rename_test", 7 }, { "sqlite_drop_column", 3 }, { "sqlite_rename_quotefix", 2 }, { "sqlite_drop_constraint", 2 }, { "sqlite_fail", 2 }, { "sqlite_add_constraint", 3 }, { "sqlite_find_constraint", 2 }, }; for(size_t i=0; ifuncFlags & SQLITE_FUNC_INTERNAL)!=0, "Function not flagged as internal"); TEST_ASSERT_MESSAGE(pDef->xSFunc != NULL, "xSFunc should be non-NULL for internal scalar"); } } void test_sqlite3AlterFunctions_case_insensitive_lookup(void){ FuncDef *p1 = sqlite3FindFunction(gDb, "SQLITE_RENAME_TABLE", 7, SQLITE_UTF8, 0); TEST_ASSERT_NOT_NULL(p1); TEST_ASSERT_EQUAL_INT(7, p1->nArg); TEST_ASSERT_TRUE((p1->funcFlags & SQLITE_FUNC_INTERNAL)!=0); } void test_sqlite3AlterFunctions_wrong_arity_returns_null(void){ /* These internal functions have fixed arity; wrong arity should not resolve */ FuncDef *pBad1 = sqlite3FindFunction(gDb, "sqlite_rename_table", 6, SQLITE_UTF8, 0); FuncDef *pBad2 = sqlite3FindFunction(gDb, "sqlite_drop_column", 2, SQLITE_UTF8, 0); TEST_ASSERT_NULL(pBad1); TEST_ASSERT_NULL(pBad2); } void test_sqlite3AlterFunctions_idempotent_registration(void){ /* Call the registrar again; lookups must still succeed */ sqlite3AlterFunctions(); FuncDef *p1 = sqlite3FindFunction(gDb, "sqlite_add_constraint", 3, SQLITE_UTF8, 0); TEST_ASSERT_NOT_NULL(p1); TEST_ASSERT_TRUE((p1->funcFlags & SQLITE_FUNC_INTERNAL)!=0); FuncDef *p2 = sqlite3FindFunction(gDb, "sqlite_find_constraint", 2, SQLITE_UTF8, 0); TEST_ASSERT_NOT_NULL(p2); TEST_ASSERT_TRUE((p2->funcFlags & SQLITE_FUNC_INTERNAL)!=0); } void test_sqlite3AlterFunctions_unknown_function_not_found(void){ FuncDef *p = sqlite3FindFunction(gDb, "sqlite_nonexistent", 1, SQLITE_UTF8, 0); TEST_ASSERT_NULL(p); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_sqlite3AlterFunctions_registers_all_expected_functions); RUN_TEST(test_sqlite3AlterFunctions_case_insensitive_lookup); RUN_TEST(test_sqlite3AlterFunctions_wrong_arity_returns_null); RUN_TEST(test_sqlite3AlterFunctions_idempotent_registration); RUN_TEST(test_sqlite3AlterFunctions_unknown_function_not_found); return UNITY_END(); }