From e4f18e3cf484d14b1b8118b3839aa59aec89aa39 Mon Sep 17 00:00:00 2001 From: Kacper Kasper Date: Sun, 29 Mar 2026 12:53:25 +0200 Subject: [PATCH] Refactor Kernel Util tests Change-Id: I4f5dbc664a621cdba3d928f2f358a73a07b71aa1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10671 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- .../system/kernel/util/AVLTreeMapTest.cpp | 41 +- src/tests/system/kernel/util/AVLTreeMapTest.h | 19 - .../system/kernel/util/BOpenHashTableTest.cpp | 399 ------ .../system/kernel/util/BOpenHashTableTest.h | 28 - src/tests/system/kernel/util/BitmapTest.cpp | 141 +- src/tests/system/kernel/util/BitmapTest.h | 16 - .../kernel/util/DoublyLinkedListTest.cpp | 260 ++-- .../system/kernel/util/DoublyLinkedListTest.h | 21 - src/tests/system/kernel/util/Jamfile | 2 +- .../kernel/util/KernelUtilsTestAddon.cpp | 28 +- .../system/kernel/util/OpenHashTableTest.cpp | 326 +++++ src/tests/system/kernel/util/OrderedMapTest.h | 1140 ----------------- .../kernel/util/SinglyLinkedListTest.cpp | 171 +-- .../system/kernel/util/SinglyLinkedListTest.h | 19 - .../system/kernel/util/VectorMapTest.cpp | 929 +++++++++++++- src/tests/system/kernel/util/VectorMapTest.h | 13 - .../system/kernel/util/VectorSetTest.cpp | 861 +++++-------- src/tests/system/kernel/util/VectorSetTest.h | 27 - src/tests/system/kernel/util/VectorTest.cpp | 1028 +++++++-------- src/tests/system/kernel/util/VectorTest.h | 29 - 20 files changed, 2225 insertions(+), 3273 deletions(-) delete mode 100644 src/tests/system/kernel/util/AVLTreeMapTest.h delete mode 100644 src/tests/system/kernel/util/BOpenHashTableTest.cpp delete mode 100644 src/tests/system/kernel/util/BOpenHashTableTest.h delete mode 100644 src/tests/system/kernel/util/BitmapTest.h delete mode 100644 src/tests/system/kernel/util/DoublyLinkedListTest.h create mode 100644 src/tests/system/kernel/util/OpenHashTableTest.cpp delete mode 100644 src/tests/system/kernel/util/OrderedMapTest.h delete mode 100644 src/tests/system/kernel/util/SinglyLinkedListTest.h delete mode 100644 src/tests/system/kernel/util/VectorMapTest.h delete mode 100644 src/tests/system/kernel/util/VectorSetTest.h delete mode 100644 src/tests/system/kernel/util/VectorTest.h diff --git a/src/tests/system/kernel/util/AVLTreeMapTest.cpp b/src/tests/system/kernel/util/AVLTreeMapTest.cpp index 9b8064287d..55b31e3bf8 100644 --- a/src/tests/system/kernel/util/AVLTreeMapTest.cpp +++ b/src/tests/system/kernel/util/AVLTreeMapTest.cpp @@ -1,32 +1,23 @@ -#include -#include -#include -#include -#include -#include +/* + * Copyright 2003-2026, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include #include -AVLTreeMapTest::AVLTreeMapTest(std::string name) - : BTestCase(name) -{ -} -CppUnit::Test* -AVLTreeMapTest::Suite() -{ - CppUnit::TestSuite *suite = new CppUnit::TestSuite("AVLTreeMap"); +class AVLTreeMapTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(AVLTreeMapTest); + CPPUNIT_TEST(Test1); + CPPUNIT_TEST_SUITE_END(); - suite->addTest(new CppUnit::TestCaller( - "SinglyLinkedList::User Strategy Test (default next parameter)", - &AVLTreeMapTest::Test1)); +public: + void Test1() {} +}; - return suite; -} - -//! Test1 -void -AVLTreeMapTest::Test1() -{ -} +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AVLTreeMapTest, getTestSuiteName()); diff --git a/src/tests/system/kernel/util/AVLTreeMapTest.h b/src/tests/system/kernel/util/AVLTreeMapTest.h deleted file mode 100644 index cbe56b2fbc..0000000000 --- a/src/tests/system/kernel/util/AVLTreeMapTest.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _avl_tree_map_test_h_ -#define _avl_tree_map_test_h_ - -#include - -class AVLTreeMapTest : public BTestCase { -public: - AVLTreeMapTest(std::string name = ""); - - static CppUnit::Test* Suite(); - - void Test1(); - -private: - template - void TestList(List &list, typename List::ValueType *values, int valueCount); -}; - -#endif // _avl_tree_map_test_h_ diff --git a/src/tests/system/kernel/util/BOpenHashTableTest.cpp b/src/tests/system/kernel/util/BOpenHashTableTest.cpp deleted file mode 100644 index a92cb7d745..0000000000 --- a/src/tests/system/kernel/util/BOpenHashTableTest.cpp +++ /dev/null @@ -1,399 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "BOpenHashTableTest.h" - - -namespace { - -class Entry { -public: - Entry(uint32_t value) - : - fValue(value), - fNext(NULL) - { - } - - const uint32_t Value() const - { - return fValue; - } - - Entry* Next() const - { - return fNext; - } - -private: - uint32_t fValue; - Entry *fNext; - - friend class EntryDefinition; -}; - - -class EntryDefinition { -public: - typedef uint32_t KeyType; - typedef Entry ValueType; - - size_t HashKey(const KeyType& key) const - { - return key; - } - - size_t Hash(Entry* entry) const - { - return entry->fValue; - } - - bool Compare(const KeyType& key, Entry* entry) const - { - return key == entry->fValue; - } - - Entry*& GetLink(Entry* entry) const - { - return entry->fNext; - } -}; - -} - - -CppUnit::Test* BOpenHashTableTest::Suite() -{ - CppUnit::TestSuite* suite = new CppUnit::TestSuite("BOpenHashTable"); - - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Insert test", - &BOpenHashTableTest::InsertTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Insert unchecked test", - &BOpenHashTableTest::InsertUncheckedTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Insert unchecked uninitialized test", - &BOpenHashTableTest::InsertUncheckedUninitializedTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Iterate and count test", - &BOpenHashTableTest::IterateAndCountTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Lookup test", - &BOpenHashTableTest::LookupTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Resize test", - &BOpenHashTableTest::ResizeTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Remove test", - &BOpenHashTableTest::RemoveTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Remove unchecked test", - &BOpenHashTableTest::RemoveUncheckedTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Remove when not present test", - &BOpenHashTableTest::RemoveWhenNotPresentTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Duplicate insert test", - &BOpenHashTableTest::DuplicateInsertTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Disable auto expand", - &BOpenHashTableTest::DisableAutoExpandTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Init with zero size", - &BOpenHashTableTest::InitWithZeroSizeTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Clear test", - &BOpenHashTableTest::ClearTest)); - suite->addTest(new CppUnit::TestCaller( - "BOpenHashTable::Clear and return test", - &BOpenHashTableTest::ClearAndReturnTest)); - - return suite; -} - - -BOpenHashTableTest::BOpenHashTableTest(std::string name) - : BTestCase(name) -{ -} - - -void BOpenHashTableTest::InsertTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); -} - - -void BOpenHashTableTest::InsertUncheckedTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - table.InsertUnchecked(&entry); -} - - -void BOpenHashTableTest::InsertUncheckedUninitializedTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - table.InsertUnchecked(&entry); -} - - -void BOpenHashTableTest::IterateAndCountTest() { - const size_t kEntryCount = 20; - - BObjectList entries(20); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(kEntryCount * 2), B_OK); - - for (uint32_t i = 0; i < kEntryCount; ++i) { - Entry* entry = new Entry(i); - entries.AddItem(entry); - CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); - } - - // Verify that the table contains the expected values. - uint64_t map = 0; - BOpenHashTable::Iterator iterator = table.GetIterator(); - while (iterator.HasNext()) { - Entry* entry = iterator.Next(); - CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value())); - map |= (1 << entry->Value()); - } - - CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1); - CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements()); -} - - -void BOpenHashTableTest::ResizeTest() -{ - // This is the same as IterateAndCountTest, except that the table will - // be resized mid insertion. - const size_t kEntryCount = 20; - BObjectList entries(20); - BOpenHashTable table; - - // Start off with capacity for 8 elements. This will mean that the table - // will be resized in the loop below since we are inserting 20 elements. - CPPUNIT_ASSERT_EQUAL(table.Init(8), B_OK); - - for (uint32_t i = 0; i < kEntryCount; ++i) { - Entry* entry = new Entry(i); - entries.AddItem(entry); - CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); - } - - // Verify that after resize the expected elements are present within - // the table. - uint64_t map = 0; - BOpenHashTable::Iterator iterator = table.GetIterator(); - while (iterator.HasNext()) { - Entry* entry = iterator.Next(); - CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value())); - map |= (1 << entry->Value()); - } - - CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1); - CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements()); -} - - -void BOpenHashTableTest::LookupTest() { - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); -} - - -void BOpenHashTableTest::RemoveTest() { - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); - - table.Remove(&entry); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), NULL); -} - - -void BOpenHashTableTest::RemoveUncheckedTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); - - table.RemoveUnchecked(&entry); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), NULL); -} - - -void BOpenHashTableTest::RemoveWhenNotPresentTest() -{ - Entry entry1(123); - Entry entry2(456); - Entry entry3(789); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - // Only add the first two entries. - table.Insert(&entry1); - table.Insert(&entry2); - - // entry3 is not in the table, but we'll remove it anyway. - table.Remove(&entry3); - table.RemoveUnchecked(&entry3); - - // The original two entries should still be there. - CPPUNIT_ASSERT_EQUAL(table.CountElements(), 2); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry1); - CPPUNIT_ASSERT_EQUAL(table.Lookup(456), &entry2); - CPPUNIT_ASSERT_EQUAL(table.Lookup(789), NULL); -} - - -void BOpenHashTableTest::DuplicateInsertTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); - - CPPUNIT_ASSERT_DEBUGGER(table.Insert(&entry)); - - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); - - // The item can basically never be removed now since there is a cycle, - // but we'll break into the debugger on remove when that happens as well. - CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry)); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); - - CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry)); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); -} - - -void BOpenHashTableTest::DisableAutoExpandTest() -{ - // Insert multiple items into a table with a fixed size of 1. This - // essentially turns this BOpenHashTable into a linked list, since resize - // will never occur. - Entry entry1(123); - Entry entry2(456); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(1), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry1), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry2), B_OK); - CPPUNIT_ASSERT_EQUAL(table.CountElements(), 2); -} - - -void BOpenHashTableTest::InitWithZeroSizeTest() -{ - Entry entry(123); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); - - CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); - CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); -} - - -void BOpenHashTableTest::ClearTest() -{ - const size_t kEntryCount = 3; - - BObjectList entries(20); - - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - for (uint32_t i = 0; i < kEntryCount; ++i) { - Entry* entry = new Entry(i); - entries.AddItem(entry); - CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); - } - - CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount); - CPPUNIT_ASSERT(table.Lookup(2) != NULL); - - CPPUNIT_ASSERT_EQUAL(table.Clear(false), NULL); - CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0); - CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL); - CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false); -} - - -void BOpenHashTableTest::ClearAndReturnTest() -{ - // Same as ClearTest(), except that Clear(true) is called, which tells - // the BOpenHashTable to return a linked list of entries before clearing - // the table. - const size_t kEntryCount = 3; - BOpenHashTable table; - CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); - - for (uint32_t i = 0; i < kEntryCount; ++i) { - Entry* entry = new Entry(i); - CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); - } - - CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount); - CPPUNIT_ASSERT(table.Lookup(2) != NULL); - - Entry* head = table.Clear(true); - CPPUNIT_ASSERT(head != NULL); - - CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0); - CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL); - CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false); - - size_t items_returned = 0; - while (head != NULL) { - Entry* next = head->Next(); - delete head; - head = next; - - ++items_returned; - } - - CPPUNIT_ASSERT_EQUAL(items_returned, kEntryCount); -} diff --git a/src/tests/system/kernel/util/BOpenHashTableTest.h b/src/tests/system/kernel/util/BOpenHashTableTest.h deleted file mode 100644 index c3bbe4d5ab..0000000000 --- a/src/tests/system/kernel/util/BOpenHashTableTest.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef BOPENHASHTABLE_TEST_H -#define BOPENHASHTABLE_TEST_H - -#include - -class BOpenHashTableTest : public BTestCase { -public: - BOpenHashTableTest(std::string name = ""); - - void InsertTest(); - void InsertUncheckedTest(); - void InsertUncheckedUninitializedTest(); - void IterateAndCountTest(); - void ResizeTest(); - void LookupTest(); - void RemoveTest(); - void RemoveUncheckedTest(); - void RemoveWhenNotPresentTest(); - void DuplicateInsertTest(); - void DisableAutoExpandTest(); - void InitWithZeroSizeTest(); - void ClearTest(); - void ClearAndReturnTest(); - - static CppUnit::Test* Suite(); -}; - -#endif // BOPENHASHTABLE_TEST_H diff --git a/src/tests/system/kernel/util/BitmapTest.cpp b/src/tests/system/kernel/util/BitmapTest.cpp index 174c9ee4d1..b7e659a72d 100644 --- a/src/tests/system/kernel/util/BitmapTest.cpp +++ b/src/tests/system/kernel/util/BitmapTest.cpp @@ -1,95 +1,94 @@ -#include -#include -#include -#include -#include +/* + * Copyright 2022-2026, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include -#include "BitmapTest.h" #include "Bitmap.h" -BitmapTest::BitmapTest(std::string name) - : BTestCase(name) -{ -} -CppUnit::Test* -BitmapTest::Suite() -{ - CppUnit::TestSuite *suite = new CppUnit::TestSuite("Bitmap"); +class BitmapTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(BitmapTest); + CPPUNIT_TEST(Shift_CorrectBitSet); + CPPUNIT_TEST(Multielement_Shift_CorrectBitSet); + CPPUNIT_TEST(Resize_CorrectBitSet); + CPPUNIT_TEST_SUITE_END(); - suite->addTest(new CppUnit::TestCaller("Bitmap::Resize test", - &BitmapTest::ResizeTest)); - suite->addTest(new CppUnit::TestCaller("Bitmap::Shift test", - &BitmapTest::ShiftTest)); +public: + void Shift_CorrectBitSet() + { + BKernel::Bitmap bitmap(20); + bitmap.Set(6); - return suite; -} + CPPUNIT_ASSERT(bitmap.Get(6)); + CPPUNIT_ASSERT(!bitmap.Get(5)); + CPPUNIT_ASSERT(!bitmap.Get(7)); -void -BitmapTest::ResizeTest() -{ - BKernel::Bitmap bitmap(10); - bitmap.Set(6); + bitmap.Shift(10); - CPPUNIT_ASSERT(bitmap.Get(6)); - CPPUNIT_ASSERT(!bitmap.Get(5)); - CPPUNIT_ASSERT(!bitmap.Get(7)); + CPPUNIT_ASSERT(bitmap.Get(16)); + CPPUNIT_ASSERT(!bitmap.Get(15)); + CPPUNIT_ASSERT(!bitmap.Get(17)); + CPPUNIT_ASSERT(!bitmap.Get(6)); - bitmap.Resize(20); + bitmap.Shift(-9); - CPPUNIT_ASSERT(bitmap.Get(6)); - CPPUNIT_ASSERT(!bitmap.Get(7)); - CPPUNIT_ASSERT(!bitmap.Get(19)); + CPPUNIT_ASSERT(bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(6)); + CPPUNIT_ASSERT(!bitmap.Get(8)); + CPPUNIT_ASSERT(!bitmap.Get(16)); + } - bitmap.Resize(200); - bitmap.Set(199); + void Multielement_Shift_CorrectBitSet() { + BKernel::Bitmap bitmap(200); + bitmap.Set(7); - CPPUNIT_ASSERT(bitmap.Get(6)); - CPPUNIT_ASSERT(!bitmap.Get(7)); - CPPUNIT_ASSERT(!bitmap.Get(19)); - CPPUNIT_ASSERT(bitmap.Get(199)); - CPPUNIT_ASSERT(!bitmap.Get(198)); -} + CPPUNIT_ASSERT(bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(6)); -void -BitmapTest::ShiftTest() -{ - BKernel::Bitmap bitmap(20); - bitmap.Set(6); + bitmap.Shift(100); - CPPUNIT_ASSERT(bitmap.Get(6)); - CPPUNIT_ASSERT(!bitmap.Get(5)); - CPPUNIT_ASSERT(!bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(7)); + CPPUNIT_ASSERT(bitmap.Get(107)); + CPPUNIT_ASSERT(!bitmap.Get(106)); - bitmap.Shift(10); + bitmap.Shift(-100); - CPPUNIT_ASSERT(bitmap.Get(16)); - CPPUNIT_ASSERT(!bitmap.Get(15)); - CPPUNIT_ASSERT(!bitmap.Get(17)); - CPPUNIT_ASSERT(!bitmap.Get(6)); + CPPUNIT_ASSERT(bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(107)); + CPPUNIT_ASSERT(!bitmap.Get(6)); + } - bitmap.Shift(-9); + void Resize_CorrectBitSet() + { + BKernel::Bitmap bitmap(10); + bitmap.Set(6); - CPPUNIT_ASSERT(bitmap.Get(7)); - CPPUNIT_ASSERT(!bitmap.Get(6)); - CPPUNIT_ASSERT(!bitmap.Get(8)); - CPPUNIT_ASSERT(!bitmap.Get(16)); + CPPUNIT_ASSERT(bitmap.Get(6)); + CPPUNIT_ASSERT(!bitmap.Get(5)); + CPPUNIT_ASSERT(!bitmap.Get(7)); - // Now test cross-element shifting. - bitmap.Resize(200); + bitmap.Resize(20); - CPPUNIT_ASSERT(bitmap.Get(7)); - CPPUNIT_ASSERT(!bitmap.Get(6)); + CPPUNIT_ASSERT(bitmap.Get(6)); + CPPUNIT_ASSERT(!bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(19)); - bitmap.Shift(100); + bitmap.Resize(200); + bitmap.Set(199); - CPPUNIT_ASSERT(!bitmap.Get(7)); - CPPUNIT_ASSERT(bitmap.Get(107)); - CPPUNIT_ASSERT(!bitmap.Get(106)); + CPPUNIT_ASSERT(bitmap.Get(6)); + CPPUNIT_ASSERT(!bitmap.Get(7)); + CPPUNIT_ASSERT(!bitmap.Get(19)); + CPPUNIT_ASSERT(bitmap.Get(199)); + CPPUNIT_ASSERT(!bitmap.Get(198)); + } +}; - bitmap.Shift(-100); - CPPUNIT_ASSERT(bitmap.Get(7)); - CPPUNIT_ASSERT(!bitmap.Get(107)); - CPPUNIT_ASSERT(!bitmap.Get(6)); -} +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BitmapTest, getTestSuiteName()); diff --git a/src/tests/system/kernel/util/BitmapTest.h b/src/tests/system/kernel/util/BitmapTest.h deleted file mode 100644 index b44b9bf71b..0000000000 --- a/src/tests/system/kernel/util/BitmapTest.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _bitmap_test_h_ -#define _bitmap_test_h_ - -#include - -class BitmapTest : public BTestCase { -public: - BitmapTest(std::string name = ""); - - static CppUnit::Test* Suite(); - - void ResizeTest(); - void ShiftTest(); -}; - -#endif // _bitmap_test_h_ diff --git a/src/tests/system/kernel/util/DoublyLinkedListTest.cpp b/src/tests/system/kernel/util/DoublyLinkedListTest.cpp index 1160799be2..9461edb3ba 100644 --- a/src/tests/system/kernel/util/DoublyLinkedListTest.cpp +++ b/src/tests/system/kernel/util/DoublyLinkedListTest.cpp @@ -1,192 +1,144 @@ -/* -** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the MIT License. -*/ +/* + * Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2026, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ -#include "DoublyLinkedListTest.h" - -#include -#include +#include #include +#include #include // Class used for testing without offset class ItemWithout { - public: - DoublyLinkedListLink fLink; - int32 value; +public: + DoublyLinkedListLink fLink; + int32 value; }; + // Class used for testing with offset class ItemWith { - public: - int32 value; - DoublyLinkedListLink fLink; +public: + int32 value; + DoublyLinkedListLink fLink; }; + // Class used for testing without offset class ItemVirtualWithout { - public: - virtual int32 Value(); +public: + DoublyLinkedListLink fLink; + int32 value; - DoublyLinkedListLink fLink; - int32 value; + int32 Value() { return value; } }; + // Class used for testing with offset class ItemVirtualWith { - public: - virtual int32 Value(); +public: + int32 value; + DoublyLinkedListLink fLink; - int32 value; - DoublyLinkedListLink fLink; + int32 Value() { return value; } }; -int32 -ItemVirtualWithout::Value() -{ - return value; -} +template +class DoublyLinkedListTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(DoublyLinkedListTest); + CPPUNIT_TEST(IsEmpty_ReturnsFalse); + CPPUNIT_TEST(Count_ReturnsItemCount); + CPPUNIT_TEST(Iterating_ItemsEqualAddedItems); + CPPUNIT_TEST(RemoveHead_ReturnsFirstItem); + CPPUNIT_TEST(HeadAndEverySecondItemRemoved_AddingFirstItem_ItemsAndCountAreCorrect); + CPPUNIT_TEST_SUITE_END(); + typedef DoublyLinkedList > List; + List* fList; + static const int fValueCount = 10; + Item fItems[fValueCount]; -int32 -ItemVirtualWith::Value() -{ - return value; -} - - -// #pragma mark - - - -DoublyLinkedListTest::DoublyLinkedListTest(std::string name) - : BTestCase(name) -{ -} - - -CppUnit::Test* -DoublyLinkedListTest::Suite() { - CppUnit::TestSuite *suite = new CppUnit::TestSuite("DLL"); - - suite->addTest(new CppUnit::TestCaller("DoublyLinkedList::no offset", &DoublyLinkedListTest::WithoutOffsetTest)); - suite->addTest(new CppUnit::TestCaller("DoublyLinkedList::with offset", &DoublyLinkedListTest::WithOffsetTest)); - suite->addTest(new CppUnit::TestCaller("DoublyLinkedList::virtual no offset", &DoublyLinkedListTest::VirtualWithoutOffsetTest)); - suite->addTest(new CppUnit::TestCaller("DoublyLinkedList::virtual with offset", &DoublyLinkedListTest::VirtualWithOffsetTest)); - - return suite; -} - - -//! Tests the given list - -template -void -DoublyLinkedListTest::TestList() -{ - DoublyLinkedList > list; - int valueCount = 10; - Item items[valueCount]; - - // initialize - - for (int i = 0; i < valueCount; i++) { - items[i].value = i; - list.Add(&items[i]); +public: + void setUp() + { + fList = new List; + for (int i = 0; i < fValueCount; i++) { + fItems[i].value = i; + fList->Add(&fItems[i]); + } } - // list must not be empty - - CHK(!list.IsEmpty()); - - // count items in list - - int count = 0; - typename DoublyLinkedList >::Iterator - iterator = list.GetIterator(); - while (iterator.Next() != NULL) - count++; - - CHK(count == valueCount); - - // test for equality - - iterator = list.GetIterator(); - - int i = 0; - Item *item; - while ((item = iterator.Next()) != NULL) { - CHK(item->value == i); - CHK(item == &items[i]); - i++; + void tearDown() + { + delete fList; } - // remove first - - Item *first = list.RemoveHead(); - CHK(first->value == 0); - CHK(first == &items[0]); - - // remove every second - - iterator = list.GetIterator(); - i = 0; - while ((item = iterator.Next()) != NULL) { - CHK(item->value == i + 1); - - if (i % 2) - list.Remove(item); - i++; + void IsEmpty_ReturnsFalse() + { + CPPUNIT_ASSERT(!fList->IsEmpty()); } - - // re-add first - - list.Add(first); - // count again + void Count_ReturnsItemCount() + { + int count = 0; + typename List::Iterator iterator = fList->GetIterator(); + while (iterator.Next() != NULL) + count++; - count = 0; - iterator = list.GetIterator(); - while (iterator.Next() != NULL) - count++; + CPPUNIT_ASSERT(count == fValueCount); + } - CHK(count == (valueCount / 2) + 1); -} + void Iterating_ItemsEqualAddedItems() + { + int i = 0; + typename List::Iterator iterator = fList->GetIterator(); + Item* item; + while ((item = iterator.Next()) != NULL) { + CPPUNIT_ASSERT(item->value == i); + CPPUNIT_ASSERT(item == &fItems[i]); + i++; + } + } + + void RemoveHead_ReturnsFirstItem() + { + Item* first = fList->RemoveHead(); + CPPUNIT_ASSERT(first->value == 0); + CPPUNIT_ASSERT(first == &fItems[0]); + } + + void HeadAndEverySecondItemRemoved_AddingFirstItem_ItemsAndCountAreCorrect() + { + fList->RemoveHead(); + typename List::Iterator iterator = fList->GetIterator(); + int i = 0; + Item* item; + while ((item = iterator.Next()) != NULL) { + CPPUNIT_ASSERT(item->value == i + 1); + + if (i % 2) + fList->Remove(item); + i++; + } + + fList->Add(&fItems[0]); + + int count = 0; + iterator = fList->GetIterator(); + while (iterator.Next() != NULL) + count++; + + CPPUNIT_ASSERT(count == (fValueCount / 2) + 1); + } +}; -//! Test using no offset, no virtual - -void -DoublyLinkedListTest::WithoutOffsetTest() { - TestList(); -} - - -//! Test using offset, no virtual - -void -DoublyLinkedListTest::WithOffsetTest() { - TestList(); -} - - -//! Test using no offset, virtual - -void -DoublyLinkedListTest::VirtualWithoutOffsetTest() { - TestList(); -} - - -//! Test using offset, virtual - -void -DoublyLinkedListTest::VirtualWithOffsetTest() { - TestList(); -} - +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DoublyLinkedListTest, getTestSuiteName()); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DoublyLinkedListTest, getTestSuiteName()); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DoublyLinkedListTest, getTestSuiteName()); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DoublyLinkedListTest, getTestSuiteName()); diff --git a/src/tests/system/kernel/util/DoublyLinkedListTest.h b/src/tests/system/kernel/util/DoublyLinkedListTest.h deleted file mode 100644 index f36c76f840..0000000000 --- a/src/tests/system/kernel/util/DoublyLinkedListTest.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _DOUBLY_LINKED_LIST_TEST_H_ -#define _DOUBLY_LINKED_LIST_TEST_H_ - -#include - -class DoublyLinkedListTest : public BTestCase { - public: - DoublyLinkedListTest(std::string name = ""); - - static CppUnit::Test *Suite(); - - void WithoutOffsetTest(); - void WithOffsetTest(); - void VirtualWithoutOffsetTest(); - void VirtualWithOffsetTest(); - - private: - template void TestList(); -}; - -#endif /* _DOUBLY_LINKED_LIST_TEST_H_ */ diff --git a/src/tests/system/kernel/util/Jamfile b/src/tests/system/kernel/util/Jamfile index 3a2d9945cb..e547480d15 100644 --- a/src/tests/system/kernel/util/Jamfile +++ b/src/tests/system/kernel/util/Jamfile @@ -12,7 +12,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src system kernel util ] ; UnitTestLib libkernelutilstest.so : KernelUtilsTestAddon.cpp # AVLTreeMapTest.cpp - BOpenHashTableTest.cpp + OpenHashTableTest.cpp BitmapTest.cpp SinglyLinkedListTest.cpp DoublyLinkedListTest.cpp diff --git a/src/tests/system/kernel/util/KernelUtilsTestAddon.cpp b/src/tests/system/kernel/util/KernelUtilsTestAddon.cpp index 05b1891010..f8a3712c81 100644 --- a/src/tests/system/kernel/util/KernelUtilsTestAddon.cpp +++ b/src/tests/system/kernel/util/KernelUtilsTestAddon.cpp @@ -1,25 +1,13 @@ +/* + * Copyright 2003-2026, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + #include #include -//#include "AVLTreeMapTest.h" -#include "BOpenHashTableTest.h" -#include "BitmapTest.h" -#include "DoublyLinkedListTest.h" -#include "SinglyLinkedListTest.h" -#include "VectorMapTest.h" -#include "VectorSetTest.h" -#include "VectorTest.h" - -BTestSuite* getTestSuite() { - BTestSuite *suite = new BTestSuite("KernelUtils"); -// suite->addTest("AVLTreeMap", AVLTreeMapTest::Suite()); - suite->addTest("BOpenHashTable", BOpenHashTableTest::Suite()); - suite->addTest("Bitmap", BitmapTest::Suite()); - suite->addTest("SinglyLinkedList", SinglyLinkedListTest::Suite()); - suite->addTest("DoublyLinkedList", DoublyLinkedListTest::Suite()); - suite->addTest("VectorMap", VectorMapTest::Suite()); - suite->addTest("VectorSet", VectorSetTest::Suite()); - suite->addTest("Vector", VectorTest::Suite()); - return suite; +const char* getTestSuiteName() { + return "KernelUtils"; } diff --git a/src/tests/system/kernel/util/OpenHashTableTest.cpp b/src/tests/system/kernel/util/OpenHashTableTest.cpp new file mode 100644 index 0000000000..6a6c565951 --- /dev/null +++ b/src/tests/system/kernel/util/OpenHashTableTest.cpp @@ -0,0 +1,326 @@ +/* + * Copyright 2020-2026, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include +#include +#include + + +namespace { + +class Entry { +public: + Entry(uint32_t value) + : + fValue(value), + fNext(NULL) + { + } + + const uint32_t Value() const { return fValue; } + + Entry* Next() const { return fNext; } + +private: + uint32_t fValue; + Entry* fNext; + + friend class EntryDefinition; +}; + + +class EntryDefinition { +public: + typedef uint32_t KeyType; + typedef Entry ValueType; + + size_t HashKey(const KeyType& key) const { return key; } + + size_t Hash(Entry* entry) const { return entry->fValue; } + + bool Compare(const KeyType& key, Entry* entry) const { return key == entry->fValue; } + + Entry*& GetLink(Entry* entry) const { return entry->fNext; } +}; + +} // namespace + + +class OpenHashTableTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(OpenHashTableTest); + CPPUNIT_TEST(Init_ZeroSize_ReturnsOk); + CPPUNIT_TEST(Clear_EmptiesTable); + CPPUNIT_TEST(Clear_ReturnElementsSet_ClearsAndReturnsEntries); + CPPUNIT_TEST(Insert_AutoExpandDisabled_InsertsEntriesWithoutResize); + CPPUNIT_TEST(Insert_DuplicateEntry_ReturnsError); + CPPUNIT_TEST(Insert_InsertsEntry_ReturnsOk); + CPPUNIT_TEST(InsertUnchecked_InsertsEntry_ReturnsOk); + CPPUNIT_TEST(IterateAndCount_IteratesEntries_ReturnsCorrectCount); + CPPUNIT_TEST(Lookup_ExistingKey_ReturnsEntry); + CPPUNIT_TEST(Remove_ExistingEntry_ReturnsOk); + CPPUNIT_TEST(Remove_NotPresent_ReturnsNull); + CPPUNIT_TEST(RemoveUnchecked_RemovesEntry_ReturnsOk); + CPPUNIT_TEST(Resize_InsertsManyEntries_ResizesSuccessfully); + CPPUNIT_TEST_SUITE_END(); + +public: + void Init_ZeroSize_ReturnsOk() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); + } + + void Clear_EmptiesTable() + { + const size_t kEntryCount = 3; + + BObjectList entries(20); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); + + for (uint32_t i = 0; i < kEntryCount; ++i) { + Entry* entry = new Entry(i); + entries.AddItem(entry); + CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); + } + + CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount); + CPPUNIT_ASSERT(table.Lookup(2) != NULL); + + CPPUNIT_ASSERT_EQUAL(table.Clear(false), NULL); + CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0); + CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL); + CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false); + } + + void Clear_ReturnElementsSet_ClearsAndReturnsEntries() + { + // Same as ClearTest(), except that Clear(true) is called, which tells + // the BOpenHashTable to return a linked list of entries before clearing + // the table. + const size_t kEntryCount = 3; + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); + + for (uint32_t i = 0; i < kEntryCount; ++i) { + Entry* entry = new Entry(i); + CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); + } + + CPPUNIT_ASSERT_EQUAL(table.CountElements(), kEntryCount); + CPPUNIT_ASSERT(table.Lookup(2) != NULL); + + Entry* head = table.Clear(true); + CPPUNIT_ASSERT(head != NULL); + + CPPUNIT_ASSERT_EQUAL(table.CountElements(), 0); + CPPUNIT_ASSERT_EQUAL(table.Lookup(2), NULL); + CPPUNIT_ASSERT_EQUAL(table.GetIterator().HasNext(), false); + + size_t items_returned = 0; + while (head != NULL) { + Entry* next = head->Next(); + delete head; + head = next; + + ++items_returned; + } + + CPPUNIT_ASSERT_EQUAL(items_returned, kEntryCount); + } + + void Insert_AutoExpandDisabled_InsertsEntriesWithoutResize() + { + // Insert multiple items into a table with a fixed size of 1. This + // essentially turns this BOpenHashTable into a linked list, since resize + // will never occur. + Entry entry1(123); + Entry entry2(456); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(1), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry1), B_OK); + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry2), B_OK); + CPPUNIT_ASSERT_EQUAL(table.CountElements(), 2); + } + + void Insert_DuplicateEntry_ReturnsError() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + + CPPUNIT_ASSERT_DEBUGGER(table.Insert(&entry)); + + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + + // The item can basically never be removed now since there is a cycle, + // but we'll break into the debugger on remove when that happens as well. + CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry)); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + + CPPUNIT_ASSERT_DEBUGGER(table.Remove(&entry)); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + } + + void Insert_InsertsEntry_ReturnsOk() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); + } + + void InsertUnchecked_InsertsEntry_ReturnsOk() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); + + table.InsertUnchecked(&entry); + } + + void IterateAndCount_IteratesEntries_ReturnsCorrectCount() + { + const size_t kEntryCount = 20; + + BObjectList entries(20); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(kEntryCount * 2), B_OK); + + for (uint32_t i = 0; i < kEntryCount; ++i) { + Entry* entry = new Entry(i); + entries.AddItem(entry); + CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); + } + + // Verify that the table contains the expected values. + uint64_t map = 0; + BOpenHashTable::Iterator iterator = table.GetIterator(); + while (iterator.HasNext()) { + Entry* entry = iterator.Next(); + CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value())); + map |= (1 << entry->Value()); + } + + CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1); + CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements()); + } + + void Lookup_ExistingKey_ReturnsEntry() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + } + + void Remove_ExistingEntry_ReturnsOk() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + + table.Remove(&entry); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), NULL); + } + + void Remove_NotPresent_ReturnsNull() + { + Entry entry1(123); + Entry entry2(456); + Entry entry3(789); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(), B_OK); + + // Only add the first two entries. + table.Insert(&entry1); + table.Insert(&entry2); + + // entry3 is not in the table, but we'll remove it anyway. + table.Remove(&entry3); + table.RemoveUnchecked(&entry3); + + // The original two entries should still be there. + CPPUNIT_ASSERT_EQUAL(table.CountElements(), 2); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry1); + CPPUNIT_ASSERT_EQUAL(table.Lookup(456), &entry2); + CPPUNIT_ASSERT_EQUAL(table.Lookup(789), NULL); + } + + void RemoveUnchecked_RemovesEntry_ReturnsOk() + { + Entry entry(123); + + BOpenHashTable table; + CPPUNIT_ASSERT_EQUAL(table.Init(0), B_OK); + + CPPUNIT_ASSERT_EQUAL(table.Insert(&entry), B_OK); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), &entry); + + table.RemoveUnchecked(&entry); + CPPUNIT_ASSERT_EQUAL(table.Lookup(123), NULL); + } + + void Resize_InsertsManyEntries_ResizesSuccessfully() + { + // This is the same as IterateAndCountTest, except that the table will + // be resized mid insertion. + const size_t kEntryCount = 20; + BObjectList entries(20); + BOpenHashTable table; + + // Start off with capacity for 8 elements. This will mean that the table + // will be resized in the loop below since we are inserting 20 elements. + CPPUNIT_ASSERT_EQUAL(table.Init(8), B_OK); + + for (uint32_t i = 0; i < kEntryCount; ++i) { + Entry* entry = new Entry(i); + entries.AddItem(entry); + CPPUNIT_ASSERT_EQUAL(table.Insert(entry), B_OK); + } + + // Verify that after resize the expected elements are present within + // the table. + uint64_t map = 0; + BOpenHashTable::Iterator iterator = table.GetIterator(); + while (iterator.HasNext()) { + Entry* entry = iterator.Next(); + CPPUNIT_ASSERT_EQUAL(0, map & (1 << entry->Value())); + map |= (1 << entry->Value()); + } + + CPPUNIT_ASSERT_EQUAL(map, (1 << kEntryCount) - 1); + CPPUNIT_ASSERT_EQUAL(kEntryCount, table.CountElements()); + } +}; + + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(OpenHashTableTest, getTestSuiteName()); diff --git a/src/tests/system/kernel/util/OrderedMapTest.h b/src/tests/system/kernel/util/OrderedMapTest.h deleted file mode 100644 index 4eb49c9eb4..0000000000 --- a/src/tests/system/kernel/util/OrderedMapTest.h +++ /dev/null @@ -1,1140 +0,0 @@ -// OrderedMapTest.h -#ifndef _ordered_map_test_h_ -#define _ordered_map_test_h_ - -#include -#include -#include - -using std::map; - -#include -#include -#include -#include -#include - -#include "common.h" - -// That's how it should be, but we need to work around compiler bugs -// (in this case an unimplemented feature). -/* -#define _ORDERED_MAP_TEST_TEMPLATE_LIST \ - template class CompareStrategy> \ - class TestStrategy> -*/ -#define _ORDERED_MAP_TEST_TEMPLATE_LIST \ - template class TestStrategy> -#define _ORDERED_MAP_TEST_CLASS_NAME OrderedMapTest - -//template class CompareStrategy> class TestStrategy> -template class TestStrategy> -class OrderedMapTest : public BTestCase { -public: - OrderedMapTest(std::string name = ""); - - static CppUnit::Test* Suite(); - - void ConstructorTest(); - void InsertTest(); - void PutTest(); - void GetTest(); - void RemoveTest(); - void EraseTest(); - void MakeEmptyTest(); - void IndexAccessTest(); - void FindTest(); - void FindCloseTest(); - void IteratorTest(); - -private: - template - void TestList(List &list, typename List::ValueType *values, int valueCount); -}; - -// SimpleValueStrategy -template -class SimpleValueStrategy { -public: - typedef _Value Value; - - SimpleValueStrategy(int32 differentValues = 100000) - : fDifferentValues(differentValues) - { - srand(0); - } - - Value Generate(); - -private: - int32 fDifferentValues; -}; - -template<> -int -SimpleValueStrategy::Generate() -{ - return rand() % fDifferentValues; -} - -template<> -string -SimpleValueStrategy::Generate() -{ - char buffer[10]; - sprintf(buffer, "%ld", rand() % fDifferentValues); - return string(buffer); -} - -// PairEntryStrategy -template -class PairEntryStrategy { -public: - typedef _KeyStrategy KeyStrategy; - typedef _ValueStrategy ValueStrategy; - typedef typename KeyStrategy::Value Key; - typedef typename ValueStrategy::Value Value; - - inline Key GenerateKey() - { - return fKeyStrategy.Generate(); - } - - inline Value GenerateValue() - { - return fValueStrategy.Generate(); - } - - inline void Generate(Key &key, Value &value) - { - key = GenerateKey(); - value = GenerateValue(); - } - -private: - KeyStrategy fKeyStrategy; - ValueStrategy fValueStrategy; -}; - -// ImplicitKeyStrategy -template -class ImplicitKeyStrategy { -public: - typedef _KeyStrategy KeyStrategy; - typedef _ValueStrategy ValueStrategy; - typedef typename KeyStrategy::Value Key; - typedef typename ValueStrategy::Value Value; - - inline Key GenerateKey() - { - return fKeyStrategy.Generate(); - } - - inline Value GenerateValue() - { - return fValueStrategy.Generate(); - } - - inline void Generate(Key &key, Value &value) - { - value = GenerateValue(); - key = fGetKey(value); - } - -private: - KeyStrategy fKeyStrategy; - ValueStrategy fValueStrategy; - GetKey fGetKey; -}; - -// Non-template wrapper for the Ascending compare strategy. -// Work-around for our compiler not eating nested template template -// parameters. -struct Ascending { - template - class Strategy : public KernelUtilsOrder::Ascending {}; -}; - -// Non-template wrapper for the Descending compare strategy. -// Work-around for our compiler not eating nested template template -// parameters. -struct Descending { - template - class Strategy : public KernelUtilsOrder::Descending {}; -}; - -// CompareWrapper -template -class CompareWrapper { -public: - inline bool operator()(const Value &a, const Value &b) const - { - return (fCompare(a, b) < 0); - } - -private: - Compare fCompare; -}; - - -// TestIterator -template -class TestIterator { -private: - typedef TestIterator - Iterator; - -public: - inline TestIterator(TestMap *s, MyIterator myIt, ReferenceIterator refIt) - : fMap(s), - fMyIterator(myIt), - fReferenceIterator(refIt) - { - } - - inline TestIterator(const Iterator &other) - : fMap(other.fMap), - fMyIterator(other.fMyIterator), - fReferenceIterator(other.fReferenceIterator) - { - CHK(fMyIterator == other.fMyIterator); - } - - inline Iterator &operator++() - { - MyIterator &myResult = ++fMyIterator; - ReferenceIterator &refResult = ++fReferenceIterator; - if (refResult == fMap->fReferenceMap.end()) - CHK(myResult == fMap->fMyMap.End()); - else { - CHK(myResult->Key() == refResult->first); - CHK(myResult->Value() == refResult->second); - } - return *this; - } - - inline Iterator operator++(int) - { - MyIterator oldMyResult = fMyIterator; - MyIterator myResult = fMyIterator++; - ReferenceIterator refResult = fReferenceIterator++; - CHK(oldMyResult == myResult); - if (refResult == fMap->fReferenceMap.end()) - CHK(myResult == fMap->fMyMap.End()); - else { - CHK(myResult->Key() == refResult->first); - CHK(myResult->Value() == refResult->second); - } - return Iterator(fMap, myResult, refResult); - } - - inline Iterator &operator--() - { - MyIterator &myResult = --fMyIterator; - ReferenceIterator &refResult = --fReferenceIterator; - CHK(myResult->Key() == refResult->first); - CHK(myResult->Value() == refResult->second); - return *this; - } - - inline Iterator operator--(int) - { - MyIterator oldMyResult = fMyIterator; - MyIterator myResult = fMyIterator--; - ReferenceIterator refResult = fReferenceIterator--; - CHK(oldMyResult == myResult); - CHK(myResult->Key() == refResult->first); - CHK(myResult->Value() == refResult->second); - return Iterator(fMap, myResult, refResult); - } - - inline Iterator &operator=(const Iterator &other) - { - fMap = other.fMap; - fMyIterator = other.fMyIterator; - fReferenceIterator = other.fReferenceIterator; - CHK(fMyIterator == other.fMyIterator); - return *this; - } - - inline bool operator==(const Iterator &other) const - { - bool result = (fMyIterator == other.fMyIterator); - CHK((fReferenceIterator == other.fReferenceIterator) == result); - return result; - } - - inline bool operator!=(const Iterator &other) const - { - bool result = (fMyIterator != other.fMyIterator); - CHK((fReferenceIterator != other.fReferenceIterator) == result); - return result; - } - - inline Entry operator*() const - { - Entry entry = *fMyIterator; - CHK(entry.Key() == fReferenceIterator->first); - CHK(entry.Value() == fReferenceIterator->second); - return entry; - } - - inline Entry operator->() const - { - Entry entry = fMyIterator.operator->(); - CHK(entry.Key() == fReferenceIterator->first); - CHK(entry.Value() == fReferenceIterator->second); - return entry; - } - - inline operator bool() const - { - bool result = fMyIterator; - CHK((fMyIterator == fMap->fMyMap.Null()) != result); - return result; - } - -public: - TestMap *fMap; - MyIterator fMyIterator; - ReferenceIterator fReferenceIterator; -}; - -// TestMap -template -class TestMap { -public: - typedef TestMap Class; - - typedef typename MyMap::Iterator MyIterator; - typedef typename ReferenceMap::iterator ReferenceIterator; - typedef typename MyMap::ConstIterator MyConstIterator; - typedef typename ReferenceMap::const_iterator ReferenceConstIterator; - typedef typename MyMap::Entry Entry; - typedef typename MyMap::ConstEntry ConstEntry; - typedef TestIterator Iterator; - typedef TestIterator ConstIterator; - - TestMap() - : fMyMap(), - fReferenceMap(), - fChecking(true) - { - } - - void Insert(const Key &key, const Value &value) - { - CHK(fMyMap.Insert(key, value) == B_OK); - fReferenceMap[key] = value; - Check(); - } - - void Put(const Key &key, const Value &value) - { - CHK(fMyMap.Put(key, value) == B_OK); - fReferenceMap[key] = value; - Check(); - } - - Value &Get(const Key &key) - { - Value &value = fMyMap.Get(key); - CHK(value == fReferenceMap[key]); - return value; - } - - const Value &Get(const Key &key) const - { - const Value &value = fMyMap.Get(key); - CHK(value == fReferenceMap.find(key)->second); - return value; - } - - void Remove(const Key &key) - { - int32 oldCount = Count(); - ReferenceIterator it = fReferenceMap.find(key); - if (it != fReferenceMap.end()) - fReferenceMap.erase(it); - int32 newCount = fReferenceMap.size(); - CHK(fMyMap.Remove(key) == oldCount - newCount); - Check(); - } - - Iterator Erase(const Iterator &iterator) - { - bool outOfRange - = (iterator.fReferenceIterator == fReferenceMap.end()); - MyIterator myIt = fMyMap.Erase(iterator.fMyIterator); - if (outOfRange) { - CHK(myIt == fMyMap.Null()); - return Iterator(this, myIt, fReferenceMap.end()); - } - Key nextKey; - ReferenceIterator refIt = iterator.fReferenceIterator; - ++refIt; - bool noNextEntry = (refIt == fReferenceMap.end()); - if (!noNextEntry) - nextKey = refIt->first; - fReferenceMap.erase(iterator.fReferenceIterator); - if (noNextEntry) - refIt = fReferenceMap.end(); - else - refIt = fReferenceMap.find(nextKey); - Check(); - if (refIt == fReferenceMap.end()) - CHK(myIt == fMyMap.End()); - else { - CHK(myIt->Key() == refIt->first); - CHK(myIt->Value() == refIt->second); - } - return Iterator(this, myIt, refIt); - } - - inline int32 Count() const - { - int32 count = fReferenceMap.size(); - CHK(fMyMap.Count() == count); - return count; - } - - inline bool IsEmpty() const - { - bool result = fReferenceMap.empty(); - CHK(fMyMap.IsEmpty() == result); - return result; - } - - void MakeEmpty() - { - fMyMap.MakeEmpty(); - fReferenceMap.clear(); - Check(); - } - - inline Iterator Begin() - { - return Iterator(this, fMyMap.Begin(), fReferenceMap.begin()); - } - - inline ConstIterator Begin() const - { - return ConstIterator(this, fMyMap.Begin(), - fReferenceMap.begin()); - } - - inline Iterator End() - { - return Iterator(this, fMyMap.End(), fReferenceMap.end()); - } - - inline ConstIterator End() const - { - return ConstIterator(this, fMyMap.End(), fReferenceMap.end()); - } - - inline Iterator Null() - { - return Iterator(this, fMyMap.Null(), fReferenceMap.end()); - } - - inline ConstIterator Null() const - { - return ConstIterator(this, fMyMap.Null(), fReferenceMap.end()); - } - - // for testing only - inline Iterator IteratorForIndex(int32 index) - { - if (index < 0 || index > Count()) - return End(); - MyIterator myIt = fMyMap.Begin(); - ReferenceIterator refIt = fReferenceMap.begin(); - for (int32 i = 0; i < index; i++) { - ++myIt; - ++refIt; - } - return Iterator(this, myIt, refIt); - } - - // for testing only - inline ConstIterator IteratorForIndex(int32 index) const - { - if (index < 0 || index > Count()) - return End(); - MyConstIterator myIt = fMyMap.Begin(); - ReferenceConstIterator refIt = fReferenceMap.begin(); - for (int32 i = 0; i < index; i++) { - ++myIt; - ++refIt; - } - return ConstIterator(this, myIt, refIt); - } - - Iterator Find(const Key &key) - { - MyIterator myIt = fMyMap.Find(key); - ReferenceIterator refIt = fReferenceMap.find(key); - if (refIt == fReferenceMap.end()) - CHK(myIt = fMyMap.End()); - else { - CHK(myIt->Key() == refIt->first); - CHK(myIt->Value() == refIt->second); - } - return Iterator(this, myIt, refIt); - } - - ConstIterator Find(const Key &key) const - { - MyConstIterator myIt = fMyMap.Find(key); - ReferenceConstIterator refIt = fReferenceMap.find(key); - if (refIt == fReferenceMap.end()) - CHK(myIt = fMyMap.End()); - else { - CHK(myIt->Key() == refIt->first); - CHK(myIt->Value() == refIt->second); - } - return ConstIterator(this, myIt, refIt); - } - - Iterator FindClose(const Key &key, bool less) - { - MyIterator myIt = fMyMap.FindClose(key, less); - if (myIt == fMyMap.End()) { - if (fMyMap.Count() > 0) { - if (less) - CHK(fCompare(fMyMap.Begin()->Key(), key) > 0); - else - CHK(fCompare((--MyIterator(myIt))->Key(), key) < 0); - } - return End(); - } - if (less) { - CHK(fCompare(myIt->Key(), key) <= 0); - MyIterator nextMyIt(myIt); - ++nextMyIt; - if (nextMyIt != fMyMap.End()) - CHK(fCompare(nextMyIt->Key(), key) > 0); - } else { - CHK(fCompare(myIt->Key(), key) >= 0); - if (myIt != fMyMap.Begin()) { - MyIterator prevMyIt(myIt); - --prevMyIt; - CHK(fCompare(prevMyIt->Key(), key) < 0); - } - } - return Iterator(this, myIt, fReferenceMap.find(myIt->Key())); - } - - ConstIterator FindClose(const Key &key, bool less) const - { - MyConstIterator myIt = fMyMap.FindClose(key, less); - if (myIt == fMyMap.End()) { - if (fMyMap.Count() > 0) { - if (less) - CHK(fCompare(fMyMap.Begin()->Key(), key) > 0); - else - CHK(fCompare((--MyConstIterator(myIt))->Key(), key) < 0); - } - return End(); - } - if (less) { - CHK(fCompare(myIt->Key(), key) <= 0); - MyConstIterator nextMyIt(myIt); - ++nextMyIt; - if (nextMyIt != fMyMap.End()) - CHK(fCompare(nextMyIt->Key(), key) > 0); - } else { - CHK(fCompare(myIt->Key(), key) >= 0); - if (myIt != fMyMap.Begin()) { - MyConstIterator prevMyIt(myIt); - --prevMyIt; - CHK(fCompare(prevMyIt->Key(), key) < 0); - } - } - return ConstIterator(this, myIt, fReferenceMap.find(myIt->Key())); - } - - void SetChecking(bool enable) - { - fChecking = enable; - } - - void Check() const - { - if (fChecking) { - int32 count = fReferenceMap.size(); - CHK(fMyMap.Count() == count); - CHK(fMyMap.IsEmpty() == fReferenceMap.empty()); - MyConstIterator myIt = fMyMap.Begin(); - ReferenceConstIterator refIt = fReferenceMap.begin(); - for (int32 i = 0; i < count; i++, ++myIt, ++refIt) { - CHK(myIt->Key() == refIt->first); - CHK(myIt->Value() == refIt->second); - CHK((*myIt).Key() == refIt->first); - CHK((*myIt).Value() == refIt->second); - } - CHK(myIt == fMyMap.End()); - } - } - -//private: -public: - MyMap fMyMap; - ReferenceMap fReferenceMap; - bool fChecking; - Compare fCompare; -}; - - -// TestStrategy -template