Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_date_toLocaltime.c190 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6#include <time.h>7#include <math.h>8 9/* The wrapper for the static function under test */10int test_toLocaltime(DateTime *p, sqlite3_context *pCtx);11 12/* Save/restore globals for osLocaltime fault injection */13static int gSavedLocaltimeFault = 0;14static int (*gSavedAltLocaltime)(const void*, void*) = 0;15 16/* An xAltLocaltime implementation that treats "local time" as UTC using gmtime() */17static int altLocaltimeUTC(const void *pIn, void *pOut){18  time_t t = *(const time_t*)pIn;19  struct tm *pTmX = NULL;20#if defined(HAVE_GMTIME_R) && HAVE_GMTIME_R21  if( gmtime_r(&t, (struct tm*)pOut)==NULL ) return 1;22  return 0;23#else24  pTmX = gmtime(&t);25  if( pTmX==NULL ) return 1;26  *(struct tm*)pOut = *pTmX;27  return 0;28#endif29}30 31/* An xAltLocaltime that always fails */32static int altLocaltimeFail(const void *pIn, void *pOut){33  (void)pIn; (void)pOut;34  return 1;35}36 37/* Helper: initialize a DateTime with Y/M/D h:m s (assumed UTC) */38static void initDateTime(DateTime *p, int Y, int M, int D, int h, int m, double s){39  memset(p, 0, sizeof(*p));40  p->Y = Y;41  p->M = M;42  p->D = D;43  p->h = h;44  p->m = m;45  p->s = s;46  p->validYMD = 1;47  p->validHMS = 1;48  p->tz = 0;49  p->rawS = 0;50}51 52/* Create a minimal sqlite3_context suitable for sqlite3_result_error() */53static void createDummyContext(sqlite3_context *pCtx, Mem *pOut, sqlite3 **ppDb){54  memset(pCtx, 0, sizeof(*pCtx));55  memset(pOut, 0, sizeof(*pOut));56  *ppDb = 0;57  /* Open a database so Mem allocations have a db handle */58  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", ppDb));59  pOut->db = *ppDb;60  pCtx->pOut = pOut;61}62 63void setUp(void) {64  /* Save existing config and force use of our alt localtime implementation */65  gSavedLocaltimeFault = sqlite3GlobalConfig.bLocaltimeFault;66  gSavedAltLocaltime = sqlite3GlobalConfig.xAltLocaltime;67  sqlite3GlobalConfig.bLocaltimeFault = 1;68  sqlite3GlobalConfig.xAltLocaltime = altLocaltimeUTC;69}70 71void tearDown(void) {72  /* Restore global config */73  sqlite3GlobalConfig.bLocaltimeFault = gSavedLocaltimeFault;74  sqlite3GlobalConfig.xAltLocaltime = gSavedAltLocaltime;75}76 77/* Test: basic in-range conversion using deterministic UTC "localtime" */78void test_toLocaltime_basic_inrange(void){79  DateTime dt;80  initDateTime(&dt, 2001, 1, 1, 0, 0, 0.0);81 82  int rc = test_toLocaltime(&dt, NULL);83  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);84 85  TEST_ASSERT_EQUAL_INT(2001, dt.Y);86  TEST_ASSERT_EQUAL_INT(1, dt.M);87  TEST_ASSERT_EQUAL_INT(1, dt.D);88  TEST_ASSERT_EQUAL_INT(0, dt.h);89  TEST_ASSERT_EQUAL_INT(0, dt.m);90  TEST_ASSERT_DOUBLE_WITHIN(1e-9, 0.0, dt.s);91 92  TEST_ASSERT_EQUAL_INT(1, dt.validYMD);93  TEST_ASSERT_EQUAL_INT(1, dt.validHMS);94  TEST_ASSERT_EQUAL_INT(0, dt.validJD);95  TEST_ASSERT_EQUAL_INT(0, dt.tz);96  TEST_ASSERT_EQUAL_INT(0, dt.rawS);97  TEST_ASSERT_EQUAL_INT(0, dt.isError);98}99 100/* Test: milliseconds preserved in p->s after conversion */101void test_toLocaltime_preserves_milliseconds(void){102  DateTime dt;103  initDateTime(&dt, 2010, 3, 5, 6, 7, 8.789);104 105  int rc = test_toLocaltime(&dt, NULL);106  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);107 108  TEST_ASSERT_EQUAL_INT(2010, dt.Y);109  TEST_ASSERT_EQUAL_INT(3, dt.M);110  TEST_ASSERT_EQUAL_INT(5, dt.D);111  TEST_ASSERT_EQUAL_INT(6, dt.h);112  TEST_ASSERT_EQUAL_INT(7, dt.m);113  TEST_ASSERT_DOUBLE_WITHIN(1e-6, 8.789, dt.s);114}115 116/* Test: year mapping for a pre-1970 date (e.g., 1900) and mapping back */117void test_toLocaltime_pre1970_year_mapping(void){118  DateTime dt;119  initDateTime(&dt, 1900, 1, 1, 12, 34, 56.250);120 121  int rc = test_toLocaltime(&dt, NULL);122  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);123 124  TEST_ASSERT_EQUAL_INT(1900, dt.Y);125  TEST_ASSERT_EQUAL_INT(1, dt.M);126  TEST_ASSERT_EQUAL_INT(1, dt.D);127  TEST_ASSERT_EQUAL_INT(12, dt.h);128  TEST_ASSERT_EQUAL_INT(34, dt.m);129  TEST_ASSERT_DOUBLE_WITHIN(1e-6, 56.250, dt.s);130}131 132/* Test: year mapping for a post-2038 date (e.g., 2090) and mapping back */133void test_toLocaltime_post2038_year_mapping(void){134  DateTime dt;135  initDateTime(&dt, 2090, 7, 15, 10, 20, 30.125);136 137  int rc = test_toLocaltime(&dt, NULL);138  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);139 140  TEST_ASSERT_EQUAL_INT(2090, dt.Y);141  TEST_ASSERT_EQUAL_INT(7, dt.M);142  TEST_ASSERT_EQUAL_INT(15, dt.D);143  TEST_ASSERT_EQUAL_INT(10, dt.h);144  TEST_ASSERT_EQUAL_INT(20, dt.m);145  TEST_ASSERT_DOUBLE_WITHIN(1e-6, 30.125, dt.s);146}147 148/* Test: osLocaltime failure path triggers SQLITE_ERROR and leaves fields intact */149void test_toLocaltime_oslocaltime_failure(void){150  /* Force osLocaltime to fail */151  sqlite3GlobalConfig.xAltLocaltime = altLocaltimeFail;152 153  DateTime dt;154  initDateTime(&dt, 2005, 12, 31, 23, 59, 59.5);155 156  /* Prepare a minimal context to allow sqlite3_result_error() to run safely */157  sqlite3_context ctx;158  Mem out;159  sqlite3 *db = 0;160  createDummyContext(&ctx, &out, &db);161 162  int rc = test_toLocaltime(&dt, &ctx);163  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);164 165  /* Ensure original Y/M/D/H/M/S remained unchanged on failure */166  TEST_ASSERT_EQUAL_INT(2005, dt.Y);167  TEST_ASSERT_EQUAL_INT(12, dt.M);168  TEST_ASSERT_EQUAL_INT(31, dt.D);169  TEST_ASSERT_EQUAL_INT(23, dt.h);170  TEST_ASSERT_EQUAL_INT(59, dt.m);171  TEST_ASSERT_DOUBLE_WITHIN(1e-6, 59.5, dt.s);172 173  /* validJD likely set by computeJD(), but validYMD/HMS should be unchanged */174  TEST_ASSERT_EQUAL_INT(1, dt.validYMD);175  TEST_ASSERT_EQUAL_INT(1, dt.validHMS);176 177  /* Cleanup context memory */178  sqlite3VdbeMemRelease(&out);179  sqlite3_close(db);180}181 182int main(void){183  UNITY_BEGIN();184  RUN_TEST(test_toLocaltime_basic_inrange);185  RUN_TEST(test_toLocaltime_preserves_milliseconds);186  RUN_TEST(test_toLocaltime_pre1970_year_mapping);187  RUN_TEST(test_toLocaltime_post2038_year_mapping);188  RUN_TEST(test_toLocaltime_oslocaltime_failure);189  return UNITY_END();190}