tests: Rework much of the testing library
I move the code into a new cpp file, so it is no longer a header-only library. I also take the chance to add a for-each function for testing iterators. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
8d3010a31e
commit
6cfd0d5c51
|
@ -4,167 +4,46 @@
|
|||
#ifndef OCARINA_TESTS_TEST_H
|
||||
#define OCARINA_TESTS_TEST_H
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <string>
|
||||
|
||||
namespace test
|
||||
{
|
||||
extern unsigned int failed;
|
||||
|
||||
void run(const std::string &, void (*)());
|
||||
|
||||
static unsigned int test_num;
|
||||
static unsigned int failed;
|
||||
void equal(const int, const int, unsigned int);
|
||||
void equal(const std::string &, const std::string &, unsigned int);
|
||||
void equal(const void *, const void *, unsigned int);
|
||||
|
||||
void new_test(const std::string &name)
|
||||
{
|
||||
std::cout << name << std::endl;
|
||||
test_num = 0;
|
||||
failed = 0;
|
||||
}
|
||||
void not_equal(const int, const int, unsigned int);
|
||||
void not_equal(const std::string &, const std::string &, unsigned int);
|
||||
void not_equal(const void *, const void *, unsigned int);
|
||||
|
||||
void begin()
|
||||
{
|
||||
std::cout << " " << test_num << ": ";
|
||||
test_num++;
|
||||
}
|
||||
void for_each(unsigned int, unsigned int, unsigned int,
|
||||
unsigned int (*)(unsigned int), unsigned int);
|
||||
|
||||
void end()
|
||||
{
|
||||
std::cout << std::endl;
|
||||
if (failed > 0) {
|
||||
std::cout << failed << " tests failed =(" << std::endl;
|
||||
std::cout << std::endl;
|
||||
exit(failed);
|
||||
}
|
||||
}
|
||||
|
||||
void success()
|
||||
{
|
||||
std::cout << "Success!" << std::endl;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void failure(const T &lhs, const T &rhs, unsigned int line)
|
||||
{
|
||||
std::cout << "Failed at line " << line << ":" << std::endl;
|
||||
std::cout << " Actual: " << lhs << std::endl;
|
||||
std::cout << " Expected: " << rhs << std::endl;
|
||||
failed++;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void check_equal(const T &lhs, const T &rhs, unsigned int line)
|
||||
{
|
||||
if (lhs == rhs)
|
||||
success();
|
||||
else
|
||||
failure(lhs, rhs, line);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void check_not_equal(const T &lhs, const T &rhs, unsigned int line)
|
||||
{
|
||||
if (lhs != rhs)
|
||||
success();
|
||||
else
|
||||
failure(lhs, rhs, line);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void equal(const T &lhs, const T &rhs, unsigned int line)
|
||||
{
|
||||
begin();
|
||||
check_equal(lhs, rhs, line);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void not_equal(const T &lhs, const T &rhs, unsigned int line)
|
||||
{
|
||||
begin();
|
||||
check_not_equal(lhs, rhs, line);
|
||||
}
|
||||
|
||||
std::string data_dir()
|
||||
{
|
||||
std::string res = g_get_user_data_dir();
|
||||
res += "/ocarina-test";
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string data_file(const std::string &name)
|
||||
{
|
||||
return data_dir() + "/" + name;
|
||||
}
|
||||
|
||||
bool data_dir_exists()
|
||||
{
|
||||
return g_file_test(data_dir().c_str(), G_FILE_TEST_IS_DIR);
|
||||
}
|
||||
|
||||
bool data_file_exists(const std::string &name)
|
||||
{
|
||||
return g_file_test(data_file(name).c_str(), G_FILE_TEST_EXISTS);
|
||||
}
|
||||
|
||||
void rm_data_dir()
|
||||
{
|
||||
std::string cmd = "rm -r " + data_dir() + " 2>/dev/null";
|
||||
if (data_dir_exists())
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void reset_data_dir()
|
||||
{
|
||||
std::string cmd = "mkdir -p " + data_dir();
|
||||
rm_data_dir();
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void cp_data_dir()
|
||||
{
|
||||
reset_data_dir();
|
||||
std::string cmd = "cp -r tests/Data/* " + data_dir();
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void gen_library()
|
||||
{
|
||||
system("tests/gen_library.sh");
|
||||
}
|
||||
|
||||
void rm_library_dirs()
|
||||
{
|
||||
system("rm -r /tmp/ocarina/dir2 /tmp/ocarina/dir4");
|
||||
}
|
||||
std::string data_dir();
|
||||
std::string data_file(const std::string &name);
|
||||
bool data_dir_exists();
|
||||
bool data_file_exists(const std::string &name);
|
||||
void rm_data_dir();
|
||||
void reset_data_dir();
|
||||
void cp_data_dir();
|
||||
void gen_library();
|
||||
void rm_library_dirs();
|
||||
}
|
||||
|
||||
#define run_test(name, func, ...) \
|
||||
do { \
|
||||
test :: new_test(name); \
|
||||
func( __VA_ARGS__ ); \
|
||||
test :: end(); \
|
||||
} while (0)
|
||||
#define test_equal(lhs, rhs) \
|
||||
test :: equal(lhs, rhs, __LINE__)
|
||||
|
||||
#define test_equal(lhs, rhs) \
|
||||
do { \
|
||||
test :: equal(lhs, rhs, __LINE__); \
|
||||
} while (0)
|
||||
#define test_not_equal(lhs, rhs) \
|
||||
test :: not_equal(lhs, rhs, __LINE__)
|
||||
|
||||
#define test_not_equal(lhs, rhs) \
|
||||
do { \
|
||||
test :: not_equal(lhs, rhs, __LINE__); \
|
||||
} while (0)
|
||||
#define test_for_each(init, max, inc, func) \
|
||||
test :: for_each(init, max, inc, func, __LINE__)
|
||||
|
||||
#define check_equal(lhs, rhs) \
|
||||
do { \
|
||||
if (lhs != rhs) \
|
||||
test :: failure(lhs, rhs, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define check_not_equal(lhs, rhs) \
|
||||
do { \
|
||||
if (lhs == rhs) \
|
||||
test :: failure(lhs, rhs, __LINE__); \
|
||||
} while (0)
|
||||
#define LOOP_PASSED 0
|
||||
#define LOOP_FAILED __LINE__
|
||||
|
||||
#endif /* OCARINA_TESTS_TEST_H */
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
*-core
|
||||
*-lib
|
||||
sanity
|
||||
|
|
|
@ -26,14 +26,17 @@ def get_test_obj(name, dir):
|
|||
return test_env.Object("%s.cpp-%s" % (name, dir), src)
|
||||
return None
|
||||
|
||||
test_lib = test_env.Object("test.cpp");
|
||||
|
||||
def generic_test(name, dir, objs, extra):
|
||||
global test_obj;
|
||||
obj = get_test_obj(name, dir)
|
||||
test_objs = extra
|
||||
if obj != None:
|
||||
objs += [ obj ]
|
||||
test_objs = extra + objs
|
||||
|
||||
exe = test_env.Program(name, [ "%s.cpp" % name ] + test_objs)
|
||||
exe = test_env.Program(name, [ "%s.cpp" % name, test_lib ] + test_objs)
|
||||
test = Command("%s.fake" % name, [], "tests/%s/%s" % (dir, name))
|
||||
|
||||
Alias("tests/%s/%s" % (dir, name), test)
|
||||
|
@ -44,7 +47,15 @@ def generic_test(name, dir, objs, extra):
|
|||
|
||||
Export("get_test_obj", "generic_test")
|
||||
|
||||
test_env.UsePackage("glib-2.0")
|
||||
exe = test_env.Program("sanity", [ "sanity.cpp", test_lib ])
|
||||
test = Command("sanity.fake", [], "tests/sanity")
|
||||
Alias("tests/sanity", test)
|
||||
Depends(test, exe)
|
||||
add_test(test, "")
|
||||
|
||||
|
||||
SConscript("core/Sconscript")
|
||||
SConscript("lib/Sconscript")
|
||||
#SConscript("lib/Sconscript")
|
||||
|
||||
Return("res")
|
||||
|
|
|
@ -189,10 +189,10 @@ void test_autopause()
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
TestDriver driver;
|
||||
run_test("Test Audio Pre-Init", test_pre_init);
|
||||
run_test("Test Audio Init", test_init);
|
||||
run_test("Test Audio Playback Controls", test_playback_controls);
|
||||
run_test("Test Audio Track Controls", test_track_controls);
|
||||
run_test("Test Audio Automatic Pausing", test_autopause);
|
||||
test :: run("Test Audio Pre-Init", test_pre_init);
|
||||
test :: run("Test Audio Init", test_init);
|
||||
test :: run("Test Audio Playback Controls", test_playback_controls);
|
||||
test :: run("Test Audio Track Controls", test_track_controls);
|
||||
test :: run("Test Audio Automatic Pausing", test_autopause);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,130 +35,122 @@ public:
|
|||
static unsigned int N = 0;
|
||||
static bool AUTOSAVE = false;
|
||||
static Database<IntEntry> *DB = NULL;
|
||||
static Database<IntEntry>::iterator IT;
|
||||
static std::vector<IntEntry *> *POINTERS;
|
||||
|
||||
|
||||
static unsigned int _test_insertion_check(unsigned int i)
|
||||
{
|
||||
IntEntry *it = DB->insert(IntEntry(i));
|
||||
if ((it == NULL) || (it->index() != i) || (it->val != i))
|
||||
return LOOP_FAILED;
|
||||
POINTERS->push_back(it);
|
||||
|
||||
return (DB->insert(IntEntry(i)) == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static unsigned int _test_insertion_pointer_check(unsigned int i)
|
||||
{
|
||||
return (POINTERS->at(i) == DB->at(i)) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static void test_insertion()
|
||||
{
|
||||
std::vector<IntEntry *> pointers;
|
||||
std::vector<IntEntry *>::iterator p_it;
|
||||
|
||||
/*
|
||||
* Check initial sizes.
|
||||
*/
|
||||
/* Check initial sizes. */
|
||||
test_equal(DB->size(), (unsigned)0);
|
||||
test_equal(DB->actual_size(), (unsigned)0);
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < N; i++) {
|
||||
IntEntry *it = DB->insert(IntEntry(i));
|
||||
check_not_equal(it, (IntEntry *)NULL);
|
||||
check_equal(it->index(), i);
|
||||
check_equal(it->val, i);
|
||||
|
||||
pointers.push_back(it);
|
||||
|
||||
it = DB->insert(IntEntry(i));
|
||||
check_equal(it, (IntEntry *)NULL);
|
||||
}
|
||||
test :: success();
|
||||
|
||||
/*
|
||||
* Size should change
|
||||
*/
|
||||
test_for_each(0, N, 1, _test_insertion_check);
|
||||
test_equal(DB->size(), N);
|
||||
test_equal(DB->actual_size(), N);
|
||||
|
||||
/*
|
||||
* Pointers should still be valid
|
||||
*/
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
check_equal(pointers[i], DB->at(i));
|
||||
test :: success();
|
||||
/* Pointers should still be valid. */
|
||||
test_for_each(0, N, 1, _test_insertion_pointer_check);
|
||||
}
|
||||
|
||||
|
||||
static void test_removal()
|
||||
{
|
||||
test :: begin();
|
||||
/* Size should have only changed once each iteration. */
|
||||
for (unsigned int i = 0; i < N; i+=2) {
|
||||
/*
|
||||
* Database size should only decrease once.
|
||||
*/
|
||||
DB->remove(i);
|
||||
DB->remove(i);
|
||||
}
|
||||
test :: success();
|
||||
|
||||
/*
|
||||
* Size should change
|
||||
*/
|
||||
test_equal(DB->size(), N / 2);
|
||||
test_equal(DB->actual_size(), N);
|
||||
|
||||
/*
|
||||
* Test out-of-bounds removal
|
||||
*/
|
||||
test :: begin();
|
||||
/* Test out-of-bounds removal. */
|
||||
for (unsigned int i = 0; i < 10; i++)
|
||||
DB->remove(N + i);
|
||||
test :: success();
|
||||
|
||||
/*
|
||||
* Size should not change
|
||||
*/
|
||||
test_equal(DB->size(), N / 2);
|
||||
test_equal(DB->actual_size(), N);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int _test_access_null(unsigned int i)
|
||||
{
|
||||
return (DB->at(i) == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static unsigned int _test_access_valid(unsigned int i)
|
||||
{
|
||||
IntEntry *ie = DB->at(i);
|
||||
|
||||
if ((ie == NULL) || (*IT != ie) ||
|
||||
(ie->val != i) || (ie->index() != i))
|
||||
return LOOP_FAILED;
|
||||
IT = DB->next(IT);
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_access()
|
||||
{
|
||||
Database<IntEntry>::iterator it;
|
||||
IT = DB->begin();
|
||||
test_for_each(0, N, 2, _test_access_null);
|
||||
test_for_each(1, N, 2, _test_access_valid);
|
||||
test_for_each(N, N + 10, 1, _test_access_null);
|
||||
}
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < N; i+=2)
|
||||
check_equal(DB->at(i), (IntEntry *)NULL);
|
||||
test :: success();
|
||||
|
||||
test :: begin();
|
||||
it = DB->begin();
|
||||
for (unsigned int i = 1; i < N; i+=2) {
|
||||
IntEntry *ie = DB->at(i);
|
||||
|
||||
check_not_equal(ie, (IntEntry *)NULL);
|
||||
check_equal(*it, ie);
|
||||
check_equal(ie->val, i);
|
||||
check_equal(ie->index(), i);
|
||||
|
||||
it = DB->next(it);
|
||||
}
|
||||
test :: success();
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 10; i++)
|
||||
check_equal(DB->at(N + i), (IntEntry *)NULL);
|
||||
test :: success();
|
||||
static unsigned int _test_reinsert_check(unsigned int i)
|
||||
{
|
||||
IntEntry *it = DB->insert(IntEntry(i));
|
||||
return (it->index() == (N + (i / 2))) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static void test_reinsert()
|
||||
{
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < N; i+=2) {
|
||||
IntEntry *it = DB->insert(IntEntry(i));
|
||||
check_equal(it->index(), N + (i / 2));
|
||||
}
|
||||
test :: success();
|
||||
|
||||
/*
|
||||
* Size should change
|
||||
*/
|
||||
test_for_each(0, N, 2, _test_reinsert_check);
|
||||
test_equal(DB->size(), N);
|
||||
test_equal(DB->actual_size(), N + (N / 2));
|
||||
}
|
||||
|
||||
|
||||
static Database<IntEntry> *DB2;
|
||||
|
||||
static unsigned int _test_save_load_check(unsigned int i)
|
||||
{
|
||||
IntEntry *ie1 = DB->at(i);
|
||||
IntEntry *ie2 = DB2->at(i);
|
||||
|
||||
if (ie1 == NULL)
|
||||
return (ie2 == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
||||
else {
|
||||
if ((ie2 == NULL) || (ie1->index() != ie2->index()) ||
|
||||
(ie1->val != ie2->val))
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_save_load()
|
||||
{
|
||||
Database<IntEntry> db2("database.db", false);
|
||||
db2.load();
|
||||
DB2 = &db2;
|
||||
|
||||
if (AUTOSAVE == false) {
|
||||
test_equal(db2.size(), (unsigned)0);
|
||||
|
@ -170,43 +162,30 @@ static void test_save_load()
|
|||
|
||||
test_equal(db2.size(), DB->size());
|
||||
test_equal(db2.actual_size(), DB->actual_size());
|
||||
|
||||
Database<IntEntry>::iterator it1;
|
||||
Database<IntEntry>::iterator it2 = db2.begin();
|
||||
|
||||
test :: begin();
|
||||
for (it1 = DB->begin(); it1 != DB->end(); it1++) {
|
||||
if (*it1 == (IntEntry *)NULL)
|
||||
check_equal(*it2, (IntEntry *)NULL);
|
||||
else {
|
||||
check_not_equal(*it2, (IntEntry *)NULL);
|
||||
check_equal((*it1)->index(), (*it2)->index());
|
||||
check_equal((*it1)->val, (*it2)->val);
|
||||
}
|
||||
it2++;
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, DB->actual_size(), 1, _test_save_load_check);
|
||||
}
|
||||
|
||||
static void db_test(unsigned int n, bool autosave)
|
||||
{
|
||||
test :: rm_data_dir();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << " (n = " << n << ")";
|
||||
const std::string n_str = ss.str();
|
||||
|
||||
Database<IntEntry> db("database.db", autosave);
|
||||
std::vector<IntEntry *> pointers;
|
||||
std::stringstream ss;
|
||||
std::string n_str;
|
||||
|
||||
ss << " (n = " << n << ")";
|
||||
n_str = ss.str();
|
||||
|
||||
N = n;
|
||||
DB = &db;
|
||||
AUTOSAVE = autosave;
|
||||
POINTERS = &pointers;
|
||||
|
||||
run_test("Database Insertion Test" + n_str, test_insertion);
|
||||
run_test("Database Removal Test" + n_str, test_removal);
|
||||
run_test("Database Access Test" + n_str, test_access);
|
||||
run_test("Database Reinsertion Test" + n_str, test_reinsert);
|
||||
run_test("Database Save and Load Test" + n_str, test_save_load);
|
||||
test :: rm_data_dir();
|
||||
test :: run("Database Insertion Test" + n_str, test_insertion);
|
||||
test :: run("Database Removal Test" + n_str, test_removal);
|
||||
test :: run("Database Access Test" + n_str, test_access);
|
||||
test :: run("Database Reinsertion Test" + n_str, test_reinsert);
|
||||
test :: run("Database Save and Load Test" + n_str, test_save_load);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -217,6 +196,5 @@ int main(int argc, char **argv)
|
|||
db_test(1000, true);
|
||||
db_test(10000, false);
|
||||
db_test(100000, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -156,8 +156,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
test :: rm_data_dir();
|
||||
|
||||
run_test("Deck Init Test", test_init);
|
||||
run_test("Deck Create, Move and Destroy Test", test_create_mv_destroy);
|
||||
run_test("Deck Next and Prev Test", test_next_prev);
|
||||
test :: run("Deck Init Test", test_init);
|
||||
test :: run("Deck Create, Move and Destroy Test", test_create_mv_destroy);
|
||||
test :: run("Deck Next and Prev Test", test_next_prev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
test :: rm_data_dir();
|
||||
|
||||
run_test("File Constructor Test", test_filepath);
|
||||
run_test("File Open Test", test_open);
|
||||
run_test("File I/O Test", test_io);
|
||||
test :: run("File Constructor Test", test_filepath);
|
||||
test :: run("File Open Test", test_open);
|
||||
test :: run("File I/O Test", test_io);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,23 +61,27 @@ static void test_add()
|
|||
"well excuse me princess");
|
||||
}
|
||||
|
||||
|
||||
static std::set<unsigned int>::iterator IT;
|
||||
static unsigned int *IDS = NULL;
|
||||
|
||||
static unsigned int _do_test_search_compare(unsigned int i)
|
||||
{
|
||||
return (*IT++ == IDS[i]) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static void do_test_search(const std::string &text, unsigned int len,
|
||||
unsigned int *ids)
|
||||
{
|
||||
int init_values[] = { 1, 2, 3, 4, 5 };
|
||||
std::set<unsigned int> res(init_values, init_values + 5);
|
||||
std::set<unsigned int>::iterator it;
|
||||
|
||||
filter :: search(text, res);
|
||||
test_equal(res.size(), (size_t)len);
|
||||
|
||||
test :: begin();
|
||||
it = res.begin();
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
check_equal(*it, ids[i]);
|
||||
it++;
|
||||
}
|
||||
test :: success();
|
||||
IDS = ids;
|
||||
IT = res.begin();
|
||||
test_for_each(0, len, 1, _do_test_search_compare);
|
||||
}
|
||||
|
||||
static void test_search()
|
||||
|
@ -102,8 +106,8 @@ static void test_search()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Filter Lowercase Test", test_lowercase);
|
||||
run_test("Filter Add Test", test_add);
|
||||
run_test("Filter Search Test", test_search);
|
||||
test :: run("Filter Lowercase Test", test_lowercase);
|
||||
test :: run("Filter Add Test", test_add);
|
||||
test :: run("Filter Search Test", test_search);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,22 @@
|
|||
|
||||
static float N = 0;
|
||||
static float cur = -1;
|
||||
static bool func_passed = false;
|
||||
|
||||
static void inc_cur(float &expected)
|
||||
{
|
||||
cur++;
|
||||
check_equal(cur, expected);
|
||||
func_passed = (cur == expected);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int _test_idle_queue_step(unsigned int i)
|
||||
{
|
||||
if (idle :: run_task() == false)
|
||||
return LOOP_FAILED;
|
||||
if (idle :: get_progress() != ((i + 1) / N))
|
||||
return LOOP_FAILED;
|
||||
return func_passed ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
static void test_idle_queue()
|
||||
|
@ -26,12 +37,7 @@ static void test_idle_queue()
|
|||
idle :: schedule(inc_cur, i);
|
||||
test_equal(idle :: get_progress(), (float)0.0);
|
||||
|
||||
test :: begin();
|
||||
for (float i = 0; i < (N - 1); i++) {
|
||||
check_equal(idle :: run_task(), true);
|
||||
check_equal(idle :: get_progress(), (i + 1) / N);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, N - 1, 1, _test_idle_queue_step);
|
||||
|
||||
test_equal(idle :: run_task(), false);
|
||||
test_equal(idle :: get_progress(), (float)1.0);
|
||||
|
@ -45,7 +51,7 @@ static void do_test(unsigned int n)
|
|||
|
||||
N = n;
|
||||
cur = -1;
|
||||
run_test("Idle Queue Test" + n_str, test_idle_queue);
|
||||
test :: run("Idle Queue Test" + n_str, test_idle_queue);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* Copyright 2014 (c) Anna Schumaker.
|
||||
* Test a Database
|
||||
*/
|
||||
|
||||
#include <core/index.h>
|
||||
#include <core/print.h>
|
||||
#include <tests/test.h>
|
||||
|
||||
#include <sstream>
|
||||
|
@ -30,69 +30,78 @@ static void test_single_item()
|
|||
test_equal(it->size(), (size_t)0);
|
||||
}
|
||||
|
||||
static void test_insertion()
|
||||
|
||||
static unsigned int _test_insertion_check(unsigned int i)
|
||||
{
|
||||
std::string key;
|
||||
IndexEntry *it;
|
||||
|
||||
test :: begin();
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
key = c;
|
||||
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
INDEX->insert(key, i);
|
||||
}
|
||||
test :: success();
|
||||
std::string key(1, (char)i);
|
||||
IndexEntry *it = INDEX->find(std::string(1, (char)i));
|
||||
|
||||
if (N == 0)
|
||||
test_equal(INDEX->size(), (unsigned int)0);
|
||||
else
|
||||
test_equal(INDEX->size(), (unsigned int)26);
|
||||
return (it == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
||||
if (it == NULL)
|
||||
return LOOP_FAILED;
|
||||
if (it->size() != N)
|
||||
return LOOP_FAILED;
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
test :: begin();
|
||||
static void test_insertion()
|
||||
{
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
key = c;
|
||||
it = INDEX->find(key);
|
||||
|
||||
if (N == 0)
|
||||
check_equal(it, (IndexEntry *)NULL);
|
||||
else {
|
||||
check_not_equal(it, (IndexEntry *)NULL);
|
||||
check_equal(it->size(), (size_t)N);
|
||||
}
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
INDEX->insert(std::string(1, c), i);
|
||||
}
|
||||
test :: success();
|
||||
|
||||
test_equal(INDEX->size(), (N == 0) ? 0 : 26);
|
||||
test_for_each('a', 'z' + 1, 1, _test_insertion_check);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int _test_removal_check(unsigned int i)
|
||||
{
|
||||
IndexEntry *it;
|
||||
std::string key(1, (char)i);
|
||||
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
INDEX->remove(key, i);
|
||||
|
||||
it = INDEX->find(key);
|
||||
if (N == 0)
|
||||
return (it == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
||||
if ((it == NULL) || (it->size() != 0))
|
||||
return LOOP_FAILED;
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_removal()
|
||||
{
|
||||
std::string key;
|
||||
IndexEntry *it;
|
||||
test_for_each('a', 'z' + 1, 1, _test_removal_check);
|
||||
}
|
||||
|
||||
test :: begin();
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
key = c;
|
||||
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
INDEX->remove(key, i);
|
||||
it = INDEX->find(key);
|
||||
if (N == 0)
|
||||
check_equal(it, (IndexEntry *)NULL);
|
||||
else {
|
||||
check_not_equal(it, (IndexEntry *)NULL);
|
||||
check_equal(it->size(), (size_t)0);
|
||||
}
|
||||
static Index *INDEX2 = NULL;
|
||||
static unsigned int _test_saving_check(unsigned int i)
|
||||
{
|
||||
std::string key(1, (char)i);
|
||||
IndexEntry *it1 = INDEX->find(key);
|
||||
IndexEntry *it2 = INDEX2->find(key);
|
||||
|
||||
if (N == 0) {
|
||||
if ((it1 != NULL) || (it2 != NULL))
|
||||
return LOOP_FAILED;
|
||||
} else {
|
||||
if ((it1 == NULL) || (it2 == NULL) ||
|
||||
(it1->size() != it2->size()))
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
test :: success();
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_saving()
|
||||
{
|
||||
std::string key;
|
||||
IndexEntry *it1, *it2;
|
||||
|
||||
Index idx2("index.idx", false);
|
||||
idx2.load();
|
||||
INDEX2 = &idx2;
|
||||
test_equal(idx2.size(), (unsigned)0);
|
||||
|
||||
INDEX->save();
|
||||
|
@ -101,42 +110,27 @@ static void test_saving()
|
|||
test_equal(idx2.size(), INDEX->size());
|
||||
test_equal(idx2.actual_size(), INDEX->actual_size());
|
||||
|
||||
test :: begin();
|
||||
for (char c = 'a'; c <= 'z'; c++) {
|
||||
key = c;
|
||||
it1 = INDEX->find(key);
|
||||
it2 = idx2.find(key);
|
||||
|
||||
if (N == 0) {
|
||||
check_equal(it1, (IndexEntry *)NULL);
|
||||
check_equal(it2, (IndexEntry *)NULL);
|
||||
} else {
|
||||
check_not_equal(it1, (IndexEntry *)NULL);
|
||||
check_not_equal(it2, (IndexEntry *)NULL);
|
||||
check_equal(it1->size(), it2->size());
|
||||
}
|
||||
}
|
||||
test :: success();
|
||||
test_for_each('a', 'z' + 1, 1, _test_saving_check);
|
||||
}
|
||||
|
||||
static void index_test(unsigned int n)
|
||||
{
|
||||
test :: rm_data_dir();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << " (n = " << n << ")";
|
||||
const std::string n_str = ss.str();
|
||||
|
||||
Index index("index.idx", false);
|
||||
std::stringstream ss;
|
||||
std::string n_str;
|
||||
|
||||
ss << " (n = " << n << ")";
|
||||
n_str = ss.str();
|
||||
|
||||
N = n;
|
||||
INDEX = &index;
|
||||
|
||||
test :: rm_data_dir();
|
||||
if (n == 0)
|
||||
run_test("Index Single Item Test", test_single_item);
|
||||
run_test("Index Insertion Test" + n_str, test_insertion);
|
||||
run_test("Index Removal Test" + n_str, test_removal);
|
||||
run_test("Index Save and Load Test" + n_str, test_saving);
|
||||
test :: run("Index Single Item Test", test_single_item);
|
||||
test :: run("Index Insertion Test" + n_str, test_insertion);
|
||||
test :: run("Index Removal Test" + n_str, test_removal);
|
||||
test :: run("Index Save and Load Test" + n_str, test_saving);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -108,9 +108,9 @@ int main(int argc, char **argv)
|
|||
{
|
||||
test :: cp_data_dir();
|
||||
|
||||
run_test("Library Init Test", test_init);
|
||||
run_test("Library Enable and Disable Test", test_enable);
|
||||
run_test("Library Delete Path Test", test_remove);
|
||||
run_test("Library Add Path Test", test_add);
|
||||
run_test("Library Update Path Test", test_update);
|
||||
test :: run("Library Init Test", test_init);
|
||||
test :: run("Library Enable and Disable Test", test_enable);
|
||||
test :: run("Library Delete Path Test", test_remove);
|
||||
test :: run("Library Add Path Test", test_add);
|
||||
test :: run("Library Update Path Test", test_update);
|
||||
}
|
||||
|
|
|
@ -90,37 +90,39 @@ static void test_delete()
|
|||
test_equal(playlist :: get_tracks("No Playlist"), IDX_NULL);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int _test_has_loop_banned(unsigned int i)
|
||||
{
|
||||
Track *track = tags :: get_track(i);
|
||||
bool has = playlist :: has(track, "Banned");
|
||||
if (i <= 3)
|
||||
return has ? LOOP_PASSED : LOOP_FAILED;
|
||||
return has ? LOOP_FAILED : LOOP_PASSED;
|
||||
}
|
||||
|
||||
static unsigned int _test_has_loop_favorites(unsigned int i)
|
||||
{
|
||||
Track *track = tags :: get_track(i);
|
||||
bool has = playlist :: has(track, "Favorites");
|
||||
if (i >= 16)
|
||||
return has ? LOOP_PASSED : LOOP_FAILED;
|
||||
return has ? LOOP_FAILED : LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_has()
|
||||
{
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
Track *track = tags :: get_track(i);
|
||||
if (i <= 3)
|
||||
check_equal(playlist :: has(track, "Banned"), true);
|
||||
else
|
||||
check_equal(playlist :: has(track, "Banned"), false);
|
||||
}
|
||||
test :: success();
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
Track *track = tags :: get_track(i);
|
||||
if (i >= 16)
|
||||
check_equal(playlist :: has(track, "Favorites"), true);
|
||||
else
|
||||
check_equal(playlist :: has(track, "Favorites"), false);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_has_loop_banned);
|
||||
test_for_each(0, 24, 1, _test_has_loop_favorites);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
test :: rm_data_dir();
|
||||
|
||||
run_test("Playlist Initialization Test", test_init);
|
||||
run_test("Playlist Queue Test", test_queue);
|
||||
run_test("Playlist Add Test", test_add);
|
||||
run_test("Playlist Delete Test", test_delete);
|
||||
run_test("Playlist Has Test", test_has);
|
||||
test :: run("Playlist Initialization Test", test_init);
|
||||
test :: run("Playlist Queue Test", test_queue);
|
||||
test :: run("Playlist Add Test", test_add);
|
||||
test :: run("Playlist Delete Test", test_delete);
|
||||
test :: run("Playlist Has Test", test_has);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ unsigned int count_add = 0;
|
|||
unsigned int count_del = 0;
|
||||
unsigned int count_updated = 0;
|
||||
unsigned int last_update = 0;
|
||||
unsigned int expected = 0;
|
||||
Track *TRACK_NULL = NULL;
|
||||
|
||||
|
||||
|
@ -25,6 +26,7 @@ public:
|
|||
std::vector <sort_info> get_sorder() { return _sort_order; };
|
||||
};
|
||||
|
||||
TestQueue *Q = NULL, *R = NULL;
|
||||
void test_add_cb_noop(Queue *q, unsigned int id) { }
|
||||
void test_del_cb_noop(Queue *q, unsigned int id) { }
|
||||
|
||||
|
@ -74,35 +76,58 @@ void test_flags()
|
|||
|
||||
void test_add_cb(Queue *q, unsigned int id)
|
||||
{
|
||||
check_equal(id, count_add);
|
||||
count_add++;
|
||||
}
|
||||
|
||||
void test_del_cb(Queue *q, unsigned int id)
|
||||
{
|
||||
if (count_del % 2 == 0)
|
||||
check_equal(id, (unsigned)0);
|
||||
else
|
||||
check_equal(id, 24 - ((count_del + 1) / 2));
|
||||
count_del++;
|
||||
}
|
||||
|
||||
void test_del_cb2(Queue *q, unsigned int id)
|
||||
|
||||
unsigned int _test_add_loop(unsigned int i)
|
||||
{
|
||||
check_equal(id, 23 - count_del);
|
||||
count_del++;
|
||||
Track *track = tags :: get_track(i % 24);
|
||||
unsigned int index = Q->add(track);
|
||||
expected += track->length();
|
||||
if (index != i)
|
||||
return LOOP_FAILED;
|
||||
if ((index + 1) != count_add)
|
||||
return LOOP_FAILED;
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
void test_del_cb3(Queue *q, unsigned int id)
|
||||
unsigned int _test_del_loop(unsigned int i)
|
||||
{
|
||||
check_equal(id, (unsigned)0);
|
||||
Track *track = tags :: get_track(i);
|
||||
unsigned int j = (i + 1) * 2;
|
||||
|
||||
Q->del(track);
|
||||
expected -= track->length() * 2;
|
||||
if (count_del != j)
|
||||
return LOOP_FAILED;
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
unsigned int _test_del_middle_loop(unsigned int i)
|
||||
{
|
||||
unsigned int j = 23 - i;
|
||||
expected -= (*Q)[j]->length();
|
||||
Q->del(j);
|
||||
return (count_del == (i + 1)) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
unsigned int _test_del_front_loop(unsigned int i)
|
||||
{
|
||||
expected -= (*Q)[0]->length();
|
||||
Q->del((unsigned int)0);
|
||||
return (count_del == (i + 1)) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
void test_add_remove()
|
||||
{
|
||||
Track *track;
|
||||
TestQueue q(0);
|
||||
unsigned int expected = 0;
|
||||
Q = &q;
|
||||
|
||||
get_callbacks()->on_queue_track_add = test_add_cb;
|
||||
get_callbacks()->on_queue_track_del = test_del_cb;
|
||||
|
@ -114,12 +139,7 @@ void test_add_remove()
|
|||
|
||||
|
||||
/* Add tracks */
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
check_equal(q.add(tags :: get_track(i)), i);
|
||||
expected += 100 + (i * 10);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_add_loop);
|
||||
test_equal(q.get_length(), expected);
|
||||
test_equal(q.length_str(), (std::string)"1 hour, 26 minutes");
|
||||
test_equal(q.size(), (unsigned)24);
|
||||
|
@ -127,12 +147,7 @@ void test_add_remove()
|
|||
|
||||
|
||||
/* Add everything again */
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
check_equal(q.add(tags :: get_track(i)), i + 24);
|
||||
expected += 100 + (i * 10);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(24, 48, 1, _test_add_loop);
|
||||
test_equal(q.get_length(), expected);
|
||||
test_equal(q.length_str(), (std::string)"2 hours, 52 minutes");
|
||||
test_equal(q.size(), (unsigned)48);
|
||||
|
@ -140,13 +155,8 @@ void test_add_remove()
|
|||
|
||||
|
||||
/* Test removing multiple tracks at once */
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 12; i++) {
|
||||
track = tags :: get_track(i);
|
||||
q.del(track);
|
||||
expected -= 2 * (100 + (i * 10));
|
||||
}
|
||||
test :: success();
|
||||
count_del = 0;
|
||||
test_for_each(0, 12, 1, _test_del_loop);
|
||||
test_equal(q.get_length(), expected);
|
||||
test_equal(q.length_str(), (std::string)"1 hour, 50 minutes");
|
||||
test_equal(q.size(), (unsigned)24);
|
||||
|
@ -155,14 +165,7 @@ void test_add_remove()
|
|||
|
||||
/* Test removing tracks one at a time */
|
||||
count_del = 0;
|
||||
get_callbacks()->on_queue_track_del = test_del_cb2;
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 23; i >= 12; i--) {
|
||||
expected -= q[i]->length();
|
||||
q.del(i);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, 12, 1, _test_del_middle_loop);
|
||||
test_equal(q.get_length(), expected);
|
||||
test_equal(q.length_str(), (std::string)"55 minutes");
|
||||
test_equal(q.size(), (unsigned)12);
|
||||
|
@ -170,12 +173,8 @@ void test_add_remove()
|
|||
|
||||
|
||||
/* Remove remaining tracks */
|
||||
get_callbacks()->on_queue_track_del = test_del_cb3;
|
||||
|
||||
test :: begin();
|
||||
while (q.size() > 0)
|
||||
q.del((unsigned)0);
|
||||
test :: success();
|
||||
count_del = 0;
|
||||
test_for_each(0, 12, 1, _test_del_front_loop);
|
||||
test_equal(q.get_length(), (unsigned)0);
|
||||
test_equal(q.length_str(), (std::string)"");
|
||||
test_equal(q.size(), (unsigned)0);
|
||||
|
@ -199,24 +198,29 @@ void test_updated_cb2(Queue *q, unsigned int row)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_fill_q()
|
||||
{
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
Q->add(tags :: get_track(i));
|
||||
}
|
||||
|
||||
unsigned int _test_update_loop(unsigned int i)
|
||||
{
|
||||
Q->updated(tags :: get_track(i));
|
||||
return (last_update == i) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
void test_updated()
|
||||
{
|
||||
Track *track;
|
||||
TestQueue q(0);
|
||||
|
||||
Q = &q;
|
||||
get_callbacks()->on_queue_track_add = test_add_cb_noop;
|
||||
get_callbacks()->on_queue_track_changed = test_updated_cb;
|
||||
|
||||
/* Add tracks */
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
check_equal(q.add(tags :: get_track(i)), i);
|
||||
test :: success();
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
q.updated(tags :: get_track(i));
|
||||
test :: success();
|
||||
test_fill_q();
|
||||
test_for_each(0, 24, 1, _test_update_loop);
|
||||
|
||||
get_callbacks()->on_queue_track_changed = test_updated_cb2;
|
||||
track = tags :: get_track(0);
|
||||
|
@ -226,30 +230,35 @@ void test_updated()
|
|||
test_equal(count_updated, (unsigned)3);
|
||||
}
|
||||
|
||||
static void test_fill_q(TestQueue *q)
|
||||
{
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
q->add(tags :: get_track(i));
|
||||
}
|
||||
|
||||
unsigned int expected_rand[] = { 1, 4, 8, 13, 19, 3, 14, 16, 20, 2, 11, 17,
|
||||
23, 6, 12, 18, 0, 5, 9, 10, 15, 21, 22, 7 };
|
||||
|
||||
|
||||
unsigned int _test_next_loop(unsigned int i)
|
||||
{
|
||||
Track *track = Q->next();
|
||||
if (track == TRACK_NULL)
|
||||
return LOOP_FAILED;
|
||||
return (track->index() == (i % 24)) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
unsigned int _test_next_rand_loop(unsigned int i)
|
||||
{
|
||||
Track *track = Q->next();
|
||||
if (track == TRACK_NULL)
|
||||
return LOOP_FAILED;
|
||||
return (track->index() == expected_rand[i]) ? LOOP_PASSED : LOOP_FAILED;
|
||||
}
|
||||
|
||||
void test_next()
|
||||
{
|
||||
Track *track;
|
||||
TestQueue q(0);
|
||||
|
||||
Q = &q;
|
||||
get_callbacks()->on_queue_track_del = test_del_cb_noop;
|
||||
test_fill_q();
|
||||
|
||||
test_fill_q(&q);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
track = q.next();
|
||||
check_not_equal(track, TRACK_NULL);
|
||||
check_equal(track->index(), i);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_next_loop);
|
||||
test_equal(q.size(), (unsigned)0);
|
||||
test_equal(q.length_str(), (std::string)"");
|
||||
test_equal(q.next(), TRACK_NULL);
|
||||
|
@ -257,15 +266,9 @@ void test_next()
|
|||
|
||||
q.set_flag(Q_RANDOM);
|
||||
random_seed(0);
|
||||
test_fill_q();
|
||||
|
||||
test_fill_q(&q);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++) {
|
||||
track = q.next();
|
||||
check_not_equal(track, TRACK_NULL);
|
||||
check_equal(track->index(), expected_rand[i]);
|
||||
}
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_next_rand_loop);
|
||||
test_equal(q.size(), (unsigned)0);
|
||||
test_equal(q.length_str(), (std::string)"");
|
||||
test_equal(q.next(), TRACK_NULL);
|
||||
|
@ -273,21 +276,18 @@ void test_next()
|
|||
|
||||
q.set_flag(Q_REPEAT);
|
||||
q.unset_flag(Q_RANDOM);
|
||||
test_fill_q(&q);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 48; i++) {
|
||||
track = q.next();
|
||||
check_not_equal(track, TRACK_NULL);
|
||||
check_equal(track->index(), i % 24);
|
||||
}
|
||||
test :: success();
|
||||
test_fill_q();
|
||||
|
||||
test_for_each(0, 48, 1, _test_next_loop);
|
||||
test_equal(q.size(), (unsigned)24);
|
||||
}
|
||||
|
||||
void test_select()
|
||||
{
|
||||
TestQueue q(0);
|
||||
test_fill_q(&q);
|
||||
|
||||
Q = &q;
|
||||
test_fill_q();
|
||||
|
||||
test_equal(q.size(), (unsigned)24);
|
||||
q.track_selected(10);
|
||||
|
@ -300,44 +300,70 @@ void test_select()
|
|||
test_equal(q.next()->index(), (unsigned)1);
|
||||
}
|
||||
|
||||
|
||||
unsigned int exp_sort_title[] = { 1, 18, 19, 16, 20, 8, 2, 9, 23, 10, 17, 11,
|
||||
3, 21, 4, 0, 5, 22, 6, 12, 7, 13, 14, 15 };
|
||||
unsigned int exp_sort_ye_ti[] = { 0, 3, 2, 1, 7, 6, 5, 4, 11, 10, 9, 8,
|
||||
22, 21, 17, 23, 20, 16, 19, 18, 15, 14, 13, 12 };
|
||||
|
||||
unsigned int _test_sort_title(unsigned int i)
|
||||
{
|
||||
if ((*Q)[i]->index() == exp_sort_title[i])
|
||||
return LOOP_PASSED;
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
unsigned int _test_sort_title_reverse(unsigned int i)
|
||||
{
|
||||
if ((*Q)[i]->index() == exp_sort_title[23 - i])
|
||||
return LOOP_PASSED;
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
unsigned int _test_sort_index(unsigned int i)
|
||||
{
|
||||
if ((*Q)[i]->index() == i)
|
||||
return LOOP_PASSED;
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
unsigned int _test_sort_ye_ti(unsigned int i)
|
||||
{
|
||||
if ((*Q)[i]->index() == exp_sort_ye_ti[i])
|
||||
return LOOP_PASSED;
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
void test_sorting()
|
||||
{
|
||||
TestQueue q(0);
|
||||
|
||||
Q = &q;
|
||||
q.sort(SORT_TITLE, true);
|
||||
test_equal(q.get_sorder().size(), (size_t)1);
|
||||
test_fill_q(&q);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
check_equal(q[i]->index(), exp_sort_title[i]);
|
||||
test :: success();
|
||||
test_fill_q();
|
||||
test_for_each(0, 24, 1, _test_sort_title);
|
||||
|
||||
q.sort(SORT_TITLE, false);
|
||||
test_equal(q.get_sorder().size(), (size_t)1);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
check_equal(q[i]->index(), exp_sort_title[23 - i]);
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_sort_title_reverse);
|
||||
|
||||
q.sort(SORT_LENGTH, true);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
check_equal(q[i]->index(), i);
|
||||
test :: success();
|
||||
test_for_each(0, 1, 24, _test_sort_index);
|
||||
|
||||
q.sort(SORT_YEAR, true);
|
||||
q.sort(SORT_TITLE, false);
|
||||
q.sort(SORT_TITLE, false);
|
||||
test_equal(q.get_sorder().size(), (size_t)2);
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < 24; i++)
|
||||
check_equal(q[i]->index(), exp_sort_ye_ti[i]);
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_sort_ye_ti);
|
||||
}
|
||||
|
||||
|
||||
unsigned int _test_saving_loop(unsigned int i)
|
||||
{
|
||||
if ((*Q)[i]->index() == (*R)[i]->index())
|
||||
return LOOP_PASSED;
|
||||
return LOOP_FAILED;
|
||||
}
|
||||
|
||||
void test_saving()
|
||||
|
@ -346,29 +372,23 @@ void test_saving()
|
|||
TestQueue r(0);
|
||||
File f("test.q", 0);
|
||||
|
||||
test_fill_q(&q);
|
||||
Q = &q;
|
||||
R = &r;
|
||||
test_fill_q();
|
||||
|
||||
test :: begin();
|
||||
f.open(OPEN_WRITE);
|
||||
q.write(f);
|
||||
f.close();
|
||||
test :: success();
|
||||
|
||||
test :: begin();
|
||||
f.open(OPEN_READ);
|
||||
r.read(f);
|
||||
f.close();
|
||||
test :: success();
|
||||
|
||||
test_equal(r.has_flag(Q_RANDOM), q.has_flag(Q_RANDOM));
|
||||
test_equal(r.size(), q.size());
|
||||
test_equal(r.size_str(), q.size_str());
|
||||
test_equal(r.length_str(), q.length_str());
|
||||
|
||||
test :: begin();
|
||||
for (unsigned int i = 0; i < q.size(); i++)
|
||||
check_equal(r[i]->index(), q[i]->index());
|
||||
test :: success();
|
||||
test_for_each(0, 24, 1, _test_saving_loop);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -376,14 +396,14 @@ int main(int argc, char **argv)
|
|||
test :: cp_data_dir();
|
||||
tags :: init();
|
||||
|
||||
run_test("Queue Default Constructor Test", test_default);
|
||||
run_test("Queue Constructor Test", test_constructor);
|
||||
run_test("Queue Flag Test", test_flags);
|
||||
run_test("Queue Add and Remove Test", test_add_remove);
|
||||
run_test("Queue Track Updated Test", test_updated);
|
||||
run_test("Queue Pick Next Test", test_next);
|
||||
run_test("Queue Select Track Test", test_select);
|
||||
run_test("Queue Sorting Test", test_sorting);
|
||||
run_test("Queue Save and Load Test", test_saving);
|
||||
test :: run("Queue Default Constructor Test", test_default);
|
||||
test :: run("Queue Constructor Test", test_constructor);
|
||||
test :: run("Queue Flag Test", test_flags);
|
||||
test :: run("Queue Add and Remove Test", test_add_remove);
|
||||
test :: run("Queue Track Updated Test", test_updated);
|
||||
test :: run("Queue Pick Next Test", test_next);
|
||||
test :: run("Queue Select Track Test", test_select);
|
||||
test :: run("Queue Sorting Test", test_sorting);
|
||||
test :: run("Queue Save and Load Test", test_saving);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,17 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
static void do_test_rng(unsigned int seed)
|
||||
unsigned int SEED = 0;
|
||||
|
||||
static void do_test_rng()
|
||||
{
|
||||
random_seed(seed);
|
||||
random_seed(SEED);
|
||||
|
||||
for (unsigned int i = 0; i <= 10; i++) {
|
||||
if (i <= seed)
|
||||
test_equal(random(seed, i), seed);
|
||||
if (i <= SEED)
|
||||
test_equal(random(SEED, i), SEED);
|
||||
else
|
||||
test_equal(random(seed, i), seed + (i % (i - seed)));
|
||||
test_equal(random(SEED, i), SEED + (i % (i - SEED)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,8 +26,9 @@ static void test_rng(unsigned int seed)
|
|||
std::stringstream ss;
|
||||
ss << " (seed = " << seed << ")";
|
||||
std::string seed_str = ss.str();
|
||||
SEED = seed;
|
||||
|
||||
run_test("Random Number Generator Test" + seed_str, do_test_rng, seed);
|
||||
test :: run("Random Number Generator Test" + seed_str, do_test_rng);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -54,7 +54,7 @@ static void test_album_tag_lookup()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Album Tag Test", test_album_tag);
|
||||
run_test("Album Tag Lookup Test", test_album_tag_lookup);
|
||||
test :: run("Album Tag Test", test_album_tag);
|
||||
test :: run("Album Tag Lookup Test", test_album_tag_lookup);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ static void test_artist_tag_lookup()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Artist Tag Test", test_artist_tag);
|
||||
run_test("Artist Tag Lookup Test", test_artist_tag_lookup);
|
||||
test :: run("Artist Tag Test", test_artist_tag);
|
||||
test :: run("Artist Tag Lookup Test", test_artist_tag_lookup);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ static void test_generic_tag_comparison()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Generic Tag Test", test_generic_tag);
|
||||
run_test("Generic Tag Compare Test", test_generic_tag_comparison);
|
||||
test :: run("Generic Tag Test", test_generic_tag);
|
||||
test :: run("Generic Tag Compare Test", test_generic_tag_comparison);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ static void test_genere_tag_lookup()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Genre Tag Test", test_artist_tag);
|
||||
run_test("Genre Tag Lookup Test", test_genere_tag_lookup);
|
||||
test :: run("Genre Tag Test", test_artist_tag);
|
||||
test :: run("Genre Tag Lookup Test", test_genere_tag_lookup);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ static void test_library_tag_lookup()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Library Tag Test", test_library_tag);
|
||||
run_test("Library Tag Lookup Test", test_library_tag_lookup);
|
||||
test :: run("Library Tag Test", test_library_tag);
|
||||
test :: run("Library Tag Lookup Test", test_library_tag_lookup);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -218,10 +218,10 @@ int main(int argc, char **argv)
|
|||
genre = tags :: get_genre("Video Game Music");
|
||||
library = tags :: get_library(MUSIC_DIR);
|
||||
|
||||
run_test("Track Tag Default Constructor Test", test_track_tag_default);
|
||||
run_test("Track Tag Constructor Test", test_track_tag_constructor);
|
||||
run_test("Track Tag Destructor Test", test_track_tag_destructor);
|
||||
run_test("Track Tag Lookup Test", test_track_tag_lookup);
|
||||
run_test("Track Tag Locale Test", test_track_tag_locale);
|
||||
test :: run("Track Tag Default Constructor Test", test_track_tag_default);
|
||||
test :: run("Track Tag Constructor Test", test_track_tag_constructor);
|
||||
test :: run("Track Tag Destructor Test", test_track_tag_destructor);
|
||||
test :: run("Track Tag Lookup Test", test_track_tag_lookup);
|
||||
test :: run("Track Tag Locale Test", test_track_tag_locale);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,6 @@ static void test_version()
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
run_test("Version Test", test_version);
|
||||
test :: run("Version Test", test_version);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2015 (c) Anna Schumaker.
|
||||
*/
|
||||
#include <tests/test.h>
|
||||
#include <cstdlib>
|
||||
|
||||
static unsigned int expected_failures = 0;
|
||||
|
||||
#define should_fail(code) \
|
||||
code; \
|
||||
expected_failures++
|
||||
|
||||
static unsigned int test_for_each_body(unsigned int i)
|
||||
{
|
||||
if (i > 10)
|
||||
return LOOP_FAILED;
|
||||
return LOOP_PASSED;
|
||||
}
|
||||
|
||||
static void test_tests()
|
||||
{
|
||||
test_equal(0, 0);
|
||||
test_equal((std::string)"2", (std::string)"2");
|
||||
test_equal((void *)4, (void *)4);
|
||||
|
||||
should_fail(test_equal(0, 1));
|
||||
should_fail(test_equal((std::string)"2", "3"));
|
||||
should_fail(test_equal((void *)4, (void *)5));
|
||||
|
||||
|
||||
test_not_equal(0, 1);
|
||||
test_not_equal((std::string)"2", "3");
|
||||
test_not_equal((void *)4, (void *)5);
|
||||
|
||||
should_fail(test_not_equal(0, 0));
|
||||
should_fail(test_not_equal((std::string)"2", "2"));
|
||||
should_fail(test_not_equal((void *)4, (void *)4));
|
||||
|
||||
|
||||
test_for_each(0, 10, 1, test_for_each_body);
|
||||
should_fail(test_for_each(0, 15, 1, test_for_each_body));
|
||||
|
||||
|
||||
test_equal(test :: failed, expected_failures);
|
||||
test :: failed -= expected_failures;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
test :: run("Testing Sanity Check", test_tests);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright 2015 (c) Anna Schumaker.
|
||||
*/
|
||||
#include <tests/test.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
static unsigned int test_num;
|
||||
unsigned int test :: failed;
|
||||
|
||||
|
||||
template <class T>
|
||||
static void generic_equal(const T &a, const T &b, const unsigned int line)
|
||||
{
|
||||
std::cout << " " << test_num++ << ": ";
|
||||
if (a == b)
|
||||
std::cout << "Success!" << std::endl;
|
||||
else {
|
||||
std::cout << "Failed at line " << line << ":" << std::endl;
|
||||
std::cout << " Actual: " << a << std::endl;
|
||||
std::cout << " Expected: " << b << std::endl;
|
||||
test :: failed++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void generic_not_equal(const T &a, const T &b, const unsigned int line)
|
||||
{
|
||||
std::cout << " " << test_num++ << ": ";
|
||||
if (a != b)
|
||||
std::cout << "Success!" << std::endl;
|
||||
else {
|
||||
std::cout << "Failed at line " << line << ":" << std::endl;
|
||||
std::cout << " Unexpected: " << a << std::endl;
|
||||
test :: failed++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test :: run(const std::string &name, void (*func)())
|
||||
{
|
||||
failed = 0;
|
||||
test_num = 0;
|
||||
std::cout << name << std::endl;
|
||||
|
||||
func();
|
||||
|
||||
std::cout << std::endl;
|
||||
if (failed > 0) {
|
||||
std::cout << failed << " tests failed =(" << std::endl << std::endl;
|
||||
exit(failed);
|
||||
}
|
||||
}
|
||||
|
||||
void test :: for_each(unsigned int init, unsigned int max, unsigned int inc,
|
||||
unsigned int (*func)(unsigned int), unsigned int line)
|
||||
{
|
||||
std::cout << " " << test_num++ << ": ";
|
||||
for (unsigned int i = init; i < max; i += inc) {
|
||||
int ret = func(i);
|
||||
if (ret != 0) {
|
||||
std::cout << "Failed loop at line: " << ret;
|
||||
std::cout << " (i = " << i << ")" << std::endl;
|
||||
std::cout << " Called from line: " << line << std::endl;
|
||||
test :: failed++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::cout << "Success!" << std::endl;
|
||||
}
|
||||
|
||||
#define DEFINE_COMPARE_FUNC(name, type) \
|
||||
void test :: name(const type a, const type b, unsigned int line) \
|
||||
{ generic_##name(a, b, line); }
|
||||
|
||||
#define DEFINE_COMPARE(type) \
|
||||
DEFINE_COMPARE_FUNC(equal, type) \
|
||||
DEFINE_COMPARE_FUNC(not_equal, type)
|
||||
|
||||
DEFINE_COMPARE(int)
|
||||
DEFINE_COMPARE(std::string &)
|
||||
DEFINE_COMPARE(void *)
|
||||
|
||||
std::string test :: data_dir()
|
||||
{
|
||||
std::string res = g_get_user_data_dir();
|
||||
res += "/ocarina-test";
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string test :: data_file(const std::string &name)
|
||||
{
|
||||
return data_dir() + "/" + name;
|
||||
}
|
||||
|
||||
bool test :: data_dir_exists()
|
||||
{
|
||||
return g_file_test(data_dir().c_str(), G_FILE_TEST_IS_DIR);
|
||||
}
|
||||
|
||||
bool test :: data_file_exists(const std::string &name)
|
||||
{
|
||||
return g_file_test(data_file(name).c_str(), G_FILE_TEST_EXISTS);
|
||||
}
|
||||
|
||||
void test :: rm_data_dir()
|
||||
{
|
||||
std::string cmd = "rm -r " + data_dir() + " 2>/dev/null";
|
||||
if (data_dir_exists())
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void test :: reset_data_dir()
|
||||
{
|
||||
std::string cmd = "mkdir -p " + data_dir();
|
||||
rm_data_dir();
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void test :: cp_data_dir()
|
||||
{
|
||||
reset_data_dir();
|
||||
std::string cmd = "cp -r tests/Data/* " + data_dir();
|
||||
system(cmd.c_str());
|
||||
}
|
||||
|
||||
void test :: gen_library()
|
||||
{
|
||||
system("tests/gen_library.sh");
|
||||
}
|
||||
|
||||
void test :: rm_library_dirs()
|
||||
{
|
||||
system("rm -r /tmp/ocarina/dir2 /tmp/ocarina/dir4");
|
||||
}
|
Loading…
Reference in New Issue