From 0e5769ca1366080d2846fcddd87b5e7818f2ff15 Mon Sep 17 00:00:00 2001 From: Alek Rudnik Date: Thu, 15 Jul 2021 17:42:26 +0200 Subject: [PATCH] [EGD-7074] Fix date and time unit tests Made sure test are not dependant on current time. --- module-utils/time/test/unittest_time.cpp | 142 ++++++++++++--------- module-utils/time/time/time_conversion.cpp | 27 ++-- module-utils/time/time/time_conversion.hpp | 19 ++- 3 files changed, 100 insertions(+), 88 deletions(-) diff --git a/module-utils/time/test/unittest_time.cpp b/module-utils/time/test/unittest_time.cpp index 1d256959c6729e8459028ba84b67e11622a52a55..eb6f92815c9260153920cadd746613e87b1e957e 100644 --- a/module-utils/time/test/unittest_time.cpp +++ b/module-utils/time/test/unittest_time.cpp @@ -175,50 +175,74 @@ TEST_CASE("TimeStamp") TEST_CASE("DateTime") { utils::setDisplayLanguage("English"); - setenv("TZ", "GMT0", 1); + auto timezone = GENERATE("GMTO", "GMT-2", "GMT+2"); + setenv("TZ", timezone, 1); TimeSettings timeSettings; + const time_t currentTime = GENERATE(1623714101, /* Monday, June 14, 2021 11:41:41 PM GMT */ + 1625084493, /* Wednesday, June 30, 2021 8:21:33 PM GMT */ + 1625170893, /* Thursday, July 1, 2021 8:21:33 PM GMT */ + 1625257293, /* Friday, July 2, 2021 8:21:33 PM GMT */ + 1640982093, /* Friday, December 31, 2021 8:21:33 PM GMT */ + 1641068493, /* Saturday, January 1, 2022 8:21:33 PM GMT */ + 1614525589, /* Sunday, February 28, 2021 3:19:49 PM GMT */ + 1614611989, /* Monday, March 1, 2021 3:19:49 PM GMT */ + 1614698389 /* Tuesday, March 2, 2021 3:19:49 PM GMT */ + ); + const auto currentTimeTimeinfo = *std::localtime(¤tTime); + SECTION("isToday") { - const auto currentTime = std::time(nullptr); - const auto currentTimeTimeinfo = *std::localtime(¤tTime); - - auto newTimeTimeinfo = currentTimeTimeinfo; SECTION("today") { - for (int i = 0; i < 24; i++) { - newTimeTimeinfo.tm_hour = i; - auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); - REQUIRE(datetime.isToday()); - } + auto newTimeTimeinfo = currentTimeTimeinfo; + auto i = GENERATE(range(0, 23)); + newTimeTimeinfo.tm_hour = i; + auto newTime = std::mktime(&newTimeTimeinfo); + DateTime datetime(timeSettings, newTime, currentTime); + REQUIRE(datetime.isToday()); } SECTION("not today") { - for (int i = 1; i < 32; i++) { - newTimeTimeinfo.tm_mday = currentTimeTimeinfo.tm_mday - i; - auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); - REQUIRE(!datetime.isToday()); + auto newTimeTimeinfo = currentTimeTimeinfo; + SECTION("different day") + { + for (int i = 1; i <= 31; i++) { + newTimeTimeinfo.tm_mday = i; + auto newTime = std::mktime(&newTimeTimeinfo); + if (newTimeTimeinfo.tm_mday == currentTimeTimeinfo.tm_mday) { + continue; + } + DateTime datetime(timeSettings, newTime, currentTime); + REQUIRE(!datetime.isToday()); + } } - for (int i = 1; i < 12; i++) { - newTimeTimeinfo.tm_mon = currentTimeTimeinfo.tm_mon - i; - auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); - REQUIRE(!datetime.isToday()); + SECTION("different month") + { + for (int i = 1; i <= 12; i++) { + newTimeTimeinfo.tm_mon = i; + auto newTime = std::mktime(&newTimeTimeinfo); + if (newTimeTimeinfo.tm_mon == currentTimeTimeinfo.tm_mon) { + continue; + } + DateTime datetime(timeSettings, newTime, currentTime); + REQUIRE(!datetime.isToday()); + } } - // previous - for (int i = 0; i < 100; i++) { + SECTION("previous years") + { + auto i = GENERATE(range(1, 100)); newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year - i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isToday()); } - // forward - for (int i = 0; i < 100; i++) { + SECTION("next years") + { + auto i = GENERATE(range(1, 100)); newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year + i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isToday()); } } @@ -226,48 +250,54 @@ TEST_CASE("DateTime") SECTION("isYesterday") { - const auto currentTime = std::time(nullptr); - const auto currentTimeTimeinfo = *std::localtime(¤tTime); - auto newTimeTimeinfo = currentTimeTimeinfo; - newTimeTimeinfo.tm_mday -= 1; SECTION("yesterday") { + newTimeTimeinfo.tm_mday -= 1; for (int i = 0; i < 24; i++) { newTimeTimeinfo.tm_hour = i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(datetime.isYesterday()); } } SECTION("not yesterday") { - SECTION("same month, different days") + SECTION("different days") { for (int i = 1; i < 32; i++) { newTimeTimeinfo.tm_mday = i; + auto newTime = std::mktime(&newTimeTimeinfo); if (newTimeTimeinfo.tm_mday == currentTimeTimeinfo.tm_mday - 1) { continue; } - auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); + REQUIRE(!datetime.isYesterday()); + } + } + SECTION("different months") + { + for (int i = 0; i < 12; i++) { + newTimeTimeinfo.tm_mon = i; + auto newTime = std::mktime(&newTimeTimeinfo); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isYesterday()); } } - SECTION("different year") + SECTION("different years") { // previous for (int i = 1; i < 100; i++) { newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year - i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isYesterday()); } // forward for (int i = 1; i < 100; i++) { newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year + i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isYesterday()); } } @@ -275,16 +305,13 @@ TEST_CASE("DateTime") SECTION("isCurrentYear") { - const auto currentTime = std::time(nullptr); - const auto currentTimeTimeinfo = *std::localtime(¤tTime); - auto newTimeTimeinfo = currentTimeTimeinfo; - SECTION("same month, different days") + SECTION("different days") { for (int i = 1; i < 32; i++) { newTimeTimeinfo.tm_mday = i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(datetime.isCurrentYear()); } } @@ -293,24 +320,24 @@ TEST_CASE("DateTime") for (int i = 0; i < 12; i++) { newTimeTimeinfo.tm_mon = i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(datetime.isCurrentYear()); } } - SECTION("different year") + SECTION("different years") { // previous for (int i = 1; i < 100; i++) { newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year - i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isCurrentYear()); } // forward for (int i = 1; i < 100; i++) { newTimeTimeinfo.tm_year = currentTimeTimeinfo.tm_year + i; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(!datetime.isCurrentYear()); } } @@ -319,17 +346,14 @@ TEST_CASE("DateTime") SECTION("Display") { - const auto currentTime = std::time(nullptr); - const auto currentTimeTimeinfo = *std::localtime(¤tTime); - - auto newTimeTimeinfo = currentTimeTimeinfo; + auto newTimeTimeinfo = currentTimeTimeinfo; timeSettings.timeFormat12h = true; timeSettings.dateFormatDDMM = true; SECTION("now") { std::regex reg = reg12h; - auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + auto newTime = std::mktime(&newTimeTimeinfo); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(std::regex_match(std::string(datetime.str()), reg)); timeSettings.timeFormat12h = false; @@ -341,7 +365,7 @@ TEST_CASE("DateTime") { newTimeTimeinfo.tm_mday -= 1; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(datetime.str() == "Yesterday"); } @@ -357,7 +381,7 @@ TEST_CASE("DateTime") } auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(std::regex_match(std::string(datetime.str()), regexSameYear)); timeSettings.dateFormatDDMM = false; regexSameYear = regexMMDD; @@ -370,7 +394,7 @@ TEST_CASE("DateTime") newTimeTimeinfo.tm_year -= 1; auto newTime = std::mktime(&newTimeTimeinfo); - DateTime datetime(timeSettings, newTime); + DateTime datetime(timeSettings, newTime, currentTime); REQUIRE(std::regex_match(std::string(datetime.str()), regexPreviousYear)); timeSettings.dateFormatDDMM = false; @@ -388,7 +412,7 @@ TEST_CASE("Time") SECTION("Display") { - const auto currentTime = std::time(nullptr); + const auto currentTime = 1623714101; // Monday, June 14, 2021 11:41:41 PM GMT timeSettings.timeFormat12h = true; timeSettings.dateFormatDDMM = true; @@ -413,7 +437,7 @@ TEST_CASE("Clock") SECTION("Display") { - const auto currentTime = std::time(nullptr); + const auto currentTime = 1623714101; // Monday, June 14, 2021 11:41:41 PM GMT timeSettings.timeFormat12h = true; timeSettings.dateFormatDDMM = true; @@ -438,7 +462,7 @@ TEST_CASE("Date") SECTION("Display") { - const auto currentTime = std::time(nullptr); + const auto currentTime = 1623714101; // Monday, June 14, 2021 11:41:41 PM GMT timeSettings.timeFormat12h = true; timeSettings.dateFormatDDMM = true; diff --git a/module-utils/time/time/time_conversion.cpp b/module-utils/time/time/time_conversion.cpp index ea83c10f55bb3974499015aeca9098399d6aa344..2c478bbc7f5f93e1092826eab2fa40e30fa3f594 100644 --- a/module-utils/time/time/time_conversion.cpp +++ b/module-utils/time/time/time_conversion.cpp @@ -139,38 +139,29 @@ namespace utils::time return Timestamp(lhs.duration + rhs.time); } - void DateTime::before_n_sec(time_t val) - { - local_time = time; - if (val) { - set_time(val); - } - } - bool DateTime::isToday() const { auto timeinfo = *std::localtime(&time); - auto newer_timeinfo = *localtime(&local_time); + auto newer_timeinfo = *std::localtime(&referenceTime); return (newer_timeinfo.tm_yday == timeinfo.tm_yday && isCurrentYear()); } bool DateTime::isYesterday() const { auto timeinfo = *std::localtime(&time); - auto newer_timeinfo = *localtime(&local_time); - bool is_leap_year = (timeinfo.tm_year % 4 == 0 && timeinfo.tm_year % 100 != 0) || timeinfo.tm_year % 400 == 0; - - return (((newer_timeinfo.tm_yday - timeinfo.tm_yday == 1) && - (newer_timeinfo.tm_year == timeinfo.tm_year)) // day difference - || - (timeinfo.tm_year == 0 && newer_timeinfo.tm_year + 364 + is_leap_year) // day next year day difference - ); + auto newer_timeinfo = *std::localtime(&referenceTime); + + newer_timeinfo.tm_mday -= 1; + std::mktime(&newer_timeinfo); + + return timeinfo.tm_year == newer_timeinfo.tm_year && timeinfo.tm_mon == newer_timeinfo.tm_mon && + timeinfo.tm_mday == newer_timeinfo.tm_mday; } bool DateTime::isCurrentYear() const { auto timeinfo = *std::localtime(&time); - auto newer_timeinfo = *localtime(&local_time); + auto newer_timeinfo = *std::localtime(&referenceTime); return (newer_timeinfo.tm_year == timeinfo.tm_year); } diff --git a/module-utils/time/time/time_conversion.hpp b/module-utils/time/time/time_conversion.hpp index f6f9fd3c1025730835f296b03f97ac9fcd01466d..0a4a9714771a27ae9ffd4a98408eb0ab632b593a 100644 --- a/module-utils/time/time/time_conversion.hpp +++ b/module-utils/time/time/time_conversion.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -126,23 +126,20 @@ namespace utils /// takes timestamp and can show time in past class DateTime : public Timestamp { - time_t local_time = 0; - /// converter -> returns time in past: (val) and stores localtime in ref_time - void before_n_sec(time_t val); + time_t referenceTime = 0; protected: const TimeSettingsInterface &timeSettings; public: - /// shows time in past + /// shows time in past in relation to reference value /// - /// @val - timestamp in seconds + /// @val - timestamp to show + /// @reference - reference timestamp /// @timeSettings - time settings interface - explicit DateTime(const TimeSettingsInterface &timeSettings, time_t val) - : Timestamp(std::time(nullptr)), timeSettings(timeSettings) - { - before_n_sec(val); - } + DateTime(const TimeSettingsInterface &timeSettings, time_t val, time_t reference = std::time(nullptr)) + : Timestamp(val), referenceTime(reference), timeSettings(timeSettings) + {} friend std::ostream &operator<<(std::ostream &os, DateTime t) {