aboutsummaryrefslogblamecommitdiffstats
path: root/test.c
blob: 5a5017e547263772bb14510b534caee7cddfaf1b (plain) (tree)










































































































































































































































                                                                                                                   
/* See LICENSE file for copyright and license details. */
#define TEST_C
#include "common.h"
#include <assert.h> /* TODO improve output */
#include <stdarg.h>
#include <stdio.h>
#include <string.h>


static uint64_t classes_1     = (1 << 1);
static uint64_t classes_1_2   = (1 << 1) | (1 << 2);
static uint64_t classes_1_2_3 = (1 << 1) | (1 << 2) | (1 << 3);
static uint64_t classes_2     = (1 << 2);

static struct libenv_variable list[] = {
	{"a",  &classes_1},
	{"aa", &classes_1_2},
	{"BB", &classes_1_2_3},
	{"bb", &classes_2},
	{"b",  &classes_1},
	{NULL, NULL}
};

#include "libenv_get_complete_list.c"


union list_process_function {
	size_t (*dyn)(char **, ...);
	size_t (*cnst)(const char **, ...);
};


static void
dealloc(char **strings)
{
	size_t i;
	for (i = 0; strings[i]; i++)
		free(strings[i]);
}


static void
check(size_t count, char **strings, ...)
{
	size_t i, len;
	const char *expect;
	va_list args;
	va_start(args, strings);
	for (i = 0; (expect = va_arg(args, const char *)); i++) {
		len = strlen(expect);
		assert(strings[i]);
		assert(!strncmp(strings[i], expect, len));
		assert(!strings[i][len] || strings[i][len] == '=');
	}
	va_end(args);
	assert(!strings[i]);
	assert(count == i);
}


#define CHECK(CALL, ...)\
	do {\
		char *strings[8];\
		char *allocations[8];\
		size_t i;\
		char *p;\
		assert(strings[0] = allocations[0] = strdup("a="));\
		assert(strings[1] = allocations[1] = strdup("aa=1"));\
		assert(strings[2] = allocations[2] = strdup("b=12"));\
		assert(strings[3] = allocations[3] = strdup("bb=34"));\
		assert(strings[4] = allocations[4] = strdup("BB"));\
		assert(strings[5] = allocations[5] = strdup("x=5"));\
		assert(strings[6] = allocations[6] = strdup("xx"));\
		strings[7] = allocations[7] = NULL;\
		if (!variable_version) {\
			for (i = 0; strings[i]; i++) {\
				for (p = strings[i]; *p && *p != '='; p++);\
				*p = '\0';\
			}\
		}\
		check(CALL, strings, __VA_ARGS__);\
		dealloc(dealloc_version ? strings : allocations);\
	} while (0)


static void
test_filter(int dealloc_version, int variable_version, const union list_process_function *function)
{
	CHECK((*function->dyn)(strings, LIBENV_END), NULL); /* each contain all of nothing, so remove all */
	if (!variable_version) {
		CHECK((*function->dyn)(strings, 3, LIBENV_END), "a", "aa", "b", "bb", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 2, LIBENV_END), "a", "b", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 1, 2, 3, LIBENV_END), "a", "aa", "b", "bb", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 1, 2, LIBENV_END), "a", "b", "bb", "x", "xx", NULL);
	} else {
		CHECK((*function->dyn)(strings, 3, LIBENV_END), "a", "aa", "b", "bb", "BB", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 2, LIBENV_END), "a", "b", "BB", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 1, 2, 3, LIBENV_END), "a", "aa", "b", "bb", "BB", "x", "xx", NULL);
		CHECK((*function->dyn)(strings, 1, 2, LIBENV_END), "a", "b", "bb", "BB", "x", "xx", NULL);
	}
	CHECK((*function->dyn)(strings, 10, LIBENV_END), "a", "aa", "b", "bb", "BB", "x", "xx", NULL);
	CHECK((*function->dyn)(strings, 64, LIBENV_END), "a", "aa", "b", "bb", "BB", "x", "xx", NULL);
	CHECK((*function->dyn)(strings, 100000, LIBENV_END), "a", "aa", "b", "bb", "BB", "x", "xx", NULL);
}


