Fist commit
This commit is contained in:
109
test/test_native_civil_time/test_main.cpp
Executable file
109
test/test_native_civil_time/test_main.cpp
Executable file
@@ -0,0 +1,109 @@
|
||||
#include <unity.h>
|
||||
|
||||
#include "CivilTime.h"
|
||||
#include "SessionClock.h"
|
||||
#include "FakeMonotonicClock.h"
|
||||
|
||||
using namespace timbre_core;
|
||||
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
static void test_fixed_utc_minus_six_conversion(void) {
|
||||
// 2024-01-01 00:00 UTC is 2023-12-31 18:00 in the fixed local zone.
|
||||
const CivilDateTime local = CivilTime::fromUnixSeconds(1704067200LL);
|
||||
TEST_ASSERT_EQUAL_INT(2023, local.year);
|
||||
TEST_ASSERT_EQUAL_INT(12, local.month);
|
||||
TEST_ASSERT_EQUAL_INT(31, local.day);
|
||||
TEST_ASSERT_EQUAL_INT(18, local.hour);
|
||||
TEST_ASSERT_EQUAL_INT(0, local.minute);
|
||||
TEST_ASSERT_EQUAL_INT(0, local.second);
|
||||
TEST_ASSERT_EQUAL_INT(0, local.weekday); // Sunday
|
||||
}
|
||||
|
||||
static void test_leap_day_and_round_trip(void) {
|
||||
CivilDateTime leap;
|
||||
leap.year = 2024;
|
||||
leap.month = 2;
|
||||
leap.day = 29;
|
||||
leap.hour = 12;
|
||||
leap.minute = 34;
|
||||
leap.second = 56;
|
||||
leap.weekday = CivilTime::weekdayForDate(leap.year, leap.month, leap.day);
|
||||
|
||||
TEST_ASSERT_TRUE(leap.valid());
|
||||
std::int64_t epoch = 0;
|
||||
TEST_ASSERT_TRUE(CivilTime::toUnixSeconds(leap, epoch));
|
||||
const CivilDateTime roundTrip = CivilTime::fromUnixSeconds(epoch);
|
||||
TEST_ASSERT_TRUE(roundTrip == leap);
|
||||
|
||||
TEST_ASSERT_TRUE(CivilTime::isLeapYear(2024));
|
||||
TEST_ASSERT_FALSE(CivilTime::isLeapYear(1900));
|
||||
TEST_ASSERT_TRUE(CivilTime::isLeapYear(2000));
|
||||
TEST_ASSERT_EQUAL_INT(29, CivilTime::daysInMonth(2024, 2));
|
||||
TEST_ASSERT_EQUAL_INT(28, CivilTime::daysInMonth(1900, 2));
|
||||
}
|
||||
|
||||
static void test_pre_epoch_values_use_floor_seconds(void) {
|
||||
const CivilDateTime local = CivilTime::fromUnixSeconds(-1);
|
||||
TEST_ASSERT_EQUAL_INT(1969, local.year);
|
||||
TEST_ASSERT_EQUAL_INT(12, local.month);
|
||||
TEST_ASSERT_EQUAL_INT(31, local.day);
|
||||
// UTC-1 is 17:59:59 in the fixed UTC-06:00 local zone.
|
||||
TEST_ASSERT_EQUAL_INT(17, local.hour);
|
||||
TEST_ASSERT_EQUAL_INT(59, local.minute);
|
||||
TEST_ASSERT_EQUAL_INT(59, local.second);
|
||||
|
||||
const CivilDateTime invalid{CivilDateTime{2023, 2, 29, 0, 0, 0, 0}};
|
||||
TEST_ASSERT_FALSE(invalid.valid());
|
||||
}
|
||||
|
||||
static void test_date_and_minute_keys_are_stable(void) {
|
||||
CivilDateTime value{2024, 1, 1, 8, 5, 0, 0};
|
||||
const LocalMinuteKey first = LocalMinuteKey::from(value);
|
||||
TEST_ASSERT_EQUAL_INT64(20240101LL, first.date);
|
||||
TEST_ASSERT_EQUAL_INT(485, first.minuteOfDay);
|
||||
|
||||
// Keep the same local time so the serial difference is exactly one day.
|
||||
CivilDateTime nextDay{2024, 1, 2, 8, 5, 0, 0};
|
||||
const LocalMinuteKey second = LocalMinuteKey::from(nextDay);
|
||||
TEST_ASSERT_TRUE(first < second);
|
||||
TEST_ASSERT_TRUE(first != second);
|
||||
TEST_ASSERT_EQUAL_INT64(1LL * 1440LL, second.serial() - first.serial());
|
||||
}
|
||||
|
||||
static void test_session_clock_anchors_first_observation_without_catchup(void) {
|
||||
FakeMonotonicClock source(100);
|
||||
SessionClock clock(source);
|
||||
|
||||
const SessionClock::Observation first = clock.observe(1704067200LL);
|
||||
TEST_ASSERT_TRUE(first.valid);
|
||||
TEST_ASSERT_TRUE(first.firstObservation);
|
||||
TEST_ASSERT_EQUAL_UINT64(100, first.monotonicMs);
|
||||
|
||||
source.advance(5000);
|
||||
const SessionClock::Observation later = clock.observe(1704067205LL);
|
||||
TEST_ASSERT_TRUE(later.valid);
|
||||
TEST_ASSERT_FALSE(later.firstObservation);
|
||||
TEST_ASSERT_FALSE(later.monotonicRegression);
|
||||
TEST_ASSERT_EQUAL_INT(2023, later.local.year);
|
||||
TEST_ASSERT_EQUAL_INT(18, later.local.hour);
|
||||
TEST_ASSERT_EQUAL_INT(0, later.local.minute);
|
||||
TEST_ASSERT_EQUAL_INT(5, later.local.second);
|
||||
|
||||
source.advance(1000);
|
||||
const SessionClock::Observation tick = clock.tick();
|
||||
TEST_ASSERT_TRUE(tick.valid);
|
||||
TEST_ASSERT_EQUAL_INT(6, tick.local.second);
|
||||
TEST_ASSERT_EQUAL_UINT64(6000, clock.sessionElapsedMs());
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_fixed_utc_minus_six_conversion);
|
||||
RUN_TEST(test_leap_day_and_round_trip);
|
||||
RUN_TEST(test_pre_epoch_values_use_floor_seconds);
|
||||
RUN_TEST(test_date_and_minute_keys_are_stable);
|
||||
RUN_TEST(test_session_clock_anchors_first_observation_without_catchup);
|
||||
return UNITY_END();
|
||||
}
|
||||
Reference in New Issue
Block a user