diff --git a/src/Dict.cc b/src/Dict.cc index fa1f9e2bc9..b60eaa16c4 100644 --- a/src/Dict.cc +++ b/src/Dict.cc @@ -6,6 +6,8 @@ #include #endif +#include "3rdparty/doctest.h" + #include "Dict.h" #include "Reporter.h" @@ -21,6 +23,8 @@ // increase the size of the hash table as needed. #define DEFAULT_DICT_SIZE 16 +TEST_SUITE_BEGIN("Dict"); + class DictEntry { public: DictEntry(void* k, int l, hash_t h, void* val) @@ -55,6 +59,140 @@ public: PList inserted; // inserted while iterating }; +TEST_CASE("dict construction") + { + PDict dict; + CHECK(dict.IsOrdered() == false); + CHECK(dict.Length() == 0); + + PDict dict2(ORDERED); + CHECK(dict2.IsOrdered() == true); + CHECK(dict2.Length() == 0); + } + +TEST_CASE("dict operation") + { + PDict dict; + + uint32_t val = 10; + uint32_t key_val = 5; + + HashKey* key = new HashKey(key_val); + dict.Insert(key, &val); + CHECK(dict.Length() == 1); + + HashKey* key2 = new HashKey(key_val); + uint32_t* lookup = dict.Lookup(key2); + CHECK(*lookup == val); + + dict.Remove(key2); + CHECK(dict.Length() == 0); + uint32_t* lookup2 = dict.Lookup(key2); + CHECK(lookup2 == (uint32_t*)0); + delete key2; + + CHECK(dict.MaxLength() == 1); + CHECK(dict.NumCumulativeInserts() == 1); + + dict.Insert(key, &val); + dict.Remove(key); + + CHECK(dict.MaxLength() == 1); + CHECK(dict.NumCumulativeInserts() == 2); + + uint32_t val2 = 15; + uint32_t key_val2 = 25; + key2 = new HashKey(key_val2); + + dict.Insert(key, &val); + dict.Insert(key2, &val2); + CHECK(dict.Length() == 2); + CHECK(dict.NumCumulativeInserts() == 4); + + dict.Clear(); + CHECK(dict.Length() == 0); + + delete key; + delete key2; + } + +TEST_CASE("dict nthentry") + { + PDict unordered(UNORDERED); + PDict ordered(ORDERED); + + uint32_t val = 15; + uint32_t key_val = 5; + HashKey* okey = new HashKey(key_val); + HashKey* ukey = new HashKey(key_val); + + uint32_t val2 = 10; + uint32_t key_val2 = 25; + HashKey* okey2 = new HashKey(key_val2); + HashKey* ukey2 = new HashKey(key_val2); + + unordered.Insert(ukey, &val); + unordered.Insert(ukey2, &val2); + + ordered.Insert(okey, &val); + ordered.Insert(okey2, &val2); + + // NthEntry returns null for unordered dicts + uint32_t* lookup = unordered.NthEntry(0); + CHECK(lookup == (uint32_t*)0); + + // Ordered dicts are based on order of insertion, nothing about the + // data itself + lookup = ordered.NthEntry(0); + CHECK(*lookup == 15); + + delete okey; + delete okey2; + delete ukey; + delete ukey2; + } + +TEST_CASE("dict iteration") + { + PDict dict; + + uint32_t val = 15; + uint32_t key_val = 5; + HashKey* key = new HashKey(key_val); + + uint32_t val2 = 10; + uint32_t key_val2 = 25; + HashKey* key2 = new HashKey(key_val2); + + dict.Insert(key, &val); + dict.Insert(key2, &val2); + + HashKey* it_key; + IterCookie* it = dict.InitForIteration(); + CHECK(it != nullptr); + int count = 0; + + while ( uint32_t* entry = dict.NextEntry(it_key, it) ) + { + if ( count == 0 ) + { + CHECK(it_key->Hash() == key2->Hash()); + CHECK(*entry == 10); + } + else + { + CHECK(it_key->Hash() == key->Hash()); + CHECK(*entry == 15); + } + count++; + + delete it_key; + } + + delete key; + delete key2; + } + Dictionary::Dictionary(dict_order ordering, int initial_size) { tbl = 0; @@ -632,3 +770,5 @@ void generic_delete_func(void* v) { free(v); } + +TEST_SUITE_END();