From 7183be262815a094e8e9cdd95be1e02af9ca4942 Mon Sep 17 00:00:00 2001
From: David Nieder <post@davidnieder.de>
Date: Sat, 31 Dec 2022 12:17:07 +0100
Subject: [PATCH] some tests

---
 tests/CMakeLists.txt       |   2 +-
 tests/test_constructor.cpp |  58 +++++++++++++
 tests/test_hashtable.cpp   | 164 +++++++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+), 1 deletion(-)
 create mode 100644 tests/test_constructor.cpp

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 98a5449..47ef1cf 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 0000000..d5e1217
--- /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 4110d2e..e7c21a2 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));
-- 
GitLab