Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_func_percentStep.c223 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdio.h>6#include <math.h>7 8/* The target wrapper we are testing (provided in the module) */9extern void test_percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv);10 11static sqlite3 *gDb = NULL;12 13/* Aggregate harness xStep: directly calls the target wrapper */14static void agg_step_forward(sqlite3_context *pCtx, int argc, sqlite3_value **argv){15  test_percentStep(pCtx, argc, argv);16}17 18/* Aggregate harness xFinal: just return a constant to indicate success */19static void agg_final_return_one(sqlite3_context *pCtx){20  sqlite3_result_int(pCtx, 1);21}22 23/* Scalar that returns +infinity to exercise "Inf input" checks */24static void scalar_make_inf(sqlite3_context *pCtx, int argc, sqlite3_value **argv){25  (void)argc; (void)argv;26  double inf = 1.0/0.0; /* +inf */27  sqlite3_result_double(pCtx, inf);28}29 30/* Helpers */31static void register_harness_functions(sqlite3 *db){32  int rc;33 34  /* pct1_harness(Y,P): P must be between 0.0 and 1.0 (user-data bit2 clear) */35  rc = sqlite3_create_function(db, "pct1_harness", 2, SQLITE_UTF8, (void*)0,36                               NULL, agg_step_forward, agg_final_return_one);37  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);38 39  /* pct100_harness(Y,P): P must be between 0 and 100 (user-data bit2 set) */40  rc = sqlite3_create_function(db, "pct100_harness", 2, SQLITE_UTF8, (void*)2,41                               NULL, agg_step_forward, agg_final_return_one);42  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);43 44  /* median_harness(Y): same as percentile(Y, 50) (argc==1 path) */45  rc = sqlite3_create_function(db, "median_harness", 1, SQLITE_UTF8, (void*)0,46                               NULL, agg_step_forward, agg_final_return_one);47  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);48 49  /* Scalar to generate +inf */50  rc = sqlite3_create_function(db, "make_inf", 0, SQLITE_UTF8, NULL,51                               scalar_make_inf, NULL, NULL);52  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);53}54 55/* Execute SQL and fetch single integer result (for success-path checks) */56static int exec_single_int(sqlite3 *db, const char *zSql, int *pOut){57  sqlite3_stmt *pStmt = NULL;58  int rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, NULL);59  if( rc!=SQLITE_OK ) return rc;60  rc = sqlite3_step(pStmt);61  if( rc==SQLITE_ROW ){62    if( pOut ) *pOut = sqlite3_column_int(pStmt, 0);63    rc = sqlite3_step(pStmt);64    /* Ensure only one row */65    if( rc==SQLITE_ROW ){66      sqlite3_finalize(pStmt);67      return SQLITE_MISUSE; /* More than one row, unexpected for these tests */68    }69    rc = SQLITE_OK;70  }else if( rc==SQLITE_DONE ){71    rc = SQLITE_OK; /* No rows - treat as OK but no output */72  }else{73    /* rc is an error code */74  }75  sqlite3_finalize(pStmt);76  return rc;77}78 79/* Execute SQL expecting an error, verify error message contains needle */80static void exec_expect_error_contains(sqlite3 *db, const char *zSql, const char *needle){81  char *zErr = NULL;82  int rc = sqlite3_exec(db, zSql, 0, 0, &zErr);83  TEST_ASSERT(rc!=SQLITE_OK);84  TEST_ASSERT_MESSAGE(zErr!=NULL, "Expected an error message but got NULL");85  if( strstr(zErr, needle)==NULL ){86    /* Build a helpful message */87    char buf[1024];88    snprintf(buf, sizeof(buf), "Error message did not contain expected substring.\nSQL: %s\nGot: %s\nExpected substring: %s",89             zSql, zErr, needle);90    TEST_FAIL_MESSAGE(buf);91  }92  sqlite3_free(zErr);93}94 95void setUp(void) {96  int rc = sqlite3_open(":memory:", &gDb);97  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);98  register_harness_functions(gDb);99}100 101void tearDown(void) {102  if( gDb ){103    sqlite3_close(gDb);104    gDb = NULL;105  }106}107 108/* Tests */109 110/* Median path (argc==1) basic success */111void test_percentStep_median_basic_success(void){112  int out = 0;113  int rc = exec_single_int(gDb,114      "SELECT median_harness(x) FROM (VALUES (1),(2),(3));",115      &out);116  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);117  TEST_ASSERT_EQUAL_INT(1, out);118}119 120/* pct1_harness: valid fraction within [0.0, 1.0] succeeds */121void test_percentStep_pct1_valid_fraction(void){122  int out = 0;123  int rc = exec_single_int(gDb,124      "SELECT pct1_harness(x, 0.25) FROM (VALUES (10),(20),(30));",125      &out);126  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);127  TEST_ASSERT_EQUAL_INT(1, out);128}129 130/* pct100_harness: valid fraction within [0, 100] succeeds */131void test_percentStep_pct100_valid_fraction(void){132  int out = 0;133  int rc = exec_single_int(gDb,134      "SELECT pct100_harness(x, 25) FROM (VALUES (1),(2));",135      &out);136  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);137  TEST_ASSERT_EQUAL_INT(1, out);138}139 140/* Non-numeric fraction argument: expect "not between 0.0 and 1.0" error */141void test_percentStep_fraction_not_numeric_pct1(void){142  exec_expect_error_contains(gDb,143      "SELECT pct1_harness(10, 'foo');",144      "the fraction argument to pct1_harness() is not between 0.0 and 1.0");145}146 147/* Fraction out of range low for [0.0,1.0] */148void test_percentStep_fraction_out_of_range_low_pct1(void){149  exec_expect_error_contains(gDb,150      "SELECT pct1_harness(10, -0.1);",151      "the fraction argument to pct1_harness() is not between 0.0 and 1.0");152}153 154/* Fraction out of range high for [0.0,1.0] */155void test_percentStep_fraction_out_of_range_high_pct1(void){156  exec_expect_error_contains(gDb,157      "SELECT pct1_harness(10, 1.1);",158      "the fraction argument to pct1_harness() is not between 0.0 and 1.0");159}160 161/* Fraction out of range high for [0,100] */162void test_percentStep_fraction_out_of_range_high_pct100(void){163  exec_expect_error_contains(gDb,164      "SELECT pct100_harness(10, 120);",165      "the fraction argument to pct100_harness() is not between 0.0 and 100.0");166}167 168/* Non-numeric Y input: expect "input to %s() is not numeric" */169void test_percentStep_input_not_numeric_Y(void){170  exec_expect_error_contains(gDb,171      "SELECT pct1_harness('abc', 0.5);",172      "input to pct1_harness() is not numeric");173}174 175/* Infinity Y input: expect "Inf input to %s()" */176void test_percentStep_infinity_input_Y(void){177  exec_expect_error_contains(gDb,178      "SELECT pct1_harness(make_inf(), 0.5);",179      "Inf input to pct1_harness()");180}181 182/* Inconsistent P across rows: expect consistency error */183void test_percentStep_inconsistent_fraction_across_rows(void){184  exec_expect_error_contains(gDb,185      "SELECT pct1_harness(x, p) "186      "FROM (SELECT 10 AS x, 0.25 AS p UNION ALL SELECT 20, 0.30);",187      "the fraction argument to pct1_harness() is not the same for all input rows");188}189 190/* NULL Y should be ignored and not cause errors */191void test_percentStep_null_Y_ignored(void){192  int out = 0;193  int rc = exec_single_int(gDb, "SELECT pct1_harness(NULL, 0.75);", &out);194  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);195  TEST_ASSERT_EQUAL_INT(1, out);196}197 198/* Median with NULLs should still be OK */199void test_percentStep_median_with_nulls(void){200  int out = 0;201  int rc = exec_single_int(gDb,202      "SELECT median_harness(x) FROM (VALUES (NULL),(NULL),(5));",203      &out);204  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);205  TEST_ASSERT_EQUAL_INT(1, out);206}207 208int main(void){209  UNITY_BEGIN();210  RUN_TEST(test_percentStep_median_basic_success);211  RUN_TEST(test_percentStep_pct1_valid_fraction);212  RUN_TEST(test_percentStep_pct100_valid_fraction);213  RUN_TEST(test_percentStep_fraction_not_numeric_pct1);214  RUN_TEST(test_percentStep_fraction_out_of_range_low_pct1);215  RUN_TEST(test_percentStep_fraction_out_of_range_high_pct1);216  RUN_TEST(test_percentStep_fraction_out_of_range_high_pct100);217  RUN_TEST(test_percentStep_input_not_numeric_Y);218  RUN_TEST(test_percentStep_infinity_input_Y);219  RUN_TEST(test_percentStep_inconsistent_fraction_across_rows);220  RUN_TEST(test_percentStep_null_Y_ignored);221  RUN_TEST(test_percentStep_median_with_nulls);222  return UNITY_END();223}