Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_date_strftimeFunc.c225 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/* The target wrapper provided by the module under test */9void test_strftimeFunc(sqlite3_context *context, int argc, sqlite3_value **argv);10 11static sqlite3 *gDb = NULL;12 13/* SQLite SQL wrapper that forwards directly to the target function */14static void x_t_strftime(sqlite3_context *ctx, int argc, sqlite3_value **argv){15    test_strftimeFunc(ctx, argc, argv);16}17 18/* Helper: Execute a scalar SQL that returns a single column.19   Returns a malloc'ed copy of the text result (sqlite3_malloc),20   or NULL if the result is SQL NULL. Sets *pIsNull accordingly. */21static char* exec_scalar_text(const char *sql, int *pIsNull){22    sqlite3_stmt *stmt = NULL;23    int rc = sqlite3_prepare_v2(gDb, sql, -1, &stmt, 0);24    if( rc!=SQLITE_OK ){25        TEST_FAIL_MESSAGE("sqlite3_prepare_v2 failed");26        return NULL;27    }28    rc = sqlite3_step(stmt);29    if( rc!=SQLITE_ROW ){30        sqlite3_finalize(stmt);31        TEST_FAIL_MESSAGE("sqlite3_step did not return a row");32        return NULL;33    }34    int t = sqlite3_column_type(stmt, 0);35    char *ret = NULL;36    if( t==SQLITE_NULL ){37        if(pIsNull) *pIsNull = 1;38    }else{39        if(pIsNull) *pIsNull = 0;40        const unsigned char *z = sqlite3_column_text(stmt, 0);41        if( z ){42            ret = (char*)sqlite3_mprintf("%s", z);43        }else{44            ret = NULL;45        }46    }47    sqlite3_finalize(stmt);48    return ret;49}50 51static void assert_sql_result_eq(const char *sql, const char *expected){52    int isNull = 0;53    char *got = exec_scalar_text(sql, &isNull);54    if( expected==NULL ){55        TEST_ASSERT_TRUE_MESSAGE(isNull!=0, "Expected NULL but got non-NULL");56        if(got) sqlite3_free(got);57        return;58    }59    TEST_ASSERT_TRUE_MESSAGE(isNull==0, "Expected non-NULL but got NULL");60    TEST_ASSERT_NOT_NULL(got);61    TEST_ASSERT_EQUAL_STRING(expected, got);62    sqlite3_free(got);63}64 65void setUp(void) {66    int rc = sqlite3_open(":memory:", &gDb);67    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);68    rc = sqlite3_create_function_v2(69        gDb, "t_strftime", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC,70        NULL, x_t_strftime, NULL, NULL, NULL71    );72    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);73}74 75void tearDown(void) {76    if( gDb ){77        sqlite3_close(gDb);78        gDb = NULL;79    }80}81 82/* Zero-argument call should return NULL */83void test_strftimeFunc_zero_args_returns_null(void){84    assert_sql_result_eq("SELECT t_strftime()", NULL);85}86 87/* Invalid format specifier should result in NULL */88void test_strftimeFunc_invalid_format_returns_null(void){89    assert_sql_result_eq("SELECT t_strftime('%Q','2000-01-01')", NULL);90}91 92/* Invalid date/time string should return NULL */93void test_strftimeFunc_invalid_datetime_returns_null(void){94    assert_sql_result_eq("SELECT t_strftime('%Y','not-a-date')", NULL);95}96 97/* Basic date fields %Y %m %d and %F */98void test_strftimeFunc_basic_date_fields(void){99    assert_sql_result_eq("SELECT t_strftime('%Y','2000-03-02')", "2000");100    assert_sql_result_eq("SELECT t_strftime('%m','2000-03-02')", "03");101    assert_sql_result_eq("SELECT t_strftime('%d','2000-03-02')", "02");102    assert_sql_result_eq("SELECT t_strftime('%F','2000-03-02')", "2000-03-02");103}104 105/* Basic time fields %H %M %S and composed %R %T */106void test_strftimeFunc_basic_time_fields(void){107    assert_sql_result_eq("SELECT t_strftime('%H','2001-02-03 04:05:06')", "04");108    assert_sql_result_eq("SELECT t_strftime('%M','2001-02-03 04:05:06')", "05");109    assert_sql_result_eq("SELECT t_strftime('%S','2001-02-03 04:05:06')", "06");110    assert_sql_result_eq("SELECT t_strftime('%R','2001-02-03 04:05:06')", "04:05");111    assert_sql_result_eq("SELECT t_strftime('%T','2001-02-03 04:05:06')", "04:05:06");112}113 114/* 12-hour clock and AM/PM variants %I, %l, %p, %P; space padding %k and %e */115void test_strftimeFunc_12hr_and_padding(void){116    /* Midnight -> 12 AM */117    assert_sql_result_eq("SELECT t_strftime('%I','2001-02-03 00:05:06')", "12");118    assert_sql_result_eq("SELECT t_strftime('%l','2001-02-03 00:05:06')", "12");119    assert_sql_result_eq("SELECT t_strftime('%p','2001-02-03 00:05:06')", "AM");120    assert_sql_result_eq("SELECT t_strftime('%P','2001-02-03 00:05:06')", "am");121 122    /* Afternoon -> 1 PM */123    assert_sql_result_eq("SELECT t_strftime('%I','2001-02-03 13:00:00')", "01");124    assert_sql_result_eq("SELECT t_strftime('%l','2001-02-03 13:00:00')", " 1");125    assert_sql_result_eq("SELECT t_strftime('%p','2001-02-03 13:00:00')", "PM");126    assert_sql_result_eq("SELECT t_strftime('%P','2001-02-03 13:00:00')", "pm");127 128    /* Space padding for hour %k and day-of-month %e */129    assert_sql_result_eq("SELECT t_strftime('%k','2001-02-03 03:00:00')", " 3");130    assert_sql_result_eq("SELECT t_strftime('%e','2001-02-03')", " 3");131}132 133/* Day of year %j, checking leap year behavior */134void test_strftimeFunc_day_of_year(void){135    /* 2000-03-01 is leap year day 61 */136    assert_sql_result_eq("SELECT t_strftime('%j','2000-03-01')", "061");137    /* 1999-03-01 is non-leap year day 60 */138    assert_sql_result_eq("SELECT t_strftime('%j','1999-03-01')", "060");139}140 141/* Julian day number %J */142void test_strftimeFunc_julian_day_number(void){143    /* 2000-01-01 00:00:00 -> JD 2451544.5 */144    assert_sql_result_eq("SELECT t_strftime('%J','2000-01-01 00:00:00')", "2451544.5");145}146 147/* Unix epoch seconds %s, with and without subseconds; fractional seconds %f */148void test_strftimeFunc_epoch_and_fractional(void){149    /* Exact epoch */150    assert_sql_result_eq("SELECT t_strftime('%s','1970-01-01 00:00:00')", "0");151 152    /* 2000-01-01 00:00:00 -> 946684800 */153    assert_sql_result_eq("SELECT t_strftime('%s','2000-01-01 00:00:00')", "946684800");154 155    /* Fractional seconds formatting and epoch fraction */156    assert_sql_result_eq("SELECT t_strftime('%f','1970-01-01 00:00:00.250')", "00.250");157    assert_sql_result_eq("SELECT t_strftime('%s','1970-01-01 00:00:00.250')", "0.250");158}159 160/* Day of week %u and %w */161void test_strftimeFunc_day_of_week(void){162    /* 2000-01-01 is Saturday */163    assert_sql_result_eq("SELECT t_strftime('%w','2000-01-01')", "6");164    assert_sql_result_eq("SELECT t_strftime('%u','2000-01-01')", "6");165 166    /* 2000-01-02 is Sunday */167    assert_sql_result_eq("SELECT t_strftime('%w','2000-01-02')", "0");168    assert_sql_result_eq("SELECT t_strftime('%u','2000-01-02')", "7");169}170 171/* Week numbers %U and %W */172void test_strftimeFunc_week_numbers_U_W(void){173    /* 2016-01-01 Friday -> Before first Sunday/Monday, both 00 */174    assert_sql_result_eq("SELECT t_strftime('%U','2016-01-01')", "00");175    assert_sql_result_eq("SELECT t_strftime('%W','2016-01-01')", "00");176 177    /* 2017-01-01 Sunday -> First Sunday is week 01; first Monday also yields 01 */178    assert_sql_result_eq("SELECT t_strftime('%U','2017-01-01')", "01");179    assert_sql_result_eq("SELECT t_strftime('%W','2017-01-01')", "01");180}181 182/* ISO week number %V and ISO year %G/%g, including a year-boundary edge case */183void test_strftimeFunc_iso_week_and_year(void){184    /* 2017-01-01 (Sunday) is ISO week 52 of 2016 */185    assert_sql_result_eq("SELECT t_strftime('%V','2017-01-01')", "52");186    assert_sql_result_eq("SELECT t_strftime('%G','2017-01-01')", "2016");187    assert_sql_result_eq("SELECT t_strftime('%g','2017-01-01')", "16");188 189    /* 2015-01-01 (Thursday) is ISO week 01 of 2015 */190    assert_sql_result_eq("SELECT t_strftime('%V','2015-01-01')", "01");191    assert_sql_result_eq("SELECT t_strftime('%G','2015-01-01')", "2015");192    assert_sql_result_eq("SELECT t_strftime('%g','2015-01-01')", "15");193}194 195/* Literal percent %% and mixed literal text */196void test_strftimeFunc_literal_percent_and_text(void){197    assert_sql_result_eq("SELECT t_strftime('%%','2000-01-01')", "%");198    assert_sql_result_eq("SELECT t_strftime('Date=%F Time=%T','2001-02-03 04:05:06')",199                         "Date=2001-02-03 Time=04:05:06");200}201 202/* Combined expansion and pass-through characters */203void test_strftimeFunc_mixed_format(void){204    assert_sql_result_eq("SELECT t_strftime('Y:%Y m:%m d:%d j:%j','1999-12-31')",205                         "Y:1999 m:12 d:31 j:365");206}207 208int main(void){209    UNITY_BEGIN();210    RUN_TEST(test_strftimeFunc_zero_args_returns_null);211    RUN_TEST(test_strftimeFunc_invalid_format_returns_null);212    RUN_TEST(test_strftimeFunc_invalid_datetime_returns_null);213    RUN_TEST(test_strftimeFunc_basic_date_fields);214    RUN_TEST(test_strftimeFunc_basic_time_fields);215    RUN_TEST(test_strftimeFunc_12hr_and_padding);216    RUN_TEST(test_strftimeFunc_day_of_year);217    RUN_TEST(test_strftimeFunc_julian_day_number);218    RUN_TEST(test_strftimeFunc_epoch_and_fractional);219    RUN_TEST(test_strftimeFunc_day_of_week);220    RUN_TEST(test_strftimeFunc_week_numbers_U_W);221    RUN_TEST(test_strftimeFunc_iso_week_and_year);222    RUN_TEST(test_strftimeFunc_literal_percent_and_text);223    RUN_TEST(test_strftimeFunc_mixed_format);224    return UNITY_END();225}