Improve Hash test coverage

Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b12b00f8
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b12b00f8
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b12b00f8

Branch: refs/heads/master
Commit: b12b00f8bbb106b341cea724f5317ff2d6fa67ec
Parents: ebf290c
Author: Nick Wellnhofer <[email protected]>
Authored: Wed May 11 17:17:54 2016 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Sun May 15 17:57:34 2016 +0200

----------------------------------------------------------------------
 runtime/core/Clownfish/Test/TestHash.c | 70 ++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b12b00f8/runtime/core/Clownfish/Test/TestHash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHash.c 
b/runtime/core/Clownfish/Test/TestHash.c
index e77c816..b00d891 100644
--- a/runtime/core/Clownfish/Test/TestHash.c
+++ b/runtime/core/Clownfish/Test/TestHash.c
@@ -19,6 +19,7 @@
 
 #define CFISH_USE_SHORT_NAMES
 #define TESTCFISH_USE_SHORT_NAMES
+#define C_CFISH_HASH
 
 #include "Clownfish/Test/TestHash.h"
 
@@ -97,6 +98,9 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
     TEST_TRUE(runner, Hash_Fetch(hash, foo) == NULL,
               "Fetch against non-existent key returns NULL");
 
+    String *twelve = (String*)Hash_Fetch_Utf8(hash, "12", 2);
+    TEST_TRUE(runner, Str_Equals_Utf8(twelve, "12", 2), "Fetch_Utf8");
+
     Obj *stored_foo = INCREF(foo);
     Hash_Store(hash, forty, stored_foo);
     TEST_TRUE(runner, Str_Equals(foo, Hash_Fetch(hash, forty)),
@@ -118,6 +122,12 @@ test_Store_and_Fetch(TestBatchRunner *runner) {
     DECREF(Hash_Delete(dupe, forty));
     TEST_TRUE(runner, Vec_Equals(got, (Obj*)expected), "Equals after Delete");
 
+    Obj *forty_one = Hash_Delete_Utf8(hash, "41", 2);
+    TEST_TRUE(runner, forty_one != NULL, "Delete_Utf8");
+    TEST_UINT_EQ(runner, Hash_Get_Size(hash), 98,
+                 "Delete_Utf8 decrements size");
+    DECREF(forty_one);
+
     Hash_Clear(hash);
     TEST_TRUE(runner, Hash_Fetch(hash, twenty) == NULL, "Clear");
     TEST_TRUE(runner, Hash_Get_Size(hash) == 0, "size is 0 after Clear");
@@ -213,6 +223,25 @@ test_stress(TestBatchRunner *runner) {
 }
 
 static void
+test_collision(TestBatchRunner *runner) {
+    Hash   *hash = Hash_new(0);
+    String *one  = Str_newf("A");
+    String *two  = Str_newf("P{2}|=~-ULE/d");
+
+    TEST_TRUE(runner, Str_Hash_Sum(one) == Str_Hash_Sum(two),
+              "Keys have the same hash sum");
+
+    Hash_Store(hash, one, INCREF(one));
+    Hash_Store(hash, two, INCREF(two));
+    String *elem = (String*)Hash_Fetch(hash, two);
+    TEST_TRUE(runner, elem == two, "Fetch works with collisions");
+
+    DECREF(one);
+    DECREF(two);
+    DECREF(hash);
+}
+
+static void
 test_store_skips_tombstone(TestBatchRunner *runner) {
     Hash *hash = Hash_new(0);
     size_t mask = Hash_Get_Capacity(hash) - 1;
@@ -243,15 +272,54 @@ test_store_skips_tombstone(TestBatchRunner *runner) {
     DECREF(hash);
 }
 
+static void
+test_threshold_accounting(TestBatchRunner *runner) {
+    Hash   *hash = Hash_new(20);
+    String *key  = Str_newf("key");
+
+    size_t threshold = hash->threshold;
+    Hash_Store(hash, key, (Obj*)CFISH_TRUE);
+    Hash_Delete(hash, key);
+    TEST_UINT_EQ(runner, hash->threshold, threshold - 1,
+                 "Tombstone creation decreases threshold");
+
+    Hash_Store(hash, key, (Obj*)CFISH_TRUE);
+    TEST_UINT_EQ(runner, hash->threshold, threshold,
+                 "Tombstone destruction increases threshold");
+
+    DECREF(key);
+    DECREF(hash);
+}
+
+static void
+test_tombstone_identification(TestBatchRunner *runner) {
+    Hash   *hash = Hash_new(20);
+    String *key  = Str_newf("P{2}|=~-U@!y>");
+
+    // Tombstones have a zero hash_sum.
+    TEST_UINT_EQ(runner, Str_Hash_Sum(key), 0, "Key has zero hash sum");
+
+    Hash_Store(hash, key, (Obj*)CFISH_TRUE);
+    Hash_Delete(hash, key);
+    TEST_TRUE(runner, Hash_Fetch(hash, key) == NULL,
+              "Key with zero hash sum isn't mistaken for tombstone");
+
+    DECREF(key);
+    DECREF(hash);
+}
+
 void
 TestHash_Run_IMP(TestHash *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 30);
+    TestBatchRunner_Plan(runner, (TestBatch*)self, 39);
     srand((unsigned int)time((time_t*)NULL));
     test_Equals(runner);
     test_Store_and_Fetch(runner);
     test_Keys_Values(runner);
     test_stress(runner);
+    test_collision(runner);
     test_store_skips_tombstone(runner);
+    test_threshold_accounting(runner);
+    test_tombstone_identification(runner);
 }
 
 

Reply via email to