diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | test.c | 606 | 
2 files changed, 601 insertions, 7 deletions
| @@ -71,7 +71,7 @@ test: test.o libcontacts.a  check: test  	@rm -rf -- .testdir -	./test +	$(CHECK_PREFIX) ./test  	@rm -rf -- .testdir  install: libcontacts.a libcontacts.$(LIBEXT) @@ -1,5 +1,6 @@  /* See LICENSE file for copyright and license details. */  #include "common.h" +#include <stdarg.h>  #define TEST(EXPR)\ @@ -28,6 +29,14 @@ strpcmp(const void *av, const void *bv)  	return strcmp(*a, *b);  } +static int +contactidcmp(const void *av, const void *bv) +{ +	const struct libcontacts_contact *const *a = av; +	const struct libcontacts_contact *const *b = bv; +	return strcmp((*a)->id, (*b)->id); +} +  static size_t  sort_contact_ids(char **ids)  { @@ -37,6 +46,15 @@ sort_contact_ids(char **ids)  	return n;  } +static size_t +sort_contacts_by_id(struct libcontacts_contact **contacts) +{ +	size_t n; +	for (n = 0; contacts[n]; n++); +	qsort(contacts, n, sizeof(*contacts), contactidcmp); +	return n; +} +  static void  free_contact_ids(char **ids)  { @@ -46,10 +64,52 @@ free_contact_ids(char **ids)  	free(ids);  } +static char * +estrdup(const char *s) +{ +	char *ret; +	TEST((ret = strdup(s))); +	return ret; +} + +static char ** +dupstrlist(const char *s, ...) +{ +	va_list ap; +	size_t n = 0, i = 0; +	char **ret; +	if (s) { +		va_start(ap, s); +		n += 1; +		while (va_arg(ap, const char *)) +			n += 1; +		va_end(ap); +	} +	TEST((ret = calloc(n + 1, sizeof(*ret)))); +	if (s) { +		ret[i++] = estrdup(s); +		va_start(ap, s); +		while ((s = va_arg(ap, const char *))) +			ret[i++] = estrdup(s); +		va_end(ap); +	} +	ret[i] = NULL; +	return ret; +} + +static void * +ecalloc(size_t n, size_t m) +{ +	char *ret; +	TEST((ret = calloc(n, m))); +	return ret; +} +  int  main(void)  { +	struct libcontacts_contact contact, **contacts;  	struct passwd user;  	char *s, **ids; @@ -94,12 +154,546 @@ main(void)  	free_contact_ids(ids);  	/* TODO test error cases */ -	/* TODO test libcontacts_parse_contact */ -	/* TODO test libcontacts_load_contact */ -	/* TODO test libcontacts_load_contacts */ -	/* TODO test libcontacts_format_contact */ -	/* TODO test libcontacts_save_contact */ -	/* TODO test libcontacts_contact_destroy */ +	contact.id = estrdup("alpha"); +	contact.name = estrdup("name"); +	contact.first_name = estrdup("first name"); +	contact.last_name = estrdup("last name"); +	contact.full_name = estrdup("full name"); +	contact.nickname = estrdup("nickname"); +	contact.photos = dupstrlist("photo 1", "photo 2", "photo 3", NULL); +	contact.groups = dupstrlist("group 1", "group 2", NULL); +	contact.notes = estrdup("line1\nline2\nline3\n"); +	contact.blocks = NULL; +	contact.organisations = NULL; +	contact.emails = NULL; +	contact.pgpkeys = NULL; +	contact.numbers = NULL; +	contact.addresses = NULL; +	contact.sites = NULL; +	contact.chats = NULL; +	contact.birthday = NULL; +	contact.in_case_of_emergency = 1; +	contact.gender = LIBCONTACTS_UNSPECIFIED_GENDER; +	contact.unrecognised_data = dupstrlist("X-1 x", "X-2", NULL); +	TEST(!libcontacts_save_contact(&contact, &user)); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("beta", &contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "beta")); +	TEST(!contact.name); +	TEST(!contact.first_name); +	TEST(!contact.last_name); +	TEST(!contact.full_name); +	TEST(!contact.nickname); +	TEST(!contact.photos); +	TEST(!contact.groups); +	TEST(!contact.notes); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(!contact.chats); +	TEST(!contact.birthday); +	TEST(!contact.in_case_of_emergency); +	TEST(!contact.gender); +	TEST(contact.gender == LIBCONTACTS_UNSPECIFIED_GENDER); +	TEST(!contact.unrecognised_data); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("alpha", &contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "alpha")); +	TEST(contact.name && !strcmp(contact.name, "name")); +	TEST(contact.first_name && !strcmp(contact.first_name, "first name")); +	TEST(contact.last_name && !strcmp(contact.last_name, "last name")); +	TEST(contact.full_name && !strcmp(contact.full_name, "full name")); +	TEST(contact.nickname && !strcmp(contact.nickname, "nickname")); +	TEST(contact.photos); +	TEST(contact.photos[0] && !strcmp(contact.photos[0], "photo 1")); +	TEST(contact.photos[1] && !strcmp(contact.photos[1], "photo 2")); +	TEST(contact.photos[2] && !strcmp(contact.photos[2], "photo 3")); +	TEST(!contact.photos[3]); +	TEST(contact.groups); +	TEST(contact.groups[0] && !strcmp(contact.groups[0], "group 1")); +	TEST(contact.groups[1] && !strcmp(contact.groups[1], "group 2")); +	TEST(!contact.groups[2]); +	TEST(contact.notes && !strcmp(contact.notes, "line1\nline2\nline3\n")); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(!contact.chats); +	TEST(!contact.birthday); +	TEST(contact.in_case_of_emergency == 1); +	TEST(contact.gender == LIBCONTACTS_UNSPECIFIED_GENDER); +	TEST(contact.unrecognised_data); +	TEST(contact.unrecognised_data[0] && !strcmp(contact.unrecognised_data[0], "X-1 x")); +	TEST(contact.unrecognised_data[1] && !strcmp(contact.unrecognised_data[1], "X-2")); +	TEST(!contact.unrecognised_data[2]); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.id = estrdup("alpha"); +	contact.photos = ecalloc(1, sizeof(*contact.photos)); +	contact.groups = ecalloc(1, sizeof(*contact.groups)); +	contact.notes = estrdup("line1\nline2\nline3"); +	contact.blocks = ecalloc(1, sizeof(*contact.blocks)); +	contact.organisations = ecalloc(1, sizeof(*contact.organisations)); +	contact.emails = ecalloc(1, sizeof(*contact.emails)); +	contact.pgpkeys = ecalloc(1, sizeof(*contact.pgpkeys)); +	contact.numbers = ecalloc(1, sizeof(*contact.numbers)); +	contact.addresses = ecalloc(1, sizeof(*contact.addresses)); +	contact.sites = ecalloc(1, sizeof(*contact.sites)); +	contact.chats = ecalloc(1, sizeof(*contact.chats)); +	contact.birthday = ecalloc(1, sizeof(*contact.birthday)); +	contact.birthday->year = 1990; +	contact.gender = LIBCONTACTS_NOT_A_PERSON; +	contact.unrecognised_data = ecalloc(1, sizeof(*contact.unrecognised_data)); +	TEST(!libcontacts_save_contact(&contact, &user)); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("alpha", &contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "alpha")); +	TEST(!contact.first_name); +	TEST(!contact.last_name); +	TEST(!contact.full_name); +	TEST(!contact.nickname); +	TEST(!contact.photos); +	TEST(!contact.groups); +	TEST(contact.notes && !strcmp(contact.notes,"line1\nline2\nline3\n")); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(!contact.chats); +	TEST(contact.birthday); +	TEST(contact.birthday->year == 1990); +	TEST(!contact.birthday->month); +	TEST(!contact.birthday->day); +	TEST(!contact.birthday->before_on_common); +	TEST(!contact.birthday->unrecognised_data); +	TEST(contact.gender == LIBCONTACTS_NOT_A_PERSON); +	TEST(!contact.unrecognised_data); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.id = estrdup("alpha"); +	contact.organisations = ecalloc(3, sizeof(*contact.organisations)); +	contact.organisations[0] = ecalloc(1, sizeof(**contact.organisations)); +	contact.organisations[0]->organisation = estrdup("org"); +	contact.organisations[1] = ecalloc(1, sizeof(**contact.organisations)); +	contact.organisations[1]->title = estrdup("title"); +	contact.organisations[1]->unrecognised_data = dupstrlist("X-1", "X-2", NULL); +	contact.pgpkeys = ecalloc(3, sizeof(*contact.pgpkeys)); +	contact.pgpkeys[0] = ecalloc(1, sizeof(**contact.pgpkeys)); +	contact.pgpkeys[0]->id = estrdup("fingerprint"); +	contact.pgpkeys[1] = ecalloc(1, sizeof(**contact.pgpkeys)); +	contact.pgpkeys[1]->context = estrdup("ctx"); +	contact.pgpkeys[1]->unrecognised_data = dupstrlist("X1", "X2", NULL); +	contact.birthday = ecalloc(1, sizeof(*contact.birthday)); +	contact.birthday->month = 2; +	contact.birthday->day = 23; +	contact.birthday->before_on_common = 1; +	contact.gender = LIBCONTACTS_FEMALE; +	TEST(!libcontacts_save_contact(&contact, &user)); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("alpha", &contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "alpha")); +	TEST(!contact.first_name); +	TEST(!contact.last_name); +	TEST(!contact.full_name); +	TEST(!contact.nickname); +	TEST(!contact.photos); +	TEST(!contact.groups); +	TEST(!contact.notes); +	TEST(!contact.blocks); +	TEST(contact.organisations); +	TEST(contact.organisations[0]); +	TEST(contact.organisations[0]->organisation && !strcmp(contact.organisations[0]->organisation, "org")); +	TEST(!contact.organisations[0]->title); +	TEST(!contact.organisations[0]->unrecognised_data); +	TEST(contact.organisations[1]); +	TEST(!contact.organisations[1]->organisation); +	TEST(contact.organisations[1]->title && !strcmp(contact.organisations[1]->title, "title")); +	TEST(contact.organisations[1]->unrecognised_data); +	TEST(contact.organisations[1]->unrecognised_data[0] && !strcmp(contact.organisations[1]->unrecognised_data[0], "X-1")); +	TEST(contact.organisations[1]->unrecognised_data[1] && !strcmp(contact.organisations[1]->unrecognised_data[1], "X-2")); +	TEST(!contact.organisations[1]->unrecognised_data[2]); +	TEST(!contact.organisations[2]); +	TEST(!contact.emails); +	TEST(contact.pgpkeys); +	TEST(contact.pgpkeys[0]); +	TEST(!contact.pgpkeys[0]->context); +	TEST(contact.pgpkeys[0]->id && !strcmp(contact.pgpkeys[0]->id, "fingerprint")); +	TEST(!contact.pgpkeys[0]->unrecognised_data); +	TEST(contact.pgpkeys[1]); +	TEST(contact.pgpkeys[1]->context && !strcmp(contact.pgpkeys[1]->context, "ctx")); +	TEST(!contact.pgpkeys[1]->id); +	TEST(contact.pgpkeys[1]->unrecognised_data); +	TEST(contact.pgpkeys[1]->unrecognised_data[0] && !strcmp(contact.pgpkeys[1]->unrecognised_data[0], "X1")); +	TEST(contact.pgpkeys[1]->unrecognised_data[1] && !strcmp(contact.pgpkeys[1]->unrecognised_data[1], "X2")); +	TEST(!contact.pgpkeys[1]->unrecognised_data[2]); +	TEST(!contact.pgpkeys[2]); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(!contact.chats); +	TEST(contact.birthday); +	TEST(!contact.birthday->year); +	TEST(contact.birthday->month == 2); +	TEST(contact.birthday->day == 23); +	TEST(contact.birthday->before_on_common == 1); +	TEST(!contact.birthday->unrecognised_data); +	TEST(contact.gender == LIBCONTACTS_FEMALE); +	TEST(!contact.unrecognised_data); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.id = estrdup("alpha"); +	contact.emails = ecalloc(3, sizeof(*contact.emails)); +	contact.emails[0] = ecalloc(1, sizeof(**contact.emails)); +	contact.emails[0]->context = estrdup("con"); +	contact.emails[0]->unrecognised_data = dupstrlist("X-1", "X-2", NULL); +	contact.emails[1] = ecalloc(1, sizeof(**contact.emails)); +	contact.emails[1]->address = estrdup("addr"); +	contact.chats = ecalloc(3, sizeof(*contact.chats)); +	contact.chats[0] = ecalloc(1, sizeof(**contact.chats)); +	contact.chats[0]->address = estrdup("a"); +	contact.chats[0]->service = estrdup("s"); +	contact.chats[1] = ecalloc(1, sizeof(**contact.chats)); +	contact.chats[1]->context = estrdup("c"); +	contact.chats[1]->unrecognised_data = dupstrlist("X1", "X2", NULL); +	TEST(!libcontacts_save_contact(&contact, &user)); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("alpha", &contact, &user)); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(contact.emails); +	TEST(contact.emails[0]); +	TEST(contact.emails[0]->context && !strcmp(contact.emails[0]->context, "con")); +	TEST(!contact.emails[0]->address); +	TEST(contact.emails[0]->unrecognised_data); +	TEST(contact.emails[0]->unrecognised_data[0] && !strcmp(contact.emails[0]->unrecognised_data[0], "X-1")); +	TEST(contact.emails[0]->unrecognised_data[1] && !strcmp(contact.emails[0]->unrecognised_data[1], "X-2")); +	TEST(!contact.emails[0]->unrecognised_data[2]); +	TEST(contact.emails[1]); +	TEST(!contact.emails[1]->context); +	TEST(contact.emails[1]->address && !strcmp(contact.emails[1]->address, "addr")); +	TEST(!contact.emails[1]->unrecognised_data); +	TEST(!contact.emails[2]); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(contact.chats); +	TEST(contact.chats[0]); +	TEST(!contact.chats[0]->context); +	TEST(contact.chats[0]->service && !strcmp(contact.chats[0]->service, "s")); +	TEST(contact.chats[0]->address && !strcmp(contact.chats[0]->address, "a")); +	TEST(!contact.chats[0]->unrecognised_data); +	TEST(contact.chats[1]); +	TEST(contact.chats[1]->context && !strcmp(contact.chats[1]->context, "c")); +	TEST(!contact.chats[1]->service); +	TEST(!contact.chats[1]->address); +	TEST(contact.chats[1]->unrecognised_data); +	TEST(contact.chats[1]->unrecognised_data[0] && !strcmp(contact.chats[1]->unrecognised_data[0], "X1")); +	TEST(contact.chats[1]->unrecognised_data[1] && !strcmp(contact.chats[1]->unrecognised_data[1], "X2")); +	TEST(!contact.chats[1]->unrecognised_data[2]); +	TEST(!contact.chats[2]); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.numbers = ecalloc(5, sizeof(*contact.numbers)); +	contact.numbers[0] = ecalloc(1, sizeof(**contact.numbers)); +	contact.numbers[0]->context = estrdup("context"); +	contact.numbers[0]->number = estrdup("number"); +	contact.numbers[0]->unrecognised_data = dupstrlist(NULL); +	contact.numbers[1] = ecalloc(1, sizeof(**contact.numbers)); +	contact.numbers[1]->is_mobile = 1; +	contact.numbers[1]->unrecognised_data = dupstrlist("X-1", "X-2", NULL); +	contact.numbers[2] = ecalloc(1, sizeof(**contact.numbers)); +	contact.numbers[2]->context = estrdup("ctx"); +	contact.numbers[2]->is_facsimile = 1; +	contact.numbers[3] = ecalloc(1, sizeof(**contact.numbers)); +	contact.numbers[3]->number = estrdup("num"); +	contact.numbers[3]->is_mobile = 2; +	contact.numbers[3]->is_facsimile = 2; +	contact.sites = ecalloc(3, sizeof(*contact.sites)); +	contact.sites[0] = ecalloc(1, sizeof(**contact.sites)); +	contact.sites[0]->context = estrdup("context"); +	contact.sites[0]->address = estrdup("address"); +	contact.sites[1] = ecalloc(1, sizeof(**contact.sites)); +	contact.sites[1]->unrecognised_data = dupstrlist("X1", "X2", NULL); +	TEST(!libcontacts_save_contact(&contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "unnamed")); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("unnamed", &contact, &user)); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(contact.numbers); +	TEST(contact.numbers[0]); +	TEST(contact.numbers[0]->context && !strcmp(contact.numbers[0]->context, "context")); +	TEST(contact.numbers[0]->number && !strcmp(contact.numbers[0]->number, "number")); +	TEST(!contact.numbers[0]->is_mobile); +	TEST(!contact.numbers[0]->is_facsimile); +	TEST(!contact.numbers[0]->unrecognised_data); +	TEST(contact.numbers[1]); +	TEST(!contact.numbers[1]->context); +	TEST(!contact.numbers[1]->number); +	TEST(contact.numbers[1]->is_mobile); +	TEST(!contact.numbers[1]->is_facsimile); +	TEST(contact.numbers[1]->unrecognised_data); +	TEST(contact.numbers[1]->unrecognised_data[0] && !strcmp(contact.numbers[1]->unrecognised_data[0], "X-1")); +	TEST(contact.numbers[1]->unrecognised_data[1] && !strcmp(contact.numbers[1]->unrecognised_data[1], "X-2")); +	TEST(!contact.numbers[1]->unrecognised_data[2]); +	TEST(contact.numbers[2]); +	TEST(contact.numbers[2]->context && !strcmp(contact.numbers[2]->context, "ctx")); +	TEST(!contact.numbers[2]->number); +	TEST(!contact.numbers[2]->is_mobile); +	TEST(contact.numbers[2]->is_facsimile); +	TEST(!contact.numbers[2]->unrecognised_data); +	TEST(contact.numbers[3]); +	TEST(!contact.numbers[3]->context); +	TEST(contact.numbers[3]->number && !strcmp(contact.numbers[3]->number, "num")); +	TEST(!contact.numbers[3]->unrecognised_data); +	TEST(contact.numbers[3]->is_mobile); +	TEST(contact.numbers[3]->is_facsimile); +	TEST(!contact.numbers[4]); +	TEST(!contact.addresses); +	TEST(contact.sites); +	TEST(contact.sites[0]); +	TEST(contact.sites[0]->context && !strcmp(contact.sites[0]->context, "context")); +	TEST(contact.sites[0]->address && !strcmp(contact.sites[0]->address, "address")); +	TEST(!contact.sites[0]->unrecognised_data); +	TEST(contact.sites[1]); +	TEST(!contact.sites[1]->context); +	TEST(!contact.sites[1]->address); +	TEST(contact.sites[1]->unrecognised_data); +	TEST(contact.sites[1]->unrecognised_data[0] && !strcmp(contact.sites[1]->unrecognised_data[0], "X1")); +	TEST(contact.sites[1]->unrecognised_data[1] && !strcmp(contact.sites[1]->unrecognised_data[1], "X2")); +	TEST(!contact.sites[1]->unrecognised_data[2]); +	TEST(!contact.sites[2]); +	TEST(!contact.chats); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.addresses = ecalloc(5, sizeof(*contact.addresses)); +	contact.addresses[0] = ecalloc(1, sizeof(**contact.addresses)); +	contact.addresses[0]->context = estrdup("context"); +	contact.addresses[0]->city = estrdup("city"); +	contact.addresses[1] = ecalloc(1, sizeof(**contact.addresses)); +	contact.addresses[1]->address = estrdup("address"); +	contact.addresses[1]->country = estrdup("Sweden"); +	contact.addresses[2] = ecalloc(1, sizeof(**contact.addresses)); +	contact.addresses[2]->postcode = estrdup("11111"); +	contact.addresses[3] = ecalloc(1, sizeof(**contact.addresses)); +	contact.addresses[3]->have_coordinates = 1; +	contact.addresses[3]->latitude = 20.11; +	contact.addresses[3]->longitude = -13.32; +	contact.addresses[3]->unrecognised_data = dupstrlist("X-1", "X-2", NULL); +	TEST(!libcontacts_save_contact(&contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "unnamed-1")); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("unnamed-1", &contact, &user)); +	TEST(!contact.blocks); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(contact.addresses); +	TEST(contact.addresses[0]); +	TEST(contact.addresses[0]->context && !strcmp(contact.addresses[0]->context, "context")); +	TEST(!contact.addresses[0]->address); +	TEST(!contact.addresses[0]->postcode); +	TEST(contact.addresses[0]->city && !strcmp(contact.addresses[0]->city, "city")); +	TEST(!contact.addresses[0]->country); +	TEST(!contact.addresses[0]->have_coordinates); +	TEST(!contact.addresses[0]->unrecognised_data); +	TEST(contact.addresses[1]); +	TEST(!contact.addresses[1]->context); +	TEST(contact.addresses[1]->address && !strcmp(contact.addresses[1]->address, "address")); +	TEST(!contact.addresses[1]->postcode); +	TEST(!contact.addresses[1]->city); +	TEST(contact.addresses[1]->country && !strcmp(contact.addresses[1]->country, "Sweden")); +	TEST(!contact.addresses[1]->have_coordinates); +	TEST(!contact.addresses[1]->unrecognised_data); +	TEST(contact.addresses[2]); +	TEST(!contact.addresses[2]->context); +	TEST(!contact.addresses[2]->address); +	TEST(contact.addresses[2]->postcode && !strcmp(contact.addresses[2]->postcode, "11111")); +	TEST(!contact.addresses[2]->city); +	TEST(!contact.addresses[2]->country); +	TEST(!contact.addresses[2]->have_coordinates); +	TEST(!contact.addresses[2]->unrecognised_data); +	TEST(contact.addresses[3]); +	TEST(!contact.addresses[3]->context); +	TEST(!contact.addresses[3]->address); +	TEST(!contact.addresses[3]->postcode); +	TEST(!contact.addresses[3]->city); +	TEST(!contact.addresses[3]->country); +	TEST(contact.addresses[3]->have_coordinates); +	TEST(20.11 - 0.000001 <= contact.addresses[3]->latitude && contact.addresses[3]->latitude <= 20.11 + 0.000001); +	TEST(-13.32 - 0.000001 <= contact.addresses[3]->longitude && contact.addresses[3]->longitude <= -13.32 + 0.000001); +	TEST(contact.addresses[3]->unrecognised_data); +	TEST(contact.addresses[3]->unrecognised_data[0] && !strcmp(contact.addresses[3]->unrecognised_data[0], "X-1")); +	TEST(contact.addresses[3]->unrecognised_data[1] && !strcmp(contact.addresses[3]->unrecognised_data[1], "X-2")); +	TEST(!contact.addresses[3]->unrecognised_data[2]); +	TEST(!contact.addresses[4]); +	TEST(!contact.sites); +	TEST(!contact.chats); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	contact.blocks = ecalloc(6, sizeof(*contact.blocks)); +	contact.blocks[0] = ecalloc(1, sizeof(**contact.blocks)); +	contact.blocks[0]->service = estrdup("service"); +	contact.blocks[1] = ecalloc(1, sizeof(**contact.blocks)); +	contact.blocks[1]->service = estrdup("srv"); +	contact.blocks[1]->explicit = 1; +	contact.blocks[1]->shadow_block = LIBCONTACTS_BLOCK_OFF; +	contact.blocks[1]->soft_unblock = 8; +	contact.blocks[2] = ecalloc(1, sizeof(**contact.blocks)); +	contact.blocks[2]->explicit = 2; +	contact.blocks[2]->shadow_block = LIBCONTACTS_BLOCK_BUSY; +	contact.blocks[2]->hard_unblock = 9; +	contact.blocks[3] = ecalloc(1, sizeof(**contact.blocks)); +	contact.blocks[3]->shadow_block = LIBCONTACTS_BLOCK_IGNORE; +	contact.blocks[3]->soft_unblock = 10; +	contact.blocks[3]->hard_unblock = 11; +	contact.blocks[4] = ecalloc(1, sizeof(**contact.blocks)); +	contact.blocks[4]->unrecognised_data = dupstrlist("X-1", "X-2", NULL); +	TEST(!libcontacts_save_contact(&contact, &user)); +	TEST(contact.id && !strcmp(contact.id, "unnamed-2")); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contact("unnamed-2", &contact, &user)); +	TEST(contact.blocks); +	TEST(contact.blocks[0]); +	TEST(contact.blocks[0]->service && !strcmp(contact.blocks[0]->service, "service")); +	TEST(!contact.blocks[0]->explicit); +	TEST(contact.blocks[0]->shadow_block == LIBCONTACTS_SILENT); +	TEST(!contact.blocks[0]->soft_unblock); +	TEST(!contact.blocks[0]->hard_unblock); +	TEST(!contact.blocks[0]->unrecognised_data); +	TEST(contact.blocks[1]); +	TEST(contact.blocks[1]->service && !strcmp(contact.blocks[1]->service, "srv")); +	TEST(contact.blocks[1]->explicit == 1); +	TEST(contact.blocks[1]->shadow_block == LIBCONTACTS_BLOCK_OFF); +	TEST(contact.blocks[1]->soft_unblock == 8); +	TEST(!contact.blocks[1]->hard_unblock); +	TEST(!contact.blocks[1]->unrecognised_data); +	TEST(contact.blocks[2]); +	TEST(!contact.blocks[2]->service); +	TEST(contact.blocks[2]->explicit == 1); +	TEST(contact.blocks[2]->shadow_block == LIBCONTACTS_BLOCK_BUSY); +	TEST(!contact.blocks[2]->soft_unblock); +	TEST(contact.blocks[2]->hard_unblock == 9); +	TEST(!contact.blocks[2]->unrecognised_data); +	TEST(contact.blocks[3]); +	TEST(!contact.blocks[3]->service); +	TEST(!contact.blocks[3]->explicit); +	TEST(contact.blocks[3]->shadow_block == LIBCONTACTS_BLOCK_IGNORE); +	TEST(contact.blocks[3]->soft_unblock == 10); +	TEST(contact.blocks[3]->hard_unblock == 11); +	TEST(!contact.blocks[3]->unrecognised_data); +	TEST(contact.blocks[4]); +	TEST(!contact.blocks[4]->service); +	TEST(!contact.blocks[4]->explicit); +	TEST(!contact.blocks[4]->shadow_block); +	TEST(!contact.blocks[4]->soft_unblock); +	TEST(!contact.blocks[4]->hard_unblock); +	TEST(contact.blocks[4]->unrecognised_data); +	TEST(contact.blocks[4]->unrecognised_data[0] && !strcmp(contact.blocks[4]->unrecognised_data[0], "X-1")); +	TEST(contact.blocks[4]->unrecognised_data[1] && !strcmp(contact.blocks[4]->unrecognised_data[1], "X-2")); +	TEST(!contact.blocks[4]->unrecognised_data[2]); +	TEST(!contact.blocks[5]); +	TEST(!contact.organisations); +	TEST(!contact.emails); +	TEST(!contact.pgpkeys); +	TEST(!contact.numbers); +	TEST(!contact.addresses); +	TEST(!contact.sites); +	TEST(!contact.chats); +	libcontacts_contact_destroy(&contact); +	memset(&contact, 0, sizeof(contact)); + +	TEST(!libcontacts_load_contacts(&contacts, &user, 0)); +	TEST(sort_contacts_by_id(contacts) == 6); +	TEST(contacts[0] && contacts[0]->id && !strcmp(contacts[0]->id, "alpha")); +	TEST(contacts[1] && contacts[1]->id && !strcmp(contacts[1]->id, "beta")); +	TEST(contacts[2] && contacts[2]->id && !strcmp(contacts[2]->id, "gamma")); +	TEST(contacts[3] && contacts[3]->id && !strcmp(contacts[3]->id, "unnamed")); +	TEST(contacts[4] && contacts[4]->id && !strcmp(contacts[4]->id, "unnamed-1")); +	TEST(contacts[5] && contacts[5]->id && !strcmp(contacts[5]->id, "unnamed-2")); +	TEST(!contacts[6]); +	libcontacts_contact_destroy(contacts[0]); +	libcontacts_contact_destroy(contacts[1]); +	libcontacts_contact_destroy(contacts[2]); +	libcontacts_contact_destroy(contacts[3]); +	libcontacts_contact_destroy(contacts[4]); +	libcontacts_contact_destroy(contacts[5]); +	free(contacts[0]); +	free(contacts[1]); +	free(contacts[2]); +	free(contacts[3]); +	free(contacts[4]); +	free(contacts[5]); +	free(contacts); + +	TEST(!libcontacts_load_contacts(&contacts, &user, 1)); +	TEST(sort_contacts_by_id(contacts) == 7); +	TEST(contacts[0] && contacts[0]->id && !strcmp(contacts[0]->id, ".me")); +	TEST(contacts[1] && contacts[1]->id && !strcmp(contacts[1]->id, "alpha")); +	TEST(contacts[2] && contacts[2]->id && !strcmp(contacts[2]->id, "beta")); +	TEST(contacts[3] && contacts[3]->id && !strcmp(contacts[3]->id, "gamma")); +	TEST(contacts[4] && contacts[4]->id && !strcmp(contacts[4]->id, "unnamed")); +	TEST(contacts[5] && contacts[5]->id && !strcmp(contacts[5]->id, "unnamed-1")); +	TEST(contacts[6] && contacts[6]->id && !strcmp(contacts[6]->id, "unnamed-2")); +	TEST(!contacts[7]); +	libcontacts_contact_destroy(contacts[0]); +	libcontacts_contact_destroy(contacts[1]); +	libcontacts_contact_destroy(contacts[2]); +	libcontacts_contact_destroy(contacts[3]); +	libcontacts_contact_destroy(contacts[4]); +	libcontacts_contact_destroy(contacts[5]); +	libcontacts_contact_destroy(contacts[6]); +	free(contacts[0]); +	free(contacts[1]); +	free(contacts[2]); +	free(contacts[3]); +	free(contacts[4]); +	free(contacts[5]); +	free(contacts[6]); +	free(contacts); + +	/* TODO test all ways to parse ADDR:COORD */ +	/* TODO test error cases in libcontacts_parse_contact */ +	/* TODO test error cases in libcontacts_load_contact */ +	/* TODO test error cases in libcontacts_load_contacts */ +	/* TODO test error cases in libcontacts_format_contact */ +	/* TODO test error cases in libcontacts_save_contact */  	/* TODO check for memory leaks */  	/* TODO check for file descriptor leaks */ | 
