From 97a8af02d9bceac05de48b62893a85a9919ce25b Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Sat, 23 Jul 2022 14:47:13 +0100 Subject: [PATCH] unit tests for util classes. --- fggl/util/guid.cpp | 18 +++++++++++++- include/fggl/util/guid.hpp | 7 +++--- include/fggl/util/safety.hpp | 10 ++++++++ tests/testfggl/CMakeLists.txt | 1 + tests/testfggl/util/guid.cpp | 15 +++++++++--- tests/testfggl/util/safety.cpp | 44 ++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 tests/testfggl/util/safety.cpp diff --git a/fggl/util/guid.cpp b/fggl/util/guid.cpp index 569353d..f2f908a 100644 --- a/fggl/util/guid.cpp +++ b/fggl/util/guid.cpp @@ -23,9 +23,13 @@ #include "fggl/util/guid.hpp" namespace fggl::util { - static std::map<GUID, std::string> guidTable; + namespace { + std::map<GUID, std::string> guidTable; + } GUID internString(const char* str) { + assert(str != nullptr); + GUID guid = make_guid(str); auto tableValue = guidTable.find(guid); if (tableValue != guidTable.end()) { @@ -33,6 +37,7 @@ namespace fggl::util { } else { guidTable[guid] = str; } + return guid; } std::string guidToString(GUID guid) { @@ -43,4 +48,15 @@ namespace fggl::util { return "FGGL_UNKNOWN_GUID"; } } + +} + +fggl::util::GUID operator "" _fid(const char* str) { + fggl::util::internString(str); + return fggl::util::make_guid(str); +} + +fggl::util::GUID operator "" _fid(const char* str, std::size_t) { + fggl::util::internString(str); + return fggl::util::make_guid(str); } diff --git a/include/fggl/util/guid.hpp b/include/fggl/util/guid.hpp index a4ac1e8..c9c85b2 100644 --- a/include/fggl/util/guid.hpp +++ b/include/fggl/util/guid.hpp @@ -68,14 +68,13 @@ namespace fggl::util { return GUID::make(hash_fnv1a_64(str)); } - constexpr GUID operator ""_fid(const char* str) { - return make_guid(str); - } - // debug-only functions GUID internString(const char* str); std::string guidToString(GUID guid); } // namespace fggl::util +fggl::util::GUID operator "" _fid(const char* str); +fggl::util::GUID operator "" _fid(const char* str, std::size_t); + #endif //FGGL_UTIL_GUID_HPP diff --git a/include/fggl/util/safety.hpp b/include/fggl/util/safety.hpp index 18797ea..6a10829 100644 --- a/include/fggl/util/safety.hpp +++ b/include/fggl/util/safety.hpp @@ -23,6 +23,16 @@ namespace fggl::util { + /** + * A type-safe opaque handle. + * + * Lots of low-level libaries we use pass around handles as some primative type. It's fairly easy to accidentally + * mix these up. This wrapper's job is to make sure that mixing up handle types is impossible (and results in + * compiler errors). + * + * @tparam T the underling type of the handle. + * @tparam Tag a unique tag used to identify the handle type. + */ template<typename T, typename Tag> struct OpaqueName { private: diff --git a/tests/testfggl/CMakeLists.txt b/tests/testfggl/CMakeLists.txt index 13fa77d..589fbb1 100644 --- a/tests/testfggl/CMakeLists.txt +++ b/tests/testfggl/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable( fggl_test # ecs3/easing.cpp # math/types.cpp util/guid.cpp + util/safety.cpp ) target_include_directories(fggl_test PUBLIC diff --git a/tests/testfggl/util/guid.cpp b/tests/testfggl/util/guid.cpp index 0d2baa9..e4dedf7 100644 --- a/tests/testfggl/util/guid.cpp +++ b/tests/testfggl/util/guid.cpp @@ -17,8 +17,6 @@ // #include <gtest/gtest.h> -#include <gmock/gmock.h> - #include "fggl/util/guid.hpp" namespace { @@ -69,7 +67,6 @@ namespace { } // sanity checks - TEST(UtilHash32, RepeatsAreEqual) { auto value = fggl::util::hash_fnv1a_32("fggl::test::scoped"); auto value2 = fggl::util::hash_fnv1a_32("fggl::test::scoped"); @@ -82,4 +79,16 @@ namespace { EXPECT_EQ( value, value2 ); } + // GUID tests + TEST(GuidTest, GuidSuffix) { + auto guid = fggl::util::make_guid("test"); + auto guidSuffix = "test"_fid; + EXPECT_EQ(guid, guidSuffix); + } + + TEST(GuidTest, GuidToString) { + fggl::util::GUID guid = fggl::util::internString("test"); + EXPECT_EQ("test", fggl::util::guidToString(guid)); + } + } diff --git a/tests/testfggl/util/safety.cpp b/tests/testfggl/util/safety.cpp new file mode 100644 index 0000000..f88475d --- /dev/null +++ b/tests/testfggl/util/safety.cpp @@ -0,0 +1,44 @@ +/* + * This file is part of FGGL. + * + * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with FGGL. + * If not, see <https://www.gnu.org/licenses/>. + */ + +// +// Created by webpigeon on 23/07/22. +// + +#include <gtest/gtest.h> +#include "fggl/util/safety.hpp" + +namespace { + + using TestType = fggl::util::OpaqueName<unsigned int, struct TestTag>; + + TEST(SafetyHandle, CheckZero) { + auto v1 = TestType::make(0); + auto v2 = TestType::make(0); + EXPECT_EQ(v1, v2); + } + + TEST(SafetyHandle, CheckValue) { + auto v1 = TestType::make(0x12345678); + auto v2 = TestType::make(0x12345678); + EXPECT_EQ(v1, v2); + } + + TEST(SafetyHandle, CheckValueNE) { + auto v1 = TestType::make(0x12345678); + auto v2 = TestType::make(0x87654321); + EXPECT_NE(v1, v2); + } + +} \ No newline at end of file -- GitLab