Test for class _PointerList_. Someone should convert it to a CppUnit test

and integrate it in the build system.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8840 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer
2004-09-04 10:00:13 +00:00
parent ad867a27fb
commit d25d8e6b16
2 changed files with 579 additions and 0 deletions
@@ -0,0 +1,511 @@
/*
** Copyright 2004, Michael Pfeiffer ([email protected]).
** Distributed under the terms of the Haiku License.
**
*/
#include "ObjectList.h"
#include <StopWatch.h>
#include <stdio.h>
#include <stdlib.h>
#include "PointerListTest.h"
AssertStatistics *AssertStatistics::fStatistics = NULL;
AssertStatistics::AssertStatistics()
{
fAssertions = 0;
fPassed = 0;
fFailed = 0;
}
AssertStatistics* AssertStatistics::GetInstance()
{
if (fStatistics == NULL) {
fStatistics = new AssertStatistics();
}
return fStatistics;
}
void AssertStatistics::Print()
{
fprintf(stderr, "Assert Statistics:\n");
fprintf(stderr, "Assertions: %d\n", fAssertions);
fprintf(stderr, "Passed: %d\n", fPassed);
fprintf(stderr, "Failed: %d\n", fFailed);
}
#undef assert
#define assert(expr) \
if (!(expr)) {\
fprintf(stderr, "FAILED [%d] ("#expr")\n", __LINE__); \
AssertStatistics::GetInstance()->AssertFailed(); \
}\
else {\
AssertStatistics::GetInstance()->AssertPassed(); \
}
int Item::Compare(const void* a, const void* b)
{
Item* itemA = (Item*)a;
Item* itemB = (Item*)b;
if (itemA == itemB) return 0;
if (itemA == NULL) return -1;
if (itemB == NULL) return 1;
return itemA->Value() - itemB->Value();
}
int Item::fNextID = 0;
int Item::fInstances = 0;
class PointerListTest
{
public:
Item* CreateItem();
void Initialize(_PointerList_& list, int size);
void Print(const _PointerList_& list);
void MakeEmpty(_PointerList_& list);
bool Equals(const _PointerList_& list1, const _PointerList_& list2);
bool IsSorted(const _PointerList_& list, int32 n);
bool IsSorted(const _PointerList_& list) { return IsSorted(list, list.CountItems()); }
bool IsHSorted(const _PointerList_& list) { return IsSorted(list, list.CountItems()-1); }
int IndexOf(const _PointerList_& list, int value);
Item* ItemFor(const _PointerList_& list, int value);
void CreationTest();
void OwningTest();
void SortTest();
void SortTestWithState();
void EachElementTest();
void BinarySearchTest();
void BinarySearchIndexTest();
void NullTest();
void Run();
};
#define MAX_ID 10000
#define NOT_USED_ID -1
#define NOT_USED_ID_HIGH (MAX_ID+1)
// Create an Item with a random value
Item* PointerListTest::CreateItem()
{
return new Item(rand() % (MAX_ID+1));
}
// Add size number of new items to the list.
void PointerListTest::Initialize(_PointerList_& list, int size)
{
for (int32 i = 0; i < size; i ++) {
list.AddItem(CreateItem());
}
}
// Print the list to stderr
void PointerListTest::Print(const _PointerList_& list)
{
const int32 n = list.CountItems();
for (int32 i = 0; i < n; i ++) {
Item* item = (Item*)list.ItemAt(i);
if (i > 0) {
fprintf(stderr, ", ");
}
if (item != NULL) {
item->Print();
} else {
fprintf(stderr, "NULL");
}
}
fprintf(stderr, "\n");
}
// delete the Items in the list
void PointerListTest::MakeEmpty(_PointerList_& list)
{
const int32 n = list.CountItems();
for (int32 i = 0; i < n; i ++) {
Item* item = (Item*)list.ItemAt(i);
if (item != NULL) {
delete item;
}
}
list.MakeEmpty();
}
// contain the lists the same items or values
bool PointerListTest::Equals(const _PointerList_& list1, const _PointerList_& list2)
{
const int32 n = list1.CountItems();
if (n != list2.CountItems()) return false;
for (int32 i = 0; i < n; i ++) {
Item* item1 = (Item*)list1.ItemAt(i);
Item* item2 = (Item*)list2.ItemAt(i);
if (item1 == item2) continue;
if (item1 == NULL || !item1->Equals(item2)) return false;
}
return true;
}
// is the list sorted
bool PointerListTest::IsSorted(const _PointerList_& list, int32 n)
{
int prevValue = -1; // item values are >= 0
for (int32 i = 0; i < n; i ++) {
Item* item = (Item*)list.ItemAt(i);
assert(item != NULL);
int value = item->Value();
if (value < prevValue) {
return false;
}
prevValue = value;
}
return true;
}
int PointerListTest::IndexOf(const _PointerList_& list, int value)
{
int n = list.CountItems();
for (int32 i = 0; i < n; i ++) {
Item* item = (Item*)list.ItemAt(i);
if (item != NULL && item->Value() == value) {
return i;
}
}
return -1;
}
Item* PointerListTest::ItemFor(const _PointerList_& list, int value)
{
int32 index = IndexOf(list, value);
if (index >= 0) {
list.ItemAt(index);
}
return NULL;
}
void PointerListTest::CreationTest()
{
_PointerList_ list;
int numberOfInstances = Item::GetNumberOfInstances();
assert(list.Owning() == false);
assert(list.CountItems() == 0);
Initialize(list, 10);
assert(list.CountItems() == 10);
int newInstances = Item::GetNumberOfInstances() - numberOfInstances;
assert(newInstances == 10);
numberOfInstances = Item::GetNumberOfInstances();
MakeEmpty(list);
int deletedInstances = numberOfInstances - Item::GetNumberOfInstances();
assert(deletedInstances == 10);
}
void PointerListTest::OwningTest()
{
_PointerList_ list(10, true);
assert(list.CountItems() == 0);
assert(list.Owning() == true);
int numberOfInstances = Item::GetNumberOfInstances();
Initialize(list, 10);
assert(list.CountItems() == 10);
assert(Item::GetNumberOfInstances() - numberOfInstances == 10);
_PointerList_* clone = new _PointerList_(list);
assert(Item::GetNumberOfInstances() - numberOfInstances == 10);
assert(clone->Owning() == true);
MakeEmpty(list);
assert(Item::GetNumberOfInstances() - numberOfInstances == 0);
delete clone;
assert(Item::GetNumberOfInstances() - numberOfInstances == 0);
}
void PointerListTest::SortTest()
{
for (int i = 0; i < 10; i ++) {
_PointerList_ list;
Initialize(list, i);
_PointerList_ clone(list);
assert(Equals(list, clone));
assert(clone.Owning() == false);
list.SortItems(Item::Compare);
assert(IsSorted(list));
int lastItem = clone.CountItems()-1;
bool hasItems = clone.CountItems() > 0;
Item* item = NULL;
if (hasItems) {
item = (Item*)clone.ItemAt(0);
}
// HSortItems seems to put the first item at the end of the list
// and sort the rest.
clone.HSortItems(Item::Compare);
assert(IsHSorted(clone));
assert(!hasItems || item == (Item*)clone.ItemAt(lastItem));
MakeEmpty(list);
}
}
static void* gData = NULL;
int Compare(const void* a, const void* b, void* data)
{
// check data has the expected value
assert(gData == data);
return Item::Compare(a, b);
}
#define FROM 10000
#define TO 10000
void PointerListTest::SortTestWithState()
{
gData = (void*)0x4711;
for (int i = FROM; i < (TO+1); i ++) {
BStopWatch* watch = new BStopWatch("Initialize");
_PointerList_ list;
Initialize(list, i);
delete watch;
watch = new BStopWatch("Clone");
_PointerList_ clone(list);
delete watch;
assert(Equals(list, clone));
assert(clone.Owning() == false);
watch = new BStopWatch("SortItems");
list.SortItems(::Compare, gData);
delete watch;
assert(IsSorted(list));
watch = new BStopWatch("SortItems (sorted list)");
list.SortItems(::Compare, gData);
delete watch;
assert(IsSorted(list));
int lastItem = clone.CountItems()-1;
bool hasItems = clone.CountItems() > 0;
Item* item = NULL;
if (hasItems) {
item = (Item*)clone.ItemAt(0);
}
// HSortItems seems to put the first item at the end of the list
// and sort the rest.
watch = new BStopWatch("HSortItems");
clone.HSortItems(Compare, gData);
delete watch;
assert(IsHSorted(clone));
assert(!hasItems || item == (Item*)clone.ItemAt(lastItem));
watch = new BStopWatch("MakeEmpty");
MakeEmpty(list);
delete watch;
}
}
void* CopyTo(void* item, void* data)
{
_PointerList_* list = (_PointerList_*)data;
list->AddItem(item);
return NULL;
}
void* FirstItem(void* item, void* data)
{
return item;
}
void PointerListTest::EachElementTest()
{
_PointerList_ list;
Initialize(list, 10);
assert(list.CountItems() == 10);
_PointerList_ clone;
list.EachElement(CopyTo, &clone);
assert(clone.CountItems() == list.CountItems());
void* item = list.EachElement(FirstItem, NULL);
assert (item == list.ItemAt(0));
MakeEmpty(list);
}
void PointerListTest::BinarySearchTest()
{
_PointerList_ list;
Initialize(list, 10);
list.SortItems(Item::Compare);
assert(IsSorted(list));
gData = (void*)0x4711;
Item notInListLow(NOT_USED_ID);
Item notInListHigh(NOT_USED_ID_HIGH);
for (int32 i = 0; i < 10; i ++) {
Item* item = (Item*)list.ItemAt(i);
assert(item != NULL);
Item* found = (Item*)list.BinarySearch(item, Item::Compare);
assert(item->Equals(found));
found = (Item*)list.BinarySearch(item, ::Compare, gData);
assert(item->Equals(found));
found = (Item*)list.BinarySearch(&notInListLow, Item::Compare);
assert(found == NULL);
found = (Item*)list.BinarySearch(&notInListLow, ::Compare, gData);
assert(found == NULL);
found = (Item*)list.BinarySearch(&notInListHigh, Item::Compare);
assert(found == NULL);
found = (Item*)list.BinarySearch(&notInListHigh, ::Compare, gData);
assert(found == NULL);
}
MakeEmpty(list);
}
class Value
{
public:
Value(int value) : value(value) {};
int value;
};
static int ValuePredicate(const void* _item, void* _value)
{
Item* item = (Item*)_item;
Value* value = (Value*)_value;
return item->Value() - value->value;
}
void PointerListTest::BinarySearchIndexTest()
{
_PointerList_ list;
Initialize(list, 10);
list.SortItems(Item::Compare);
assert(IsSorted(list));
Item notInListLow(NOT_USED_ID);
Item notInListHigh(NOT_USED_ID_HIGH);
gData = (void*)0x4711;
for (int32 i = 0; i < 10; i ++) {
Item* item = (Item*)list.ItemAt(i);
assert(item != NULL);
Value value(item->Value());
int index = IndexOf(list, item->Value());
int searchIndex;
searchIndex = list.BinarySearchIndex(item, Item::Compare);
assert(index == searchIndex);
searchIndex = list.BinarySearchIndex(item, ::Compare, gData);
assert(index == searchIndex);
searchIndex = list.BinarySearchIndexByPredicate(&value, ValuePredicate);
assert(index == searchIndex);
// notInListLow
searchIndex = list.BinarySearchIndex(&notInListLow, Item::Compare);
assert(searchIndex == -1);
searchIndex = list.BinarySearchIndex(&notInListLow, ::Compare, gData);
assert(searchIndex == -1);
value.value = notInListLow.Value();
searchIndex = list.BinarySearchIndexByPredicate(&value, ValuePredicate);
assert(searchIndex == -1);
// notInListHigh
searchIndex = list.BinarySearchIndex(&notInListHigh, Item::Compare);
assert(searchIndex == -(list.CountItems()+1));
searchIndex = list.BinarySearchIndex(&notInListHigh, ::Compare, gData);
assert(searchIndex == -(list.CountItems()+1));
value.value = notInListHigh.Value();
searchIndex = list.BinarySearchIndexByPredicate(&value, ValuePredicate);
assert(searchIndex == -(list.CountItems()+1));
}
MakeEmpty(list);
for (int i = 0; i < 3; i ++) {
list.AddItem(new Item(2 * i));
}
Item notInList(3);
assert(IndexOf(list, 3) == -1);
int index = list.BinarySearchIndex(&notInList, Item::Compare);
assert (index == -3);
index = list.BinarySearchIndex(&notInList, ::Compare, gData);
assert (index == -3);
Value value(notInList.Value());
index = list.BinarySearchIndexByPredicate(&value, ValuePredicate);
assert (index == -3);
MakeEmpty(list);
}
void PointerListTest::NullTest()
{
_PointerList_ list;
Initialize(list, 10);
// R5 crashes
// list.EachElement(NULL, NULL);
// list.SortItems(NULL);
// list.SortItems(NULL, NULL);
// list.HSortItems(NULL);
// list.HSortItems(NULL, NULL);
// list.BinarySearch(NULL, NULL);
// list.BinarySearch(NULL, NULL, NULL);
// list.BinarySearchIndex(NULL, NULL);
// list.BinarySearchIndex(NULL, NULL, NULL);
// list.BinarySearchIndexByPredicate(NULL, NULL);
assert(!list.ReplaceItem(-1, NULL));
assert(!list.ReplaceItem(100, NULL));
}
void PointerListTest::Run()
{
CreationTest();
OwningTest();
SortTest();
SortTestWithState();
EachElementTest();
BinarySearchTest();
BinarySearchIndexTest();
NullTest();
}
int main(int argc, char* argv[])
{
// initialize srand with constant to get reproducable results
srand(0);
PointerListTest test;
test.Run();
AssertStatistics::GetInstance()->Print();
}
@@ -0,0 +1,68 @@
/*
** Copyright 2004, Michael Pfeiffer ([email protected]).
** Distributed under the terms of the Haiku License.
**
*/
#ifndef _TEST_H
#define _TEST_H
#include <stdio.h>
class AssertStatistics {
private:
AssertStatistics();
public:
static AssertStatistics* GetInstance();
void AssertFailed() { fAssertions++; fFailed++; }
void AssertPassed() { fAssertions++; fPassed++; }
void Print();
int fAssertions;
int fPassed;
int fFailed;
static AssertStatistics* fStatistics;
};
class Item
{
public:
Item() { Init(); }
Item(const Item& item) : fValue(item.fValue) { Init(); };
Item(int value) : fValue(value) { Init(); };
virtual ~Item() { fInstances --; }
int Value() { return fValue; }
bool Equals(Item* item) {
return item != NULL && fValue == item->fValue;
}
static int GetNumberOfInstances() { return fInstances; }
void Print() {
fprintf(stderr, "[%d] %d", fID, fValue);
// fprintf(stderr, "id: %d; value: %d", fID, fValue);
}
static int Compare(const void* a, const void* b);
private:
void Init() {
fID = fNextID ++;
fInstances ++;
}
int fID; // unique id for each created Item
int fValue; // the value of the item
static int fNextID;
static int fInstances;
};
#endif