#include <u.h>
#include <libc.h>
#include "common.h"
#include "debug.h"
#include "string.h"
#include "collection.h"
#include "function.h"
#include "array.h"
#include "set.h"
#include "unittest.h"
#define DEBUG_TESTSET false
enum
{
TESTSET_START = 1,
TESTSET_END = 1000,
TESTSET_STEP = 3
};
typedef struct TestSet
{
Set *set;
int start;
int end;
int step;
Set *paths;
Array *pathstrings;
} TestSet;
static bool integer_isequal(void *a, void *b)
{
return ((int)a) == ((int)b);
}
static void *testset_setup(void)
{
int i;
TestSet *result = (TestSet *)emalloc_fs(sizeof(*result));
char *paths[] =
{
"/usr/src",
"/usr/src/fs",
"/usr/src/fs/main.c",
"/usr/src/fs/rule.c",
"/usr/src/fs/set.c",
"/usr/bin/fs",
"/home/fs",
"fs/rule.h",
"tests/testmain.h"
};
NOISE(DEBUG_TESTSET, "entering testset_setup");
result->set = set_new(integer_isequal, collection_address_hash);
result->start = TESTSET_START;
result->end = TESTSET_END;
result->step = TESTSET_STEP;
NOISE(DEBUG_TESTSET, "testset_setup about to fill in stuff");
for(i = result->start; i < result->end; i += result->step)
{
set_add(result->set, (void *)i);
}
result->pathstrings = array_new();
result->paths = set_new(string_isequal, string_hash);
for(i = 0; i < static_array_length(paths); ++i)
{
array_add(result->pathstrings, estrdup_fs(paths[i]));
set_add(result->paths, estrdup_fs(paths[i]));
}
NOISE(DEBUG_TESTSET, "leaving testset_setup");
return result;
}
static void testset_teardown(void *data)
{
TestSet *testset = (TestSet *)data;
set_free(testset->set);
array_do(testset->pathstrings, collection_free_each, nil);
array_free(testset->pathstrings);
set_do(testset->paths, collection_free_each, nil);
set_free(testset->paths);
free(testset);
}
static bool testset_add(void *data)
{
int i;
uint size;
TestSet *testset = (TestSet *)data;
assert_valid(testset);
for(i = testset->start; i < testset->end; i += testset->step)
{
test_assert(set_includes(testset->set, (void *)i));
}
for(i = testset->end; i < (testset->end + 20); ++i)
{
test_assert_false(set_includes(testset->set, (void *)i));
}
size = set_size(testset->set);
for(i = testset->start; i < testset->end; i += testset->step)
{
set_add(testset->set, (void *)i);
}
test_assert(set_size(testset->set) == size);
test_assert(set_size(testset->paths) == array_size(testset->pathstrings));
for(i = 0; i < array_size(testset->pathstrings); ++i)
{
set_includes(testset->paths, array_at(testset->pathstrings, i));
}
for(i = 0; i < array_size(testset->pathstrings); ++i)
{
set_add(testset->paths, array_at(testset->pathstrings, i));
test_assert(set_size(testset->paths) == array_size(testset->pathstrings));
}
return true;
}
static bool testset_remove(void *data)
{
int remove;
TestSet *testset = (TestSet *)data;
assert_valid(testset);
remove = testset->start;
test_assert(set_remove(testset->set, (void *)remove));
test_assert_false(set_includes(testset->set, (void *)remove));
test_assert_false(set_remove(testset->set, (void *)remove));
remove = testset->start + testset->step;
test_assert(set_includes(testset->set, (void *)remove));
test_assert(set_remove(testset->set, (void *)remove));
test_assert_false(set_includes(testset->set, (void *)remove));
test_assert_false(set_remove(testset->set, (void *)remove));
return true;
}
typedef struct TestSetDoEachData
{
bool result;
uint total;
} TestSetDoEachData;
collection_do_ret testset_do_each(void *p, void *arg)
{
int item = (int)p;
TestSetDoEachData *data = (TestSetDoEachData *)arg;
assert_valid(data);
data->result = (item % 3 == 1);
++(data->total);
return (data->result) ? COLLECTION_DO_CONTINUE : COLLECTION_DO_STOP;
}
collection_do_ret testset_do_stop_each(void *, void *arg)
{
TestSetDoEachData *data = (TestSetDoEachData *)arg;
assert_valid(data);
++(data->total);
return COLLECTION_DO_STOP;
}
static bool testset_do(void *data)
{
int size;
TestSetDoEachData doeachdata = (TestSetDoEachData) {true, 0};
TestSet *testset = (TestSet *)data;
assert_valid(testset);
size = set_size(testset->set);
set_do(testset->set, testset_do_each, &doeachdata);
test_assert(doeachdata.result);
test_assert(doeachdata.total == size);
doeachdata.total = 0;
set_do(testset->set, testset_do_stop_each, &doeachdata);
test_assert(doeachdata.total == 1);
return true;
}
static TestFixure testset_fixure =
{
.setup = testset_setup,
.teardown = testset_teardown
};
static TestCaseNamePair testset_testcases[] =
{
testcasenamepair_make(testset_add),
testcasenamepair_make(testset_remove),
testcasenamepair_make(testset_do)
};
AbstractTest *testset_testsuite(void)
{
return (AbstractTest *)
testsuite_make("testset",
testset_testcases, static_array_length(testset_testcases),
&testset_fixure);
}
|