shithub: xml-9atom

ref: 4e09200f7e4bf8791c9c720922734e0759206b72
dir: /libxpath/test/t.c/

View raw version
#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);
}