AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6static sqlite3 *gDb = NULL;7 8void setUp(void) {9 int rc = sqlite3_open(":memory:", &gDb);10 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);11 TEST_ASSERT_NOT_NULL(gDb);12}13 14void tearDown(void) {15 if (gDb) {16 sqlite3_close(gDb);17 gDb = NULL;18 }19}20 21/* Helpers to set db configs and assert success */22static void setWritableSchema(sqlite3 *db, int onoff){23 int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, onoff, (int*)0);24 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);25}26static void setDefensive(sqlite3 *db, int onoff){27 int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, onoff, (int*)0);28 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);29}30 31/* Convenience to init a Parse object for tests */32static void initParse(Parse *pParse, sqlite3 *db, int nested){33 memset(pParse, 0, sizeof(*pParse));34 pParse->db = db;35 pParse->nested = nested;36}37 38/* 1) No flags: expect writable (0) */39void test_tabIsReadOnly_noFlags_returnsWritable(void){40 Parse parse;41 Table tab;42 memset(&tab, 0, sizeof(tab));43 initParse(&parse, gDb, 0);44 45 /* Ensure defaults: writable_schema off, defensive off (defaults anyway). */46 setWritableSchema(gDb, 0);47 setDefensive(gDb, 0);48 49 int ro = test_tabIsReadOnly(&parse, &tab);50 TEST_ASSERT_EQUAL_INT(0, ro);51}52 53/* 2) TF_Readonly with writable_schema OFF and top-level (nested==0): expect 1 */54void test_tabIsReadOnly_readonly_writableSchemaOff_topLevel(void){55 Parse parse;56 Table tab;57 memset(&tab, 0, sizeof(tab));58 tab.tabFlags = TF_Readonly;59 initParse(&parse, gDb, 0);60 61 setWritableSchema(gDb, 0);62 63 int ro = test_tabIsReadOnly(&parse, &tab);64 TEST_ASSERT_EQUAL_INT(1, ro);65}66 67/* 3) TF_Readonly with writable_schema ON and top-level: expect 0 */68void test_tabIsReadOnly_readonly_writableSchemaOn_topLevel(void){69 Parse parse;70 Table tab;71 memset(&tab, 0, sizeof(tab));72 tab.tabFlags = TF_Readonly;73 initParse(&parse, gDb, 0);74 75 setWritableSchema(gDb, 1);76 77 int ro = test_tabIsReadOnly(&parse, &tab);78 TEST_ASSERT_EQUAL_INT(0, ro);79}80 81/* 4) TF_Readonly with nested parse (nested!=0), writable_schema OFF: expect 0 */82void test_tabIsReadOnly_readonly_nestedParse(void){83 Parse parse;84 Table tab;85 memset(&tab, 0, sizeof(tab));86 tab.tabFlags = TF_Readonly;87 initParse(&parse, gDb, 1); /* nested parse */88 89 setWritableSchema(gDb, 0);90 91 int ro = test_tabIsReadOnly(&parse, &tab);92 TEST_ASSERT_EQUAL_INT(0, ro);93}94 95/* 5) TF_Shadow with defensive ON: expect sqlite3ReadOnlyShadowTables(db) -> 1 */96void test_tabIsReadOnly_shadow_defensiveOn(void){97 Parse parse;98 Table tab;99 memset(&tab, 0, sizeof(tab));100 tab.tabFlags = TF_Shadow;101 initParse(&parse, gDb, 0);102 103 setDefensive(gDb, 1);104 105 int ro = test_tabIsReadOnly(&parse, &tab);106 TEST_ASSERT_EQUAL_INT(1, ro);107}108 109/* 6) TF_Shadow with defensive OFF: expect 0 */110void test_tabIsReadOnly_shadow_defensiveOff(void){111 Parse parse;112 Table tab;113 memset(&tab, 0, sizeof(tab));114 tab.tabFlags = TF_Shadow;115 initParse(&parse, gDb, 0);116 117 setDefensive(gDb, 0);118 119 int ro = test_tabIsReadOnly(&parse, &tab);120 TEST_ASSERT_EQUAL_INT(0, ro);121}122 123/* 7) Both TF_Readonly and TF_Shadow: readonly branch takes precedence */124void test_tabIsReadOnly_bothFlags_prefersReadonlyBranch(void){125 Parse parse;126 Table tab;127 memset(&tab, 0, sizeof(tab));128 tab.tabFlags = TF_Readonly | TF_Shadow;129 initParse(&parse, gDb, 0);130 131 /* Even if defensive is ON, readonly branch controls result. */132 setDefensive(gDb, 1);133 setWritableSchema(gDb, 0); /* writable_schema OFF -> expect 1 */134 135 int ro1 = test_tabIsReadOnly(&parse, &tab);136 TEST_ASSERT_EQUAL_INT(1, ro1);137 138 /* Now turn writable_schema ON, expect 0 despite defensive ON */139 setWritableSchema(gDb, 1);140 int ro2 = test_tabIsReadOnly(&parse, &tab);141 TEST_ASSERT_EQUAL_INT(0, ro2);142}143 144int main(void){145 UNITY_BEGIN();146 RUN_TEST(test_tabIsReadOnly_noFlags_returnsWritable);147 RUN_TEST(test_tabIsReadOnly_readonly_writableSchemaOff_topLevel);148 RUN_TEST(test_tabIsReadOnly_readonly_writableSchemaOn_topLevel);149 RUN_TEST(test_tabIsReadOnly_readonly_nestedParse);150 RUN_TEST(test_tabIsReadOnly_shadow_defensiveOn);151 RUN_TEST(test_tabIsReadOnly_shadow_defensiveOff);152 RUN_TEST(test_tabIsReadOnly_bothFlags_prefersReadonlyBranch);153 return UNITY_END();154}