Release 1.25.0 -- Buddy Idle Time, RTF
[siplcs.git] / src / core / sipe-xml-tests.c
blob10031807e5637490488a5ea87a6c97332393a340
1 /**
2 * @file sipe-xml-tests.c
4 * pidgin-sipe
6 * Copyright (C) 2010-2016 SIPE Project <http://sipe.sourceforge.net/>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Tests for sipe-xml.c */
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <time.h>
31 #include <glib.h>
33 #include "sip-transport.h"
34 #include "sipe-common.h"
35 #include "sipe-backend.h"
36 #include "sipe-digest.h"
37 #include "sipe-xml.h"
38 #include "sipe-utils.h"
39 #include "uuid.h"
41 /* stub functions for backend API */
42 void sipe_backend_debug_literal(sipe_debug_level level,
43 const gchar *msg)
45 printf("DEBUG %d: %s", level, msg);
47 void sipe_backend_debug(sipe_debug_level level,
48 const gchar *format,
49 ...)
51 va_list args;
52 gchar *msg;
53 va_start(args, format);
54 msg = g_strdup_vprintf(format, args);
55 va_end(args);
57 sipe_backend_debug_literal(level, msg);
58 g_free(msg);
60 gboolean sipe_backend_debug_enabled(void)
62 return TRUE;
65 void sipe_digest_sha1(SIPE_UNUSED_PARAMETER const guchar *data,
66 SIPE_UNUSED_PARAMETER gsize length,
67 SIPE_UNUSED_PARAMETER guchar *digest) {}
68 const gchar *sip_transport_epid(SIPE_UNUSED_PARAMETER struct sipe_core_private *sipe_private) { return(NULL); }
69 const gchar *sip_transport_ip_address(SIPE_UNUSED_PARAMETER struct sipe_core_private *sipe_private) { return(NULL); }
70 char *generateUUIDfromEPID(SIPE_UNUSED_PARAMETER const gchar *epid) { return(NULL); }
71 char *sipe_get_epid(SIPE_UNUSED_PARAMETER const char *self_sip_uri,
72 SIPE_UNUSED_PARAMETER const char *hostname,
73 SIPE_UNUSED_PARAMETER const char *ip_address) { return(NULL); }
75 /* test helpers */
76 static guint succeeded = 0;
77 static guint failed = 0;
78 static const gchar *teststring;
80 static sipe_xml *assert_parse(const gchar *s, gboolean ok)
82 sipe_xml *xml = sipe_xml_parse(s, s ? strlen(s) : 0);
84 teststring = s ? s : "(nil)";
86 if ((ok && xml) || (!ok && !xml)) {
87 succeeded++;
88 } else {
89 printf("[%s]\nXML parse FAILED: %p\n",
90 teststring, xml);
91 failed++;
93 return(xml);
96 static void assert_name(const sipe_xml *xml, const gchar *s)
98 const gchar *name = sipe_xml_name(xml);
100 if (sipe_strequal(name, s)) {
101 succeeded++;
102 } else {
103 printf("[%s]\nXML name FAILED: '%s' expected: '%s'\n",
104 teststring, name ? name : "(nil)", s ? s : "(nil)");
105 failed++;
110 static const sipe_xml *assert_child(const sipe_xml *xml, const gchar *s, gboolean ok)
112 const sipe_xml *child = sipe_xml_child(xml, s);
114 if ((ok && child) || (!ok && !child)) {
115 succeeded++;
116 } else {
117 printf("[%s]\nXML child FAILED: %p '%s'\n",
118 teststring, xml, s ? s : "(nil)");
119 failed++;
121 return(child);
124 static void assert_data(const sipe_xml *xml, const gchar *s)
126 gchar *data = sipe_xml_data(xml);
128 if (sipe_strequal(s, data)) {
129 succeeded++;
130 } else {
131 printf("[%s]\nXML data FAILED: '%s' expected: '%s'\n",
132 teststring, data ? data : "(nil)", s ? s : "(nil)");
133 failed++;
135 g_free(data);
138 static void assert_attribute(const sipe_xml *xml,
139 const gchar *key, const gchar *value)
141 const gchar *attr = sipe_xml_attribute(xml, key);
143 if (sipe_strequal(value, attr)) {
144 succeeded++;
145 } else {
146 printf("[%s]\nXML attr FAILED: '%s': '%s' expected: '%s'\n",
147 teststring, key ? key : "(nil)",
148 attr ? attr : "(nil)", value ? value : "(nil)");
149 failed++;
153 static void assert_int_attribute(const sipe_xml *xml,
154 const gchar *key, gint value, gint fallback)
156 gint attr = sipe_xml_int_attribute(xml, key, fallback);
158 if ((attr == value) || (attr == fallback)) {
159 succeeded++;
160 } else {
161 printf("[%s]\nXML int attr FAILED: '%s': %d expected: %d/%d\n",
162 teststring, key ? key : "(nil)",
163 attr, value, fallback);
164 failed++;
168 static void assert_stringify(const sipe_xml *xml,
169 int expected, ...)
171 va_list args;
172 gchar *string = sipe_xml_stringify(xml);
174 va_start(args, expected);
175 while (expected-- > 0) {
176 const gchar *alternative = va_arg(args, const gchar *);
177 if (sipe_strequal(string, alternative)) {
178 succeeded++;
179 break;
180 } else {
181 printf("XML stringify alternative FAILED: '%s' (trying next...)\n",
182 alternative ? alternative : "(nil)");
185 va_end(args);
187 if (expected < 0) {
188 printf("[%s]\nXML stringify all alternatives FAILED: '%s'\n",
189 teststring, string ? string : "(nil)");
190 failed++;
193 g_free(string);
196 static void assert_raw(const gchar *raw,
197 const gchar *tag,
198 gboolean include_tag,
199 const char *expected)
201 gchar *string = sipe_xml_extract_raw(raw, tag, include_tag);
202 if (expected) {
203 if (string) {
204 if (sipe_strequal(string, expected)) {
205 succeeded++;
206 } else {
207 printf("[%s]\nXML raw extract FAILED: '%s' expected: '%s'\n",
208 raw, string, expected);
209 failed++;
211 } else {
212 printf("[%s]\nXML raw extract not found FAILED: '%s' expected: '%s'\n",
213 raw, tag, expected);
214 failed++;
216 } else {
217 if (string) {
218 printf("[%s]\nXML raw extract no match FAILED: '%s' matched: '%s'\n",
219 raw, tag, string);
220 failed++;
221 } else {
222 succeeded++;
226 g_free(string);
230 /* memory leak check */
231 static gsize allocated = 0;
233 static gpointer test_malloc(gsize n_bytes)
235 gsize *m = malloc(sizeof(gsize) + n_bytes);
236 if (!m) return(NULL);
237 allocated += n_bytes;
238 m[0] = n_bytes;
239 return(m + 1);
242 static void test_free(gpointer mem)
244 gsize *m = mem;
245 if (!m) return;
246 m--;
247 allocated -= m[0];
248 free(m);
251 static gpointer test_realloc(gpointer mem, gsize n_bytes)
253 guint8 *n = NULL;
254 if (n_bytes) {
255 n = test_malloc(n_bytes);
256 if (mem && n) {
257 memcpy(n, mem, n_bytes);
260 test_free(mem);
261 return(n);
264 static GMemVTable memory_leak_check = {
265 &test_malloc,
266 &test_realloc,
267 &test_free,
268 NULL,
269 NULL,
270 NULL,
273 int main(SIPE_UNUSED_PARAMETER int argc, SIPE_UNUSED_PARAMETER char **argv)
275 sipe_xml *xml;
276 const sipe_xml *child1, *child2;
278 #if 0
280 * No idea why the memory leak checks work on some platforms
281 * but fail on others :-( Disable for now...
283 g_mem_set_vtable(&memory_leak_check);
284 #else
285 (void) memory_leak_check;
286 #endif
288 /* empty XML */
289 xml = assert_parse(NULL, FALSE);
290 assert_stringify(xml, 1, NULL);
291 sipe_xml_free(xml);
292 xml = assert_parse("", FALSE);
293 sipe_xml_free(xml);
294 xml = assert_parse("<?xml version=\"1.0\" ?>", FALSE);
295 sipe_xml_free(xml);
297 /* one node */
298 xml = assert_parse("<test></test>", TRUE);
299 assert_name(xml, "test");
300 assert_data(xml, NULL);
301 assert_stringify(xml, 1, "<test/>");
302 sipe_xml_free(xml);
303 xml = assert_parse("<test/>", TRUE);
304 assert_name(xml, "test");
305 assert_data(xml, NULL);
306 assert_stringify(xml, 1, teststring);
307 sipe_xml_free(xml);
308 xml = assert_parse("<test>a</test>", TRUE);
309 assert_name(xml, "test");
310 assert_data(xml, "a");
311 assert_stringify(xml, 1, teststring);
312 sipe_xml_free(xml);
313 xml = assert_parse("<test>a\nb</test>", TRUE);
314 assert_name(xml, "test");
315 assert_data(xml, "a\nb");
316 assert_stringify(xml, 1, teststring);
317 sipe_xml_free(xml);
319 /* child node */
320 xml = assert_parse("<test>a<child>b</child></test>", TRUE);
321 assert_name(xml, "test");
322 assert_data(xml, "a");
323 child1 = assert_child(xml, NULL, FALSE);
324 child1 = assert_child(xml, "child", TRUE);
325 assert_name(child1, "child");
326 assert_data(child1, "b");
327 child1 = assert_child(xml, "shouldnotmatch", FALSE);
328 assert_data(child1, NULL);
329 assert_stringify(xml, 1, teststring);
330 sipe_xml_free(xml);
332 xml = assert_parse("<test>a<child/></test>", TRUE);
333 assert_name(xml, "test");
334 assert_data(xml, "a");
335 child1 = assert_child(xml, "child", TRUE);
336 assert_name(child1, "child");
337 assert_data(child1, NULL);
338 child1 = assert_child(xml, "shouldnotmatch", FALSE);
339 assert_data(child1, NULL);
340 assert_stringify(xml, 1, teststring);
341 sipe_xml_free(xml);
343 xml = assert_parse("<test>a<child>b<inner>c</inner></child></test>", TRUE);
344 assert_name(xml, "test");
345 assert_data(xml, "a");
346 child1 = assert_child(xml, "child", TRUE);
347 assert_name(child1, "child");
348 assert_data(child1, "b");
349 child1 = assert_child(child1, "inner", TRUE);
350 assert_name(child1, "inner");
351 assert_data(child1, "c");
352 child1 = assert_child(xml, "child/inner", TRUE);
353 assert_name(child1, "inner");
354 assert_data(child1, "c");
355 assert_stringify(xml, 1, teststring);
356 sipe_xml_free(xml);
358 xml = assert_parse("<test>a<child>b<inner>c<innerinner>d</innerinner></inner></child></test>", TRUE);
359 assert_name(xml, "test");
360 assert_data(xml, "a");
361 child1 = assert_child(xml, "child", TRUE);
362 assert_name(child1, "child");
363 assert_data(child1, "b");
364 child2 = assert_child(child1, "inner/innerinner", TRUE);
365 assert_name(child2, "innerinner");
366 assert_data(child2, "d");
367 child1 = assert_child(child1, "inner", TRUE);
368 assert_name(child1, "inner");
369 assert_data(child1, "c");
370 child1 = assert_child(child1, "innerinner", TRUE);
371 assert_name(child1, "innerinner");
372 assert_data(child1, "d");
373 child1 = assert_child(xml, "child/inner", TRUE);
374 assert_name(child1, "inner");
375 assert_data(child1, "c");
376 child1 = assert_child(xml, "child/inner/innerinner", TRUE);
377 assert_name(child1, "innerinner");
378 assert_data(child1, "d");
379 assert_stringify(xml, 1, teststring);
380 sipe_xml_free(xml);
382 /* attributes */
383 xml = assert_parse("<test a=\"\">a</test>", TRUE);
384 assert_name(xml, "test");
385 assert_data(xml, "a");
386 assert_attribute(xml, NULL, NULL);
387 assert_attribute(xml, "a", "");
388 assert_attribute(xml, "b", NULL);
389 assert_stringify(xml, 1, teststring);
390 sipe_xml_free(xml);
392 xml = assert_parse("<test a=\"1\" b=\"abc\">a</test>", TRUE);
393 assert_name(xml, "test");
394 assert_data(xml, "a");
395 assert_attribute(xml, "a", "1");
396 assert_int_attribute(xml, "a", 1, 0);
397 assert_attribute(xml, "b", "abc");
398 assert_attribute(xml, "c", NULL);
399 assert_int_attribute(xml, "d", 100, 200);
400 /* the attribute order depends on glib hashing :-( */
401 assert_stringify(xml, 2, teststring, "<test b=\"abc\" a=\"1\">a</test>");
402 sipe_xml_free(xml);
404 /* attributes with namespace */
405 xml = assert_parse("<m:row m:uri=\"sip:\" m:displayName=\"X\" m:title=\"Y\" m:office=\"Z\" m:phone=\"0\" m:company=\"A\" m:city=\"B\" m:state=\"C\" m:country=\"D\" m:email=\"E\" />", TRUE);
406 assert_name(xml, "row");
407 assert_data(xml, NULL);
408 assert_attribute(xml, "uri", "sip:");
409 assert_attribute(xml, "displayName", "X");
410 assert_attribute(xml, "title", "Y");
411 assert_attribute(xml, "office", "Z");
412 assert_attribute(xml, "phone", "0");
413 assert_attribute(xml, "company", "A");
414 assert_attribute(xml, "city", "B");
415 assert_attribute(xml, "state", "C");
416 assert_attribute(xml, "country", "D");
417 assert_attribute(xml, "email", "E");
418 sipe_xml_free(xml);
420 xml = assert_parse("<state xsi:type=\"aggregateState\" lastActive=\"date\" xmlns:xsi=\"http://one\" xmlns=\"http://two\"><availability>15500</availability></state>", TRUE);
421 assert_name(xml, "state");
422 assert_data(xml, NULL);
423 assert_attribute(xml, "type", "aggregateState");
424 assert_attribute(xml, "lastActive", "date");
425 assert_attribute(xml, "xsi", "http://one");
426 assert_attribute(xml, "xmlns", "http://two");
427 child1 = assert_child(xml, "availability", TRUE);
428 assert_name(child1, "availability");
429 assert_data(child1, "15500");
430 sipe_xml_free(xml);
432 /* broken XML */
433 xml = assert_parse("t", FALSE);
434 sipe_xml_free(xml);
435 xml = assert_parse("<>", FALSE);
436 sipe_xml_free(xml);
437 xml = assert_parse("<></>", FALSE);
438 sipe_xml_free(xml);
439 xml = assert_parse("<test>", FALSE);
440 sipe_xml_free(xml);
441 xml = assert_parse("<a a=\"1\" a=\"2\"></a>", FALSE);
442 sipe_xml_free(xml);
444 /* XML raw extract */
445 assert_raw("<tag>data</tag>", "tag", FALSE, "data");
446 assert_raw("<tag>data</tag>", "tag", TRUE, "<tag>data</tag>");
447 assert_raw("<tag>data</tag>", "tag1", FALSE, NULL);
448 assert_raw("<tag>data</tag>", "tag1", TRUE, NULL);
449 assert_raw("<ns:tag>data</ns:tag>", "tag", FALSE, "data");
450 assert_raw("<ns:tag>data</ns:tag>", "tag", TRUE, "<ns:tag>data</ns:tag>");
451 assert_raw("<ns:tag>data</ns:tag>", "tag1", FALSE, NULL);
452 assert_raw("<ns:tag>data</ns:tag>", "tag1", TRUE, NULL);
453 assert_raw("<ns:tag>data</ns:tag>", "ns:tag", FALSE, "data");
454 assert_raw("<ns:tag>data</ns:tag>", "ns:tag", TRUE, "<ns:tag>data</ns:tag>");
455 assert_raw("<ns:tag>data</ns:tag>", "ns:tag1", FALSE, NULL);
456 assert_raw("<ns:tag>data</ns:tag>", "ns:tag1", TRUE, NULL);
458 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag", FALSE, "data");
459 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag", TRUE, "<tag>data</tag>");
460 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag", FALSE, "data");
461 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag", TRUE, "<tag>data</tag>");
462 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag1", FALSE, NULL);
463 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag1", TRUE, NULL);
464 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag1", FALSE, NULL);
465 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag1", TRUE, NULL);
466 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag", FALSE, "data");
467 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag", TRUE, "<ns:tag>data</ns:tag>");
468 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag", FALSE, "data");
469 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag", TRUE, "<ns:tag>data</ns:tag>");
470 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag1", FALSE, NULL);
471 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag1", TRUE, NULL);
472 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag1", FALSE, NULL);
473 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag1", TRUE, NULL);
475 /* broken XML raw extract */
476 assert_raw("tag>data</tag>", "tag", FALSE, NULL);
477 assert_raw(":tag>data</tag>", "tag", FALSE, NULL);
478 assert_raw("<tag>data</tag", "tag", FALSE, NULL);
479 assert_raw("<tag>data</tag1>", "tag", FALSE, NULL);
480 assert_raw("<ns:tag>data</tag1>", "tag", FALSE, NULL);
481 assert_raw("<ns:tag>data</ns:tag1>", "tag", FALSE, NULL);
483 if (allocated) {
484 printf("MEMORY LEAK: %" G_GSIZE_FORMAT " still allocated\n", allocated);
485 failed++;
486 } else {
487 printf("MEMORY LEAK CHECK OK\n");
488 succeeded++;
491 printf("Result: %d PASSED %d FAILED\n", succeeded, failed);
492 return(failed);
496 Local Variables:
497 mode: c
498 c-file-style: "bsd"
499 indent-tabs-mode: t
500 tab-width: 8
501 End: