summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2025-03-30 23:08:43 -0500
committerDominick Allen <djallen@librehumanitas.org>2025-03-30 23:08:43 -0500
commitcb9fa588ba8144fcdd52ba4b83d69d93fb18066f (patch)
tree214574ca68c1551ec76e7fbb9e0263793180231d /test
parent1d357adfa19725ee69fb267a363f1fd217b1272f (diff)
Add hash map.
Diffstat (limited to 'test')
-rw-r--r--test/.clang-tidy2
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/test_directory.cpp4
-rw-r--r--test/test_file.cpp4
-rw-r--r--test/test_format.cpp160
-rw-r--r--test/test_hash_map.cpp146
-rw-r--r--test/test_option.cpp8
-rw-r--r--test/test_vector.cpp32
8 files changed, 278 insertions, 79 deletions
diff --git a/test/.clang-tidy b/test/.clang-tidy
index 97da183..0b184c0 100644
--- a/test/.clang-tidy
+++ b/test/.clang-tidy
@@ -1,2 +1,2 @@
-Checks: -readability-function-cognitive-complexity
+Checks: -readability-function-cognitive-complexity,-readability-magic-numbers
InheritParentConfig: true
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index cdc8c6e..9b905c9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -67,6 +67,7 @@ fud_add_test(test_csv SOURCES test_csv.cpp)
# fud_add_test(test_c_file SOURCES test_c_file.cpp)
fud_add_test(test_directory SOURCES test_directory.cpp)
fud_add_test(test_file SOURCES test_file.cpp)
+fud_add_test(test_hash_map SOURCES test_hash_map.cpp)
fud_add_test(test_format SOURCES test_format.cpp)
fud_add_test(test_option SOURCES test_option.cpp)
fud_add_test(test_result SOURCES test_result.cpp)
diff --git a/test/test_directory.cpp b/test/test_directory.cpp
index 7a420ca..905e503 100644
--- a/test/test_directory.cpp
+++ b/test/test_directory.cpp
@@ -81,7 +81,7 @@ TEST(FudDirectory, Basic)
DirectoryEntry{String::from(files[0]).takeOkay(), 0, files[0].size(), 1, 0, DirectoryEntryType::RegularFile},
DirectoryEntry{String::from(files[1]).takeOkay(), 0, files[1].size(), 1, 0, DirectoryEntryType::RegularFile},
};
- ASSERT_TRUE(expectedFiles[0].name.compare(expectedFiles[0].name));
+ ASSERT_EQ(expectedFiles[0].name, expectedFiles[0].name);
for (auto idx = 0; idx < expectedFiles.size(); ++idx) {
debugPrint(u8"On iteration {} - '{}' \n", idx, expectedFiles[idx].name.asView());
@@ -95,7 +95,7 @@ TEST(FudDirectory, Basic)
const auto* expected = std::ranges::find_if(
expectedFiles,
[&dirEntry](const DirectoryEntry& entry) {
- return entry.name.compare(dirEntry.name) && entry.entryType == dirEntry.entryType;
+ return entry.name == dirEntry.name && entry.entryType == dirEntry.entryType;
});
EXPECT_NE(expected, nullptr);
EXPECT_NE(expected, expectedFiles.end());
diff --git a/test/test_file.cpp b/test/test_file.cpp
index c1ce4f1..878c740 100644
--- a/test/test_file.cpp
+++ b/test/test_file.cpp
@@ -25,8 +25,6 @@
#include <fcntl.h>
#include <ftw.h>
-// NOLINTBEGIN(readability-magic-numbers)
-
namespace fud {
TEST(FudFile, Basic)
@@ -169,5 +167,3 @@ TEST(FudBufferedFile, OpenReadWrite)
}
} // namespace fud
-
-// NOLINTEND(readability-magic-numbers)
diff --git a/test/test_format.cpp b/test/test_format.cpp
index 738b551..0c5c520 100644
--- a/test/test_format.cpp
+++ b/test/test_format.cpp
@@ -17,10 +17,13 @@
#include "fud_format.hpp"
#include "fud_string_view.hpp"
+#include "fud_print.hpp"
#include "gtest/gtest.h"
#include <format>
+// NOLINTBEGIN(readability-magic-numbers)
+
namespace fud {
TEST(FormatTest, BasePositionalTest)
@@ -506,27 +509,27 @@ TEST(FormatTest, OneBoolFormatTest)
TEST(FormatTest, OneFloatFormatUnspecifiedTest)
{
-/*
- String sink{};
-
- ASSERT_EQ(sink.clear(), FudStatus::Success);
- auto expected = std::format("{:}", 42.0);
- auto formatResult = format(sink, FormatCharMode::Unchecked, u8"{:}", 42.0);
- EXPECT_TRUE(formatResult.isOkay());
- EXPECT_STREQ(sink.c_str(), expected.c_str());
-
- ASSERT_EQ(sink.clear(), FudStatus::Success);
- expected = std::format("{:1.0}", 42.0);
- formatResult = format(sink, FormatCharMode::Unchecked, u8"{:1.0}", 42.0);
- EXPECT_TRUE(formatResult.isOkay());
- EXPECT_STREQ(sink.c_str(), expected.c_str());
- expected = std::format("{:1.0}", 42.0);
- expected = std::format("u {:}", 10.0);
- expected = std::format("u {:}", 100.0);
- expected = std::format("u {:}", 1000.0);
- expected = std::format("u {:}", 10000.0);
- expected = std::format("u {:}", 100000.0);
-*/
+ /*
+ String sink{};
+
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ auto expected = std::format("{:}", 42.0);
+ auto formatResult = format(sink, FormatCharMode::Unchecked, u8"{:}", 42.0);
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ expected = std::format("{:1.0}", 42.0);
+ formatResult = format(sink, FormatCharMode::Unchecked, u8"{:1.0}", 42.0);
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+ expected = std::format("{:1.0}", 42.0);
+ expected = std::format("u {:}", 10.0);
+ expected = std::format("u {:}", 100.0);
+ expected = std::format("u {:}", 1000.0);
+ expected = std::format("u {:}", 10000.0);
+ expected = std::format("u {:}", 100000.0);
+ */
}
TEST(FormatTest, OneFloatFormatScientificTest)
@@ -648,50 +651,50 @@ TEST(FormatTest, OneFloatFormatScientificTest)
// Which is: "E#+ +0003.0000000000000000000000000000000000E+00"
// Which is: "E#+ +0003.00000000000000000000000000000000000000000000000000E+00"
-/*
- expected = std::format("E#+ {:Z>+#060.30E}", val);
- ASSERT_EQ(sink.clear(), FudStatus::Success);
- formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z>+#060.30E}", val);
- EXPECT_TRUE(formatResult.isOkay());
- EXPECT_STREQ(sink.c_str(), expected.c_str());
-
- expected = std::format("E#+ {:Z<+#060.30E}", val);
- ASSERT_EQ(sink.clear(), FudStatus::Success);
- formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z<+#060.30E}", val);
- EXPECT_TRUE(formatResult.isOkay());
- EXPECT_STREQ(sink.c_str(), expected.c_str());
-
- expected = std::format("E#+ {:Z^+#060.30E}", val);
- ASSERT_EQ(sink.clear(), FudStatus::Success);
- formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z^+#060.30E}", val);
- EXPECT_TRUE(formatResult.isOkay());
- EXPECT_STREQ(sink.c_str(), expected.c_str());
-*/
-
-/*
- double val = 3.0;
- expected = std::format("u {:}", val);
- expected = std::format("f {:f}", val);
- expected = std::format("F {:F}", val);
- expected = std::format("a {:a}", val);
- expected = std::format("A {:A}", val);
- expected = std::format("g {:g}", val);
- expected = std::format("G {:G}", val);
- expected = std::format("u# {:#}", val);
- expected = std::format("f# {:#f}", val);
- expected = std::format("F# {:#F}", val);
- expected = std::format("a# {:#a}", val);
- expected = std::format("A# {:#A}", val);
- expected = std::format("g# {:#g}", val);
- expected = std::format("G# {:#G}", val);
- expected = std::format("u#+ {:+#}", val);
- expected = std::format("f#+ {:+#f}", val);
- expected = std::format("F#+ {:+#F}", val);
- expected = std::format("a#+ {:+#a}", val);
- expected = std::format("A#+ {:+#A}", val);
- expected = std::format("g#+ {:+#g}", val);
- expected = std::format("G#+ {:+#010.3G}", val);
-*/
+ /*
+ expected = std::format("E#+ {:Z>+#060.30E}", val);
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z>+#060.30E}", val);
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+
+ expected = std::format("E#+ {:Z<+#060.30E}", val);
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z<+#060.30E}", val);
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+
+ expected = std::format("E#+ {:Z^+#060.30E}", val);
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ formatResult = format(sink, FormatCharMode::Unchecked, u8"E#+ {:Z^+#060.30E}", val);
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+ */
+
+ /*
+ double val = 3.0;
+ expected = std::format("u {:}", val);
+ expected = std::format("f {:f}", val);
+ expected = std::format("F {:F}", val);
+ expected = std::format("a {:a}", val);
+ expected = std::format("A {:A}", val);
+ expected = std::format("g {:g}", val);
+ expected = std::format("G {:G}", val);
+ expected = std::format("u# {:#}", val);
+ expected = std::format("f# {:#f}", val);
+ expected = std::format("F# {:#F}", val);
+ expected = std::format("a# {:#a}", val);
+ expected = std::format("A# {:#A}", val);
+ expected = std::format("g# {:#g}", val);
+ expected = std::format("G# {:#G}", val);
+ expected = std::format("u#+ {:+#}", val);
+ expected = std::format("f#+ {:+#f}", val);
+ expected = std::format("F#+ {:+#F}", val);
+ expected = std::format("a#+ {:+#a}", val);
+ expected = std::format("A#+ {:+#A}", val);
+ expected = std::format("g#+ {:+#g}", val);
+ expected = std::format("G#+ {:+#010.3G}", val);
+ */
}
TEST(FormatTest, TwoArgFormatTest)
@@ -716,6 +719,33 @@ TEST(FormatTest, StringView)
auto formatResult = format(sink, FormatCharMode::Unchecked, u8"Test {}", StringView{u8"Hello, World!"});
EXPECT_TRUE(formatResult.isOkay());
EXPECT_STREQ(sink.c_str(), expected.c_str());
+
+ ASSERT_EQ(sink.clear(), FudStatus::Success);
+ formatResult = fud::format(
+ sink,
+ fud::FormatCharMode::Unchecked,
+ u8"CREATE TABLE IF NOT EXISTS {} ({} {} {});",
+ StringView{u8"AtomicSymbol"}.as_string_view(),
+ StringView{u8"AtomicNumber INTEGER PRIMARY KEY"}.as_string_view(),
+ StringView{u8"Symbol TEXT NOT NULL"}.as_string_view(),
+ StringView{u8"Name TEXT NOT NULL"}.as_string_view());
+ expected = std::format(
+ "CREATE TABLE IF NOT EXISTS {} ({} {} {});",
+ StringView{u8"AtomicSymbol"}.as_string_view(),
+ StringView{u8"AtomicNumber INTEGER PRIMARY KEY"}.as_string_view(),
+ StringView{u8"Symbol TEXT NOT NULL"}.as_string_view(),
+ StringView{u8"Name TEXT NOT NULL"}.as_string_view());
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+}
+
+TEST(FormatTest, NumArgs)
+{
+ String sink{};
+ auto formatResult = format(sink, FormatCharMode::Unchecked, u8"Test {} {} {}", StringView{u8"Hello, World!"});
+ ASSERT_EQ(formatResult.status, FudStatus::FormatInvalid);
}
} // namespace fud
+
+// NOLINTEND(readability-magic-numbers)
diff --git a/test/test_hash_map.cpp b/test/test_hash_map.cpp
new file mode 100644
index 0000000..00c4693
--- /dev/null
+++ b/test/test_hash_map.cpp
@@ -0,0 +1,146 @@
+/*
+ * libfud
+ * Copyright 2025 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "fud_hash_map.hpp"
+#include "fud_string.hpp"
+#include "fud_vector.hpp"
+// #include "test_common.hpp"
+
+#include "gtest/gtest.h"
+
+namespace fud {
+
+TEST(FudHash, InsertMoveKeyMoveValue)
+{
+ auto stringList{
+ Vector<String>::from(
+ NullOpt,
+ String::makeFromCString("foo").takeOkay(),
+ String::makeFromCString("bar").takeOkay(),
+ String::makeFromCString("baz").takeOkay(),
+ String::makeFromCString("qux").takeOkay(),
+ String::makeFromCString("Tom").takeOkay(),
+ String::makeFromCString("Dick").takeOkay(),
+ String::makeFromCString("Harry").takeOkay(),
+ String::makeFromCString("Alice").takeOkay(),
+ String::makeFromCString("Bob").takeOkay())
+ .takeOkay()};
+ HashMap<int, String> mapInt2String{};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ auto insertStatus = mapInt2String.insert(index * 1, String::from(stringList[index]).takeOkay());
+ EXPECT_EQ(insertStatus, FudStatus::Success);
+ }
+ EXPECT_EQ(mapInt2String.size(), stringList.size());
+ EXPECT_GT(mapInt2String.capacity(), mapInt2String.size());
+
+ const String invalid{String::makeFromCString("Invalid").takeOkay()};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ EXPECT_EQ(mapInt2String.getConstRef(index).valueOr(invalid), stringList[index]);
+ }
+}
+
+TEST(FudHash, InsertMoveKeyCopyValue)
+{
+ auto stringList{
+ Vector<String>::from(
+ NullOpt,
+ String::makeFromCString("foo").takeOkay(),
+ String::makeFromCString("bar").takeOkay(),
+ String::makeFromCString("baz").takeOkay(),
+ String::makeFromCString("qux").takeOkay(),
+ String::makeFromCString("Tom").takeOkay(),
+ String::makeFromCString("Dick").takeOkay(),
+ String::makeFromCString("Harry").takeOkay(),
+ String::makeFromCString("Alice").takeOkay(),
+ String::makeFromCString("Bob").takeOkay())
+ .takeOkay()};
+ HashMap<String, int> mapString2Int{};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ auto insertStatus = mapString2Int.insert(String::from(stringList[index]).takeOkay(), index * 1);
+ EXPECT_EQ(insertStatus, FudStatus::Success);
+ }
+
+ EXPECT_EQ(mapString2Int.size(), stringList.size());
+ EXPECT_GT(mapString2Int.capacity(), mapString2Int.size());
+
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ const int invalid = -1;
+ EXPECT_EQ(mapString2Int.getConstRef(stringList[index]).valueOr(invalid), index);
+ }
+}
+
+TEST(FudHash, InsertCopyKeyMoveValue)
+{
+ auto stringList{
+ Vector<String>::from(
+ NullOpt,
+ String::makeFromCString("foo").takeOkay(),
+ String::makeFromCString("bar").takeOkay(),
+ String::makeFromCString("baz").takeOkay(),
+ String::makeFromCString("qux").takeOkay(),
+ String::makeFromCString("Tom").takeOkay(),
+ String::makeFromCString("Dick").takeOkay(),
+ String::makeFromCString("Harry").takeOkay(),
+ String::makeFromCString("Alice").takeOkay(),
+ String::makeFromCString("Bob").takeOkay())
+ .takeOkay()};
+ HashMap<int, String> mapInt2String{};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ auto insertStatus = mapInt2String.insert(index, String::from(stringList[index]).takeOkay());
+ EXPECT_EQ(insertStatus, FudStatus::Success);
+ }
+
+ EXPECT_EQ(mapInt2String.size(), stringList.size());
+ EXPECT_GT(mapInt2String.capacity(), mapInt2String.size());
+
+ const String invalid{String::makeFromCString("Invalid").takeOkay()};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ EXPECT_EQ(mapInt2String.getConstRef(index).valueOr(invalid), stringList[index]);
+ }
+}
+
+TEST(FudHash, InsertCopyKeyCopyValue)
+{
+ auto stringList{
+ Vector<StringView>::from(
+ NullOpt,
+ StringView::makeFromCString("foo"),
+ StringView::makeFromCString("bar"),
+ StringView::makeFromCString("baz"),
+ StringView::makeFromCString("qux"),
+ StringView::makeFromCString("Tom"),
+ StringView::makeFromCString("Dick"),
+ StringView::makeFromCString("Harry"),
+ StringView::makeFromCString("Alice"),
+ StringView::makeFromCString("Bob"))
+ .takeOkay()};
+ HashMap<StringView, int> mapView2Int{};
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ auto insertStatus = mapView2Int.insert(stringList[index], index);
+ EXPECT_EQ(insertStatus, FudStatus::Success);
+ }
+
+ EXPECT_EQ(mapView2Int.size(), stringList.size());
+ EXPECT_GT(mapView2Int.capacity(), mapView2Int.size());
+
+ for (int index = 0; index < static_cast<int>(stringList.size()); ++index) {
+ const int invalid = -1;
+ EXPECT_EQ(mapView2Int.getConstRef(stringList[index]).valueOr(invalid), index);
+ }
+}
+
+} // namespace fud
diff --git a/test/test_option.cpp b/test/test_option.cpp
index a503a5f..b900858 100644
--- a/test/test_option.cpp
+++ b/test/test_option.cpp
@@ -16,6 +16,7 @@
*/
#include "fud_option.hpp"
+#include "fud_string.hpp"
#include "gtest/gtest.h"
@@ -51,4 +52,11 @@ TEST(OptionTest, OptionRef)
ASSERT_EQ(value, 42);
}
+TEST(OptionTest, OptionString)
+{
+ Option<String> optString{std::move(String::makeFromCString("foo").takeOkay())};
+ EXPECT_TRUE(optString.hasValue());
+}
+
+
} // namespace fud
diff --git a/test/test_vector.cpp b/test/test_vector.cpp
index ba0272e..3f4e584 100644
--- a/test/test_vector.cpp
+++ b/test/test_vector.cpp
@@ -24,9 +24,14 @@ namespace fud {
template <size_t Size>
struct TestLinearAllocator : public Allocator {
- virtual ~TestLinearAllocator() override = default;
-
- virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override
+ TestLinearAllocator() = default;
+ TestLinearAllocator(const TestLinearAllocator&) = delete;
+ TestLinearAllocator(TestLinearAllocator&&) = delete;
+ TestLinearAllocator& operator=(const TestLinearAllocator&) = delete;
+ TestLinearAllocator& operator=(TestLinearAllocator&&) = delete;
+ ~TestLinearAllocator() override = default;
+
+ Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override
{
auto allocIndex = m_next;
if (allocIndex % alignment != 0) {
@@ -39,13 +44,13 @@ struct TestLinearAllocator : public Allocator {
return Okay<std::byte*>{m_backing.data() + allocIndex};
}
- virtual void deallocate(std::byte* pointer, size_t bytes) override
+ void deallocate(std::byte* pointer, size_t bytes) override
{
static_cast<void>(pointer);
static_cast<void>(bytes);
}
- virtual bool isEqual(const Allocator& rhs) const override {
+ [[nodiscard]] bool isEqual(const Allocator& rhs) const override {
return &rhs == static_cast<const Allocator*>(this);
}
@@ -82,7 +87,7 @@ struct NonTrivial {
counter++;
}
NonTrivial(const NonTrivial&) = delete;
- NonTrivial(NonTrivial&& rhs) : value{rhs.value}, destroyed{rhs.destroyed}
+ NonTrivial(NonTrivial&& rhs) noexcept : value{rhs.value}, destroyed{rhs.destroyed}
{
rhs.destroyed = true;
}
@@ -94,7 +99,7 @@ struct NonTrivial {
}
}
NonTrivial& operator=(const NonTrivial& rhs) = delete;
- NonTrivial& operator=(NonTrivial&& rhs)
+ NonTrivial& operator=(NonTrivial&& rhs) noexcept
{
value = rhs.value;
destroyed = rhs.destroyed;
@@ -183,4 +188,17 @@ TEST(VectorTest, NestedVector)
// Result<Vector<Vector<FallibleObject>>, FudStatus>
}
+TEST(VectorTest, WithElements)
+{
+ auto vectorResult{Vector<int>::from(NullOpt, 1, 2, 3, 42, -100)};
+ ASSERT_TRUE(vectorResult.isOkay());
+ auto intVector{vectorResult.takeOkay()};
+ ASSERT_EQ(intVector.size(), 5);
+ ASSERT_EQ(intVector[0], 1);
+ ASSERT_EQ(intVector[1], 2);
+ ASSERT_EQ(intVector[2], 3);
+ ASSERT_EQ(intVector[3], 42);
+ ASSERT_EQ(intVector[4], -100);
+}
+
} // namespace fud