Repository: lucy-clownfish
Updated Branches:
  refs/heads/master cdbcf1b3c -> fbaafea1c


Fix HashIterator error message

When accessing a HashIterator before calling Next, the wrong error was
thrown because (size_t)-1 is always larger than the Hash's capacity.
Move the check before the check for end of iteration.

This broke when upgrading Hash to size_t indices.

Fixes CLOWNFISH-98.


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

Branch: refs/heads/master
Commit: 732f7508ebcf461bf0d7efc9caf3a9f4b69af135
Parents: cdbcf1b
Author: Nick Wellnhofer <[email protected]>
Authored: Sat May 14 17:54:21 2016 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Sun May 15 12:09:33 2016 +0200

----------------------------------------------------------------------
 runtime/core/Clownfish/HashIterator.c          | 16 ++++++++--------
 runtime/core/Clownfish/Test/TestHashIterator.c | 11 ++++++++++-
 2 files changed, 18 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/732f7508/runtime/core/Clownfish/HashIterator.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/HashIterator.c 
b/runtime/core/Clownfish/HashIterator.c
index 806c325..da0ddf8 100644
--- a/runtime/core/Clownfish/HashIterator.c
+++ b/runtime/core/Clownfish/HashIterator.c
@@ -82,12 +82,12 @@ HashIter_Get_Key_IMP(HashIterator *self) {
     if (self->capacity != self->hash->capacity) {
         THROW(ERR, "Hash modified during iteration.");
     }
-    if (self->tick >= self->capacity) {
-        THROW(ERR, "Invalid call to Get_Key after end of iteration.");
-    }
-    else if (self->tick == (size_t)-1) {
+    if (self->tick == (size_t)-1) {
         THROW(ERR, "Invalid call to Get_Key before iteration.");
     }
+    else if (self->tick >= self->capacity) {
+        THROW(ERR, "Invalid call to Get_Key after end of iteration.");
+    }
 
     HashEntry *const entry
         = (HashEntry*)self->hash->entries + self->tick;
@@ -102,12 +102,12 @@ HashIter_Get_Value_IMP(HashIterator *self) {
     if (self->capacity != self->hash->capacity) {
         THROW(ERR, "Hash modified during iteration.");
     }
-    if (self->tick >= self->capacity) {
-        THROW(ERR, "Invalid call to Get_Value after end of iteration.");
-    }
-    else if (self->tick == (size_t)-1) {
+    if (self->tick == (size_t)-1) {
         THROW(ERR, "Invalid call to Get_Value before iteration.");
     }
+    else if (self->tick >= self->capacity) {
+        THROW(ERR, "Invalid call to Get_Value after end of iteration.");
+    }
 
     HashEntry *const entry
         = (HashEntry*)self->hash->entries + self->tick;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/732f7508/runtime/core/Clownfish/Test/TestHashIterator.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHashIterator.c 
b/runtime/core/Clownfish/Test/TestHashIterator.c
index 3822b08..fac7d69 100644
--- a/runtime/core/Clownfish/Test/TestHashIterator.c
+++ b/runtime/core/Clownfish/Test/TestHashIterator.c
@@ -122,6 +122,7 @@ test_Get_Key_and_Get_Value(TestBatchRunner *runner) {
     Hash   *hash = Hash_new(0);
     String *str  = Str_newf("foo");
     Hash_Store(hash, str, (Obj*)str);
+    bool ok;
 
     HashIterator *iter = HashIter_new(hash);
     DECREF(hash);
@@ -129,11 +130,15 @@ test_Get_Key_and_Get_Value(TestBatchRunner *runner) {
     Err *get_key_error = Err_trap(S_invoke_Get_Key, iter);
     TEST_TRUE(runner, get_key_error != NULL,
               "Get_Key throws exception before first call to Next.");
+    ok = Str_Contains_Utf8(Err_Get_Mess(get_key_error), "before", 6);
+    TEST_TRUE(runner, ok, "Get_Key before Next throws correct message");
     DECREF(get_key_error);
 
     Err *get_value_error = Err_trap(S_invoke_Get_Value, iter);
     TEST_TRUE(runner, get_value_error != NULL,
               "Get_Value throws exception before first call to Next.");
+    ok = Str_Contains_Utf8(Err_Get_Mess(get_value_error), "before", 6);
+    TEST_TRUE(runner, ok, "Get_Value before Next throws correct message");
     DECREF(get_value_error);
 
     HashIter_Next(iter);
@@ -146,11 +151,15 @@ test_Get_Key_and_Get_Value(TestBatchRunner *runner) {
     get_key_error = Err_trap(S_invoke_Get_Key, iter);
     TEST_TRUE(runner, get_key_error != NULL,
               "Get_Key throws exception after end of iteration.");
+    ok = Str_Contains_Utf8(Err_Get_Mess(get_key_error), "after", 5);
+    TEST_TRUE(runner, ok, "Get_Key after end throws correct message");
     DECREF(get_key_error);
 
     get_value_error = Err_trap(S_invoke_Get_Value, iter);
     TEST_TRUE(runner, get_value_error != NULL,
               "Get_Value throws exception after end of iteration.");
+    ok = Str_Contains_Utf8(Err_Get_Mess(get_value_error), "after", 5);
+    TEST_TRUE(runner, ok, "Get_Value after end throws correct message");
     DECREF(get_value_error);
 
 
@@ -232,7 +241,7 @@ test_tombstone(TestBatchRunner *runner) {
 
 void
 TestHashIterator_Run_IMP(TestHashIterator *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 17);
+    TestBatchRunner_Plan(runner, (TestBatch*)self, 21);
     srand((unsigned int)time((time_t*)NULL));
     test_Next(runner);
     test_empty(runner);

Reply via email to