221 lines
4.0 KiB
C++
221 lines
4.0 KiB
C++
/*
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
* Test a Database
|
|
*/
|
|
|
|
#include <database.h>
|
|
#include <print.h>
|
|
|
|
#include <sstream>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
|
|
unsigned int test_num = 0;
|
|
|
|
|
|
class IntEntry : public DatabaseEntry {
|
|
public:
|
|
unsigned int val;
|
|
|
|
IntEntry();
|
|
IntEntry(unsigned int);
|
|
const std::string primary_key();
|
|
void write(File &);
|
|
void read(File &);
|
|
void print();
|
|
};
|
|
|
|
IntEntry :: IntEntry() : val(0) {}
|
|
IntEntry :: IntEntry(unsigned int v) : val(v) {}
|
|
const std::string IntEntry :: primary_key()
|
|
{
|
|
std::stringstream ss;
|
|
ss << val;
|
|
return ss.str();
|
|
}
|
|
|
|
void IntEntry :: write(File &f) { f << val; }
|
|
void IntEntry :: read(File &f) { f >> val; }
|
|
void IntEntry :: print() { :: print(primary_key().c_str()); }
|
|
|
|
void test_results(bool success, unsigned int line)
|
|
{
|
|
print(" %u: ", test_num);
|
|
if (success)
|
|
print("Success!\n");
|
|
else {
|
|
print("FAILED (%u) =(\n", line);
|
|
exit(1);
|
|
}
|
|
test_num++;
|
|
}
|
|
|
|
void test_size(Database<IntEntry> &db, unsigned int size,
|
|
unsigned int actual, unsigned int line)
|
|
{
|
|
test_results( (db.size() == size) || (db.actual_size() == actual), line );
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
bool autosave = false;
|
|
unsigned int n = 0, size = 0, actual = 0;
|
|
char c;
|
|
|
|
while ((c = getopt(argc, argv, "a")) != -1) {
|
|
switch (c) {
|
|
case 'a':
|
|
autosave = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
n = atoi(argv[optind]);
|
|
Database<IntEntry> db("database.db", autosave);
|
|
|
|
|
|
/**
|
|
* 0: Test initial size
|
|
*/
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* 1: Test insertion
|
|
*/
|
|
for (unsigned int i = 0; i < n; i++) {
|
|
if (db.insert(IntEntry(i)) != i)
|
|
test_results(false, __LINE__);
|
|
}
|
|
test_results(true, __LINE__);
|
|
size += n;
|
|
actual += n;
|
|
|
|
|
|
/**
|
|
* 2: Test that size changes
|
|
*/
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* 3: Test inserting ... again.
|
|
*/
|
|
for (unsigned int i = 0; i < n; i++) {
|
|
if (db.insert(IntEntry(i)) != i)
|
|
test_results(false, __LINE__);
|
|
}
|
|
test_results(true, __LINE__);
|
|
|
|
|
|
/**
|
|
* 4: Test that size didn't change
|
|
*/
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* 5: Test that size changes when removing
|
|
* Also test out-of-bounds removal
|
|
*
|
|
* Note: This test removes all even-index entries
|
|
*/
|
|
for (unsigned int i = 0; i < n + 10; i+=2) {
|
|
db.remove(i);
|
|
size--;
|
|
}
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* 6: Test that removing again doesn't change anything
|
|
*/
|
|
for (unsigned int i = 0; i < n; i+=2)
|
|
db.remove(i);
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* 7: Test iterating
|
|
*/
|
|
Database<IntEntry>::iterator it;
|
|
unsigned int index = 1;
|
|
for (it = db.begin(); it != db.end(); it = db.next(it)) {
|
|
if ((*it).val != index)
|
|
test_results(false, __LINE__);
|
|
index+=2;
|
|
};
|
|
test_results(true, __LINE__);
|
|
|
|
|
|
/**
|
|
* 8. Test access by id
|
|
*/
|
|
for (unsigned int i = 0; i < n + 10; i++) {
|
|
Database<IntEntry>::iterator it = db.at(i);
|
|
if (((i % 2) == 0) && (it != db.end()))
|
|
test_results(false, __LINE__);
|
|
if ((i >= n) && (it != db.end()))
|
|
test_results(false, __LINE__);
|
|
}
|
|
test_results(true, __LINE__);
|
|
|
|
|
|
/**
|
|
* 9. Test inserting once again
|
|
*/
|
|
for (unsigned int i = 0; i < n; i++) {
|
|
index = db.insert(i);
|
|
if ((i % 2) == 0) {
|
|
size++;
|
|
actual++;
|
|
if (index != (n + (i / 2)))
|
|
test_results(false, __LINE__);
|
|
} else {
|
|
if (index != i)
|
|
test_results(false, __LINE__);
|
|
}
|
|
}
|
|
test_results(true, __LINE__);
|
|
|
|
|
|
/**
|
|
* 10. Test that size changed for every other insert
|
|
*/
|
|
test_size(db, size, actual, __LINE__);
|
|
|
|
|
|
/**
|
|
* Everything after this point tests loading from a file
|
|
*/
|
|
if (autosave == false)
|
|
return 0;
|
|
|
|
Database<IntEntry> db2("database.db", autosave);
|
|
db2.load();
|
|
|
|
|
|
/**
|
|
* 11. Sizes should match
|
|
*/
|
|
test_size(db2, db.size(), db.actual_size(), __LINE__);
|
|
|
|
|
|
/**
|
|
* 12. Values should match
|
|
*/
|
|
Database<IntEntry>::iterator it2 = db2.begin();
|
|
for (it = db.begin(); it != db.end(); it++) {
|
|
if (it->valid != it2->valid)
|
|
test_results(false, __LINE__);
|
|
if (it->valid == true) {
|
|
if (it->val != it2->val)
|
|
test_results(false, __LINE__);
|
|
}
|
|
it2++;
|
|
}
|
|
test_results(true, __LINE__);
|
|
return 0;
|
|
}
|