AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdint.h>5 6/* Wrapper provided in the module under test */7extern u32 test_jsonTranslateBlobToPrettyText(JsonPretty *pPretty, u32 i);8 9/* Helper: initialize a JsonString to a small-stack buffer so appends work */10static void initJsonString(JsonString *pJs){11 memset(pJs, 0, sizeof(*pJs));12 /* Replicate jsonStringZero/jsonStringInit behavior */13 pJs->zBuf = pJs->zSpace;14 pJs->nAlloc = (u32)sizeof(pJs->zSpace);15 pJs->nUsed = 0;16 pJs->bStatic = 1;17 pJs->eErr = 0;18 pJs->pCtx = NULL;19}20 21/* Helper: NUL-terminate the current content of JsonString (safe for small outputs) */22static void terminateJsonString(JsonString *pJs){23 if( pJs->nUsed < pJs->nAlloc ){24 pJs->zBuf[pJs->nUsed] = '\0';25 }else if( pJs->nAlloc > 0 ){26 /* In practice we do not hit this because outputs are small, but guard anyway */27 pJs->zBuf[pJs->nAlloc - 1] = '\0';28 }29}30 31/* Common setup/teardown for Unity */32void setUp(void) {33 /* No global setup needed */34}35void tearDown(void) {36 /* No global teardown needed */37}38 39/* Test 1: Invalid header (needs 1 more size byte) -> malformed and return nBlob+1 */40void test_jsonTranslateBlobToPrettyText_invalid_short_header(void){41 /* Construct a blob with first byte: upper nibble=12 (extended 1-byte size), lower nibble=ARRAY(11) => 0xCB42 But provide only this 1 byte. jsonbPayloadSize should return 0, triggering MALFORMED. */43 const u8 blob[] = { 0xCB };44 JsonParse jp;45 memset(&jp, 0, sizeof(jp));46 jp.aBlob = (u8*)blob;47 jp.nBlob = (u32)sizeof(blob);48 jp.delta = 0;49 50 JsonString js;51 initJsonString(&js);52 53 JsonPretty pr;54 memset(&pr, 0, sizeof(pr));55 pr.pParse = &jp;56 pr.pOut = &js;57 pr.zIndent = " ";58 pr.szIndent = 2;59 pr.nIndent = 0;60 61 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);62 terminateJsonString(&js);63 64 TEST_ASSERT_NOT_EQUAL(0, js.eErr & JSTRING_MALFORMED);65 TEST_ASSERT_EQUAL_UINT32(jp.nBlob + 1, ret);66 /* Output should be empty for this early error */67 TEST_ASSERT_EQUAL_UINT32(0, js.nUsed);68 TEST_ASSERT_EQUAL_STRING("", js.zBuf);69 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);70}71 72/* Test 2: Pretty print empty array [] */73void test_jsonTranslateBlobToPrettyText_empty_array(void){74 /* ARRAY type (11) with size 0 in upper nibble => 0x0B and no payload */75 const u8 blob[] = { 0x0B };76 JsonParse jp;77 memset(&jp, 0, sizeof(jp));78 jp.aBlob = (u8*)blob;79 jp.nBlob = (u32)sizeof(blob);80 jp.delta = 0;81 82 JsonString js;83 initJsonString(&js);84 85 JsonPretty pr;86 memset(&pr, 0, sizeof(pr));87 pr.pParse = &jp;88 pr.pOut = &js;89 pr.zIndent = " ";90 pr.szIndent = 2;91 pr.nIndent = 0;92 93 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);94 terminateJsonString(&js);95 96 TEST_ASSERT_EQUAL_UINT32(0, js.eErr);97 TEST_ASSERT_EQUAL_UINT32(1u, ret);98 TEST_ASSERT_EQUAL_STRING("[]", js.zBuf);99 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);100}101 102/* Test 3: Pretty print empty object {} */103void test_jsonTranslateBlobToPrettyText_empty_object(void){104 /* OBJECT type (12) with size 0 => 0x0C and no payload */105 const u8 blob[] = { 0x0C };106 JsonParse jp;107 memset(&jp, 0, sizeof(jp));108 jp.aBlob = (u8*)blob;109 jp.nBlob = (u32)sizeof(blob);110 jp.delta = 0;111 112 JsonString js;113 initJsonString(&js);114 115 JsonPretty pr;116 memset(&pr, 0, sizeof(pr));117 pr.pParse = &jp;118 pr.pOut = &js;119 pr.zIndent = " ";120 pr.szIndent = 2;121 pr.nIndent = 0;122 123 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);124 terminateJsonString(&js);125 126 TEST_ASSERT_EQUAL_UINT32(0, js.eErr);127 TEST_ASSERT_EQUAL_UINT32(1u, ret);128 TEST_ASSERT_EQUAL_STRING("{}", js.zBuf);129 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);130}131 132/* Test 4: Pretty array with values: [null, true] */133void test_jsonTranslateBlobToPrettyText_array_with_values(void){134 /* Elements:135 - NULL: type=0, size=0 => 0x00136 - TRUE: type=1, size=0 => 0x01137 ARRAY payload size = 2 bytes => upper nibble 2, type 11 => 0x2B138 Blob: [ 0x2B, 0x00, 0x01 ]139 */140 const u8 blob[] = { 0x2B, 0x00, 0x01 };141 JsonParse jp;142 memset(&jp, 0, sizeof(jp));143 jp.aBlob = (u8*)blob;144 jp.nBlob = (u32)sizeof(blob);145 jp.delta = 0;146 147 JsonString js;148 initJsonString(&js);149 150 JsonPretty pr;151 memset(&pr, 0, sizeof(pr));152 pr.pParse = &jp;153 pr.pOut = &js;154 pr.zIndent = " ";155 pr.szIndent = 2;156 pr.nIndent = 0;157 158 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);159 terminateJsonString(&js);160 161 const char *expected =162 "[\n"163 " null,\n"164 " true\n"165 "]";166 TEST_ASSERT_EQUAL_UINT32(0, js.eErr);167 TEST_ASSERT_EQUAL_UINT32(3u, ret); /* header(1) + payload(2) */168 TEST_ASSERT_EQUAL_STRING(expected, js.zBuf);169 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);170}171 172/* Test 5: Pretty object with one pair: {"a": false} */173void test_jsonTranslateBlobToPrettyText_object_one_pair(void){174 /* Key "a" as TEXT:175 TEXT type=7, payload="a"(1 byte) -> header upper nibble=1, lower=7 => 0x17, payload 'a'176 Value FALSE: 0x02177 OBJECT payload size = 2 (key) + 1 (value) = 3 => header upper nibble=3, lower=12 => 0x3C178 Blob: [ 0x3C, 0x17, 'a', 0x02 ]179 */180 const u8 blob[] = { 0x3C, 0x17, 'a', 0x02 };181 JsonParse jp;182 memset(&jp, 0, sizeof(jp));183 jp.aBlob = (u8*)blob;184 jp.nBlob = (u32)sizeof(blob);185 jp.delta = 0;186 187 JsonString js;188 initJsonString(&js);189 190 JsonPretty pr;191 memset(&pr, 0, sizeof(pr));192 pr.pParse = &jp;193 pr.pOut = &js;194 pr.zIndent = " ";195 pr.szIndent = 2;196 pr.nIndent = 0;197 198 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);199 terminateJsonString(&js);200 201 const char *expected =202 "{\n"203 " \"a\": false\n"204 "}";205 TEST_ASSERT_EQUAL_UINT32(0, js.eErr);206 TEST_ASSERT_EQUAL_UINT32(4u, ret); /* header(1) + payload(3) */207 TEST_ASSERT_EQUAL_STRING(expected, js.zBuf);208 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);209}210 211/* Test 6: Nested: [ { "a": false } ] */212void test_jsonTranslateBlobToPrettyText_nested_array_object(void){213 /* Inner object {"a": false} as before: [0x3C, 0x17, 'a', 0x02]214 Array with payload size 4 => array header: upper nibble=4, type=11 => 0x4B215 Blob: [ 0x4B, 0x3C, 0x17, 'a', 0x02 ]216 */217 const u8 blob[] = { 0x4B, 0x3C, 0x17, 'a', 0x02 };218 JsonParse jp;219 memset(&jp, 0, sizeof(jp));220 jp.aBlob = (u8*)blob;221 jp.nBlob = (u32)sizeof(blob);222 jp.delta = 0;223 224 JsonString js;225 initJsonString(&js);226 227 JsonPretty pr;228 memset(&pr, 0, sizeof(pr));229 pr.pParse = &jp;230 pr.pOut = &js;231 pr.zIndent = " ";232 pr.szIndent = 2;233 pr.nIndent = 0;234 235 u32 ret = test_jsonTranslateBlobToPrettyText(&pr, 0);236 terminateJsonString(&js);237 238 const char *expected =239 "[\n"240 " {\n"241 " \"a\": false\n"242 " }\n"243 "]";244 TEST_ASSERT_EQUAL_UINT32(0, js.eErr);245 TEST_ASSERT_EQUAL_UINT32(5u, ret); /* header(1) + payload(4) */246 TEST_ASSERT_EQUAL_STRING(expected, js.zBuf);247 TEST_ASSERT_EQUAL_UINT32(0, pr.nIndent);248}249 250int main(void){251 UNITY_BEGIN();252 RUN_TEST(test_jsonTranslateBlobToPrettyText_invalid_short_header);253 RUN_TEST(test_jsonTranslateBlobToPrettyText_empty_array);254 RUN_TEST(test_jsonTranslateBlobToPrettyText_empty_object);255 RUN_TEST(test_jsonTranslateBlobToPrettyText_array_with_values);256 RUN_TEST(test_jsonTranslateBlobToPrettyText_object_one_pair);257 RUN_TEST(test_jsonTranslateBlobToPrettyText_nested_array_object);258 return UNITY_END();259}