(root)/
libredwg-0.13/
test/
unit-testing/
common_test.c
       1  #define COMMON_TEST_C
       2  #include <stdlib.h>
       3  #include <stddef.h>
       4  #include <locale.h>
       5  #include "tests_common.h"
       6  #include "../../src/codepages.h"
       7  #include "../../src/common.c"
       8  #include "../../programs/escape.c"
       9  
      10  static void
      11  common_memmem_tests (void)
      12  {
      13    static char *hay = (char *)"0123456789";
      14    char *needle = (char *)"01";
      15    void *p;
      16  
      17    // positive
      18    if (my_memmem (hay, 10, needle, 2) != hay)
      19      fail ("memmem %s not at 0", needle);
      20    needle = (char *)"1234567890";
      21    if (my_memmem (hay, 10, needle, 9) != &hay[1])
      22      fail ("memmem %s not at 0", needle);
      23    needle = (char *)"789";
      24    if ((p = my_memmem (hay, 10, needle, 3)) != &hay[7])
      25      fail ("memmem %s not at 7 but at %p of %p", needle, p, hay);
      26  
      27    // not found
      28    needle = (char *)"012344567890";
      29    if (my_memmem (hay, 10, needle, 11))
      30      fail ("memmem %s found", needle);
      31    needle = (char *)"1234456780";
      32    if (my_memmem (hay, 10, needle, 9))
      33      fail ("memmem %s found", needle);
      34    needle = (char *)"7890";
      35    if (my_memmem (hay, 10, needle, 4))
      36      fail ("memmem %s found", needle);
      37    else
      38      ok ("memmem");
      39  }
      40  
      41  // test versions:
      42  // strict ordering of dwg_version
      43  // matching enum <=> release type
      44  static void
      45  common_versions_tests (void)
      46  {
      47    uint8_t prev_version = 0;
      48    assert (R_AFTER + 1 == ARRAY_SIZE (dwg_versions));
      49    assert (strEQc (dwg_versions[R_2018].type, "r2018"));
      50    assert (strEQc (dwg_versions[R_2007].type, "r2007"));
      51    assert (strEQc (dwg_versions[R_2004].type, "r2004"));
      52    assert (strEQc (dwg_versions[R_2000].type, "r2000"));
      53    assert (strEQc (dwg_versions[R_13].type, "r13"));
      54    assert (strEQc (dwg_versions[R_11].type, "r11"));
      55    assert (strEQc (dwg_versions[R_2_0].type, "r2.0"));
      56    assert (strEQc (dwg_versions[R_AFTER].type, "r>2022"));
      57    assert (!dwg_versions[R_AFTER].hdr);
      58    if (!failed)
      59      ok ("dwg_versions messup");
      60  
      61    for (int i = 0; i < R_AFTER; i++)
      62      {
      63        const uint8_t dwg_version = dwg_versions[i].dwg_version;
      64        // strict ordering of dwg_versions
      65        if (dwg_version < prev_version)
      66          fail ("dwg_versions[%d].dwg_version %x >= %x", i, dwg_version,
      67                prev_version);
      68        prev_version = dwg_version;
      69      }
      70    if (!failed)
      71      ok ("dwg_versions ordered");
      72  
      73    if (!dwg_version_struct (R_AFTER))
      74      ok ("!dwg_version_struct (R_AFTER)");
      75    else
      76      fail ("!dwg_version_struct (R_AFTER)");
      77  
      78    assert (strEQc (dwg_version_codes (R_2018), "AC1032"));
      79    assert (strEQc (dwg_version_codes (R_2000), "AC1015"));
      80    assert (dwg_version_as ("r2000") == R_2000);
      81    assert (dwg_version_as ("r2018") == R_2018);
      82  
      83    assert (dwg_version_hdr_type ("AC1032") == R_2018);
      84    assert (dwg_version_hdr_type ("AC1015") == R_2000);
      85    assert (dwg_version_hdr_type2 ("AC1500", 0x16) == R_2000b);
      86    assert (dwg_version_hdr_type2 ("AC1016", 0x17) == R_2000i);
      87    assert (dwg_version_hdr_type2 ("AC1017", 0x17) == R_2002);
      88    assert (dwg_version_hdr_type2 ("AC1018", 0x18) == R_2004c);
      89    assert (dwg_version_hdr_type2 ("AC402b", 0) == R_2004b);
      90    assert (dwg_version_hdr_type2 ("AC1018", 0x19) == R_2004);
      91    assert (dwg_version_hdr_type2 ("AC1019", 0x18) == R_INVALID);
      92    assert (dwg_version_hdr_type2 ("AC1021", 0x1a) == R_2007b);
      93    assert (dwg_version_hdr_type2 ("AC1021", 0x1b) == R_2007);
      94    assert (dwg_version_hdr_type ("AC1018") == R_2004);
      95  
      96    ok ("versions");
      97  }
      98  
      99  // basic sanity: no illegal struct tm fields
     100  static void
     101  common_cvt_TIMEBLL_tests (void)
     102  {
     103    const unsigned long maxtries = 10000000LU;
     104    static struct tm tm = { 0 };
     105    static BITCODE_TIMEBLL date = { 0U, 0U, 0.0 };
     106    int g_failed = failed;
     107    failed = 0;
     108    setlocale (LC_TIME, "en_UK.utf8");
     109  
     110    date.days = 2456795;
     111    date.ms = 18527023;
     112    cvt_TIMEBLL (&tm, date);
     113    if (tm.tm_year + 1900 != 2014)
     114      fail ("tm.tm_year %d != 2014 with 2456795.18527023", tm.tm_year + 1900);
     115  
     116    // check over- and underflows of each field
     117    for (unsigned long i = 0; i < maxtries; i++)
     118      {
     119        time_t time;
     120        struct tm tm1;
     121        char buf[30];
     122        char buf1[30];
     123  
     124        date.days = rand ();
     125        date.ms = rand ();
     126        if (sizeof (long) > sizeof (int))
     127          {
     128            date.days |= (uint64_t)rand () << 32;
     129            date.ms |= (uint64_t)rand () << 32;
     130          }
     131        // 2020 is the latest possible year for these tests
     132        if (date.days > 2459191)
     133          date.days %= 2459191;
     134        // 1970 is the oldest possible year for gmtime cross-checks
     135        if (date.days < 25567)
     136          date.days += 25567;
     137        if (date.ms > 24 * 60 * 60 * 1000)
     138          date.ms %= 24 * 60 * 60 * 1000;
     139  
     140        cvt_TIMEBLL (&tm, date);
     141  
     142        if (tm.tm_mon < 0 || tm.tm_mon > 11)
     143          fail ("tm.tm_mon %d [0-11] with %u.%u", tm.tm_mon, date.days, date.ms);
     144        if (tm.tm_mday < 1 || tm.tm_mday > 31)
     145          fail ("tm.tm_mday %d [1-31] with %u.%u", tm.tm_mday, date.days,
     146                date.ms);
     147        if (tm.tm_hour < 0 || tm.tm_hour > 23)
     148          fail ("tm.tm_hour %d [0-23] with %u.%u", tm.tm_hour, date.days,
     149                date.ms);
     150        if (tm.tm_min < 0 || tm.tm_min > 60)
     151          fail ("tm.tm_min %d [0-60] with %u.%u", tm.tm_min, date.days, date.ms);
     152        if (tm.tm_sec < 0 || tm.tm_sec > 60)
     153          fail ("tm.tm_sec %d [0-60] with %u.%u", tm.tm_sec, date.days, date.ms);
     154  
     155  #if 0
     156      // and compare against UTC time
     157      time = 3600 * (date.days - 25567); // 1970 - 1900 in days => seconds since 1970
     158      time += (date.ms / 1000);
     159      tm1 = *gmtime(&time);
     160      strftime (buf, sizeof (buf), "%F %X", &tm);
     161      strftime (buf1, sizeof (buf1), "%F %X", &tm1);
     162  
     163      if (tm.tm_year != tm1.tm_year)
     164        fail ("tm.tm_year %d != %d with %u.%u\n    %s vs %s", tm.tm_year + 1900,
     165              tm1.tm_year + 1900, date.days, date.ms, buf, buf1);
     166      if (tm.tm_mon != tm1.tm_mon)
     167        fail ("tm.tm_mon %d != %d", tm.tm_mon, tm1.tm_mon);
     168      if (tm.tm_mday != tm1.tm_mday)
     169        fail ("tm.tm_mday %d != %d", tm.tm_mday, tm1.tm_mday);
     170      if (tm.tm_hour != tm1.tm_hour)
     171        fail ("tm.tm_hour %d != %d", tm.tm_hour, tm1.tm_hour);
     172      if (tm.tm_min != tm1.tm_min)
     173        fail ("tm.tm_mon %d != %d", tm.tm_mon, tm1.tm_mon);
     174      if (tm.tm_sec != tm1.tm_sec)
     175        fail ("tm.tm_sec %d != %d", tm.tm_sec, tm1.tm_sec);
     176  #endif
     177  
     178        if (failed)
     179          break;
     180      }
     181  
     182    failed += g_failed;
     183    if (g_failed == failed)
     184      ok ("cvt_TIMEBLL");
     185  }
     186  
     187  static void
     188  dwg_find_color_index_tests (void)
     189  {
     190    BITCODE_BL rgb;
     191    BITCODE_BS ret;
     192  
     193  #define test_rgb_case(_rgb, _ret)                                             \
     194    rgb = _rgb;                                                                 \
     195    ret = dwg_find_color_index (rgb);                                           \
     196    if (ret == _ret)                                                            \
     197      ok ("dwg_find_color_index (0x%0x) -> %u", rgb, ret);                      \
     198    else                                                                        \
     199      fail ("dwg_find_color_index (0x%0x) -> %u != %u", rgb, ret, _ret);
     200  
     201    test_rgb_case (0xabff0000, 1);
     202    test_rgb_case (0xab00ff00, 3);
     203    test_rgb_case (0xab0000ff, 5);
     204    test_rgb_case (0xabffffff, 7);
     205    test_rgb_case (0xabbebebe, 254);
     206    test_rgb_case (0xab000007, 256);
     207  }
     208  
     209  static void
     210  escape_htmlescape_tests (void)
     211  {
     212    char *s = htmlescape ("'test'&{}", CP_ISO_8859_1); // forces a realloc
     213    if (strEQc (s, "&#39;test&#39;&amp;&#123;&#125;"))
     214      pass ();
     215    else
     216      fail ("htmlescape => %s", s);
     217    free (s);
     218  
     219    // to multi-byte
     220    s = htmlescape ("'%test'&{}", CP_CP864);
     221    if (strEQc (s, "&#39;&#x66A;test&#39;&amp;&#123;&#125;"))
     222      pass ();
     223    else
     224      fail ("htmlescape CP864 => %s", s);
     225    free (s);
     226  
     227    // from multi-byte: echo -n "시험" | iconv -f utf-8 -t cp949 | od -t x1
     228    // to: echo -n "시험" | iconv -f utf-8 -t ucs-2 | od -t x2
     229    s = htmlescape ("'\xbc\xc3\xc7\xe8", CP_CP949); // "시험"
     230    if (strEQc (s, "&#39;&#xC14C;&#xD5D8;"))
     231      pass ();
     232    else
     233      fail ("htmlescape CP949 => %s", s);
     234    free (s);
     235  }
     236  
     237  static void
     238  escape_htmlwescape_tests (void)
     239  {
     240    uint16_t tu[] = { 'T', 'e', 'i', 'g', 'h', 'a', 0x2122, 0 };
     241    char *s = htmlwescape (tu);
     242    if (strEQc (s, "Teigha&#x2122;"))
     243      pass ();
     244    else
     245      fail ("htmlwescape => %s", s);
     246    free (s);
     247  }
     248  
     249  int
     250  main (int argc, char const *argv[])
     251  {
     252    loglevel = is_make_silent () ? 0 : 2;
     253    common_memmem_tests ();
     254    common_versions_tests ();
     255    common_cvt_TIMEBLL_tests ();
     256    dwg_find_color_index_tests ();
     257    escape_htmlescape_tests ();
     258    escape_htmlwescape_tests ();
     259    return failed;
     260  }