ref: 4e09200f7e4bf8791c9c720922734e0759206b72
dir: /libxpath/test/t.c/
#include <u.h> #include <libc.h> #include <xml.h> #include <xpath.h> typedef struct Test Test; struct Test { char *s; int num; int err; int type; char *e; }; Test tests[] = { { "/path//to[2]/node[@a='b']/@attr", 0, 0, 0, nil }, { "/path/text()", 0, 0, 0, nil }, { "/html/a", 3, 0, Xelem, "help.php, whatever.php, p.php" }, { "/html/a[2]/text()", 1, 0, Xstring, "Other link" }, { "/html//e", 2, 0, Xelem, "a='1', a='2'" }, { "/html/a[@href='p.php']/text()", 1, 0, Xstring, "Second link" }, { "/html/a[position()='2']/text()", 0, 1, 0, nil }, { "/html/a[position()=2]/text()", 1, 0, Xstring, "Other link" }, { "/html/'2'", 1, 0, Xstring, "2" }, { "/html/2", 1, 0, Xnum, "2" }, { "/html/'hello'", 1, 0, Xstring, "hello" }, { "/[inval]", 0, 1, 0, nil }, { "position()", 1, 0, Xnum, "number 1" }, { "/html/processing-instruction()", 1, 0, Xelem, "?pi attr=value" }, { "/html/comment()", 1, 0, Xstring, "comment with many words" }, { nil, 0, 0, 0, nil }, }; static char* type2str(int type) { switch (type) { case Xnum: return "Xnum"; case Xstring: return "Xstring"; case Xelem: return "Xelem"; } return "invalid"; } Xml *x; void printelem(Elem *e) { Attr *a; print("el: <%s", e->name); for (a = e->attrs; a; a = a->next) print(" %s='%s'", a->name, a->value); if (e->name[0] == '?') print(" ?>\n"); else print(" />\n"); } void printstring(char *s) { print("st: %s\n", s); } void printnum(int n) { print("nr: %d\n", n); } void runtest(Test *t) { XpResult r; char *s; s = t->s; if (t != tests) print("\n"); print("====== test ======\n - %s\n", s); r = xmllookpath(x->root, s); if (r.num == t->num) { print("√ correct number of results: %d\n", r.num); } else { print("× wrong number of results: %d (%d)\n", r.num, t->num); } if (t->err == r.error) { if (t->err) { print("√ is error: %r\n"); werrstr(""); } else print("√ is not error\n"); } else { if (r.error) print("× is error: (%d (%d)): %r\n", r.error, t->err); else print("× no error: (%d (%d))\n", r.error, t->err); } if (t->type == r.type) print("√ type is correct: %s\n", type2str(r.type)); else print("× type is incorrect: %s (%s)\n", type2str(r.type), type2str(t->type)); if (t->e) print("expect: %s\n", t->e); print("===== result =====\n"); for (int i = 0; i < r.num; i++) { switch (r.type) { case Xelem: if (!r.elems) sysfatal("elems not set"); printelem(r.elems[i]); break; case Xstring: if (!r.strings) sysfatal("strings not set"); printstring(r.strings[i]); break; case Xnum: if (!r.numbers) sysfatal("numbers not set"); printnum(r.numbers[i]); break; } } switch (r.type) { case Xelem: if (r.num && r.elems) free(r.elems); break; case Xstring: if (r.num && r.strings) free(r.strings); break; case Xnum: if (r.num && r.numbers) free(r.numbers); break; } } void main(int argc, char **argv) { USED(argc, argv); int fd; Test *t; fd = open("test.xml", OREAD); if (fd < 0) sysfatal("unable to test: %r"); xmldebug = 0; x = xmlparse(fd, 8192, 0); if (!x) sysfatal("parse error: %r"); close(fd); // xmlprint(x, 2); // exits(nil); xmldebug = 0; for (t = tests; t->s; t++) { runtest(t); } exits(nil); }