AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdio.h>6 7/* Wrapper exported by the module under test */8extern int test_parseTimezone(const char *zDate, DateTime *p);9 10void setUp(void) {11 /* No global setup needed */12}13void tearDown(void) {14 /* No global teardown needed */15}16 17/* Helper to init a DateTime struct with sentinel values */18static void initDateTime(DateTime *p, int tz, int isLocal, int isUtc){19 memset(p, 0xA5, sizeof(*p)); /* poison to catch unintended assumptions */20 p->tz = tz;21 p->isLocal = (char)isLocal;22 p->isUtc = (char)isUtc;23}24 25/* Empty string: success, tz set to 0, flags unchanged */26void test_parseTimezone_empty_ok(void){27 DateTime dt;28 initDateTime(&dt, 1234, 7, 2);29 int rc = test_parseTimezone("", &dt);30 TEST_ASSERT_EQUAL_INT(0, rc);31 TEST_ASSERT_EQUAL_INT(0, dt.tz);32 TEST_ASSERT_EQUAL_INT(7, dt.isLocal);33 TEST_ASSERT_EQUAL_INT(2, dt.isUtc);34}35 36/* Whitespace-only: success, tz set to 0, flags unchanged */37void test_parseTimezone_spaces_only_ok(void){38 DateTime dt;39 initDateTime(&dt, -1, 5, 6);40 int rc = test_parseTimezone(" \t \n", &dt);41 TEST_ASSERT_EQUAL_INT(0, rc);42 TEST_ASSERT_EQUAL_INT(0, dt.tz);43 TEST_ASSERT_EQUAL_INT(5, dt.isLocal);44 TEST_ASSERT_EQUAL_INT(6, dt.isUtc);45}46 47/* 'Z' sets UTC flags and allows trailing spaces */48void test_parseTimezone_uppercase_Z_sets_flags(void){49 DateTime dt;50 initDateTime(&dt, 999, 1, 0);51 int rc = test_parseTimezone("Z ", &dt);52 TEST_ASSERT_EQUAL_INT(0, rc);53 TEST_ASSERT_EQUAL_INT(0, dt.tz);54 TEST_ASSERT_EQUAL_INT(0, dt.isLocal);55 TEST_ASSERT_EQUAL_INT(1, dt.isUtc);56}57 58/* 'z' sets UTC flags */59void test_parseTimezone_lowercase_z_sets_flags(void){60 DateTime dt;61 initDateTime(&dt, 999, 1, 0);62 int rc = test_parseTimezone("z", &dt);63 TEST_ASSERT_EQUAL_INT(0, rc);64 TEST_ASSERT_EQUAL_INT(0, dt.tz);65 TEST_ASSERT_EQUAL_INT(0, dt.isLocal);66 TEST_ASSERT_EQUAL_INT(1, dt.isUtc);67}68 69/* "+05:30" parsed correctly, flags not changed (non-zero offset) */70void test_parseTimezone_plus_0530_ok_no_flag_change(void){71 DateTime dt;72 initDateTime(&dt, -777, 1, 0);73 int rc = test_parseTimezone("+05:30", &dt);74 TEST_ASSERT_EQUAL_INT(0, rc);75 TEST_ASSERT_EQUAL_INT(5*60 + 30, dt.tz);76 TEST_ASSERT_EQUAL_INT(1, dt.isLocal);77 TEST_ASSERT_EQUAL_INT(0, dt.isUtc);78}79 80/* "-12:34" parsed correctly (negative offset), flags unchanged */81void test_parseTimezone_minus_1234_ok(void){82 DateTime dt;83 initDateTime(&dt, 0, 3, 4);84 int rc = test_parseTimezone("-12:34", &dt);85 TEST_ASSERT_EQUAL_INT(0, rc);86 TEST_ASSERT_EQUAL_INT(-(12*60 + 34), dt.tz);87 TEST_ASSERT_EQUAL_INT(3, dt.isLocal);88 TEST_ASSERT_EQUAL_INT(4, dt.isUtc);89}90 91/* "+00:00" normalized to UTC (tz==0 triggers UTC flags) */92void test_parseTimezone_plus_0000_sets_utc_flags(void){93 DateTime dt;94 initDateTime(&dt, 111, 1, 0);95 int rc = test_parseTimezone("+00:00", &dt);96 TEST_ASSERT_EQUAL_INT(0, rc);97 TEST_ASSERT_EQUAL_INT(0, dt.tz);98 TEST_ASSERT_EQUAL_INT(0, dt.isLocal);99 TEST_ASSERT_EQUAL_INT(1, dt.isUtc);100}101 102/* "-00:00" also normalized to UTC */103void test_parseTimezone_minus_0000_sets_utc_flags(void){104 DateTime dt;105 initDateTime(&dt, 222, 1, 0);106 int rc = test_parseTimezone("-00:00", &dt);107 TEST_ASSERT_EQUAL_INT(0, rc);108 TEST_ASSERT_EQUAL_INT(0, dt.tz);109 TEST_ASSERT_EQUAL_INT(0, dt.isLocal);110 TEST_ASSERT_EQUAL_INT(1, dt.isUtc);111}112 113/* Upper bound for hour is 14; minutes can be up to 59 */114void test_parseTimezone_upper_bound_14_59_ok(void){115 DateTime dt;116 initDateTime(&dt, -5, 9, 8);117 int rc = test_parseTimezone("+14:59", &dt);118 TEST_ASSERT_EQUAL_INT(0, rc);119 TEST_ASSERT_EQUAL_INT(14*60 + 59, dt.tz);120 TEST_ASSERT_EQUAL_INT(9, dt.isLocal);121 TEST_ASSERT_EQUAL_INT(8, dt.isUtc);122}123 124/* "+15:00" invalid (hour > 14) */125void test_parseTimezone_hour_15_invalid(void){126 DateTime dt;127 initDateTime(&dt, 333, 7, 2);128 int rc = test_parseTimezone("+15:00", &dt);129 TEST_ASSERT_NOT_EQUAL(0, rc);130 TEST_ASSERT_EQUAL_INT(0, dt.tz); /* tz reset at start of function */131 TEST_ASSERT_EQUAL_INT(7, dt.isLocal);132 TEST_ASSERT_EQUAL_INT(2, dt.isUtc);133}134 135/* Incomplete: "+" only is invalid */136void test_parseTimezone_plus_only_invalid(void){137 DateTime dt;138 initDateTime(&dt, 444, 6, 5);139 int rc = test_parseTimezone("+", &dt);140 TEST_ASSERT_NOT_EQUAL(0, rc);141 TEST_ASSERT_EQUAL_INT(0, dt.tz);142 TEST_ASSERT_EQUAL_INT(6, dt.isLocal);143 TEST_ASSERT_EQUAL_INT(5, dt.isUtc);144}145 146/* Single-digit hour invalid ("+5:30") */147void test_parseTimezone_single_digit_hour_invalid(void){148 DateTime dt;149 initDateTime(&dt, -99, 4, 3);150 int rc = test_parseTimezone("+5:30", &dt);151 TEST_ASSERT_NOT_EQUAL(0, rc);152 TEST_ASSERT_EQUAL_INT(0, dt.tz);153 TEST_ASSERT_EQUAL_INT(4, dt.isLocal);154 TEST_ASSERT_EQUAL_INT(3, dt.isUtc);155}156 157/* Missing minute digit ("+12:3") invalid */158void test_parseTimezone_missing_minute_digit_invalid(void){159 DateTime dt;160 initDateTime(&dt, -88, 1, 1);161 int rc = test_parseTimezone("+12:3", &dt);162 TEST_ASSERT_NOT_EQUAL(0, rc);163 TEST_ASSERT_EQUAL_INT(0, dt.tz);164}165 166/* Trailing garbage after valid offset => error return but tz already computed */167void test_parseTimezone_trailing_garbage_invalid_but_tz_set(void){168 DateTime dt;169 initDateTime(&dt, 0, 1, 0);170 int rc = test_parseTimezone("+02:00xyz", &dt);171 TEST_ASSERT_NOT_EQUAL(0, rc);172 TEST_ASSERT_EQUAL_INT(2*60, dt.tz); /* tz computed before trailing check */173 TEST_ASSERT_EQUAL_INT(1, dt.isLocal); /* flags unchanged since tz != 0 */174 TEST_ASSERT_EQUAL_INT(0, dt.isUtc);175}176 177/* Invalid start character (not '+', '-', 'Z'/'z', or end-of-string) */178void test_parseTimezone_invalid_start_char(void){179 DateTime dt;180 initDateTime(&dt, 777, 9, 9);181 int rc = test_parseTimezone("UTC", &dt);182 TEST_ASSERT_NOT_EQUAL(0, rc);183 TEST_ASSERT_EQUAL_INT(0, dt.tz);184 TEST_ASSERT_EQUAL_INT(9, dt.isLocal);185 TEST_ASSERT_EQUAL_INT(9, dt.isUtc);186}187 188/* Leading and trailing whitespace around a valid offset */189void test_parseTimezone_spaces_around_valid_offset_ok(void){190 DateTime dt;191 initDateTime(&dt, -1, 3, 0);192 int rc = test_parseTimezone(" +00:00 ", &dt);193 TEST_ASSERT_EQUAL_INT(0, rc);194 TEST_ASSERT_EQUAL_INT(0, dt.tz);195 TEST_ASSERT_EQUAL_INT(0, dt.isLocal);196 TEST_ASSERT_EQUAL_INT(1, dt.isUtc);197}198 199int main(void){200 UNITY_BEGIN();201 RUN_TEST(test_parseTimezone_empty_ok);202 RUN_TEST(test_parseTimezone_spaces_only_ok);203 RUN_TEST(test_parseTimezone_uppercase_Z_sets_flags);204 RUN_TEST(test_parseTimezone_lowercase_z_sets_flags);205 RUN_TEST(test_parseTimezone_plus_0530_ok_no_flag_change);206 RUN_TEST(test_parseTimezone_minus_1234_ok);207 RUN_TEST(test_parseTimezone_plus_0000_sets_utc_flags);208 RUN_TEST(test_parseTimezone_minus_0000_sets_utc_flags);209 RUN_TEST(test_parseTimezone_upper_bound_14_59_ok);210 RUN_TEST(test_parseTimezone_hour_15_invalid);211 RUN_TEST(test_parseTimezone_plus_only_invalid);212 RUN_TEST(test_parseTimezone_single_digit_hour_invalid);213 RUN_TEST(test_parseTimezone_missing_minute_digit_invalid);214 RUN_TEST(test_parseTimezone_trailing_garbage_invalid_but_tz_set);215 RUN_TEST(test_parseTimezone_invalid_start_char);216 RUN_TEST(test_parseTimezone_spaces_around_valid_offset_ok);217 return UNITY_END();218}