static void
test_select(int dealloc_version, int variable_version, const union list_process_function *function)
{
	const char *BB = variable_version ? NULL : "BB";
	CHECK((*function->dyn)(strings, LIBENV_END), NULL); /* none contain any of nothing, so select all */
	CHECK((*function->dyn)(strings, 3, LIBENV_END), BB, NULL);
	CHECK((*function->dyn)(strings, 2, LIBENV_END), "aa", "bb", BB, NULL);
	CHECK((*function->dyn)(strings, 1, 2, 3, LIBENV_END), "a", "aa", "b", "bb", BB, NULL);
	CHECK((*function->dyn)(strings, 1, 2, LIBENV_END), "a", "aa", "b", "bb", BB, NULL);
	CHECK((*function->dyn)(strings, 1, 3, LIBENV_END), "a", "aa", "b", BB, NULL);
	CHECK((*function->dyn)(strings, 10, LIBENV_END), NULL);
	CHECK((*function->dyn)(strings, 64, LIBENV_END), NULL);
	CHECK((*function->dyn)(strings, 100000, LIBENV_END), NULL);
}


#undef CHECK


static void
test_get_chosen_list(void) /* TODO check memory failure behaviour */
{
	const char **r;

	assert(r = libenv_get_chosen_list(LIBENV_END));
	assert(!r[0]);
	free(r);

	assert(r = libenv_get_chosen_list(1, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "a"));
	assert(r[1] && !strcmp(r[1], "aa"));
	assert(r[2] && !strcmp(r[2], "BB"));
	assert(r[3] && !strcmp(r[3], "b"));
	assert(!r[4]);
	free(r);

	assert(r = libenv_get_chosen_list(2, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "aa"));
	assert(r[1] && !strcmp(r[1], "BB"));
	assert(r[2] && !strcmp(r[2], "bb"));
	assert(!r[3]);
	free(r);

	assert(r = libenv_get_chosen_list(3, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "BB"));
	assert(!r[1]);
	free(r);

	assert(r = libenv_get_chosen_list(1, 2, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "a"));
	assert(r[1] && !strcmp(r[1], "aa"));
	assert(r[2] && !strcmp(r[2], "BB"));
	assert(r[3] && !strcmp(r[3], "bb"));
	assert(r[4] && !strcmp(r[4], "b"));
	assert(!r[5]);
	free(r);

	assert(r = libenv_get_chosen_list(2, 3, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "aa"));
	assert(r[1] && !strcmp(r[1], "BB"));
	assert(r[2] && !strcmp(r[2], "bb"));
	assert(!r[3]);
	free(r);

	assert(r = libenv_get_chosen_list(3, 1, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "a"));
	assert(r[1] && !strcmp(r[1], "aa"));
	assert(r[2] && !strcmp(r[2], "BB"));
	assert(r[3] && !strcmp(r[3], "b"));
	assert(!r[4]);
	free(r);

	assert(r = libenv_get_chosen_list(1, 2, 3, LIBENV_END));
	assert(r[0] && !strcmp(r[0], "a"));
	assert(r[1] && !strcmp(r[1], "aa"));
	assert(r[2] && !strcmp(r[2], "BB"));
	assert(r[3] && !strcmp(r[3], "bb"));
	assert(r[4] && !strcmp(r[4], "b"));
	assert(!r[5]);
	free(r);

	assert(r = libenv_get_chosen_list(10, LIBENV_END));
	assert(!r[0]);
	free(r);

	assert(r = libenv_get_chosen_list(64, LIBENV_END));
	assert(!r[0]);
	free(r);

	assert(r = libenv_get_chosen_list(1000, LIBENV_END));
	assert(!r[0]);
	free(r);
}


int
main(void)
{
	union list_process_function f;

	f.cnst = &libenv_filter_name_list;
	test_filter(0, 0, &f);

	f.dyn = &libenv_filter_name_list_with_dealloc;
	test_filter(1, 0, &f);

	f.cnst = &libenv_filter_variable_list;
	test_filter(0, 1, &f);

	f.dyn = &libenv_filter_variable_list_with_dealloc;
	test_filter(1, 1, &f);

	f.cnst = &libenv_select_name_list;
	test_select(0, 0, &f);

	f.dyn = &libenv_select_name_list_with_dealloc;
	test_select(1, 0, &f);

	f.cnst = &libenv_select_variable_list;
	test_select(0, 1, &f);

	f.dyn = &libenv_select_variable_list_with_dealloc;
	test_select(1, 1, &f);

	test_get_chosen_list();

	/* TODO check for memory leaks */
	return 0;
}