Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_json_jsonRemoveFunc.c191 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6#include <stdint.h>7 8/* Forward declaration of the auto-generated test wrapper from the module */9void test_jsonRemoveFunc(sqlite3_context *ctx, int argc, sqlite3_value **argv);10 11/* Global database handle for tests */12static sqlite3 *gDb = NULL;13 14/* SQLite wrapper function that forwards to the target under test */15static void xJsonRemove(sqlite3_context *ctx, int argc, sqlite3_value **argv){16  /* Use wrapper to directly call the function-under-test in a valid SQLite context */17  test_jsonRemoveFunc(ctx, argc, argv);18}19 20/* Helper: prepare a statement and bind a sequence of text parameters.21   Any const char* in params[] that is NULL will bind as SQL NULL. */22static sqlite3_stmt* prepare_with_text_binds(const char *sql, const char **params, int nParams){23  sqlite3_stmt *stmt = NULL;24  int rc = sqlite3_prepare_v2(gDb, sql, -1, &stmt, 0);25  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");26  for(int i=0; i<nParams; i++){27    if( params[i]==NULL ){28      rc = sqlite3_bind_null(stmt, i+1);29    }else{30      rc = sqlite3_bind_text(stmt, i+1, params[i], -1, SQLITE_TRANSIENT);31    }32    TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "bind failed");33  }34  return stmt;35}36 37/* Helper: step a scalar SELECT and return the first column as const char*.38   Asserts that row is returned and value is TEXT. */39static const unsigned char* step_text_result(sqlite3_stmt *stmt){40  int rc = sqlite3_step(stmt);41  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ROW, rc, "expected one row result");42  TEST_ASSERT_EQUAL_INT(SQLITE_TEXT, sqlite3_column_type(stmt, 0));43  return sqlite3_column_text(stmt, 0);44}45 46/* Helper: step a scalar SELECT and assert the first column is NULL */47static void step_null_result(sqlite3_stmt *stmt){48  int rc = sqlite3_step(stmt);49  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ROW, rc, "expected one row (NULL) result");50  TEST_ASSERT_EQUAL_INT(SQLITE_NULL, sqlite3_column_type(stmt, 0));51}52 53/* Helper: step expecting an error */54static void step_expect_error(sqlite3_stmt *stmt){55  int rc = sqlite3_step(stmt);56  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ERROR, rc, "expected SQLITE_ERROR during step");57}58 59/* Unity setUp/tearDown */60void setUp(void) {61  int rc = sqlite3_open(":memory:", &gDb);62  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");63 64  /* Register our forwarding function. No JSON_BLOB flag (user-data = 0) so results are text. */65  rc = sqlite3_create_function_v2(66    gDb, "x_json_remove", -1, SQLITE_UTF8, (void*)(intptr_t)0,67    xJsonRemove, 0, 0, 068  );69  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "create_function failed");70}71 72void tearDown(void) {73  if( gDb ){74    sqlite3_close(gDb);75    gDb = NULL;76  }77}78 79/* Tests */80 81void test_jsonRemoveFunc_basic_object_key_removal(void){82  const char *sql = "SELECT x_json_remove(?1, ?2)";83  const char *params[] = { "{\"a\":1,\"b\":2}", "$.a" };84  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);85  const unsigned char *res = step_text_result(stmt);86  TEST_ASSERT_EQUAL_STRING("{\"b\":2}", (const char*)res);87  sqlite3_finalize(stmt);88}89 90void test_jsonRemoveFunc_array_index_removal(void){91  const char *sql = "SELECT x_json_remove(?1, ?2)";92  const char *params[] = { "[10,20,30]", "$[1]" };93  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);94  const unsigned char *res = step_text_result(stmt);95  TEST_ASSERT_EQUAL_STRING("[10,30]", (const char*)res);96  sqlite3_finalize(stmt);97}98 99void test_jsonRemoveFunc_nested_object_removal(void){100  const char *sql = "SELECT x_json_remove(?1, ?2)";101  const char *params[] = { "{\"a\":{\"b\":1,\"c\":2},\"d\":3}", "$.a.b" };102  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);103  const unsigned char *res = step_text_result(stmt);104  TEST_ASSERT_EQUAL_STRING("{\"a\":{\"c\":2},\"d\":3}", (const char*)res);105  sqlite3_finalize(stmt);106}107 108void test_jsonRemoveFunc_root_path_returns_null(void){109  const char *sql = "SELECT x_json_remove(?1, '$')";110  const char *params[] = { "{\"x\":1}" };111  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 1);112  step_null_result(stmt);113  sqlite3_finalize(stmt);114}115 116void test_jsonRemoveFunc_nonexistent_path_is_noop(void){117  const char *sql = "SELECT x_json_remove(?1, ?2)";118  const char *params[] = { "{\"a\":1}", "$.x" };119  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);120  const unsigned char *res = step_text_result(stmt);121  TEST_ASSERT_EQUAL_STRING("{\"a\":1}", (const char*)res);122  sqlite3_finalize(stmt);123}124 125void test_jsonRemoveFunc_multiple_paths_remove_two_keys(void){126  const char *sql = "SELECT x_json_remove(?1, ?2, ?3)";127  const char *params[] = { "{\"a\":1,\"b\":2,\"c\":3}", "$.a", "$.b" };128  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 3);129  const unsigned char *res = step_text_result(stmt);130  TEST_ASSERT_EQUAL_STRING("{\"c\":3}", (const char*)res);131  sqlite3_finalize(stmt);132}133 134void test_jsonRemoveFunc_array_oob_index_is_noop(void){135  const char *sql = "SELECT x_json_remove(?1, ?2)";136  const char *params[] = { "[1,2]", "$[5]" };137  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);138  const unsigned char *res = step_text_result(stmt);139  TEST_ASSERT_EQUAL_STRING("[1,2]", (const char*)res);140  sqlite3_finalize(stmt);141}142 143void test_jsonRemoveFunc_array_last_element_with_hash_minus_one(void){144  const char *sql = "SELECT x_json_remove(?1, ?2)";145  const char *params[] = { "[1,2,3,4]", "$[#-1]" };146  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);147  const unsigned char *res = step_text_result(stmt);148  TEST_ASSERT_EQUAL_STRING("[1,2,3]", (const char*)res);149  sqlite3_finalize(stmt);150}151 152void test_jsonRemoveFunc_path_error_reports_error(void){153  const char *sql = "SELECT x_json_remove(?1, ?2)";154  /* Path does not start with '$' -> path error */155  const char *params[] = { "{\"a\":1}", "a" };156  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);157  step_expect_error(stmt);158  sqlite3_finalize(stmt);159}160 161void test_jsonRemoveFunc_malformed_json_reports_error(void){162  const char *sql = "SELECT x_json_remove(?1, ?2)";163  const char *params[] = { "not json", "$.a" };164  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);165  step_expect_error(stmt);166  sqlite3_finalize(stmt);167}168 169void test_jsonRemoveFunc_null_path_argument_returns_null(void){170  const char *sql = "SELECT x_json_remove(?1, ?2)";171  const char *params[] = { "{\"a\":1}", NULL };172  sqlite3_stmt *stmt = prepare_with_text_binds(sql, params, 2);173  step_null_result(stmt);174  sqlite3_finalize(stmt);175}176 177int main(void) {178  UNITY_BEGIN();179  RUN_TEST(test_jsonRemoveFunc_basic_object_key_removal);180  RUN_TEST(test_jsonRemoveFunc_array_index_removal);181  RUN_TEST(test_jsonRemoveFunc_nested_object_removal);182  RUN_TEST(test_jsonRemoveFunc_root_path_returns_null);183  RUN_TEST(test_jsonRemoveFunc_nonexistent_path_is_noop);184  RUN_TEST(test_jsonRemoveFunc_multiple_paths_remove_two_keys);185  RUN_TEST(test_jsonRemoveFunc_array_oob_index_is_noop);186  RUN_TEST(test_jsonRemoveFunc_array_last_element_with_hash_minus_one);187  RUN_TEST(test_jsonRemoveFunc_path_error_reports_error);188  RUN_TEST(test_jsonRemoveFunc_malformed_json_reports_error);189  RUN_TEST(test_jsonRemoveFunc_null_path_argument_returns_null);190  return UNITY_END();191}