bucket_hash_map.t.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // bucket_hash_map.t.h
  3. // bucket_hash_map
  4. //
  5. // Created by Sam Jaffe on 2/7/17.
  6. //
  7. #pragma once
  8. #include <cxxtest/TestSuite.h>
  9. #include "bucket_hash_map.hpp"
  10. class bucket_hash_map_TestSuite : public CxxTest::TestSuite {
  11. public:
  12. using hashmap = bucket_hash_map<int, int>;
  13. public:
  14. // Construction Postconditions
  15. void test_default_is_empty() {
  16. TS_ASSERT( hashmap{}.empty() );
  17. }
  18. void test_construct_from_initializer_list() {
  19. hashmap hm{{0, 1}, {1, 2}, {2, 3}};
  20. TS_ASSERT_EQUALS(hm.size(), 3);
  21. }
  22. void test_swap_hashmaps() {
  23. hashmap hm1{};
  24. hashmap hm2{{0, 1}, {1, 2}, {2, 3}};
  25. swap(hm1, hm2);
  26. TS_ASSERT(hm2.empty());
  27. TS_ASSERT_EQUALS(hm1.size(), 3);
  28. }
  29. // Insertion Behaviors
  30. void test_insert_elements_effects_size() {
  31. hashmap hm{};
  32. TS_ASSERT_THROWS_NOTHING( hm.insert({0, 1}) );
  33. TS_ASSERT_EQUALS(hm.size(), 1);
  34. }
  35. void test_insert_element_contains_expected() {
  36. hashmap hm{};
  37. hm.insert({0, 1});
  38. TS_ASSERT_EQUALS(hm[0], 1);
  39. }
  40. void test_insert_element_return_true() {
  41. hashmap hm{};
  42. TS_ASSERT( hm.insert({0, 1}).second );
  43. }
  44. void test_insert_element_return_iterator_to_elements() {
  45. hashmap hm{};
  46. auto it = hm.insert({0, 1}).first;
  47. TS_ASSERT_EQUALS( it->first, 0 );
  48. TS_ASSERT_EQUALS( it->second, 1 );
  49. }
  50. void test_insert_same_element_does_not_create_duplicate() {
  51. hashmap hm{};
  52. hm.insert({0, 1});
  53. TS_ASSERT_THROWS_NOTHING( hm.insert({0, 1}) );
  54. TS_ASSERT_EQUALS(hm.size(), 1);
  55. }
  56. void test_insert_same_element_returns_false() {
  57. hashmap hm{};
  58. hm.insert({0, 1});
  59. TS_ASSERT( !hm.insert({0, 1}).second );
  60. }
  61. void test_insert_same_element_return_same_iterator() {
  62. hashmap hm{};
  63. auto it = hm.insert({0, 1}).first;
  64. TS_ASSERT_EQUALS(hm.insert({0, 2}).first, it);
  65. }
  66. void test_can_insert_range() {
  67. hashmap hm{};
  68. TS_ASSERT_THROWS_NOTHING(hm.insert({{0, 1}, {0, 2}, {1, 3}}));
  69. }
  70. void test_inserted_range_contains_all_correct_elements() {
  71. hashmap hm{};
  72. hm.insert({{0, 1}, {0, 2}, {1, 3}});
  73. TS_ASSERT_EQUALS(hm.size(), 2);
  74. TS_ASSERT_EQUALS(hm[0], 1);
  75. TS_ASSERT_EQUALS(hm[1], 3);
  76. }
  77. // Find/Access Behaviors
  78. void test_can_find_element_in_map() {
  79. hashmap hm{};
  80. hm.insert({0, 1});
  81. TS_ASSERT_DIFFERS(hm.find(0), hm.end());
  82. }
  83. void test_count_element_in_map() {
  84. hashmap hm{};
  85. hm.insert({0, 1});
  86. TS_ASSERT_EQUALS(hm.count(0), 1);
  87. }
  88. void test_count_element_not_in_map() {
  89. hashmap hm{};
  90. hm.insert({0, 1});
  91. TS_ASSERT_EQUALS(hm.count(1), 0);
  92. }
  93. void test_equal_range_contains_element_if_present() {
  94. hashmap hm{};
  95. hm.insert({0, 1});
  96. auto p = hm.equal_range(0);
  97. TS_ASSERT_DIFFERS(p.first, p.second);
  98. TS_ASSERT_EQUALS(std::distance(p.first, p.second), 1);
  99. }
  100. void test_equal_range_contains_end_if_absent() {
  101. hashmap hm{};
  102. hm.insert({0, 1});
  103. auto p = hm.equal_range(1);
  104. TS_ASSERT_EQUALS(p.first, p.second);
  105. TS_ASSERT_EQUALS(p.first, hm.end());
  106. }
  107. void test_found_element_is_as_expected() {
  108. hashmap hm{};
  109. hm.insert({0, 1});
  110. TS_ASSERT_EQUALS(hm.find(0)->first, 0);
  111. TS_ASSERT_EQUALS(hm.find(0)->second, 1);
  112. }
  113. void test_cannot_find_fake_element() {
  114. hashmap hm{};
  115. hm.insert({0, 1});
  116. TS_ASSERT_EQUALS(hm.find(1), hm.end());
  117. }
  118. void test_operator_bracket_constructs_element() {
  119. hashmap hm{};
  120. hm[0] = 1;
  121. TS_ASSERT_EQUALS(hm.size(), 1);
  122. }
  123. void test_at_throws_on_no_key_present() {
  124. hashmap hm{};
  125. hm.insert({0, 1});
  126. TS_ASSERT_THROWS(hm.at(1), std::out_of_range);
  127. }
  128. void test_at_nothrow_is_element_present() {
  129. hashmap hm{};
  130. hm.insert({0, 1});
  131. TS_ASSERT_THROWS_NOTHING(hm.at(0));
  132. }
  133. void test_at_is_same_as_bracket_if_element_exists() {
  134. hashmap hm{};
  135. hm.insert({0, 1});
  136. TS_ASSERT_EQUALS(hm[0], hm.at(0));
  137. TS_ASSERT_EQUALS(&hm[0], &hm.at(0));
  138. }
  139. void test_at_can_mutate_element() {
  140. hashmap hm{};
  141. hm.insert({0, 1});
  142. hm.at(0) = 2;
  143. TS_ASSERT_EQUALS(hm.find(0)->second, 2);
  144. }
  145. // Iteration Behaviors
  146. void test_iterator_advance_different() {
  147. hashmap hm{};
  148. hm.insert({0, 1});
  149. hm.insert({1, 2});
  150. auto it = hm.begin();
  151. auto it2 = ++hm.begin();
  152. TS_ASSERT_DIFFERS(*it, *it2);
  153. }
  154. void test_iterator_begin_is_end_if_empty() { // Test case in join iterator for empty first element
  155. hashmap hm{};
  156. TS_ASSERT_EQUALS(hm.begin(), hm.end());
  157. }
  158. void test_iterator_reaches_end() {
  159. hashmap hm{};
  160. hm.insert({0, 1});
  161. TS_ASSERT_EQUALS(++hm.begin(), hm.end());
  162. }
  163. // Erase Behaviors
  164. void test_erasing_element_reduces_size() {
  165. hashmap hm{};
  166. hm.insert({0, 1});
  167. TS_ASSERT_THROWS_NOTHING( hm.erase(hm.find(0)) );
  168. TS_ASSERT_EQUALS(hm.size(), 0);
  169. }
  170. void test_erase_end_is_fine() {
  171. hashmap hm{};
  172. TS_ASSERT_THROWS_NOTHING(hm.erase(hm.end()));
  173. hm.insert({0, 1});
  174. TS_ASSERT_THROWS_NOTHING(hm.erase(hm.end()));
  175. }
  176. void test_erase_end_does_not_effect_size() {
  177. hashmap hm{};
  178. hm.insert({0, 1});
  179. hm.erase(hm.end());
  180. TS_ASSERT_EQUALS(hm.size(), 1);
  181. }
  182. void test_erase_end_returns_end() {
  183. hashmap hm{};
  184. TS_ASSERT_EQUALS(hm.erase(hm.end()), hm.end());
  185. }
  186. void test_erase_key_missing_key_no_result() {
  187. hashmap hm{};
  188. TS_ASSERT_EQUALS(hm.erase(0), 0);
  189. }
  190. void test_erase_key_incorrect_key_no_result() {
  191. hashmap hm{};
  192. hm.insert({0, 1});
  193. TS_ASSERT_EQUALS(hm.erase(1), 0);
  194. }
  195. void test_erase_key_correct_key_one() {
  196. hashmap hm{};
  197. hm.insert({0, 1});
  198. TS_ASSERT_EQUALS(hm.erase(0), 1);
  199. }
  200. void test_erase_range() {
  201. hashmap hm{{0, 1}, {1, 2}, {2, 3}};
  202. auto it = hm.begin();
  203. auto it2 = it;
  204. std::advance(it2, 2);
  205. TS_ASSERT_THROWS_NOTHING(hm.erase(it, it2));
  206. TS_ASSERT_EQUALS(hm.size(), 1);
  207. }
  208. void test_clear() {
  209. hashmap hm{{0, 1}, {1, 2}, {2, 3}};
  210. TS_ASSERT_THROWS_NOTHING(hm.clear());
  211. TS_ASSERT(hm.empty());
  212. }
  213. void test_resize_not_destructive() {
  214. hashmap hm{{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}};
  215. hashmap const copy{hm};
  216. hm.reserve(6);
  217. TS_ASSERT_EQUALS(hm, copy);
  218. }
  219. };