Index: tests/Makefile
===================================================================
--- tests/Makefile	(revision dcf0f3e77ffd38ce3cc5d3c1eedfc655ff75a8f9)
+++ tests/Makefile	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -13,5 +13,5 @@
 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 
 
-test_objs = check.o check_util.o check_nick.o check_md5.o check_irc.o
+test_objs = check.o check_util.o check_nick.o check_md5.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o
 
 check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o
Index: tests/check.c
===================================================================
--- tests/check.c	(revision dcf0f3e77ffd38ce3cc5d3c1eedfc655ff75a8f9)
+++ tests/check.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -21,4 +21,14 @@
 }
 
+irc_t *torture_irc(void)
+{
+	irc_t *irc;
+	GIOChannel *ch1, *ch2;
+	if (!g_io_channel_pair(&ch1, &ch2))
+		return NULL;
+	irc = irc_new(g_io_channel_unix_get_fd(ch1));
+	return irc;
+}
+
 double gettime()
 {
@@ -40,4 +50,16 @@
 /* From check_irc.c */
 Suite *irc_suite(void);
+
+/* From check_help.c */
+Suite *help_suite(void);
+
+/* From check_user.c */
+Suite *user_suite(void);
+
+/* From check_crypting.c */
+Suite *crypting_suite(void);
+
+/* From check_set.c */
+Suite *set_suite(void);
 
 int main (int argc, char **argv)
@@ -67,5 +89,7 @@
 	if (verbose) {
 		log_link( LOGLVL_ERROR, LOGOUTPUT_CONSOLE );
+#ifdef DEBUG
 		log_link( LOGLVL_DEBUG, LOGOUTPUT_CONSOLE );
+#endif
 		log_link( LOGLVL_INFO, LOGOUTPUT_CONSOLE );
 		log_link( LOGLVL_WARNING, LOGOUTPUT_CONSOLE );
@@ -79,4 +103,8 @@
 	srunner_add_suite(sr, md5_suite());
 	srunner_add_suite(sr, irc_suite());
+	srunner_add_suite(sr, help_suite());
+	srunner_add_suite(sr, user_suite());
+	srunner_add_suite(sr, crypting_suite());
+	srunner_add_suite(sr, set_suite());
 	if (no_fork)
 		srunner_set_fork_status(sr, CK_NOFORK);
Index: tests/check_crypting.c
===================================================================
--- tests/check_crypting.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
+++ tests/check_crypting.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <check.h>
+#include <string.h>
+#include "bitlbee.h"
+#include "crypting.h"
+#include "testsuite.h"
+
+START_TEST(test_check_pass_valid)
+	fail_unless (checkpass ("foo", "acbd18db4cc2f85cedef654fccc4a4d8") == 0);
+	fail_unless (checkpass ("invalidpass", "acbd18db4cc2f85cedef654fccc4a4d8") == -1);
+
+END_TEST
+
+START_TEST(test_hashpass)
+	fail_unless (strcmp(hashpass("foo"), "acbd18db4cc2f85cedef654fccc4a4d8") == 0);
+END_TEST
+
+START_TEST(test_obfucrypt)
+	char *raw = obfucrypt("some line", "bla");
+	fail_unless(strcmp(raw, "\xd5\xdb\xce\xc7\x8c\xcd\xcb\xda\xc6") == 0);
+END_TEST
+
+START_TEST(test_deobfucrypt)
+	char *raw = deobfucrypt("\xd5\xdb\xce\xc7\x8c\xcd\xcb\xda\xc6", "bla");
+	fail_unless(strcmp(raw, "some line") == 0);
+END_TEST
+
+START_TEST(test_obfucrypt_bidirectional)
+	char *plain = g_strdup("this is a line");
+	char *raw = obfucrypt(plain, "foo");
+	fail_unless(strcmp(plain, deobfucrypt(raw, "foo")) == 0);
+END_TEST
+
+Suite *crypting_suite (void)
+{
+	Suite *s = suite_create("Crypting");
+	TCase *tc_core = tcase_create("Core");
+	suite_add_tcase (s, tc_core);
+	tcase_add_test (tc_core, test_check_pass_valid);
+	tcase_add_test (tc_core, test_hashpass);
+	tcase_add_test (tc_core, test_obfucrypt);
+	tcase_add_test (tc_core, test_deobfucrypt);
+	tcase_add_test (tc_core, test_obfucrypt_bidirectional);
+	return s;
+}
Index: tests/check_help.c
===================================================================
--- tests/check_help.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
+++ tests/check_help.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <check.h>
+#include <string.h>
+#include <stdio.h>
+#include "help.h"
+
+START_TEST(test_help_none)
+	help_t *h, *r;
+	r = help_init(&h, "/dev/null");
+	fail_if(r == NULL);
+	fail_if(r != h);
+END_TEST
+
+START_TEST(test_help_nonexistent)
+	help_t *h, *r;
+	r = help_init(&h, "/dev/null");
+	fail_unless(help_get(&h, "nonexistent") == NULL);
+END_TEST
+
+Suite *help_suite (void)
+{
+	Suite *s = suite_create("Help");
+	TCase *tc_core = tcase_create("Core");
+	suite_add_tcase (s, tc_core);
+	tcase_add_test (tc_core, test_help_none);
+	tcase_add_test (tc_core, test_help_nonexistent);
+	return s;
+}
Index: tests/check_set.c
===================================================================
--- tests/check_set.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
+++ tests/check_set.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -0,0 +1,130 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <check.h>
+#include <string.h>
+#include "set.h"
+#include "testsuite.h"
+
+START_TEST(test_set_add)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "default", NULL, data);
+	fail_unless(s == t);
+	fail_unless(t->data == data);
+	fail_unless(strcmp(t->def, "default") == 0);
+END_TEST
+
+START_TEST(test_set_add_existing)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "default", NULL, data);
+	t = set_add(&s, "name", "newdefault", NULL, data);
+	fail_unless(s == t);
+	fail_unless(strcmp(t->def, "newdefault") == 0);
+END_TEST
+
+START_TEST(test_set_find_unknown)
+	set_t *s = NULL, *t;
+	fail_unless (set_find(&s, "foo") == NULL);
+END_TEST
+
+START_TEST(test_set_find)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "default", NULL, data);
+	fail_unless(s == t);
+	fail_unless(set_find(&s, "name") == t);
+END_TEST
+
+START_TEST(test_set_get_str_default)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "default", NULL, data);
+	fail_unless(s == t);
+	fail_unless(strcmp(set_getstr(&s, "name"), "default") == 0);
+END_TEST
+
+START_TEST(test_set_get_bool_default)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "true", NULL, data);
+	fail_unless(s == t);
+	fail_unless(set_getbool(&s, "name"));
+END_TEST
+
+START_TEST(test_set_get_bool_integer)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "3", NULL, data);
+	fail_unless(s == t);
+	fail_unless(set_getbool(&s, "name") == 3);
+END_TEST
+
+START_TEST(test_set_get_bool_unknown)
+	set_t *s = NULL;
+	fail_unless(set_getbool(&s, "name") == 0);
+END_TEST
+
+START_TEST(test_set_get_str_value)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "default", NULL, data);
+	set_setstr(&s, "name", "foo");
+	fail_unless(strcmp(set_getstr(&s, "name"), "foo") == 0);
+END_TEST
+
+START_TEST(test_set_get_str_unknown)
+	set_t *s = NULL;
+	fail_unless(set_getstr(&s, "name") == NULL);
+END_TEST
+
+START_TEST(test_setint)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "10", NULL, data);
+	set_setint(&s, "name", 3);
+	fail_unless(set_getint(&s, "name") == 3);
+END_TEST
+
+START_TEST(test_setstr)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	t = set_add(&s, "name", "foo", NULL, data);
+	set_setstr(&s, "name", "bloe");
+	fail_unless(strcmp(set_getstr(&s, "name"), "bloe") == 0);
+END_TEST
+
+START_TEST(test_setstr_implicit)
+	void *data = "data";
+	set_t *s = NULL, *t;
+	set_setstr(&s, "name", "bloe");
+	fail_unless(set_find(&s, "name") != NULL);
+END_TEST
+
+START_TEST(test_set_get_int_unknown)
+	set_t *s = NULL;
+	fail_unless(set_getint(&s, "foo") == 0);
+END_TEST
+
+Suite *set_suite (void)
+{
+	Suite *s = suite_create("Set");
+	TCase *tc_core = tcase_create("Core");
+	suite_add_tcase (s, tc_core);
+	tcase_add_test (tc_core, test_set_add);
+	tcase_add_test (tc_core, test_set_add_existing);
+	tcase_add_test (tc_core, test_set_find_unknown);
+	tcase_add_test (tc_core, test_set_find);
+	tcase_add_test (tc_core, test_set_get_str_default);
+	tcase_add_test (tc_core, test_set_get_str_value);
+	tcase_add_test (tc_core, test_set_get_str_unknown);
+	tcase_add_test (tc_core, test_set_get_bool_default);
+	tcase_add_test (tc_core, test_set_get_bool_integer);
+	tcase_add_test (tc_core, test_set_get_bool_unknown);
+	tcase_add_test (tc_core, test_set_get_int_unknown);
+	tcase_add_test (tc_core, test_setint);
+	tcase_add_test (tc_core, test_setstr);
+	tcase_add_test (tc_core, test_setstr_implicit);
+	return s;
+}
Index: tests/check_user.c
===================================================================
--- tests/check_user.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
+++ tests/check_user.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -0,0 +1,75 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <check.h>
+#include <string.h>
+#include "bitlbee.h"
+#include "user.h"
+#include "testsuite.h"
+
+START_TEST(test_user_add)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_if(user == NULL);
+	fail_if(strcmp(user->nick, "foo") != 0);
+	fail_unless(user_find(irc, "foo") == user);
+END_TEST
+
+START_TEST(test_user_add_exists)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_if(user == NULL);
+	user = user_add(irc, "foo");
+	fail_unless(user == NULL);
+END_TEST
+
+START_TEST(test_user_add_invalid)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, ":foo");
+	fail_unless(user == NULL);
+END_TEST
+
+START_TEST(test_user_del_invalid)
+	irc_t *irc = torture_irc();
+	fail_unless(user_del(irc, ":foo") == 0);
+END_TEST
+
+START_TEST(test_user_del)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	fail_unless(user_del(irc, "foo") == 1);
+	fail_unless(user_find(irc, "foo") == NULL);
+END_TEST
+
+START_TEST(test_user_del_nonexistant)
+	irc_t *irc = torture_irc();
+	fail_unless(user_del(irc, "foo") == 0);
+END_TEST
+
+START_TEST(test_user_rename)
+	irc_t *irc = torture_irc();
+	user_t *user;
+	user = user_add(irc, "foo");
+	user_rename(irc, "foo", "bar");
+	fail_unless(user_find(irc, "foo") == NULL);
+	fail_if(user_find(irc, "bar") == NULL);
+END_TEST
+
+Suite *user_suite (void)
+{
+	Suite *s = suite_create("User");
+	TCase *tc_core = tcase_create("Core");
+	suite_add_tcase (s, tc_core);
+	tcase_add_test (tc_core, test_user_add);
+	tcase_add_test (tc_core, test_user_add_invalid);
+	tcase_add_test (tc_core, test_user_add_exists);
+	tcase_add_test (tc_core, test_user_del_invalid);
+	tcase_add_test (tc_core, test_user_del_nonexistant);
+	tcase_add_test (tc_core, test_user_del);
+	tcase_add_test (tc_core, test_user_rename);
+	return s;
+}
Index: tests/check_util.c
===================================================================
--- tests/check_util.c	(revision dcf0f3e77ffd38ce3cc5d3c1eedfc655ff75a8f9)
+++ tests/check_util.c	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -7,4 +7,5 @@
 #include "set.h"
 #include "misc.h"
