Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_json_jsonEachPathLength.c167 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6#include <stdint.h>7 8/* Wrapper for the static function under test, provided by the module */9int test_jsonEachPathLength(JsonEachCursor *p);10 11/* Hand-crafted minimal JSONB blob for {"a":[1,2,3]}12   Bytes:13     0: 0x9c  OBJECT, payload 9 bytes14     1: 0x17  TEXT label, payload 1 byte15     2: 0x61  'a'16     3: 0x6b  ARRAY, payload 6 bytes17     4: 0x13  INT, payload 1 byte18     5: 0x31  '1'19     6: 0x13  INT, payload 1 byte20     7: 0x32  '2'21     8: 0x13  INT, payload 1 byte22     9: 0x33  '3'23*/24static unsigned char gBlob_ObjAArray123[] = {25  0x9c, 0x17, 0x61, 0x6b, 0x13, 0x31, 0x13, 0x32, 0x13, 0x3326};27 28static void initCursor(JsonEachCursor *pCur,29                       unsigned char *aBlob, int nBlob,30                       char *zPath, int iVal, sqlite3_int64 iRowid,31                       int bRecursive){32  memset(pCur, 0, sizeof(*pCur));33  /* Minimal fields used by jsonEachPathLength and called internals */34  pCur->sParse.aBlob = aBlob;35  pCur->sParse.nBlob = (u32)nBlob;36  pCur->sParse.eEdit = 0;   /* assert in function requires this */37  pCur->sParse.delta = 0;38 39  pCur->path.zBuf = zPath;40  pCur->path.nUsed = (u32)strlen(zPath);41 42  pCur->i = (u32)iVal;43  pCur->iRowid = iRowid;44  pCur->bRecursive = (u8)bRecursive;45}46 47/* Utility to duplicate a path into a mutable buffer */48static char* dupPath(const char *z){49  size_t n = strlen(z);50  char *p = (char*)sqlite3_malloc64(n+1);51  TEST_ASSERT_NOT_NULL(p);52  memcpy(p, z, n+1);53  return p;54}55 56void setUp(void) {57  /* No global setup needed */58}59void tearDown(void) {60  /* No global teardown needed */61}62 63/* bRecursive==0: function should return nUsed unchanged */64static void test_jsonEachPathLength_non_recursive_returns_full_length(void){65  JsonEachCursor cur;66  char *z = dupPath("$.a[2].b");67  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),68             z, 9 /* arbitrary */, 0 /* rowid */, 0 /* bRecursive */);69  int got = test_jsonEachPathLength(&cur);70  TEST_ASSERT_EQUAL_INT((int)strlen(z), got);71  sqlite3_free(z);72}73 74/* iRowid!=0: function should return nUsed unchanged */75static void test_jsonEachPathLength_non_zero_rowid_returns_full_length(void){76  JsonEachCursor cur;77  char *z = dupPath("$.a[2].b");78  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),79             z, 9, 5 /* rowid!=0 */, 1 /* bRecursive */);80  int got = test_jsonEachPathLength(&cur);81  TEST_ASSERT_EQUAL_INT((int)strlen(z), got);82  sqlite3_free(z);83}84 85/* Short path n<2: return nUsed unchanged (which is 1 for "$") */86static void test_jsonEachPathLength_short_path_returns_one(void){87  JsonEachCursor cur;88  char *z = dupPath("$");89  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),90             z, 1 /* any */, 0 /* rowid */, 1 /* bRecursive */);91  int got = test_jsonEachPathLength(&cur);92  TEST_ASSERT_EQUAL_INT(1, got);93  sqlite3_free(z);94}95 96/* Match on last '.' before 'b' for "$.a[2].b": p->i = payload start of ".a[2]" = 9, expect index of that dot (6) */97static void test_jsonEachPathLength_matches_after_last_dot(void){98  JsonEachCursor cur;99  char *z = dupPath("$.a[2].b");100  /* For ".a[2]": header index x=8, header len n=1 => payload start p->i=9 */101  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),102             z, 9 /* p->i */, 0 /* rowid */, 1 /* bRecursive */);103  /* Keep a copy to verify no corruption */104  char before[32]; memset(before, 0, sizeof(before)); strncpy(before, z, sizeof(before)-1);105  int got = test_jsonEachPathLength(&cur);106  TEST_ASSERT_EQUAL_INT(6, got);107  TEST_ASSERT_EQUAL_STRING(before, z);108  sqlite3_free(z);109}110 111/* Match on '[' for "$.a[2]": p->i = payload start of ".a" = 4, expect index of '[' (3) */112static void test_jsonEachPathLength_matches_at_bracket(void){113  JsonEachCursor cur;114  char *z = dupPath("$.a[2]");115  /* For ".a": header index x=3, header len n=1 => payload start p->i=4 */116  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),117             z, 4 /* p->i */, 0 /* rowid */, 1 /* bRecursive */);118  int got = test_jsonEachPathLength(&cur);119  TEST_ASSERT_EQUAL_INT(3, got);120  sqlite3_free(z);121}122 123/* No match at last separators; earlier match at ".a": expect index 3 for "$.a[2].b.c" with p->i = payload of ".a" */124static void test_jsonEachPathLength_skips_to_earlier_matching_prefix(void){125  JsonEachCursor cur;126  char *z = dupPath("$.a[2].b.c");127  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),128             z, 4 /* payload start of ".a" */, 0 /* rowid */, 1 /* bRecursive */);129  int got = test_jsonEachPathLength(&cur);130  TEST_ASSERT_EQUAL_INT(3, got);131  sqlite3_free(z);132}133 134/* Prefix causing PATHERROR should be skipped; earlier valid ".a" still matches */135static void test_jsonEachPathLength_ignores_error_prefix_and_matches_earlier(void){136  JsonEachCursor cur;137  char *z = dupPath("$.a[xyz].b");138  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),139             z, 4 /* payload start of ".a" */, 0 /* rowid */, 1 /* bRecursive */);140  int got = test_jsonEachPathLength(&cur);141  TEST_ASSERT_EQUAL_INT(3, got);142  sqlite3_free(z);143}144 145/* No matching prefix: return 1 */146static void test_jsonEachPathLength_no_match_returns_one(void){147  JsonEachCursor cur;148  char *z = dupPath("$.a[2].b");149  initCursor(&cur, gBlob_ObjAArray123, (int)sizeof(gBlob_ObjAArray123),150             z, 42 /* not a valid payload-start for any prefix */, 0 /* rowid */, 1 /* bRecursive */);151  int got = test_jsonEachPathLength(&cur);152  TEST_ASSERT_EQUAL_INT(1, got);153  sqlite3_free(z);154}155 156int main(void){157  UNITY_BEGIN();158  RUN_TEST(test_jsonEachPathLength_non_recursive_returns_full_length);159  RUN_TEST(test_jsonEachPathLength_non_zero_rowid_returns_full_length);160  RUN_TEST(test_jsonEachPathLength_short_path_returns_one);161  RUN_TEST(test_jsonEachPathLength_matches_after_last_dot);162  RUN_TEST(test_jsonEachPathLength_matches_at_bracket);163  RUN_TEST(test_jsonEachPathLength_skips_to_earlier_matching_prefix);164  RUN_TEST(test_jsonEachPathLength_ignores_error_prefix_and_matches_earlier);165  RUN_TEST(test_jsonEachPathLength_no_match_returns_one);166  return UNITY_END();167}