Repository: keon/algorithms
Pull request #386 (2018-07-29 10:47:06)

Add test for map
(Put an `X` inside the `[ ]` to denote check mark `[X]`.)


- [x] **If creating a new file :**
  - [x] added links to it in the README files ?
  - [x] included tests with it ?
  - [x] added description (overview of algorithm, time and space compleixty, and possible edge case) in docstrings ?

- [ ] **if done some changes :**
  - [ ] wrote short description in the PR explaining what the changes do ?
  - [ ] Fixes #[issue number] if related to any issue

- [ ] **other**


coveralls: ## Pull Request Test Coverage Report for [Build 706](https://coveralls.io/builds/18215530)

* **122** of **123**   **(99.19%)**  changed or added relevant lines in **1** file are covered.
* **1** unchanged line in **1** file lost coverage.
* Overall coverage increased (+**0.2%**) to **71.556%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [tests/test_map.py](https://coveralls.io/builds/18215530/source?filename=tests%2Ftest_map.py#L152) | 122 | 123 | 99.19%
<!-- | **Total:** | **122** | **123** | **99.19%** | -->

|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [algorithms/linkedlist/is_palindrome.py](https://coveralls.io/builds/18215530/source?filename=algorithms%2Flinkedlist%2Fis_palindrome.py#L85) | 1 | 93.33% |
<!-- | **Total:** | **1** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/18215530/badge)](https://coveralls.io/builds/18215530) |
| :-- | --: |
| Change from base [Build 702](https://coveralls.io/builds/18211086): |  0.2% |
| Covered Lines: | 4088 |
| Relevant Lines: | 5713 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/algorithms/map/__init__.py b/algorithms/map/__init__.py
new file mode 100644
index 0000000..a663c8a
--- /dev/null
+++ b/algorithms/map/__init__.py
@@ -0,0 +1,2 @@
+from .hashtable import *
+from .separate_chaining_hashtable import *
diff --git a/algorithms/map/hashtable.py b/algorithms/map/hashtable.py
index 1c98ee2..f579c0b 100644
--- a/algorithms/map/hashtable.py
+++ b/algorithms/map/hashtable.py
@@ -1,6 +1,3 @@
-from unittest import TestCase
-import unittest
-
 class HashTable(object):
     """
     HashMap Data Type
@@ -120,93 +117,3 @@ class ResizableHashTable(HashTable):
         for key, value in zip(keys, values):
             if key is not self._empty and key is not self._deleted:
                 self.put(key, value)
-
-
-class TestHashTable(TestCase):
-    def test_one_entry(self):
-        m = HashTable(10)
-        m.put(1, '1')
-        self.assertEqual('1', m.get(1))
-
-    def test_add_entry_bigger_than_table_size(self):
-        m = HashTable(10)
-        m.put(11, '1')
-        self.assertEqual('1', m.get(11))
-
-    def test_get_none_if_key_missing_and_hash_collision(self):
-        m = HashTable(10)
-        m.put(1, '1')
-        self.assertEqual(None, m.get(11))
-
-    def test_two_entries_with_same_hash(self):
-        m = HashTable(10)
-        m.put(1, '1')
-        m.put(11, '11')
-        self.assertEqual('1', m.get(1))
-        self.assertEqual('11', m.get(11))
-
-    def test_get_on_full_table_does_halts(self):
-        # and does not search forever
-        m = HashTable(10)
-        for i in range(10, 20):
-            m.put(i, i)
-        self.assertEqual(None, m.get(1))
-
-    def test_delete_key(self):
-        m = HashTable(10)
-        for i in range(5):
-            m.put(i, i**2)
-        m.del_(1)
-        self.assertEqual(None, m.get(1))
-        self.assertEqual(4,m.get(2))
-
-    def test_delete_key_and_reassign(self):
-        m = HashTable(10)
-        m.put(1, 1)
-        del m[1]
-        m.put(1, 2)
-        self.assertEqual(2, m.get(1))
-
-    def test_assigning_to_full_table_throws_error(self):
-        m = HashTable(3)
-        m.put(1, 1)
-        m.put(2, 2)
-        m.put(3, 3)
-        with self.assertRaises(ValueError):
-            m.put(4, 4)
-
-    def test_len_trivial(self):
-        m = HashTable(10)
-        self.assertEqual(0, len(m))
-        for i in range(10):
-            m.put(i, i)
-            self.assertEqual(i + 1, len(m))
-
-    def test_len_after_deletions(self):
-        m = HashTable(10)
-        m.put(1, 1)
-        self.assertEqual(1, len(m))
-        m.del_(1)
-        self.assertEqual(0, len(m))
-        m.put(11, 42)
-        self.assertEqual(1, len(m))
-
-    def test_resizable_hash_table(self):
-        m = ResizableHashTable()
-        self.assertEqual(ResizableHashTable.MIN_SIZE, m.size)
-        for i in range(ResizableHashTable.MIN_SIZE):
-            m.put(i, 'foo')
-        self.assertEqual(ResizableHashTable.MIN_SIZE * 2, m.size)
-        self.assertEqual('foo', m.get(1))
-        self.assertEqual('foo', m.get(3))
-        self.assertEqual('foo', m.get(ResizableHashTable.MIN_SIZE - 1))
-        
-    def test_fill_up_the_limit(self):
-        m = HashTable(10)
-        for i in range(10):
-            m.put(i,i**2)
-        for i in range(10):
-            self.assertEqual(i**2,m.get(i))
-
-if __name__ == "__main__":
-    unittest.main()
\ No newline at end of file
diff --git a/algorithms/map/separate_chaining_hashtable.py b/algorithms/map/separate_chaining_hashtable.py
index 5feb50a..fecb251 100644
--- a/algorithms/map/separate_chaining_hashtable.py
+++ b/algorithms/map/separate_chaining_hashtable.py
@@ -82,62 +82,3 @@ class SeparateChainingHashTable(object):
 
     def __setitem__(self, key, value):
         self.put(key, value)
-
-
-class TestSeparateChainingHashTable(unittest.TestCase):
-    def test_one_entry(self):
-        m = SeparateChainingHashTable(10)
-        m.put(1, '1')
-        self.assertEqual('1', m.get(1))
-
-    def test_two_entries_with_same_hash(self):
-        m = SeparateChainingHashTable(10)
-        m.put(1, '1')
-        m.put(11, '11')
-        self.assertEqual('1', m.get(1))
-        self.assertEqual('11', m.get(11))
-
-    def test_len_trivial(self):
-        m = SeparateChainingHashTable(10)
-        self.assertEqual(0, len(m))
-        for i in range(10):
-            m.put(i, i)
-            self.assertEqual(i + 1, len(m))
-
-    def test_len_after_deletions(self):
-        m = SeparateChainingHashTable(10)
-        m.put(1, 1)
-        self.assertEqual(1, len(m))
-        m.del_(1)
-        self.assertEqual(0, len(m))
-        m.put(11, 42)
-        self.assertEqual(1, len(m))
-
-    def test_delete_key(self):
-        m = SeparateChainingHashTable(10)
-        for i in range(5):
-            m.put(i, i**2)
-        m.del_(1)
-        self.assertEqual(None, m.get(1))
-        self.assertEqual(4, m.get(2))
-
-    def test_delete_key_and_reassign(self):
-        m = SeparateChainingHashTable(10)
-        m.put(1, 1)
-        del m[1]
-        m.put(1, 2)
-        self.assertEqual(2, m.get(1))
-
-    def test_add_entry_bigger_than_table_size(self):
-        m = SeparateChainingHashTable(10)
-        m.put(11, '1')
-        self.assertEqual('1', m.get(11))
-
-    def test_get_none_if_key_missing_and_hash_collision(self):
-        m = SeparateChainingHashTable(10)
-        m.put(1, '1')
-        self.assertEqual(None, m.get(11))
-
-
-if __name__ == '__main__':
-    unittest.main()


Test patch:
diff --git a/tests/test_map.py b/tests/test_map.py
new file mode 100644
index 0000000..5786803
--- /dev/null
+++ b/tests/test_map.py
@@ -0,0 +1,152 @@
+from algorithms.map import (
+    HashTable, ResizableHashTable,
+    Node, SeparateChainingHashTable
+)
+
+import unittest
+
+class TestHashTable(unittest.TestCase):
+    def test_one_entry(self):
+        m = HashTable(10)
+        m.put(1, '1')
+        self.assertEqual('1', m.get(1))
+
+    def test_add_entry_bigger_than_table_size(self):
+        m = HashTable(10)
+        m.put(11, '1')
+        self.assertEqual('1', m.get(11))
+
+    def test_get_none_if_key_missing_and_hash_collision(self):
+        m = HashTable(10)
+        m.put(1, '1')
+        self.assertEqual(None, m.get(11))
+
+    def test_two_entries_with_same_hash(self):
+        m = HashTable(10)
+        m.put(1, '1')
+        m.put(11, '11')
+        self.assertEqual('1', m.get(1))
+        self.assertEqual('11', m.get(11))
+
+    def test_get_on_full_table_does_halts(self):
+        # and does not search forever
+        m = HashTable(10)
+        for i in range(10, 20):
+            m.put(i, i)
+        self.assertEqual(None, m.get(1))
+
+    def test_delete_key(self):
+        m = HashTable(10)
+        for i in range(5):
+            m.put(i, i**2)
+        m.del_(1)
+        self.assertEqual(None, m.get(1))
+        self.assertEqual(4,m.get(2))
+
+    def test_delete_key_and_reassign(self):
+        m = HashTable(10)
+        m.put(1, 1)
+        del m[1]
+        m.put(1, 2)
+        self.assertEqual(2, m.get(1))
+
+    def test_assigning_to_full_table_throws_error(self):
+        m = HashTable(3)
+        m.put(1, 1)
+        m.put(2, 2)
+        m.put(3, 3)
+        with self.assertRaises(ValueError):
+            m.put(4, 4)
+
+    def test_len_trivial(self):
+        m = HashTable(10)
+        self.assertEqual(0, len(m))
+        for i in range(10):
+            m.put(i, i)
+            self.assertEqual(i + 1, len(m))
+
+    def test_len_after_deletions(self):
+        m = HashTable(10)
+        m.put(1, 1)
+        self.assertEqual(1, len(m))
+        m.del_(1)
+        self.assertEqual(0, len(m))
+        m.put(11, 42)
+        self.assertEqual(1, len(m))
+
+    def test_resizable_hash_table(self):
+        m = ResizableHashTable()
+        self.assertEqual(ResizableHashTable.MIN_SIZE, m.size)
+        for i in range(ResizableHashTable.MIN_SIZE):
+            m.put(i, 'foo')
+        self.assertEqual(ResizableHashTable.MIN_SIZE * 2, m.size)
+        self.assertEqual('foo', m.get(1))
+        self.assertEqual('foo', m.get(3))
+        self.assertEqual('foo', m.get(ResizableHashTable.MIN_SIZE - 1))
+
+    def test_fill_up_the_limit(self):
+        m = HashTable(10)
+        for i in range(10):
+            m.put(i,i**2)
+        for i in range(10):
+            self.assertEqual(i**2,m.get(i))
+
+
+class TestSeparateChainingHashTable(unittest.TestCase):
+    def test_one_entry(self):
+        m = SeparateChainingHashTable(10)
+        m.put(1, '1')
+        self.assertEqual('1', m.get(1))
+
+    def test_two_entries_with_same_hash(self):
+        m = SeparateChainingHashTable(10)
+        m.put(1, '1')
+        m.put(11, '11')
+        self.assertEqual('1', m.get(1))
+        self.assertEqual('11', m.get(11))
+
+    def test_len_trivial(self):
+        m = SeparateChainingHashTable(10)
+        self.assertEqual(0, len(m))
+        for i in range(10):
+            m.put(i, i)
+            self.assertEqual(i + 1, len(m))
+
+    def test_len_after_deletions(self):
+        m = SeparateChainingHashTable(10)
+        m.put(1, 1)
+        self.assertEqual(1, len(m))
+        m.del_(1)
+        self.assertEqual(0, len(m))
+        m.put(11, 42)
+        self.assertEqual(1, len(m))
+
+    def test_delete_key(self):
+        m = SeparateChainingHashTable(10)
+        for i in range(5):
+            m.put(i, i**2)
+        m.del_(1)
+        self.assertEqual(None, m.get(1))
+        self.assertEqual(4, m.get(2))
+
+    def test_delete_key_and_reassign(self):
+        m = SeparateChainingHashTable(10)
+        m.put(1, 1)
+        del m[1]
+        m.put(1, 2)
+        self.assertEqual(2, m.get(1))
+
+    def test_add_entry_bigger_than_table_size(self):
+        m = SeparateChainingHashTable(10)
+        m.put(11, '1')
+        self.assertEqual('1', m.get(11))
+
+    def test_get_none_if_key_missing_and_hash_collision(self):
+        m = SeparateChainingHashTable(10)
+        m.put(1, '1')
+        self.assertEqual(None, m.get(11))
+
+
+
+if __name__ == "__main__":
+    unittest.main()