+#include "url.h"
 
 START_TEST(test_strip_linefeed)
@@ -43,4 +44,64 @@
 END_TEST
 
+START_TEST(test_set_url_http)
+	url_t url;
+	
+	fail_if (0 == url_set(&url, "http://host/"));
+	fail_unless (!strcmp(url.host, "host"));
+	fail_unless (!strcmp(url.file, "/"));
+	fail_unless (!strcmp(url.user, ""));
+	fail_unless (!strcmp(url.pass, ""));
+	fail_unless (url.proto == PROTO_HTTP);
+	fail_unless (url.port == 80);
+END_TEST
+
+START_TEST(test_set_url_https)
+	url_t url;
+	
+	fail_if (0 == url_set(&url, "https://ahost/AimeeMann"));
+	fail_unless (!strcmp(url.host, "ahost"));
+	fail_unless (!strcmp(url.file, "/AimeeMann"));
+	fail_unless (!strcmp(url.user, ""));
+	fail_unless (!strcmp(url.pass, ""));
+	fail_unless (url.proto == PROTO_HTTPS);
+	fail_unless (url.port == 443);
+END_TEST
+
+START_TEST(test_set_url_port)
+	url_t url;
+	
+	fail_if (0 == url_set(&url, "https://ahost:200/Lost/In/Space"));
+	fail_unless (!strcmp(url.host, "ahost"));
+	fail_unless (!strcmp(url.file, "/Lost/In/Space"));
+	fail_unless (!strcmp(url.user, ""));
+	fail_unless (!strcmp(url.pass, ""));
+	fail_unless (url.proto == PROTO_HTTPS);
+	fail_unless (url.port == 200);
+END_TEST
+
+START_TEST(test_set_url_username)
+	url_t url;
+	
+	fail_if (0 == url_set(&url, "socks4://user@ahost/Space"));
+	fail_unless (!strcmp(url.host, "ahost"));
+	fail_unless (!strcmp(url.file, "/Space"));
+	fail_unless (!strcmp(url.user, "user"));
+	fail_unless (!strcmp(url.pass, ""));
+	fail_unless (url.proto == PROTO_SOCKS4);
+	fail_unless (url.port == 1080);
+END_TEST
+
+START_TEST(test_set_url_username_pwd)
+	url_t url;
+	
+	fail_if (0 == url_set(&url, "socks5://user:pass@ahost/"));
+	fail_unless (!strcmp(url.host, "ahost"));
+	fail_unless (!strcmp(url.file, "/"));
+	fail_unless (!strcmp(url.user, "user"));
+	fail_unless (!strcmp(url.pass, "pass"));
+	fail_unless (url.proto == PROTO_SOCKS5);
+	fail_unless (url.port == 1080);
+END_TEST
+
 Suite *util_suite (void)
 {
@@ -50,4 +111,9 @@
 	tcase_add_test (tc_core, test_strip_linefeed);
 	tcase_add_test (tc_core, test_strip_newlines);
+	tcase_add_test (tc_core, test_set_url_http);
+	tcase_add_test (tc_core, test_set_url_https);
+	tcase_add_test (tc_core, test_set_url_port);
+	tcase_add_test (tc_core, test_set_url_username);
+	tcase_add_test (tc_core, test_set_url_username_pwd);
 	return s;
 }
Index: tests/testsuite.h
===================================================================
--- tests/testsuite.h	(revision dcf0f3e77ffd38ce3cc5d3c1eedfc655ff75a8f9)
+++ tests/testsuite.h	(revision 1da00b12d498951219141000947927120b2fdbcc)
@@ -2,4 +2,7 @@
 #define __BITLBEE_CHECK_H__ 
 
+#include "irc.h"
+
+irc_t *torture_irc(void);
 gboolean g_io_channel_pair(GIOChannel **ch1, GIOChannel **ch2);
 
