Standardize all protocol header guard macros.
[pidgin-git.git] / libpurple / tests / test_util.c
blob2450c31003d04e6a8300f1ffd5c04e9f264afc91
1 /*
2 * purple
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 #include <glib.h>
25 #include "../util.h"
27 /******************************************************************************
28 * base 16 tests
29 *****************************************************************************/
30 static void
31 test_util_base_16_encode(void) {
32 gchar *in = purple_base16_encode((const guchar *)"hello, world!", 14);
33 g_assert_cmpstr("68656c6c6f2c20776f726c642100", ==, in);
36 static void
37 test_util_base_16_decode(void) {
38 gsize sz = 0;
39 guchar *out = purple_base16_decode("21646c726f77202c6f6c6c656800", &sz);
41 g_assert_cmpint(sz, ==, 14);
42 g_assert_cmpstr("!dlrow ,olleh", ==, (const gchar *)out);
45 /******************************************************************************
46 * filename escape tests
47 *****************************************************************************/
48 static void
49 test_util_filename_escape(void) {
50 g_assert_cmpstr("foo", ==, purple_escape_filename("foo"));
51 g_assert_cmpstr("@oo", ==, purple_escape_filename("@oo"));
52 g_assert_cmpstr("#oo", ==, purple_escape_filename("#oo"));
53 g_assert_cmpstr("-oo", ==, purple_escape_filename("-oo"));
54 g_assert_cmpstr("_oo", ==, purple_escape_filename("_oo"));
55 g_assert_cmpstr(".oo", ==, purple_escape_filename(".oo"));
56 g_assert_cmpstr("%25oo", ==, purple_escape_filename("%oo"));
57 g_assert_cmpstr("%21oo", ==, purple_escape_filename("!oo"));
60 static void
61 test_util_filename_unescape(void) {
62 g_assert_cmpstr("bar", ==, purple_unescape_filename("bar"));
63 g_assert_cmpstr("@ar", ==, purple_unescape_filename("@ar"));
64 g_assert_cmpstr("!ar", ==, purple_unescape_filename("!ar"));
65 g_assert_cmpstr("!ar", ==, purple_unescape_filename("%21ar"));
66 g_assert_cmpstr("%ar", ==, purple_unescape_filename("%25ar"));
69 /******************************************************************************
70 * text_strip tests
71 *****************************************************************************/
72 static void
73 test_util_text_strip_mnemonic(void) {
74 g_assert_cmpstr("", ==, purple_text_strip_mnemonic(""));
75 g_assert_cmpstr("foo", ==, purple_text_strip_mnemonic("foo"));
76 g_assert_cmpstr("foo", ==, purple_text_strip_mnemonic("_foo"));
80 /******************************************************************************
81 * email tests
82 *****************************************************************************/
84 * Many of the valid and invalid email addresses lised below are from
85 * http://fightingforalostcause.net/misc/2006/compare-email-regex.php
87 const gchar *valid_emails[] = {
88 "purple-devel@lists.sf.net",
89 "l3tt3rsAndNumb3rs@domain.com",
90 "has-dash@domain.com",
91 "hasApostrophe.o'leary@domain.org",
92 "uncommonTLD@domain.museum",
93 "uncommonTLD@domain.travel",
94 "uncommonTLD@domain.mobi",
95 "countryCodeTLD@domain.uk",
96 "countryCodeTLD@domain.rw",
97 "lettersInDomain@911.com",
98 "underscore_inLocal@domain.net",
99 "IPInsteadOfDomain@127.0.0.1",
100 /* "IPAndPort@127.0.0.1:25", */
101 "subdomain@sub.domain.com",
102 "local@dash-inDomain.com",
103 "dot.inLocal@foo.com",
104 "a@singleLetterLocal.org",
105 "singleLetterDomain@x.org",
106 "&*=?^+{}'~@validCharsInLocal.net",
107 "foor@bar.newTLD",
108 "HenryTheGreatWhiteCricket@live.ca",
109 "HenryThe__WhiteCricket@hotmail.com"
112 static void
113 test_util_email_is_valid(void) {
114 size_t i;
116 for (i = 0; i < G_N_ELEMENTS(valid_emails); i++)
117 g_assert_true(purple_email_is_valid(valid_emails[i]));
120 const gchar *invalid_emails[] = {
121 "purple-devel@@lists.sf.net",
122 "purple@devel@lists.sf.net",
123 "purple-devel@list..sf.net",
124 "purple-devel",
125 "purple-devel@",
126 "@lists.sf.net",
127 "totally bogus",
128 "missingDomain@.com",
129 "@missingLocal.org",
130 "missingatSign.net",
131 "missingDot@com",
132 "two@@signs.com",
133 "colonButNoPort@127.0.0.1:",
135 /* "someone-else@127.0.0.1.26", */
136 ".localStartsWithDot@domain.com",
137 /* "localEndsWithDot.@domain.com", */ /* I don't think this is invalid -- Stu */
138 /* "two..consecutiveDots@domain.com", */ /* I don't think this is invalid -- Stu */
139 "domainStartsWithDash@-domain.com",
140 "domainEndsWithDash@domain-.com",
141 /* "numbersInTLD@domain.c0m", */
142 /* "missingTLD@domain.", */ /* This certainly isn't invalid -- Stu */
143 "! \"#$%(),/;<>[]`|@invalidCharsInLocal.org",
144 "invalidCharsInDomain@! \"#$%(),/;<>_[]`|.org",
145 /* "local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org" */
148 static void
149 test_util_email_is_invalid(void) {
150 size_t i;
152 for (i = 0; i < G_N_ELEMENTS(invalid_emails); i++)
153 g_assert_false(purple_email_is_valid(invalid_emails[i]));
156 /******************************************************************************
157 * ipv6 tests
158 *****************************************************************************/
159 static void
160 test_util_ipv6_is_valid(void) {
161 g_assert_true(purple_ipv6_address_is_valid("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
162 g_assert_true(purple_ipv6_address_is_valid("2001:db8:85a3:0:0:8a2e:370:7334"));
163 g_assert_true(purple_ipv6_address_is_valid("2001:db8:85a3::8a2e:370:7334"));
164 g_assert_true(purple_ipv6_address_is_valid("2001:0db8:0:0::1428:57ab"));
165 g_assert_true(purple_ipv6_address_is_valid("::1"));
166 g_assert_true(purple_ipv6_address_is_valid("1::"));
167 g_assert_true(purple_ipv6_address_is_valid("1::1"));
168 g_assert_true(purple_ipv6_address_is_valid("::"));
171 static void
172 test_util_ipv6_is_invalid(void) {
173 g_assert_false(purple_ipv6_address_is_valid(""));
174 g_assert_false(purple_ipv6_address_is_valid(":"));
175 g_assert_false(purple_ipv6_address_is_valid("1.2.3.4"));
176 g_assert_false(purple_ipv6_address_is_valid("2001::FFD3::57ab"));
177 g_assert_false(purple_ipv6_address_is_valid("200000000::1"));
178 g_assert_false(purple_ipv6_address_is_valid("QWERTY::1"));
181 /******************************************************************************
182 * str_to_time tests
183 *****************************************************************************/
184 static void
185 test_util_str_to_time(void) {
186 struct tm tm;
187 glong tz_off;
188 const gchar *rest;
189 time_t timestamp;
191 g_assert_cmpint(377182200, ==, purple_str_to_time("19811214T12:50:00", TRUE, NULL, NULL, NULL));
192 g_assert_cmpint(1175919261, ==, purple_str_to_time("20070407T04:14:21", TRUE, NULL, NULL, NULL));
193 g_assert_cmpint(1282941722, ==, purple_str_to_time("2010-08-27.204202", TRUE, NULL, NULL, NULL));
195 timestamp = purple_str_to_time("2010-08-27.134202-0700PDT", FALSE, &tm, &tz_off, &rest);
196 g_assert_cmpint(1282941722, ==, timestamp);
197 g_assert_cmpint((-7 * 60 * 60), ==, tz_off);
198 g_assert_cmpstr("PDT", ==, rest);
201 /******************************************************************************
202 * str_to_date_time tests
203 *****************************************************************************/
204 static void
205 test_util_str_to_date_time(void)
207 GDateTime *dt;
209 dt = purple_str_to_date_time("19811214T12:50:00", TRUE);
210 g_assert_cmpint(377182200, ==, g_date_time_to_unix(dt));
211 g_assert_cmpint(0, ==, g_date_time_get_utc_offset(dt));
212 g_date_time_unref(dt);
214 dt = purple_str_to_date_time("20070407T04:14:21.1234", TRUE);
215 g_assert_cmpint(1175919261, ==, g_date_time_to_unix(dt));
216 g_assert_cmpint(0, ==, g_date_time_get_utc_offset(dt));
217 g_assert_cmpint(123400, ==, g_date_time_get_microsecond(dt));
218 g_date_time_unref(dt);
220 dt = purple_str_to_date_time("2010-08-27.204202", TRUE);
221 g_assert_cmpint(1282941722, ==, g_date_time_to_unix(dt));
222 g_assert_cmpint(0, ==, g_date_time_get_utc_offset(dt));
223 g_date_time_unref(dt);
225 dt = purple_str_to_date_time("2010-08-27.204202.123456", TRUE);
226 g_assert_cmpint(1282941722, ==, g_date_time_to_unix(dt));
227 g_assert_cmpint(0, ==, g_date_time_get_utc_offset(dt));
228 g_assert_cmpint(123456, ==, g_date_time_get_microsecond(dt));
229 g_date_time_unref(dt);
231 dt = purple_str_to_date_time("2010-08-27.134202-0700PDT", FALSE);
232 g_assert_cmpint(1282941722, ==, g_date_time_to_unix(dt));
233 g_assert_cmpint((-7LL * 60 * 60 * G_USEC_PER_SEC), ==, g_date_time_get_utc_offset(dt));
235 dt = purple_str_to_date_time("2010-08-27.134202.1234-0700PDT", FALSE);
236 g_assert_cmpint(1282941722, ==, g_date_time_to_unix(dt));
237 g_assert_cmpint(123400, ==, g_date_time_get_microsecond(dt));
238 g_assert_cmpint((-7LL * 60 * 60 * G_USEC_PER_SEC), ==, g_date_time_get_utc_offset(dt));
241 /******************************************************************************
242 * Markup tests
243 *****************************************************************************/
244 typedef struct {
245 gchar *markup;
246 gchar *xhtml;
247 gchar *plaintext;
248 } MarkupTestData;
250 static void
251 test_util_markup_html_to_xhtml(void) {
252 gint i;
253 MarkupTestData data[] = {
255 "<a>",
256 "<a href=\"\"></a>",
258 }, {
259 "<A href='URL'>ABOUT</a>",
260 "<a href=\"URL\">ABOUT</a>",
261 "ABOUT <URL>",
262 }, {
263 "<a href='URL'>URL</a>",
264 "<a href=\"URL\">URL</a>",
265 "URL",
266 }, {
267 "<a href='mailto:mail'>mail</a>",
268 "<a href=\"mailto:mail\">mail</a>",
269 "mail",
270 }, {
271 "<A href='\"U&apos;R&L'>ABOUT</a>",
272 "<a href=\"&quot;U&apos;R&amp;L\">ABOUT</a>",
273 "ABOUT <\"U'R&L>",
274 }, {
275 "<img src='SRC' alt='ALT'/>",
276 "<img src='SRC' alt='ALT' />",
277 "ALT",
278 }, {
279 "<img src=\"'S&apos;R&C\" alt=\"'A&apos;L&T\"/>",
280 "<img src='&apos;S&apos;R&amp;C' alt='&apos;A&apos;L&amp;T' />",
281 "'A'L&T",
282 }, {
283 "<unknown>",
284 "&lt;unknown>",
285 "<unknown>",
286 }, {
287 "&eacute;&amp;",
288 "&eacute;&amp;",
289 "&eacute;&",
290 }, {
291 "<h1>A<h2>B</h2>C</h1>",
292 "<h1>A<h2>B</h2>C</h1>",
293 "ABC",
294 }, {
295 "<h1><h2><h3><h4>",
296 "<h1><h2><h3><h4></h4></h3></h2></h1>",
298 }, {
299 "<italic/>",
300 "<em/>",
302 }, {
303 "</",
304 "&lt;/",
305 "</",
306 }, {
307 "</div>",
310 }, {
311 "<hr/>",
312 "<br/>",
313 "\n",
314 }, {
315 "<hr>",
316 "<br/>",
317 "\n",
318 }, {
319 "<br />",
320 "<br/>",
321 "\n",
322 }, {
323 "<br>INSIDE</br>",
324 "<br/>INSIDE",
325 "\nINSIDE",
326 }, {
327 "<div></div>",
328 "<div></div>",
330 }, {
331 "<div/>",
332 "<div/>",
334 }, {
335 "<div attr='\"&<>'/>",
336 "<div attr='&quot;&amp;&lt;&gt;'/>",
338 }, {
339 "<div attr=\"'\"/>",
340 "<div attr=\"&apos;\"/>",
342 }, {
343 "<div/> < <div/>",
344 "<div/> &lt; <div/>",
345 " < ",
346 }, {
347 "<div>x</div>",
348 "<div>x</div>",
349 "x",
350 }, {
351 "<b>x</b>",
352 "<span style='font-weight: bold;'>x</span>",
353 "x",
354 }, {
355 "<bold>x</bold>",
356 "<span style='font-weight: bold;'>x</span>",
357 "x",
358 }, {
359 "<strong>x</strong>",
360 "<span style='font-weight: bold;'>x</span>",
361 "x",
362 }, {
363 "<u>x</u>",
364 "<span style='text-decoration: underline;'>x</span>",
365 "x",
366 }, {
367 "<underline>x</underline>",
368 "<span style='text-decoration: underline;'>x</span>",
369 "x",
370 }, {
371 "<s>x</s>",
372 "<span style='text-decoration: line-through;'>x</span>",
373 "x",
374 }, {
375 "<strike>x</strike>",
376 "<span style='text-decoration: line-through;'>x</span>",
377 "x",
378 }, {
379 "<sub>x</sub>",
380 "<span style='vertical-align:sub;'>x</span>",
381 "x",
382 }, {
383 "<sup>x</sup>",
384 "<span style='vertical-align:super;'>x</span>",
385 "x",
386 }, {
387 "<FONT>x</FONT>",
388 "x",
389 "x",
390 }, {
391 "<font face=\"'Times&gt;New & Roman'\">x</font>",
392 "<span style='font-family: \"Times&gt;New &amp; Roman\";'>x</span>",
393 "x",
394 }, {
395 "<font back=\"'color&gt;blue&red'\">x</font>",
396 "<span style='background: \"color&gt;blue&amp;red\";'>x</span>",
397 "x",
398 }, {
399 "<font color=\"'color&gt;blue&red'\">x</font>",
400 "<span style='color: \"color&gt;blue&amp;red\";'>x</span>",
401 "x",
402 }, {
403 "<font size=1>x</font>",
404 "<span style='font-size: xx-small;'>x</span>",
405 "x",
406 }, {
407 "<font size=432>x</font>",
408 "<span style='font-size: medium;'>x</span>",
409 "x",
410 }, {
411 "<!--COMMENT-->",
412 "<!--COMMENT-->",
413 "COMMENT-->",
414 }, {
415 "<br />",
416 "&lt;br />",
417 "<br />",
418 }, {
419 "<hr />",
420 "&lt;hr />",
421 "<hr />"
422 }, {
423 NULL, NULL, NULL,
427 for(i = 0; data[i].markup; i++) {
428 gchar *xhtml = NULL, *plaintext = NULL;
430 purple_markup_html_to_xhtml(data[i].markup, &xhtml, &plaintext);
432 g_assert_cmpstr(data[i].xhtml, ==, xhtml);
433 g_free(xhtml);
435 g_assert_cmpstr(data[i].plaintext, ==, plaintext);
436 g_free(plaintext);
440 /******************************************************************************
441 * UTF8 tests
442 *****************************************************************************/
443 typedef struct {
444 gchar *input;
445 gchar *output;
446 } UTF8TestData;
448 static void
449 test_util_utf8_strip_unprintables(void) {
450 gint i;
451 UTF8TestData data[] = {
453 /* \t, \n, \r, space */
454 "ab \tcd\nef\r ",
455 "ab \tcd\nef\r ",
456 }, {
457 /* ASCII control characters (stripped) */
458 "\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0E\x0F\x10 aaaa "
459 "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
460 " aaaa ",
461 }, {
462 /* Basic ASCII */
463 "Foobar",
464 "Foobar",
465 }, {
466 /* 0xE000 - 0xFFFD (UTF-8 encoded) */
467 /* U+F1F7 */
468 "aaaa\xef\x87\xb7",
469 "aaaa\xef\x87\xb7",
470 }, {
471 /* U+FEFF (should not be stripped) */
472 "aaaa\xef\xbb\xbf",
473 "aaaa\xef\xbb\xbf",
474 }, {
475 /* U+FFFE (should be stripped) */
476 "aaaa\xef\xbf\xbe",
477 "aaaa",
478 }, {
479 NULL,
480 NULL,
484 for(i = 0; ; i++) {
485 gchar *result = purple_utf8_strip_unprintables(data[i].input);
487 g_assert_cmpstr(data[i].output, ==, result);
489 g_free(result);
491 /* NULL as input is a valid test, but it's the last test, so we break
492 * after it.
494 if(data[i].input == NULL)
495 break;
499 /******************************************************************************
500 * strdup_withhtml tests
501 *****************************************************************************/
502 static void
503 test_util_strdup_withhtml(void) {
504 gchar *result = purple_strdup_withhtml("hi\r\nthere\n");
506 g_assert_cmpstr("hi<BR>there<BR>", ==, result);
508 g_free(result);
511 /******************************************************************************
512 * URI Escaping
513 *****************************************************************************/
514 static void
515 test_uri_escape_for_open(void) {
516 /* make sure shell stuff is escaped... */
517 gchar *result = purple_uri_escape_for_open("https://$(xterm)");
518 g_assert_cmpstr("https://%24%28xterm%29", ==, result);
519 g_free(result);
521 result = purple_uri_escape_for_open("https://`xterm`");
522 g_assert_cmpstr("https://%60xterm%60", ==, result);
523 g_free(result);
525 result = purple_uri_escape_for_open("https://$((25 + 13))");
526 g_assert_cmpstr("https://%24%28%2825%20+%2013%29%29", ==, result);
527 g_free(result);
529 /* ...but keep brackets so that ipv6 links can be opened. */
530 result = purple_uri_escape_for_open("https://[123:4567:89a::::]");
531 g_assert_cmpstr("https://[123:4567:89a::::]", ==, result);
532 g_free(result);
535 /******************************************************************************
536 * MANE
537 *****************************************************************************/
538 gint
539 main(gint argc, gchar **argv) {
540 g_test_init(&argc, &argv, NULL);
542 g_test_add_func("/util/base/16/encode",
543 test_util_base_16_encode);
544 g_test_add_func("/util/base/16/decode",
545 test_util_base_16_decode);
547 g_test_add_func("/util/filename/escape",
548 test_util_filename_escape);
549 g_test_add_func("/util/filename/unescape",
550 test_util_filename_unescape);
552 g_test_add_func("/util/mnemonic/strip",
553 test_util_text_strip_mnemonic);
555 g_test_add_func("/util/email/is valid",
556 test_util_email_is_valid);
557 g_test_add_func("/util/email/is invalid",
558 test_util_email_is_invalid);
560 g_test_add_func("/util/ipv6/is valid",
561 test_util_ipv6_is_valid);
562 g_test_add_func("/util/ipv6/is invalid",
563 test_util_ipv6_is_invalid);
565 g_test_add_func("/util/str to time",
566 test_util_str_to_time);
568 g_test_add_func("/util/str to date time",
569 test_util_str_to_date_time);
571 g_test_add_func("/util/markup/html to xhtml",
572 test_util_markup_html_to_xhtml);
574 g_test_add_func("/util/utf8/strip unprintables",
575 test_util_utf8_strip_unprintables);
577 g_test_add_func("/util/test_strdup_withhtml",
578 test_util_strdup_withhtml);
580 g_test_add_func("/util/test_uri_escape_for_open",
581 test_uri_escape_for_open);
583 return g_test_run();