Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_json_jsonObjectFunc.c169 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6#include <stdio.h>7 8/* Provided by the module under test (wrapper for static function) */9extern void test_jsonObjectFunc(sqlite3_context *ctx, int argc, sqlite3_value **argv);10 11static sqlite3 *gDb = NULL;12 13/* Trampoline function to invoke the target via SQLite SQL layer */14static void xjson_object_test_sqlfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv){15  /* Directly call the provided wrapper */16  test_jsonObjectFunc(ctx, argc, argv);17}18 19/* Helper function to return raw JSON text with JSON subtype */20static void rawjson_sqlfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv){21  (void)argc;22  const unsigned char *z = sqlite3_value_text(argv[0]);23  int n = sqlite3_value_bytes(argv[0]);24  if( z==NULL ){25    sqlite3_result_null(ctx);26    return;27  }28  sqlite3_result_text(ctx, (const char*)z, n, SQLITE_TRANSIENT);29  sqlite3_result_subtype(ctx, JSON_SUBTYPE);30}31 32void setUp(void) {33  int rc = sqlite3_open(":memory:", &gDb);34  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");35 36  /* Register a variable-arg function that forwards to test_jsonObjectFunc */37  rc = sqlite3_create_function(gDb, "xjson_object_test", -1, SQLITE_UTF8, NULL,38                               xjson_object_test_sqlfunc, NULL, NULL);39  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "create_function xjson_object_test failed");40 41  /* Register helper to produce TEXT with JSON subtype */42  rc = sqlite3_create_function(gDb, "rawjson", 1, SQLITE_UTF8, NULL,43                               rawjson_sqlfunc, NULL, NULL);44  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "create_function rawjson failed");45}46 47void tearDown(void) {48  if( gDb ){49    int rc = sqlite3_close(gDb);50    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");51    gDb = NULL;52  }53}54 55/* Helper: run SQL that should yield exactly one row, one column, compare to expected,56   and confirm JSON subtype. */57static void assertQueryResultJson(const char *sql, const char *expected){58  sqlite3_stmt *pStmt = NULL;59  int rc = sqlite3_prepare_v2(gDb, sql, -1, &pStmt, NULL);60  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");61 62  rc = sqlite3_step(pStmt);63  if( rc!=SQLITE_ROW ){64    const char *errmsg = sqlite3_errmsg(gDb);65    sqlite3_finalize(pStmt);66    TEST_FAIL_MESSAGE(errmsg ? errmsg : "Expected SQLITE_ROW");67  }68 69  const unsigned char *z = sqlite3_column_text(pStmt, 0);70  int subtype = sqlite3_column_subtype(pStmt, 0);71  TEST_ASSERT_NOT_NULL(z);72  TEST_ASSERT_EQUAL_STRING(expected, (const char*)z);73  TEST_ASSERT_EQUAL_INT(JSON_SUBTYPE, subtype);74 75  rc = sqlite3_step(pStmt);76  TEST_ASSERT_EQUAL_INT(SQLITE_DONE, rc);77 78  rc = sqlite3_finalize(pStmt);79  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);80}81 82/* Helper: run SQL expected to error; compare error message */83static void assertQueryError(const char *sql, const char *expMsg){84  sqlite3_stmt *pStmt = NULL;85  int rc = sqlite3_prepare_v2(gDb, sql, -1, &pStmt, NULL);86  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");87 88  rc = sqlite3_step(pStmt);89  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);90 91  const char *errmsg = sqlite3_errmsg(gDb);92  TEST_ASSERT_NOT_NULL(errmsg);93  TEST_ASSERT_EQUAL_STRING(expMsg, errmsg);94 95  rc = sqlite3_finalize(pStmt);96  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);97}98 99/* Tests */100 101void test_jsonObjectFunc_empty(void){102  assertQueryResultJson("SELECT xjson_object_test()", "{}", /* subtype JSON */ 0);103}104 105void test_jsonObjectFunc_simple_types(void){106  /* Expect integer, text (quoted), and null */107  assertQueryResultJson(108    "SELECT xjson_object_test('a', 1, 'b', 'x', 'c', NULL)",109    "{\"a\":1,\"b\":\"x\",\"c\":null}"110  );111}112 113void test_jsonObjectFunc_odd_number_of_args_error(void){114  assertQueryError(115    "SELECT xjson_object_test('a')",116    "json_object() requires an even number of arguments"117  );118}119 120void test_jsonObjectFunc_nontext_label_error(void){121  assertQueryError(122    "SELECT xjson_object_test(1, 'x')",123    "json_object() labels must be TEXT"124  );125}126 127void test_jsonObjectFunc_blob_value_error(void){128  assertQueryError(129    "SELECT xjson_object_test('bin', x'0102')",130    "JSON cannot hold BLOB values"131  );132}133 134void test_jsonObjectFunc_label_escaping(void){135  /* Label with double-quote and backslash: a"b\c => "a\"b\\c" */136  assertQueryResultJson(137    "SELECT xjson_object_test('a\"b\\c', 1)",138    "{\"a\\\"b\\\\c\":1}"139  );140}141 142void test_jsonObjectFunc_value_escaping_newline_and_quote(void){143  /* Value contains newline (char(10)) and quote; build via concatenation */144  assertQueryResultJson(145    "SELECT xjson_object_test('nl', char(10), 'q', 'a\"b')",146    "{\"nl\":\"\\n\",\"q\":\"a\\\"b\"}"147  );148}149 150void test_jsonObjectFunc_json_subtype_passthrough(void){151  /* rawjson returns its text argument with JSON subtype => inserted as raw JSON (no quotes) */152  assertQueryResultJson(153    "SELECT xjson_object_test('j', rawjson('{\"a\":1}'))",154    "{\"j\":{\"a\":1}}"155  );156}157 158int main(void){159  UNITY_BEGIN();160  RUN_TEST(test_jsonObjectFunc_empty);161  RUN_TEST(test_jsonObjectFunc_simple_types);162  RUN_TEST(test_jsonObjectFunc_odd_number_of_args_error);163  RUN_TEST(test_jsonObjectFunc_nontext_label_error);164  RUN_TEST(test_jsonObjectFunc_blob_value_error);165  RUN_TEST(test_jsonObjectFunc_label_escaping);166  RUN_TEST(test_jsonObjectFunc_value_escaping_newline_and_quote);167  RUN_TEST(test_jsonObjectFunc_json_subtype_passthrough);168  return UNITY_END();169}