LCOV - code coverage report
Current view: top level - tests - catch_timestamp.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.6 % 44 39
Test Date: 2026-09-06 14:21:58 Functions: 100.0 % 2 2
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2026  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/snapdev
       4              : // contact@m2osw.com
       5              : //
       6              : // This program is free software: you can redistribute it and/or modify
       7              : // it under the terms of the GNU General Public License as published by
       8              : // the Free Software Foundation, either version 3 of the License, or
       9              : // (at your option) any later version.
      10              : //
      11              : // This program is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : //
      16              : // You should have received a copy of the GNU General Public License
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : 
      19              : /** \file
      20              :  * \brief Verify that the timestamp functions work as expected.
      21              :  *
      22              :  * This file implements tests for the Unix timestamp functions which
      23              :  * convert separate integers into a time_t value at compile.
      24              :  */
      25              : 
      26              : // self
      27              : //
      28              : #include    <snapdev/timestamp.h>
      29              : 
      30              : #include    <snapdev/math.h>
      31              : 
      32              : #include    "catch_main.h"
      33              : 
      34              : 
      35              : // snapdev
      36              : //
      37              : #include    <snapdev/not_reached.h>
      38              : 
      39              : 
      40              : // C++
      41              : //
      42              : #include    <algorithm>
      43              : #include    <iomanip>
      44              : #include    <ranges>
      45              : 
      46              : 
      47              : // last include
      48              : //
      49              : #include    <snapdev/poison.h>
      50              : 
      51              : 
      52              : 
      53              : namespace
      54              : {
      55              : 
      56              : 
      57              : 
      58              : int const g_leap_years[] = {
      59              :     1584, 1588, 1592, 1596, 1600, 1604, 1608, 1612,
      60              :     1616, 1620, 1624, 1628, 1632, 1636, 1640, 1644,
      61              :     1648, 1652, 1656, 1660, 1664, 1668, 1672, 1676,
      62              :     1680, 1684, 1688, 1692, 1696, 1704, 1708, 1712,
      63              :     1716, 1720, 1724, 1728, 1732, 1736, 1740, 1744,
      64              :     1748, 1752, 1756, 1760, 1764, 1768, 1772, 1776,
      65              :     1780, 1784, 1788, 1792, 1796, 1804, 1808, 1812,
      66              :     1816, 1820, 1824, 1828, 1832, 1836, 1840, 1844,
      67              :     1848, 1852, 1856, 1860, 1864, 1868, 1872, 1876,
      68              :     1880, 1884, 1888, 1892, 1896, 1904, 1908, 1912,
      69              :     1916, 1920, 1924, 1928, 1932, 1936, 1940, 1944,
      70              :     1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976,
      71              :     1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008,
      72              :     2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040,
      73              :     2044, 2048, 2052, 2056, 2060, 2064, 2068, 2072,
      74              :     2076, 2080, 2084, 2088, 2092, 2096, 2104, 2108,
      75              :     2112, 2116, 2120, 2124, 2128, 2132, 2136, 2140,
      76              :     2144, 2148, 2152, 2156, 2160, 2164, 2168, 2172,
      77              :     2176, 2180, 2184, 2188, 2192, 2196, 2204, 2208,
      78              :     2212, 2216, 2220, 2224, 2228, 2232, 2236, 2240,
      79              :     2244, 2248, 2252, 2256, 2260, 2264, 2268, 2272,
      80              :     2276, 2280, 2284, 2288, 2292, 2296, 2304, 2308,
      81              :     2312, 2316, 2320, 2324, 2328, 2332, 2336, 2340,
      82              :     2344, 2348, 2352, 2356, 2360, 2364, 2368, 2372,
      83              :     2376, 2380, 2384, 2388, 2392, 2396, 2400,
      84              : };
      85              : 
      86              : 
      87              : 
      88              : }
      89              : // no name namespace
      90              : 
      91              : 
      92              : 
      93            3 : CATCH_TEST_CASE("timestamp", "[time][math]")
      94              : {
      95            3 :     CATCH_START_SECTION("timestamp: verify that the math is working as expected for February")
      96              :     {
      97              :         // the Gregorian leap years were introduced in Sept. 1752
      98              :         // where we started to see exceptions for the years dividable
      99              :         // by 100 (not a leap) or 400 (except those)
     100              :         //
     101          824 :         for(int year(1581); year <= 2403; ++year)
     102              :         {
     103          823 :             int const days(snapdev::unix_timestamp_february_days(year));
     104          823 :             if(days != (std::ranges::contains(g_leap_years, year) ? 29 : 28))
     105              :             {
     106            0 :                 std::cerr << "error: for year " << year << ", expected "
     107            0 :                     << (std::ranges::contains(g_leap_years, days) ? 29 : 28)
     108            0 :                     << ", but got " << days << " instead." << std::endl;
     109              :             }
     110          823 :             CATCH_REQUIRE(days == (std::ranges::contains(g_leap_years, year) ? 29 : 28));
     111              :         }
     112              :     }
     113            3 :     CATCH_END_SECTION()
     114              : 
     115            3 :     CATCH_START_SECTION("timestamp: check number of days in a month")
     116              :     {
     117              :         // random year
     118              :         //
     119            1 :         int const year(snapdev::random(1581, 2403));
     120              : 
     121           13 :         for(int month(1); month <= 12; ++month)
     122              :         {
     123           12 :             int const days(snapdev::unix_timestamp_month_days(year, month));
     124              : 
     125           12 :             switch(month)
     126              :             {
     127            7 :             case 1:
     128              :             case 3:
     129              :             case 5:
     130              :             case 7:
     131              :             case 8:
     132              :             case 10:
     133              :             case 12:
     134            7 :                 CATCH_REQUIRE(days == 31);
     135            7 :                 break;
     136              : 
     137            4 :             case 4:
     138              :             case 6:
     139              :             case 9:
     140              :             case 11:
     141            4 :                 CATCH_REQUIRE(days == 30);
     142            4 :                 break;
     143              : 
     144            1 :             case 2:
     145              :                 {
     146            1 :                     int const expected_days(std::ranges::contains(g_leap_years, year) ? 29 : 28);
     147              : 
     148            1 :                     CATCH_REQUIRE(expected_days == days);
     149              :                 }
     150            1 :                 break;
     151              : 
     152            0 :             default:
     153            0 :                 CATCH_FAIL("invalid month?!");
     154              :                 break;
     155              : 
     156              :             }
     157              :         }
     158              :     }
     159            3 :     CATCH_END_SECTION()
     160              : 
     161            3 :     CATCH_START_SECTION("timestamp: check some random time_t")
     162              :     {
     163         1001 :         for(int count(0); count < 1'000; ++count)
     164              :         {
     165         1000 :             time_t const org(snapdev::random(-1'000'000LL, 2'000'000'000LL));
     166              : 
     167         1000 :             struct tm t;
     168         1000 :             gmtime_r(&org, &t);
     169              : 
     170         1000 :             time_t const timestamp(snapdev::unix_timestamp(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec));
     171              : 
     172         1000 :             CATCH_REQUIRE(org == timestamp);
     173              :         }
     174              :     }
     175            3 :     CATCH_END_SECTION()
     176            3 : }
     177              : 
     178              : 
     179            1 : CATCH_TEST_CASE("timestamp_error", "[time][error]")
     180              : {
     181            1 :     CATCH_START_SECTION("timestamp_error: verify that the month must be between 1 and 12 calling unix_timestamp_month_days()")
     182              :     {
     183           38 :         for(int month(-12); month <= 24; ++month)
     184              :         {
     185           37 :             if(month < 1 || month > 12)
     186              :             {
     187           25 :                 CATCH_REQUIRE_THROWS_MATCHES(
     188              :                           snapdev::unix_timestamp_month_days(2000, month)
     189              :                         , std::logic_error
     190              :                         , Catch::Matchers::ExceptionMessage(
     191              :                                   "snapdev::unix_timestamp_month_days() called with "
     192              :                                 + std::to_string(month)
     193              :                                 + " which is not a valid month number."));
     194              :             }
     195              :         }
     196              :     }
     197            1 :     CATCH_END_SECTION()
     198            1 : }
     199              : 
     200              : 
     201              : 
     202              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions