diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 98a544984b20e8d87c31d8acc2117126942e2e26..47ef1cf71f7146f15767471b2dc2cee907f3f7b0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,7 +6,7 @@ include(CTest) # the executables that run the tests add_executable(test_main test_main.cpp) -add_executable(test_hashtable test_hashtable.cpp) +add_executable(test_hashtable test_constructor.cpp test_hashtable.cpp) # link needed libraries target_link_libraries(test_main gtest gtest_main) diff --git a/tests/test_constructor.cpp b/tests/test_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5e1217f8b2e0439707cc36d0c1b19f8339775f7 --- /dev/null +++ b/tests/test_constructor.cpp @@ -0,0 +1,58 @@ +#include <gtest/gtest.h> +#include "hashtable.h" + + +TEST(HashtableConstructor, DefaultParams) { + Hashtable h; + + EXPECT_EQ(0, h.size()); + EXPECT_EQ(8, h.capacity()); + EXPECT_EQ(0, h.load_factor()); +} + +TEST(HashtableConstructor, TableSizeZero) { + Hashtable h(0); + + EXPECT_EQ(0, h.size()); + EXPECT_EQ(0, h.capacity()); + EXPECT_EQ(0, h.load_factor()); +} + +TEST(HashtableConstructor, VariousTableSizes) { + Hashtable h1(1); + EXPECT_EQ(0, h1.size()); + EXPECT_EQ(1, h1.capacity()); + EXPECT_EQ(0, h1.load_factor()); + + Hashtable h2(42); + EXPECT_EQ(0, h2.size()); + EXPECT_EQ(42, h2.capacity()); + EXPECT_EQ(0, h2.load_factor()); + + Hashtable h3(65535); + EXPECT_EQ(0, h3.size()); + EXPECT_EQ(65535, h3.capacity()); + EXPECT_EQ(0, h3.load_factor()); +} + +TEST(HashtableConstructor, ValidArguments) { + EXPECT_NO_THROW(Hashtable h1(0, 0.01)); + EXPECT_NO_THROW(Hashtable h1(0, 0.5)); + EXPECT_NO_THROW(Hashtable h1(0, 0.99)); + EXPECT_NO_THROW(Hashtable h1(0, 0.75, 1.01)); + EXPECT_NO_THROW(Hashtable h1(0, 0.01, 1.5)); + EXPECT_NO_THROW(Hashtable h1(0, 0.01, 8)); +} + +TEST(HashtableConstructor, InvalidArguments) { + EXPECT_THROW(Hashtable h1(0, 0), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, -1.2), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 1.0), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 1.01), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 5), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 0.75, -1), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 0.75, 0), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 0.75, 0.1), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 0.75, 0.99), std::invalid_argument); + EXPECT_THROW(Hashtable h1(0, 0.75, 1), std::invalid_argument); +} diff --git a/tests/test_hashtable.cpp b/tests/test_hashtable.cpp index 4110d2ee58644c324caf9f131abc82470c7693b2..e7c21a2a6f1b1d6699cb613bf82b165c2cc0475d 100644 --- a/tests/test_hashtable.cpp +++ b/tests/test_hashtable.cpp @@ -1,2 +1,166 @@ #include <gtest/gtest.h> +#include <iostream> + #include "hashtable.h" + +using ::testing::TestWithParam; +using ::testing::ValuesIn; + + +struct HashtableArguments { + size_t m; + float a; + float s; + + // make error output readable + friend std::ostream& operator<<(std::ostream& os, const HashtableArguments& args) { + return os << "[m: " << args.m << ", a: " << args.a << ", s: " << args.s << "]"; + } +}; + +// below tests will run on hashtables contstructed with these arguments +HashtableArguments argv[] = { + {8, 0.75, 2}, // default table + {0, 0.75, 2}, // empty table + {65536, 0.75, 2},// big table + {8, 0.10, 2}, // small alpha, default s + {8, 0.95, 2}, // large alpha, default s + {8, 0.10, 1.1}, // small alpha, tiny s + {8, 0.95, 1.5}, // large alpha, small s + {8, 0.10, 4}, // small alpha, large s + {8, 0.95, 1.1}, // large alpha, tiny s + {8, 0.10, 1.5}, // small alpha, small s + {8, 0.95, 4} // large alpha, large s +}; + + +class PTest : public TestWithParam<HashtableArguments> { + public: + Hashtable *table; + size_t m; + float a; + float s; + + void SetUp() override { + m = GetParam().m; a = GetParam().a; s = GetParam().s; + table = new Hashtable(m, a, s); + } + + void TearDown() override { delete table; table = nullptr; } +}; + +TEST_P(PTest, TestSetup) { + EXPECT_EQ(m, table->capacity()); + EXPECT_EQ(0, table->size()); + EXPECT_EQ(0, table->load_factor()); +} + +TEST_P(PTest, InsertIntoEmpty) { + EXPECT_EQ(true, table->insert(0)); + EXPECT_EQ(true, table->insert(23)); + EXPECT_EQ(true, table->insert(512)); +} + +TEST_P(PTest, InsertExisting) { + EXPECT_EQ(true, table->insert(2)); + EXPECT_EQ(true, table->insert(9)); + EXPECT_EQ(true, table->insert(32)); + EXPECT_EQ(true, table->insert(575)); + + EXPECT_EQ(false, table->insert(2)); + EXPECT_EQ(false, table->insert(9)); + EXPECT_EQ(false, table->insert(32)); + EXPECT_EQ(false, table->insert(575)); +} + +TEST_P(PTest, RemoveFromEmpty) { + EXPECT_EQ(false, table->remove(0)); + EXPECT_EQ(false, table->remove(7)); + EXPECT_EQ(false, table->remove(77)); + EXPECT_EQ(false, table->remove(2087)); +} + +TEST_P(PTest, RemoveExisting) { + EXPECT_EQ(true, table->insert(4)); + EXPECT_EQ(true, table->insert(64)); + EXPECT_EQ(true, table->insert(1023)); + EXPECT_EQ(true, table->insert(408)); + + EXPECT_EQ(true, table->remove(4)); + EXPECT_EQ(true, table->remove(64)); + EXPECT_EQ(true, table->remove(1023)); + EXPECT_EQ(true, table->remove(408)); +} + +TEST_P(PTest, RemoveSome) { + for (int i=0; i<=100; i+=2) { + EXPECT_EQ(true, table->insert(i)); + EXPECT_EQ(true, table->contains(i)); + EXPECT_EQ(false, table->contains(i+1)); + } + + for (int i=0; i<=100; i+=2) { + EXPECT_EQ(true, table->remove(i)); + EXPECT_EQ(false, table->remove(i+1)); + EXPECT_EQ(false, table->contains(i)); + } +} + +TEST_P(PTest, Contains) { + EXPECT_EQ(false, table->contains(3)); + EXPECT_EQ(false, table->contains(53)); + EXPECT_EQ(false, table->contains(4265)); + EXPECT_EQ(false, table->contains(10e6)); + + for (int i=0; i<200; i++) + EXPECT_EQ(true, table->insert(i)); + + for (int i=0; i<200; i++) + EXPECT_EQ(true, table->contains(i)); + + for (int i=0; i<200; i++) + EXPECT_EQ(true, table->remove(i)); + + for (int i=0; i<200; i++) + EXPECT_EQ(false, table->contains(i)); +} + +TEST_P(PTest, Size) { + EXPECT_EQ(0, table->size()); + + table->insert(0); + EXPECT_EQ(1, table->size()); + table->insert(23); + EXPECT_EQ(2, table->size()); + table->remove(55); + EXPECT_EQ(2, table->size()); + table->remove(80); + EXPECT_EQ(2, table->size()); + table->remove(23); + EXPECT_EQ(1, table->size()); + table->remove(0); + EXPECT_EQ(0, table->size()); + + for (int i=0; i<200; i++) { + EXPECT_EQ(i, table->size()); + table->insert(i); + EXPECT_EQ(i+1, table->size()); + } + + for (int i=0; i<200; i++) { + EXPECT_EQ(200-i, table->size()); + table->remove(i); + EXPECT_EQ(199-i, table->size()); + } +} + +TEST_P(PTest, Capacity) { + EXPECT_EQ(m, table->capacity()); + + for (int i=0; i<200; i++) { + table->insert(i); + EXPECT_GT(table->capacity(), table->size()); + } +} + +INSTANTIATE_TEST_SUITE_P(ParameterizedTests, PTest, ValuesIn(argv));