filevercmp.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*
  2. lib/strutil - tests for lib/strutil/fileverscmp function.
  3. Copyright (C) 2019-2024
  4. Free Software Foundation, Inc.
  5. Written by:
  6. Andrew Borodin <aborodin@vmail.ru>, 2019
  7. This file is part of the Midnight Commander.
  8. The Midnight Commander is free software: you can redistribute it
  9. and/or modify it under the terms of the GNU General Public License as
  10. published by the Free Software Foundation, either version 3 of the License,
  11. or (at your option) any later version.
  12. The Midnight Commander is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #define TEST_SUITE_NAME "/lib/strutil"
  20. #include "tests/mctest.h"
  21. #include "lib/strutil.h"
  22. #include "lib/util.h" /* _GL_CMP() */
  23. /* --------------------------------------------------------------------------------------------- */
  24. /* @Before */
  25. static void
  26. setup (void)
  27. {
  28. }
  29. /* --------------------------------------------------------------------------------------------- */
  30. /* @After */
  31. static void
  32. teardown (void)
  33. {
  34. }
  35. /* --------------------------------------------------------------------------------------------- */
  36. static int
  37. sign (int n)
  38. {
  39. return _GL_CMP (n, 0);
  40. }
  41. /* --------------------------------------------------------------------------------------------- */
  42. /*
  43. * Return filevercmp (a, a), checking that a similar result is gotten after replacing all '\1's
  44. * with '\0's and calling filenvercmp with the embedded '\0's.
  45. */
  46. static int
  47. test_filevercmp (char const *a, char const *b)
  48. {
  49. int result;
  50. char buffer[BUF_1K];
  51. size_t alen, blen;
  52. size_t i;
  53. int nresult;
  54. result = filevercmp (a, b);
  55. alen = strlen (a);
  56. blen = strlen (b);
  57. ck_assert_int_le (alen + blen, sizeof (buffer));
  58. memcpy (buffer, a, alen);
  59. memcpy (buffer + alen, b, blen);
  60. for (i = 0; i < alen + blen; i++)
  61. if (buffer[i] == '\1')
  62. buffer[i] = '\0';
  63. nresult = filenvercmp (buffer, alen, buffer + alen, blen);
  64. ck_assert_int_eq (sign (nresult), sign (result));
  65. return result;
  66. }
  67. /* --------------------------------------------------------------------------------------------- */
  68. /* @DataSource("filevercmp_test_ds1") */
  69. /* Testcases are taken from Gnulib */
  70. /* *INDENT-OFF* */
  71. static const struct filevercmp_test_struct
  72. {
  73. const char *s1;
  74. const char *s2;
  75. int expected_result;
  76. } filevercmp_test_ds1[] =
  77. {
  78. { "", "", 0 },
  79. { "a", "a", 0 },
  80. { "a", "b", -1 },
  81. { "b", "a", 1 },
  82. { "00", "01", -1 },
  83. { "01", "010", -1 },
  84. { "9", "10", -1 },
  85. { "0a", "0", 1 }
  86. };
  87. /* *INDENT-ON* */
  88. /* @Test(dataSource = "filevercmp_test_ds1") */
  89. /* *INDENT-OFF* */
  90. START_TEST (filevercmp_test1)
  91. /* *INDENT-ON* */
  92. {
  93. /* given */
  94. int actual_result;
  95. const struct filevercmp_test_struct *data = &filevercmp_test_ds1[_i];
  96. /* when */
  97. actual_result = filevercmp (data->s1, data->s2);
  98. /* then */
  99. ck_assert_int_eq (sign (actual_result), sign (data->expected_result));
  100. }
  101. /* *INDENT-OFF* */
  102. END_TEST
  103. /* *INDENT-ON* */
  104. /* --------------------------------------------------------------------------------------------- */
  105. /* @DataSource("filevercmp_test_ds2") */
  106. /* Testcases are taken from Gnulib */
  107. static const char *filevercmp_test_ds2[] = {
  108. "",
  109. ".",
  110. "..",
  111. ".0",
  112. ".9",
  113. ".A",
  114. ".Z",
  115. ".a~",
  116. ".a",
  117. ".b~",
  118. ".b",
  119. ".z",
  120. ".zz~",
  121. ".zz",
  122. ".zz.~1~",
  123. ".zz.0",
  124. ".\1",
  125. ".\1.txt",
  126. ".\1x",
  127. ".\1x\1",
  128. ".\1.0",
  129. "0",
  130. "9",
  131. "A",
  132. "Z",
  133. "a~",
  134. "a",
  135. "a.b~",
  136. "a.b",
  137. "a.bc~",
  138. "a.bc",
  139. "a+",
  140. "a.",
  141. "a..a",
  142. "a.+",
  143. "b~",
  144. "b",
  145. "gcc-c++-10.fc9.tar.gz",
  146. "gcc-c++-10.fc9.tar.gz.~1~",
  147. "gcc-c++-10.fc9.tar.gz.~2~",
  148. "gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2",
  149. "gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2.~1~",
  150. "glibc-2-0.1.beta1.fc10.rpm",
  151. "glibc-common-5-0.2.beta2.fc9.ebuild",
  152. "glibc-common-5-0.2b.deb",
  153. "glibc-common-11b.ebuild",
  154. "glibc-common-11-0.6rc2.ebuild",
  155. "libstdc++-0.5.8.11-0.7rc2.fc10.tar.gz",
  156. "libstdc++-4a.fc8.tar.gz",
  157. "libstdc++-4.10.4.20040204svn.rpm",
  158. "libstdc++-devel-3.fc8.ebuild",
  159. "libstdc++-devel-3a.fc9.tar.gz",
  160. "libstdc++-devel-8.fc8.deb",
  161. "libstdc++-devel-8.6.2-0.4b.fc8",
  162. "nss_ldap-1-0.2b.fc9.tar.bz2",
  163. "nss_ldap-1-0.6rc2.fc8.tar.gz",
  164. "nss_ldap-1.0-0.1a.tar.gz",
  165. "nss_ldap-10beta1.fc8.tar.gz",
  166. "nss_ldap-10.11.8.6.20040204cvs.fc10.ebuild",
  167. "z",
  168. "zz~",
  169. "zz",
  170. "zz.~1~",
  171. "zz.0",
  172. "zz.0.txt",
  173. "\1",
  174. "\1.txt",
  175. "\1x",
  176. "\1x\1",
  177. "\1.0",
  178. "#\1.b#",
  179. "#.b#"
  180. };
  181. static const size_t filevercmp_test_ds2_len = G_N_ELEMENTS (filevercmp_test_ds2);
  182. /* @Test(dataSource = "filevercmp_test_ds2") */
  183. /* *INDENT-OFF* */
  184. START_TEST (filevercmp_test2)
  185. /* *INDENT-ON* */
  186. {
  187. const char *i = filevercmp_test_ds2[_i];
  188. size_t _j;
  189. for (_j = 0; _j < filevercmp_test_ds2_len; _j++)
  190. {
  191. const char *j = filevercmp_test_ds2[_j];
  192. int result;
  193. result = test_filevercmp (i, j);
  194. if (result < 0)
  195. ck_assert_int_lt ((size_t) _i, _j);
  196. else if (result > 0)
  197. ck_assert_int_gt ((size_t) _i, _j);
  198. else
  199. ck_assert_int_eq ((size_t) _i, _j);
  200. }
  201. }
  202. /* *INDENT-OFF* */
  203. END_TEST
  204. /* *INDENT-ON* */
  205. /* @DataSource("filevercmp_test_ds3") */
  206. /* Ticket #3959 */
  207. static const char *filevercmp_test_ds3[] = {
  208. "application-1.10.tar.gz",
  209. "application-1.10.1.tar.gz"
  210. };
  211. static const size_t filevercmp_test_ds3_len = G_N_ELEMENTS (filevercmp_test_ds3);
  212. /* @Test(dataSource = "filevercmp_test_ds3") */
  213. /* *INDENT-OFF* */
  214. START_TEST (filevercmp_test3)
  215. /* *INDENT-ON* */
  216. {
  217. const char *i = filevercmp_test_ds3[_i];
  218. size_t _j;
  219. for (_j = 0; _j < filevercmp_test_ds3_len; _j++)
  220. {
  221. const char *j = filevercmp_test_ds3[_j];
  222. int result;
  223. result = filevercmp (i, j);
  224. if (result < 0)
  225. ck_assert_int_lt ((size_t) _i, _j);
  226. else if (result > 0)
  227. ck_assert_int_gt ((size_t) _i, _j);
  228. else
  229. ck_assert_int_eq ((size_t) _i, _j);
  230. }
  231. }
  232. /* *INDENT-OFF* */
  233. END_TEST
  234. /* *INDENT-ON* */
  235. /* @DataSource("filevercmp_test_ds4") */
  236. /* Ticket #3905 */
  237. static const char *filevercmp_test_ds4[] = {
  238. "firefox-58.0.1+build1.tar.gz",
  239. "firefox-59.0~b14+build1.tar.gz",
  240. "firefox-59.0.1+build1.tar.gz"
  241. };
  242. static const size_t filevercmp_test_ds4_len = G_N_ELEMENTS (filevercmp_test_ds4);
  243. /* @Test(dataSource = "filevercmp_test_ds4") */
  244. /* *INDENT-OFF* */
  245. START_TEST (filevercmp_test4)
  246. /* *INDENT-ON* */
  247. {
  248. const char *i = filevercmp_test_ds4[_i];
  249. size_t _j;
  250. for (_j = 0; _j < filevercmp_test_ds4_len; _j++)
  251. {
  252. const char *j = filevercmp_test_ds4[_j];
  253. int result;
  254. result = filevercmp (i, j);
  255. if (result < 0)
  256. ck_assert_int_lt ((size_t) _i, _j);
  257. else if (result > 0)
  258. ck_assert_int_gt ((size_t) _i, _j);
  259. else
  260. ck_assert_int_eq ((size_t) _i, _j);
  261. }
  262. }
  263. /* *INDENT-OFF* */
  264. END_TEST
  265. /* *INDENT-ON* */
  266. /* @DataSource("filevercmp_test_ds5") */
  267. /* Testcases are taken from Gnulib */
  268. static const char *filevercmp_test_ds5[] = {
  269. "a",
  270. "a0",
  271. "a0000",
  272. NULL,
  273. "a\1c-27.txt",
  274. "a\1c-027.txt",
  275. "a\1c-00000000000000000000000000000000000000000000000000000027.txt",
  276. NULL,
  277. ".a\1c-27.txt",
  278. ".a\1c-027.txt",
  279. ".a\1c-00000000000000000000000000000000000000000000000000000027.txt",
  280. NULL,
  281. "a\1c-",
  282. "a\1c-0",
  283. "a\1c-00",
  284. NULL,
  285. ".a\1c-",
  286. ".a\1c-0",
  287. ".a\1c-00",
  288. NULL,
  289. "a\1c-0.txt",
  290. "a\1c-00.txt",
  291. NULL,
  292. ".a\1c-1\1.txt",
  293. ".a\1c-001\1.txt",
  294. NULL
  295. };
  296. static const size_t filevercmp_test_ds5_len = G_N_ELEMENTS (filevercmp_test_ds5);
  297. /* @Test(dataSource = "filevercmp_test_ds5") */
  298. /* *INDENT-OFF* */
  299. START_TEST (filevercmp_test5)
  300. /* *INDENT-ON* */
  301. {
  302. size_t ii;
  303. for (ii = 0; ii < filevercmp_test_ds5_len; ii++)
  304. for (; filevercmp_test_ds5[ii] != NULL; ii++)
  305. {
  306. const char *i = filevercmp_test_ds5[ii];
  307. size_t jj;
  308. for (jj = ii; filevercmp_test_ds5[jj] != NULL; jj++)
  309. {
  310. const char *j = filevercmp_test_ds5[jj];
  311. ck_assert_int_eq (test_filevercmp (i, j), 0);
  312. ck_assert_int_eq (test_filevercmp (j, i), 0);
  313. }
  314. }
  315. }
  316. /* *INDENT-OFF* */
  317. END_TEST
  318. /* *INDENT-ON* */
  319. /* --------------------------------------------------------------------------------------------- */
  320. int
  321. main (void)
  322. {
  323. TCase *tc_core;
  324. tc_core = tcase_create ("Core");
  325. tcase_add_checked_fixture (tc_core, setup, teardown);
  326. /* Add new tests here: *************** */
  327. mctest_add_parameterized_test (tc_core, filevercmp_test1, filevercmp_test_ds1);
  328. tcase_add_loop_test (tc_core, filevercmp_test2, 0, filevercmp_test_ds2_len);
  329. tcase_add_loop_test (tc_core, filevercmp_test3, 0, filevercmp_test_ds3_len);
  330. tcase_add_loop_test (tc_core, filevercmp_test4, 0, filevercmp_test_ds4_len);
  331. tcase_add_test (tc_core, filevercmp_test5);
  332. /* *********************************** */
  333. return mctest_run_all (tc_core);
  334. }
  335. /* --------------------------------------------------------------------------------------------- */