426 lines
9.7 KiB
C++
426 lines
9.7 KiB
C++
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <dlib/queue.h>
|
|
#include <dlib/memory_manager_global.h>
|
|
|
|
#include "tester.h"
|
|
|
|
// This is called an unnamed-namespace and it has the effect of making everything inside this file "private"
|
|
// so that everything you declare will have static linkage. Thus we won't have any multiply
|
|
// defined symbol errors coming out of the linker when we try to compile the test suite.
|
|
namespace
|
|
{
|
|
|
|
using namespace test;
|
|
using namespace dlib;
|
|
using namespace std;
|
|
|
|
// Declare the logger we will use in this test. The name of the tester
|
|
// should start with "test."
|
|
logger dlog("test.queue");
|
|
|
|
template <
|
|
typename queue
|
|
>
|
|
void queue_sort_test (
|
|
)
|
|
/*!
|
|
requires
|
|
- queue is an implementation of queue/queue_sort_abstract.h
|
|
is instantiated with int
|
|
ensures
|
|
- runs tests on queue for compliance with the specs
|
|
!*/
|
|
{
|
|
|
|
print_spinner();
|
|
srand(static_cast<unsigned int>(time(0)));
|
|
|
|
queue q,q2;
|
|
|
|
enumerable<int>& e = q;
|
|
|
|
// I will use these DLIB_TEST_MSG macros to assert that conditions are true. If they are
|
|
// false then it means we have detected an error in the queue object. CASSERT
|
|
// will then throw an exception which we will catch at the end of this function and
|
|
// report as an error/failed test.
|
|
DLIB_TEST(e.at_start() == true);
|
|
|
|
int a = 0;
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == true);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
|
|
q.sort();
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == true);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
|
|
DLIB_TEST (q.move_next() == false);
|
|
DLIB_TEST (q.move_next() == false);
|
|
DLIB_TEST (q.move_next() == false);
|
|
DLIB_TEST (q.move_next() == false);
|
|
DLIB_TEST (q.move_next() == false);
|
|
DLIB_TEST (q.move_next() == false);
|
|
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == false);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
|
|
|
|
q.reset();
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == true);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
q.clear();
|
|
q2.clear();
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 0);
|
|
|
|
for (int i = 0; i < 10000; ++i)
|
|
{
|
|
int a = i;
|
|
q.enqueue(a);
|
|
}
|
|
|
|
q2.cat(q);
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 10000);
|
|
|
|
int g = 0;
|
|
while (q2.move_next())
|
|
{
|
|
DLIB_TEST_MSG(q2.element() == g,g);
|
|
++g;
|
|
}
|
|
|
|
for (int i = 0;i < 10000; ++i)
|
|
{
|
|
int a = 0;
|
|
q2.dequeue(a);
|
|
DLIB_TEST(a == i);
|
|
}
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 0);
|
|
q.clear();
|
|
q2.clear();
|
|
|
|
|
|
|
|
|
|
print_spinner();
|
|
|
|
|
|
dlog << LTRACE << "creating big pre-sorted queue";
|
|
q.clear();
|
|
DLIB_TEST(q.size() == 0);
|
|
|
|
for (int i = 0; i < 10000; ++i)
|
|
{
|
|
int a = i;
|
|
q.enqueue(a);
|
|
}
|
|
|
|
dlog << LTRACE << "sorting already sorted queue";
|
|
q.sort();
|
|
|
|
|
|
dlog << LTRACE << "done sorting, checking the results";
|
|
for (int i = 0; i < 10000; ++i)
|
|
{
|
|
q.dequeue(a);
|
|
DLIB_TEST(a == i);
|
|
}
|
|
|
|
|
|
q.clear();
|
|
dlog << LTRACE << "done with the big pre-sorted queue test";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
q.clear();
|
|
q2.clear();
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 0);
|
|
|
|
for (int i = 0; i < 1; ++i)
|
|
{
|
|
int a = i;
|
|
q.enqueue(a);
|
|
}
|
|
|
|
q2.cat(q);
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 1);
|
|
|
|
|
|
|
|
g = 0;
|
|
while (q2.move_next())
|
|
{
|
|
DLIB_TEST_MSG(q2.element() == g,g);
|
|
++g;
|
|
}
|
|
|
|
for (int i = 0;i < 1; ++i)
|
|
{
|
|
int a = 0;
|
|
q2.dequeue(a);
|
|
DLIB_TEST(a == i);
|
|
}
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q2.size() == 0);
|
|
q.clear();
|
|
q2.clear();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_spinner();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < 3; ++j)
|
|
{
|
|
for (int i = 0; i < 10000; ++i)
|
|
{
|
|
a = ::rand();
|
|
q.enqueue(a);
|
|
}
|
|
|
|
while (q.move_next()) ;
|
|
|
|
DLIB_TEST(q.at_start() == false);
|
|
|
|
q.sort();
|
|
|
|
DLIB_TEST(q.at_start() == true);
|
|
|
|
// serialize the state of q, then clear q, then
|
|
// load the state back into q.
|
|
ostringstream sout;
|
|
serialize(q,sout);
|
|
DLIB_TEST(q.at_start() == true);
|
|
istringstream sin(sout.str());
|
|
q.clear();
|
|
deserialize(q,sin);
|
|
|
|
|
|
DLIB_TEST(q.at_start() == true);
|
|
|
|
a = 0;
|
|
int last = 0;
|
|
while (q.move_next())
|
|
{
|
|
++a;
|
|
DLIB_TEST_MSG(last <= q.element(),"items weren't actually sorted");
|
|
last = q.element();
|
|
DLIB_TEST(q.current_element_valid() == true);
|
|
DLIB_TEST(q.at_start() == false);
|
|
DLIB_TEST(q.current_element_valid() == true);
|
|
|
|
|
|
}
|
|
DLIB_TEST_MSG(a == 10000,"some items were lost between the sorting and iterating");
|
|
|
|
|
|
DLIB_TEST(q.size() == 10000);
|
|
swap(q,q2);
|
|
DLIB_TEST(q2.at_start() == false);
|
|
DLIB_TEST(q2.current_element_valid() == false);
|
|
|
|
DLIB_TEST (q2.move_next() == false);
|
|
DLIB_TEST (q2.move_next() == false);
|
|
DLIB_TEST (q2.move_next() == false);
|
|
DLIB_TEST (q2.move_next() == false);
|
|
DLIB_TEST (q2.move_next() == false);
|
|
DLIB_TEST (q2.move_next() == false);
|
|
|
|
|
|
DLIB_TEST(q2.size() == 10000);
|
|
DLIB_TEST(q2.at_start() == false);
|
|
DLIB_TEST(q2.current_element_valid() == false);
|
|
|
|
q2.clear();
|
|
|
|
q.swap(q2);
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == true);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
}
|
|
|
|
|
|
|
|
print_spinner();
|
|
|
|
|
|
|
|
// try the above code but this time with just one element
|
|
// in the queue
|
|
for (int j = 0; j < 3; ++j)
|
|
{
|
|
for (int i = 0; i < 1; ++i)
|
|
{
|
|
a = ::rand();
|
|
q.enqueue(a);
|
|
}
|
|
|
|
q.sort();
|
|
|
|
a = 0;
|
|
int last = 0;
|
|
while (q.move_next())
|
|
{
|
|
++a;
|
|
DLIB_TEST_MSG(last <= q.element(),"items weren't actually sorted");
|
|
DLIB_TEST(q.current_element_valid() == true);
|
|
|
|
}
|
|
DLIB_TEST_MSG(a == 1,"some items were lost between the sorting and iterating");
|
|
|
|
|
|
DLIB_TEST(q.size() == 1);
|
|
DLIB_TEST(q.at_start() == false);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
|
|
q.clear();
|
|
|
|
DLIB_TEST(q.size() == 0);
|
|
DLIB_TEST(q.at_start() == true);
|
|
DLIB_TEST(q.current_element_valid() == false);
|
|
}
|
|
|
|
|
|
print_spinner();
|
|
|
|
{
|
|
q.clear();
|
|
remover<int>& go = q;
|
|
for (int i = 0; i < 100; ++i)
|
|
{
|
|
int a = 3;
|
|
q.enqueue(a);
|
|
}
|
|
DLIB_TEST(go.size() == 100);
|
|
for (int i = 0; i < 100; ++i)
|
|
{
|
|
int a = 9;
|
|
q.remove_any(a);
|
|
DLIB_TEST(a == 3);
|
|
}
|
|
DLIB_TEST(go.size() == 0);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
struct factory
|
|
{
|
|
template <typename U>
|
|
struct return_type {
|
|
typedef typename memory_manager<U>::kernel_3c type;
|
|
};
|
|
|
|
template <typename U>
|
|
static typename return_type<U>::type* get_instance (
|
|
)
|
|
{
|
|
static typename return_type<U>::type a;
|
|
return &a;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
class queue_tester : public tester
|
|
{
|
|
/*!
|
|
WHAT THIS OBJECT REPRESENTS
|
|
This object represents a test for the queue object. When it is constructed
|
|
it adds itself into the testing framework. The command line switch is
|
|
specified as test_queue by passing that string to the tester constructor.
|
|
!*/
|
|
public:
|
|
queue_tester (
|
|
) :
|
|
tester ("test_queue",
|
|
"Runs tests on the queue component.")
|
|
{}
|
|
|
|
void perform_test (
|
|
)
|
|
{
|
|
// There are multiple implementations of the queue object so use
|
|
// the templated function defined above to test them all and report
|
|
// a failed test if any of them don't pass.
|
|
|
|
typedef dlib::memory_manager_global<char,factory>::kernel_1a mm;
|
|
|
|
|
|
dlog << LINFO << "testing sort_1a_c";
|
|
queue_sort_test<queue<int, mm>::sort_1a_c> ();
|
|
dlog << LINFO << "testing sort_1a";
|
|
queue_sort_test<queue<int, mm>::sort_1a>();
|
|
dlog << LINFO << "testing sort_1b";
|
|
queue_sort_test<queue<int, mm>::sort_1b> ();
|
|
dlog << LINFO << "testing sort_1b_c";
|
|
queue_sort_test<queue<int, mm>::sort_1b_c>();
|
|
dlog << LINFO << "testing sort_1c";
|
|
queue_sort_test<queue<int, mm>::sort_1c> ();
|
|
dlog << LINFO << "testing sort_1c_c";
|
|
queue_sort_test<queue<int, mm>::sort_1c_c>();
|
|
}
|
|
} a;
|
|
|
|
}
|
|
|