// // bucket_hash_map.t.h // bucket_hash_map // // Created by Sam Jaffe on 2/7/17. // #pragma once #include #include "bucket_hash_map.hpp" class bucket_hash_map_TestSuite : public CxxTest::TestSuite { public: using hashmap = bucket_hash_map; public: // Construction Postconditions void test_default_is_empty() { TS_ASSERT( hashmap{}.empty() ); } void test_construct_from_initializer_list() { hashmap hm{{0, 1}, {1, 2}, {2, 3}}; TS_ASSERT_EQUALS(hm.size(), 3); } void test_swap_hashmaps() { hashmap hm1{}; hashmap hm2{{0, 1}, {1, 2}, {2, 3}}; swap(hm1, hm2); TS_ASSERT(hm2.empty()); TS_ASSERT_EQUALS(hm1.size(), 3); } // Insertion Behaviors void test_insert_elements_effects_size() { hashmap hm{}; TS_ASSERT_THROWS_NOTHING( hm.insert({0, 1}) ); TS_ASSERT_EQUALS(hm.size(), 1); } void test_insert_element_contains_expected() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm[0], 1); } void test_insert_element_return_true() { hashmap hm{}; TS_ASSERT( hm.insert({0, 1}).second ); } void test_insert_element_return_iterator_to_elements() { hashmap hm{}; auto it = hm.insert({0, 1}).first; TS_ASSERT_EQUALS( it->first, 0 ); TS_ASSERT_EQUALS( it->second, 1 ); } void test_insert_same_element_does_not_create_duplicate() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_THROWS_NOTHING( hm.insert({0, 1}) ); TS_ASSERT_EQUALS(hm.size(), 1); } void test_insert_same_element_returns_false() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT( !hm.insert({0, 1}).second ); } void test_insert_same_element_return_same_iterator() { hashmap hm{}; auto it = hm.insert({0, 1}).first; TS_ASSERT_EQUALS(hm.insert({0, 2}).first, it); } void test_can_insert_range() { hashmap hm{}; TS_ASSERT_THROWS_NOTHING(hm.insert({{0, 1}, {0, 2}, {1, 3}})); } void test_inserted_range_contains_all_correct_elements() { hashmap hm{}; hm.insert({{0, 1}, {0, 2}, {1, 3}}); TS_ASSERT_EQUALS(hm.size(), 2); TS_ASSERT_EQUALS(hm[0], 1); TS_ASSERT_EQUALS(hm[1], 3); } // Find/Access Behaviors void test_can_find_element_in_map() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_DIFFERS(hm.find(0), hm.end()); } void test_count_element_in_map() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.count(0), 1); } void test_count_element_not_in_map() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.count(1), 0); } void test_equal_range_contains_element_if_present() { hashmap hm{}; hm.insert({0, 1}); auto p = hm.equal_range(0); TS_ASSERT_DIFFERS(p.first, p.second); TS_ASSERT_EQUALS(std::distance(p.first, p.second), 1); } void test_equal_range_contains_end_if_absent() { hashmap hm{}; hm.insert({0, 1}); auto p = hm.equal_range(1); TS_ASSERT_EQUALS(p.first, p.second); TS_ASSERT_EQUALS(p.first, hm.end()); } void test_found_element_is_as_expected() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.find(0)->first, 0); TS_ASSERT_EQUALS(hm.find(0)->second, 1); } void test_cannot_find_fake_element() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.find(1), hm.end()); } void test_operator_bracket_constructs_element() { hashmap hm{}; hm[0] = 1; TS_ASSERT_EQUALS(hm.size(), 1); } void test_at_throws_on_no_key_present() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_THROWS(hm.at(1), std::out_of_range); } void test_at_nothrow_is_element_present() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_THROWS_NOTHING(hm.at(0)); } void test_at_is_same_as_bracket_if_element_exists() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm[0], hm.at(0)); TS_ASSERT_EQUALS(&hm[0], &hm.at(0)); } void test_at_can_mutate_element() { hashmap hm{}; hm.insert({0, 1}); hm.at(0) = 2; TS_ASSERT_EQUALS(hm.find(0)->second, 2); } // Iteration Behaviors void test_iterator_advance_different() { hashmap hm{}; hm.insert({0, 1}); hm.insert({1, 2}); auto it = hm.begin(); auto it2 = ++hm.begin(); TS_ASSERT_DIFFERS(*it, *it2); } void test_iterator_begin_is_end_if_empty() { // Test case in join iterator for empty first element hashmap hm{}; TS_ASSERT_EQUALS(hm.begin(), hm.end()); } void test_iterator_reaches_end() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(++hm.begin(), hm.end()); } // Erase Behaviors void test_erasing_element_reduces_size() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_THROWS_NOTHING( hm.erase(hm.find(0)) ); TS_ASSERT_EQUALS(hm.size(), 0); } void test_erase_end_is_fine() { hashmap hm{}; TS_ASSERT_THROWS_NOTHING(hm.erase(hm.end())); hm.insert({0, 1}); TS_ASSERT_THROWS_NOTHING(hm.erase(hm.end())); } void test_erase_end_does_not_effect_size() { hashmap hm{}; hm.insert({0, 1}); hm.erase(hm.end()); TS_ASSERT_EQUALS(hm.size(), 1); } void test_erase_end_returns_end() { hashmap hm{}; TS_ASSERT_EQUALS(hm.erase(hm.end()), hm.end()); } void test_erase_key_missing_key_no_result() { hashmap hm{}; TS_ASSERT_EQUALS(hm.erase(0), 0); } void test_erase_key_incorrect_key_no_result() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.erase(1), 0); } void test_erase_key_correct_key_one() { hashmap hm{}; hm.insert({0, 1}); TS_ASSERT_EQUALS(hm.erase(0), 1); } void test_erase_range() { hashmap hm{{0, 1}, {1, 2}, {2, 3}}; auto it = hm.begin(); auto it2 = it; std::advance(it2, 2); TS_ASSERT_THROWS_NOTHING(hm.erase(it, it2)); TS_ASSERT_EQUALS(hm.size(), 1); } void test_clear() { hashmap hm{{0, 1}, {1, 2}, {2, 3}}; TS_ASSERT_THROWS_NOTHING(hm.clear()); TS_ASSERT(hm.empty()); } void test_resize_not_destructive() { hashmap hm{{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}}; hashmap const copy{hm}; hm.reserve(6); TS_ASSERT_EQUALS(hm, copy); } };