ref: 524f6890a72aa3629cc91ecf5c505ffa52f7eda4
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" },
{ 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);
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");
x = xmlparse(fd, 8192, 0);
close(fd);
// xmldebug = 1;
for (t = tests; t->s; t++) {
runtest(t);
}
exits(nil);
}