| #include "sqliteInt.h" |
| #include "unity.h" |
|
|
| #include <string.h> |
| #include <stdlib.h> |
|
|
| |
| extern void test_renameColumnIdlistNames( |
| Parse *pParse, |
| RenameCtx *pCtx, |
| const IdList *pIdList, |
| const char *zOld |
| ); |
|
|
| |
| static sqlite3 *gDb = NULL; |
| static Parse gParse; |
|
|
| |
| static IdList *makeIdList(Parse *pParse, const char **azName, int nName){ |
| IdList *pList = 0; |
| for(int i = 0; i < nName; i++){ |
| Token t; |
| t.z = azName[i]; |
| t.n = (int)strlen(azName[i]); |
| pList = sqlite3IdListAppend(pParse, pList, &t); |
| TEST_ASSERT_NOT_NULL_MESSAGE(pList, "sqlite3IdListAppend returned NULL"); |
| } |
| return pList; |
| } |
|
|
| |
| void setUp(void) { |
| int rc = sqlite3_open(":memory:", &gDb); |
| TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed"); |
| memset(&gParse, 0, sizeof(gParse)); |
| gParse.db = gDb; |
| } |
|
|
| void tearDown(void) { |
| if( gDb ){ |
| sqlite3_close(gDb); |
| gDb = NULL; |
| } |
| } |
|
|
| |
|
|
| void test_renameColumnIdlistNames_null_list_noop(void){ |
| RenameCtx ctx, ctxBefore; |
| memset(&ctx, 0, sizeof(ctx)); |
| memcpy(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, NULL, "x"); |
|
|
| TEST_ASSERT_EQUAL_MEMORY(&ctxBefore, &ctx, sizeof(ctx)); |
| } |
|
|
| void test_renameColumnIdlistNames_empty_list_noop(void){ |
| RenameCtx ctx, ctxBefore; |
| memset(&ctx, 0, sizeof(ctx)); |
| memcpy(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| IdList *pList = (IdList*)sqlite3DbMallocZero(gParse.db, sizeof(IdList)); |
| TEST_ASSERT_NOT_NULL(pList); |
| |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "anything"); |
|
|
| TEST_ASSERT_EQUAL_MEMORY(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_no_match_ctx_unchanged(void){ |
| const char *names[] = {"alpha","beta","gamma"}; |
| IdList *pList = makeIdList(&gParse, names, 3); |
|
|
| RenameCtx ctx, ctxBefore; |
| memset(&ctx, 0, sizeof(ctx)); |
| memcpy(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "delta"); |
|
|
| TEST_ASSERT_EQUAL_MEMORY(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_single_match_exact_no_crash(void){ |
| const char *names[] = {"alpha","beta","gamma"}; |
| IdList *pList = makeIdList(&gParse, names, 3); |
|
|
| RenameCtx ctx; |
| memset(&ctx, 0, sizeof(ctx)); |
|
|
| |
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "beta"); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(3, pList->nId); |
| TEST_ASSERT_NOT_NULL(pList->a); |
| TEST_ASSERT_NOT_NULL(pList->a[1].zName); |
| TEST_ASSERT_EQUAL_STRING("beta", pList->a[1].zName); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_single_match_case_insensitive_no_crash(void){ |
| const char *names[] = {"alpha","BeTa","gamma"}; |
| IdList *pList = makeIdList(&gParse, names, 3); |
|
|
| RenameCtx ctx; |
| memset(&ctx, 0, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "bEtA"); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(3, pList->nId); |
| TEST_ASSERT_NOT_NULL(pList->a[1].zName); |
| TEST_ASSERT_EQUAL_STRING("BeTa", pList->a[1].zName); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_multiple_matches_no_crash(void){ |
| const char *names[] = {"a","A","b","a","c","A"}; |
| IdList *pList = makeIdList(&gParse, names, 6); |
|
|
| RenameCtx ctx; |
| memset(&ctx, 0, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "a"); |
|
|
| |
| TEST_ASSERT_EQUAL_INT(6, pList->nId); |
| TEST_ASSERT_EQUAL_STRING("a", pList->a[0].zName); |
| TEST_ASSERT_EQUAL_STRING("A", pList->a[1].zName); |
| TEST_ASSERT_EQUAL_STRING("a", pList->a[3].zName); |
| TEST_ASSERT_EQUAL_STRING("A", pList->a[5].zName); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_long_strings_and_mixed_case_no_crash(void){ |
| const char *names[] = { |
| "MiXeDCaSeName", |
| "another_name_with_underscores", |
| "yetAnotherName123", |
| "LONGNAME_LONGNAME_LONGNAME" |
| }; |
| IdList *pList = makeIdList(&gParse, names, 4); |
|
|
| RenameCtx ctx; |
| memset(&ctx, 0, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "mixedcasename"); |
|
|
| |
| TEST_ASSERT_EQUAL_STRING("MiXeDCaSeName", pList->a[0].zName); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| } |
|
|
| void test_renameColumnIdlistNames_large_list_no_match_no_crash(void){ |
| enum { N = 200 }; |
| const char *arr[N]; |
| char *storage[N]; |
| for(int i=0; i<N; i++){ |
| char buf[32]; |
| sqlite3_snprintf(sizeof(buf), buf, "col%d", i); |
| storage[i] = sqlite3_mprintf("%s", buf); |
| TEST_ASSERT_NOT_NULL(storage[i]); |
| arr[i] = storage[i]; |
| } |
|
|
| IdList *pList = makeIdList(&gParse, arr, N); |
|
|
| RenameCtx ctx, ctxBefore; |
| memset(&ctx, 0, sizeof(ctx)); |
| memcpy(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| test_renameColumnIdlistNames(&gParse, &ctx, pList, "no_such_column"); |
|
|
| TEST_ASSERT_EQUAL_MEMORY(&ctxBefore, &ctx, sizeof(ctx)); |
|
|
| sqlite3IdListDelete(gParse.db, pList); |
| for(int i=0; i<N; i++){ |
| sqlite3_free(storage[i]); |
| } |
| } |
|
|
| int main(void){ |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_renameColumnIdlistNames_null_list_noop); |
| RUN_TEST(test_renameColumnIdlistNames_empty_list_noop); |
| RUN_TEST(test_renameColumnIdlistNames_no_match_ctx_unchanged); |
| RUN_TEST(test_renameColumnIdlistNames_single_match_exact_no_crash); |
| RUN_TEST(test_renameColumnIdlistNames_single_match_case_insensitive_no_crash); |
| RUN_TEST(test_renameColumnIdlistNames_multiple_matches_no_crash); |
| RUN_TEST(test_renameColumnIdlistNames_long_strings_and_mixed_case_no_crash); |
| RUN_TEST(test_renameColumnIdlistNames_large_list_no_match_no_crash); |
|
|
| return UNITY_END(); |
| } |