AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Prototype of the test wrapper for the static function */7int test_jsonStringGrow(JsonString *p, u32 N);8 9/* Helpers to initialize JsonString for tests without calling static helpers */10static void initStaticJsonString(JsonString *p){11 memset(p, 0, sizeof(*p));12 p->zBuf = p->zSpace;13 p->nAlloc = (u32)sizeof(p->zSpace);14 p->nUsed = 0;15 p->bStatic = 1;16 p->pCtx = 0;17 p->eErr = 0;18}19 20static void initDynamicJsonString(JsonString *p, u64 initialAlloc, const void *data, u32 nData){21 memset(p, 0, sizeof(*p));22 p->zBuf = sqlite3RCStrNew(initialAlloc);23 TEST_ASSERT_NOT_NULL_MESSAGE(p->zBuf, "sqlite3RCStrNew failed in test setup");24 p->bStatic = 0;25 p->nAlloc = (u32)initialAlloc;26 p->nUsed = nData;27 if( data && nData>0 ){28 memcpy(p->zBuf, data, nData);29 }30}31 32/* Unity fixtures */33void setUp(void) {34 /* No global setup needed */35}36void tearDown(void) {37 /* No global teardown needed */38}39 40/* Test 1: Grow from static buffer with N < nAlloc (doubling), verify conversion to dynamic and content copy */41void test_jsonStringGrow_from_static_doubling(void){42 JsonString js;43 initStaticJsonString(&js);44 45 /* Put some initial content into the static buffer */46 static const char payload[] = "hello";47 memcpy(js.zBuf, payload, sizeof(payload)-1);48 js.nUsed = (u32)(sizeof(payload)-1);49 50 u32 N = 1; /* less than current nAlloc */51 u64 expectedAlloc = (u64)js.nAlloc * 2;52 53 int rc = test_jsonStringGrow(&js, N);54 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55 TEST_ASSERT_EQUAL_INT(0, js.bStatic);56 TEST_ASSERT_NOT_EQUAL_PTR(js.zSpace, js.zBuf);57 TEST_ASSERT_TRUE(js.nAlloc == expectedAlloc);58 59 /* Verify content preserved */60 TEST_ASSERT_EQUAL_UINT32((u32)(sizeof(payload)-1), js.nUsed);61 TEST_ASSERT_EQUAL_INT(0, memcmp(js.zBuf, payload, js.nUsed));62 63 /* Cleanup */64 if( !js.bStatic && js.zBuf ){65 sqlite3RCStrUnref(js.zBuf);66 js.zBuf = NULL;67 }68}69 70/* Test 2: Grow an already dynamic buffer with N < nAlloc (doubling), verify capacity and content preserved */71void test_jsonStringGrow_dynamic_resize_doubling(void){72 JsonString js;73 const char data[] = "dynamic-data";74 const u32 nData = (u32)(sizeof(data)-1);75 const u32 initialAlloc = 64;76 77 initDynamicJsonString(&js, initialAlloc, data, nData);78 79 u32 N = 10; /* N < nAlloc -> doubling */80 u64 expectedAlloc = (u64)js.nAlloc * 2;81 82 char *oldBuf = js.zBuf; /* may or may not change after resize */83 84 int rc = test_jsonStringGrow(&js, N);85 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);86 TEST_ASSERT_EQUAL_INT(0, js.bStatic);87 TEST_ASSERT_NOT_NULL(js.zBuf);88 TEST_ASSERT_TRUE(js.nAlloc == expectedAlloc);89 90 /* Verify content preserved */91 TEST_ASSERT_EQUAL_UINT32(nData, js.nUsed);92 TEST_ASSERT_EQUAL_INT(0, memcmp(js.zBuf, data, js.nUsed));93 94 /* Cleanup: current buffer (even if pointer changed) must be unref'd */95 if( js.zBuf ){96 sqlite3RCStrUnref(js.zBuf);97 js.zBuf = NULL;98 }99 (void)oldBuf; /* suppress unused warning if not used */100}101 102/* Test 3: Grow an already dynamic buffer with N >= nAlloc (additive), verify capacity and content preserved */103void test_jsonStringGrow_dynamic_resize_additive(void){104 JsonString js;105 const char data[] = "xyz";106 const u32 nData = (u32)(sizeof(data)-1);107 const u32 initialAlloc = 40;108 109 initDynamicJsonString(&js, initialAlloc, data, nData);110 111 u32 N = 50; /* N >= nAlloc -> nAlloc + N + 10 */112 u64 expectedAlloc = (u64)js.nAlloc + (u64)N + 10;113 114 int rc = test_jsonStringGrow(&js, N);115 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);116 TEST_ASSERT_EQUAL_INT(0, js.bStatic);117 TEST_ASSERT_NOT_NULL(js.zBuf);118 TEST_ASSERT_TRUE(js.nAlloc == expectedAlloc);119 120 /* Verify content preserved */121 TEST_ASSERT_EQUAL_UINT32(nData, js.nUsed);122 TEST_ASSERT_EQUAL_INT(0, memcmp(js.zBuf, data, js.nUsed));123 124 /* Cleanup */125 if( js.zBuf ){126 sqlite3RCStrUnref(js.zBuf);127 js.zBuf = NULL;128 }129}130 131/* Test 4: When bStatic and eErr != 0, function returns 1 and makes no changes */132void test_jsonStringGrow_static_with_error_flag_returns_1(void){133 JsonString js;134 initStaticJsonString(&js);135 136 /* Mark an error condition */137 js.eErr = 1234; /* non-zero */138 139 /* Prepare some content to ensure no changes happen */140 const char c = 'Q';141 js.nUsed = 1;142 js.zBuf[0] = c;143 144 u32 N = 5;145 u32 prevAlloc = js.nAlloc;146 int prevBStatic = js.bStatic;147 char *prevBuf = js.zBuf;148 149 int rc = test_jsonStringGrow(&js, N);150 TEST_ASSERT_EQUAL_INT(1, rc);151 152 /* Verify no changes */153 TEST_ASSERT_EQUAL_INT(prevBStatic, js.bStatic);154 TEST_ASSERT_EQUAL_PTR(prevBuf, js.zBuf);155 TEST_ASSERT_EQUAL_UINT32(prevAlloc, js.nAlloc);156 TEST_ASSERT_EQUAL_UINT32(1, js.nUsed);157 TEST_ASSERT_EQUAL_INT(c, js.zBuf[0]);158 159 /* No cleanup needed; still static */160}161 162int main(void){163 UNITY_BEGIN();164 RUN_TEST(test_jsonStringGrow_from_static_doubling);165 RUN_TEST(test_jsonStringGrow_dynamic_resize_doubling);166 RUN_TEST(test_jsonStringGrow_dynamic_resize_additive);167 RUN_TEST(test_jsonStringGrow_static_with_error_flag_returns_1);168 return UNITY_END();169}