LCOV - code coverage report
Current view: top level - src/ctlib/unittests - cs_convert_date.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 34 36 94.4 %
Date: 2025-12-03 08:48:55 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Test conversions to date and CS_DT_CONVFMT
       3             :  */
       4             : #include "common.h"
       5             : 
       6             : #include <freetds/replacements.h>
       7             : 
       8             : static CS_CONTEXT *ctx;
       9             : static bool failed = false;
      10             : static const char *test_name = NULL;
      11             : 
      12             : typedef struct
      13             : {
      14             :         CS_INT convfmt;
      15             :         const char *convfmt_name;
      16             :         const char *datetime;
      17             :         const char *date;
      18             :         const char *time;
      19             : } TEST;
      20             : 
      21             : #define ONE(convfmt, datetime, date, time) \
      22             :         { convfmt, #convfmt, datetime, date, time }
      23             : static const TEST tests[] = {
      24             :         ONE(CS_DATES_SHORT, "Sep  7 2025  4:32PM", "Sep  7 2025", " 4:32PM"),
      25             :         ONE(CS_DATES_MDY1, "09/07/25", "09/07/25", ""),
      26             :         ONE(CS_DATES_YMD1, "25.09.07", "25.09.07", ""),
      27             :         ONE(CS_DATES_DMY1, "07/09/25", "07/09/25", ""),
      28             :         ONE(CS_DATES_DMY2, "07.09.25", "07.09.25", ""),
      29             :         ONE(CS_DATES_DMY3, "07-09-25", "07-09-25", ""),
      30             :         ONE(CS_DATES_DMY4, "07 Sep 25", "07 Sep 25", ""),
      31             :         ONE(CS_DATES_MDY2, "Sep 07, 25", "Sep 07, 25", ""),
      32             :         ONE(CS_DATES_HMS, "16:32:53", "00:00:00", "16:32:53"),
      33             :         ONE(CS_DATES_LONG, "Sep  7 2025  4:32:53:490PM", "Sep  7 2025", " 4:32:53:490PM"),
      34             :         ONE(CS_DATES_MDY3, "09-07-25", "09-07-25", ""),
      35             :         ONE(CS_DATES_YMD2, "25/09/07", "25/09/07", ""),
      36             :         ONE(CS_DATES_YMD3, "250907", "250907", ""),
      37             :         ONE(CS_DATES_YDM1, "25/07/09", "25/07/09", ""),
      38             :         ONE(CS_DATES_MYD1, "09/25/07", "09/25/07", ""),
      39             :         ONE(CS_DATES_DYM1, "07/25/09", "07/25/09", ""),
      40             :         ONE(CS_DATES_MDYHMS, "Sep  7 2025 16:32:53", "Sep  7 2025 00:00:00", "Jan  1 1900 16:32:53"),
      41             :         ONE(CS_DATES_HMA, " 4:32PM", "12:00AM", " 4:32PM"),
      42             :         ONE(CS_DATES_HM, "16:32", "00:00", "16:32"),
      43             :         ONE(CS_DATES_HMSZA, " 4:32:53:490PM", "12:00:00:000AM", " 4:32:53:490PM"),
      44             :         ONE(CS_DATES_HMSZ, "16:32:53:490", "00:00:00:000", "16:32:53:490"),
      45             :         ONE(CS_DATES_YMDHMS, "25/09/07 16:32:53", "25/09/07 00:00:00", "00/01/01 16:32:53"),
      46             :         ONE(CS_DATES_YMDHMA, "25/09/07  4:32PM", "25/09/07 12:00AM", "00/01/01  4:32PM"),
      47             :         ONE(CS_DATES_YMDTHMS, "2025-09-07T16:32:53", "2025-09-07T00:00:00", "1900-01-01T16:32:53"),
      48             :         ONE(CS_DATES_HMSUSA, " 4:32:53.490000PM", "12:00:00.000000AM", " 4:32:53.490000PM"),
      49             :         ONE(CS_DATES_HMSUS, "16:32:53.490000", "00:00:00.000000", "16:32:53.490000"),
      50             :         ONE(CS_DATES_LONGUSA, "Sep  7 25  4:32:53.490000PM", "Sep  7 25 12:00:00.000000AM", "Jan  1 00  4:32:53.490000PM"),
      51             :         ONE(CS_DATES_LONGUS, "Sep  7 25 16:32:53.490000", "Sep  7 25 00:00:00.000000", "Jan  1 00 16:32:53.490000"),
      52             :         ONE(CS_DATES_YMDHMSUS, "25-09-07 16:32:53.490000", "25-09-07 00:00:00.000000", "00-01-01 16:32:53.490000"),
      53             :         ONE(CS_DATES_SHORT_ALT, "Sep  7 2025  4:32PM", "Sep  7 2025 12:00AM", "Jan  1 1900  4:32PM"),
      54             :         ONE(CS_DATES_MDY1_YYYY, "09/07/2025", "09/07/2025", ""),
      55             :         ONE(CS_DATES_YMD1_YYYY, "2025.09.07", "2025.09.07", ""),
      56             :         ONE(CS_DATES_DMY1_YYYY, "07/09/2025", "07/09/2025", ""),
      57             :         ONE(CS_DATES_DMY2_YYYY, "07.09.2025", "07.09.2025", ""),
      58             :         ONE(CS_DATES_DMY3_YYYY, "07-09-2025", "07-09-2025", ""),
      59             :         ONE(CS_DATES_DMY4_YYYY, "07 Sep 2025", "07 Sep 2025", ""),
      60             :         ONE(CS_DATES_MDY2_YYYY, "Sep 07, 2025", "Sep 07, 2025", ""),
      61             :         ONE(CS_DATES_HMS_ALT, "16:32:53", "00:00:00", "16:32:53"),
      62             :         ONE(CS_DATES_LONG_ALT, "Sep  7 2025  4:32:53:490PM", "Sep  7 2025 12:00:00:000AM", "Jan  1 1900  4:32:53:490PM"),
      63             :         ONE(CS_DATES_MDY3_YYYY, "09-07-2025", "09-07-2025", ""),
      64             :         ONE(CS_DATES_YMD2_YYYY, "2025/09/07", "2025/09/07", ""),
      65             :         ONE(CS_DATES_YMD3_YYYY, "20250907", "20250907", ""),
      66             :         ONE(CS_DATES_YDM1_YYYY, "2025/07/09", "2025/07/09", ""),
      67             :         ONE(CS_DATES_MYD1_YYYY, "09/2025/07", "09/2025/07", ""),
      68             :         ONE(CS_DATES_DYM1_YYYY, "07/2025/09", "07/2025/09", ""),
      69             :         ONE(CS_DATES_MDYHMS_ALT, "Sep  7 2025 16:32:53", "Sep  7 2025 00:00:00", "Jan  1 1900 16:32:53"),
      70             :         ONE(CS_DATES_HMA_ALT, " 4:32PM", "12:00AM", " 4:32PM"),
      71             :         ONE(CS_DATES_HM_ALT, "16:32", "00:00", "16:32"),
      72             :         ONE(CS_DATES_YMDHMS_YYYY, "2025/09/07 16:32:53", "2025/09/07 00:00:00", "1900/01/01 16:32:53"),
      73             :         ONE(CS_DATES_YMDHMA_YYYY, "2025/09/07  4:32PM", "2025/09/07 12:00AM", "1900/01/01  4:32PM"),
      74             :         ONE(CS_DATES_HMSUSA_YYYY, " 4:32:53.490000PM", "12:00:00.000000AM", " 4:32:53.490000PM"),
      75             :         ONE(CS_DATES_HMSUS_YYYY, "16:32:53.490000", "00:00:00.000000", "16:32:53.490000"),
      76             :         ONE(CS_DATES_LONGUSA_YYYY, "Sep  7 2025  4:32:53.490000PM", "Sep  7 2025 12:00:00.000000AM",
      77             :             "Jan  1 1900  4:32:53.490000PM"),
      78             :         ONE(CS_DATES_LONGUS_YYYY, "Sep  7 2025 16:32:53.490000", "Sep  7 2025 00:00:00.000000", "Jan  1 1900 16:32:53.490000"),
      79             :         ONE(CS_DATES_YMDHMSUS_YYYY, "2025-09-07 16:32:53.490000", "2025-09-07 00:00:00.000000", "1900-01-01 16:32:53.490000"),
      80             :         {0, NULL, NULL, NULL, NULL}
      81             : };
      82             : 
      83             : static void
      84        1650 : single_value(CS_INT type, void *input, size_t input_size, const char *expected)
      85             : {
      86             :         CS_DATAFMT destfmt, srcfmt;
      87             :         CS_INT reslen;
      88             :         char buffer[1024];
      89             : 
      90        1650 :         memset(&destfmt, 0, sizeof(destfmt));
      91             :         destfmt.datatype = CS_CHAR_TYPE;
      92        1650 :         destfmt.maxlength = sizeof(buffer);
      93             :         destfmt.format = CS_FMT_UNUSED;
      94             : 
      95        1650 :         memset(&srcfmt, 0, sizeof(srcfmt));
      96        1650 :         srcfmt.datatype = type;
      97        1650 :         srcfmt.maxlength = (CS_INT) input_size;
      98             : 
      99             :         /*
     100             :          * FIXME this fix some thing but if error cs_convert should return
     101             :          * CS_UNUSED; note that this is defined 5.. a valid result ...
     102             :          */
     103        1650 :         reslen = 0;
     104             : 
     105             :         /* do convert */
     106        1650 :         memset(buffer, 23, sizeof(buffer));
     107        1650 :         check_call(cs_convert, (ctx, &srcfmt, input, &destfmt, buffer, &reslen));
     108             : 
     109        1650 :         assert(reslen >= 0 && reslen < sizeof(buffer));
     110        1650 :         buffer[reslen] = 0;
     111             : 
     112        1650 :         if (strcmp(buffer, expected) != 0) {
     113           0 :                 fprintf(stderr, "Wrong result test %s type %d:\ngot %s\nexp %s\n", test_name, type, buffer, expected);
     114           0 :                 failed = true;
     115             :         }
     116        1650 : }
     117             : 
     118             : static void
     119         550 : single_test(const TEST *test)
     120             : {
     121             :         /* 2025-09-07 16:32:53.490000
     122             :          * This date was chosen for different reasons:
     123             :          * - all components are different;
     124             :          * - all components are not zero;
     125             :          * - month and day are different so we can distinguish the order;
     126             :          * - month and day are one digit so we can distinguish padding.
     127             :          */
     128         550 :         CS_DATETIME date = { 45905, ((16 * 60 + 32) * 60 + 53) * 300 + 147 };
     129             :         CS_INT i_value;
     130             : 
     131         550 :         test_name = test->convfmt_name;
     132             : 
     133         550 :         i_value = test->convfmt;
     134         550 :         check_call(cs_dt_info, (ctx, CS_SET, NULL, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     135             : 
     136         550 :         single_value(CS_DATETIME_TYPE, &date, sizeof(date), test->datetime);
     137         550 :         single_value(CS_DATE_TYPE, &date.dtdays, sizeof(date.dtdays), test->date);
     138         550 :         single_value(CS_TIME_TYPE, &date.dttime, sizeof(date.dttime), test->time);
     139         550 : }
     140             : 
     141          10 : TEST_MAIN()
     142             : {
     143          10 :         int verbose = 1;
     144             :         const TEST *test;
     145             : 
     146             :         /* Force default us_enlish */
     147          10 :         unsetenv("LC_ALL");
     148          10 :         setenv("LANG", "C", 1);
     149             : 
     150          10 :         printf("%s: Testing date conversions\n", __FILE__);
     151             : 
     152          10 :         check_call(cs_ctx_alloc, (CS_VERSION_100, &ctx));
     153             : 
     154         560 :         for (test = tests; test->convfmt_name != NULL; ++test)
     155         550 :                 single_test(test);
     156             : 
     157          10 :         check_call(cs_ctx_drop, (ctx));
     158             : 
     159          10 :         if (verbose && !failed)
     160          10 :                 printf("Test succeded\n");
     161             : 
     162          10 :         return failed ? 1 : 0;
     163             : }

Generated by: LCOV version 1.13