// docker-finance | modern accounting for the power-user // // Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //! \file //! \author Aaron Fiore (Founder, Evergreen Crypto LLC) //! \note File intended to be loaded into ROOT.cern framework / Cling interpreter //! \since docker-finance 1.0.0 #ifndef CONTAINER_SRC_ROOT_TEST_UNIT_UTILITY_HH_ #define CONTAINER_SRC_ROOT_TEST_UNIT_UTILITY_HH_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../common/utility.hh" //! \namespace dfi //! \since docker-finance 1.0.0 namespace dfi { //! \namespace dfi::tests //! \brief docker-finance common test framework //! \ingroup cpp_tests //! \since docker-finance 1.0.0 namespace tests { //! \namespace dfi::tests::unit //! \brief docker-finance unit test cases //! \ingroup cpp_tests //! \since docker-finance 1.0.0 namespace unit { //! \brief Tools utility fixture //! \since docker-finance 1.0.0 struct Tools : public ::testing::Test, public tests::ToolsFixture { }; TEST_F(Tools, random_dist_TRandom1) { ASSERT_NO_THROW(tools.dist_range<::TRandom1>(min, max)); } TEST_F(Tools, random_dist_TRandom2) { ASSERT_NO_THROW(tools.dist_range<::TRandom2>(min, max)); } TEST_F(Tools, random_dist_TRandom3) { ASSERT_NO_THROW(tools.dist_range<::TRandom3>(min, max)); } TEST_F(Tools, random_dist_TRandomMixMax) { ASSERT_NO_THROW(tools.dist_range<::TRandomMixMax>(min, max)); } TEST_F(Tools, random_dist_TRandomMixMax17) { ASSERT_NO_THROW(tools.dist_range<::TRandomMixMax17>(min, max)); } TEST_F(Tools, random_dist_TRandomMixMax256) { ASSERT_NO_THROW(tools.dist_range<::TRandomMixMax256>(min, max)); } TEST_F(Tools, random_dist_TRandomMT64) { ASSERT_NO_THROW(tools.dist_range<::TRandomMT64>(min, max)); } TEST_F(Tools, random_dist_TRandomRanlux48) { ASSERT_NO_THROW(tools.dist_range<::TRandomRanlux48>(min, max)); } TEST_F(Tools, random_dist_TRandomRanluxpp) { ASSERT_NO_THROW(tools.dist_range<::TRandomRanluxpp>(min, max)); } //! \brief Byte transformation fixture //! \since docker-finance 1.0.0 struct ByteTransform : public ::testing::Test, public tests::ByteFixture { }; TEST_F(ByteTransform, byte) { ASSERT_EQ(byte.encode(uint8_t{0x01}), std::byte{0x01}); ASSERT_EQ(byte.decode(std::byte{0x01}), uint8_t{0x01}); } TEST_F(ByteTransform, basic_string) { using t_one = std::basic_string; t_one one{fixed_bytes()()}; using t_two = std::basic_string; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, vector) { using t_one = std::vector; t_one one{fixed_bytes()()}; using t_two = std::vector; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, deque) { using t_one = std::deque; t_one one{fixed_bytes()()}; using t_two = std::deque; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, list) { using t_one = std::list; t_one one{fixed_bytes()()}; using t_two = std::list; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, forward_list) { using t_one = std::forward_list; t_one one{fixed_bytes()()}; using t_two = std::forward_list; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, map) { using t_one = std::map; t_one one{fixed_bytes()()}; using t_two = std::map; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, multimap) { using t_one = std::multimap; t_one one{fixed_bytes()()}; using t_two = std::multimap; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, multiset) { using t_one = std::multiset; t_one one{fixed_bytes()()}; using t_two = std::multiset; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, set) { using t_one = std::set; t_one one{fixed_bytes()()}; using t_two = std::set; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, unordered_map) { using t_one = std::unordered_map; t_one one{fixed_bytes()()}; using t_two = std::unordered_map; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, unordered_multimap) { using t_one = std::unordered_multimap; t_one one{fixed_bytes()()}; using t_two = std::unordered_multimap; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, unordered_multiset) { using t_one = std::unordered_multiset; t_one one{fixed_bytes()()}; using t_two = std::unordered_multiset; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } TEST_F(ByteTransform, unordered_set) { using t_one = std::unordered_set; t_one one{fixed_bytes()()}; using t_two = std::unordered_set; t_two two{fixed_bytes()()}; ASSERT_EQ(byte.encode(one), two); ASSERT_EQ(byte.decode(two), one); } //! \brief Common fixture (raw files) //! \note Not a 'common' fixture but rather a fixture for 'common' //! \since docker-finance 1.1.0 struct CommonRawFiles : public ::testing::Test, public ::dfi::tests::CommonFixture { std::string path_1, path_2; void SetUp() override { try { path_1 = std::tmpnam(nullptr); path_2 = std::tmpnam(nullptr); } catch (...) { THROW(std::runtime_error, "could not generate path"); } std::ofstream file_1(path_1), file_2(path_2); THROW_IF( !file_1.is_open() || !file_2.is_open(), std::runtime_error, "could not create file"); file_1 << "using my_foo = int;\n"; file_1.close(); file_2 << "using my_bar = char;\n"; file_2.close(); THROW_IF( file_1.bad() || file_2.bad(), std::runtime_error, "could not write to file"); } void TearDown() override { THROW_IF( std::remove(path_1.c_str()), std::runtime_error, "could not remove file '" + path_1 + "'"); THROW_IF( std::remove(path_2.c_str()), std::runtime_error, "could not remove file '" + path_2 + "'"); } }; TEST_F(CommonRawFiles, RawLoadSingle) { ASSERT_THROW( ::dfi::common::Command::load({path_1 + "should-not-exist"}), std::runtime_error); gInterpreter->ProcessLine("my_foo foo;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_NE(*ecode, EErrorCode::kNoError); ASSERT_NO_THROW(::dfi::common::Command::load(path_1)); gInterpreter->ProcessLine("my_foo foo;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_EQ(*ecode, EErrorCode::kNoError); } TEST_F(CommonRawFiles, RawLoadMultiple) { ASSERT_THROW( ::dfi::common::Command::load( {{path_1 + "should-not-exist"}, {path_2 + "nor-should-this"}}), std::runtime_error); gInterpreter->ProcessLine("my_bar bar;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_NE(*ecode, EErrorCode::kNoError); ASSERT_NO_THROW(::dfi::common::Command::load({path_1, path_2})); gInterpreter->ProcessLine("my_bar bar;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_EQ(*ecode, EErrorCode::kNoError); } // TODO(afiore): RawUnload //! \brief Common fixture (repo files) //! \note Not a 'common' fixture but rather a fixture for 'common' //! \since docker-finance 1.1.0 struct CommonRepoFiles : public ::testing::Test, public ::dfi::tests::CommonFixture { }; TEST_F(CommonRepoFiles, MacroLoad) { ASSERT_THROW( ::dfi::macro::load("macro/should-not/exist.C"), std::runtime_error); gInterpreter->ProcessLine( "dfi::macro::common::crypto::botan::Hash h;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_NE(*ecode, EErrorCode::kNoError); ASSERT_NO_THROW(::dfi::macro::load("crypto/hash.C")); gInterpreter->ProcessLine( "dfi::macro::common::crypto::botan::Hash h;", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_EQ(*ecode, EErrorCode::kNoError); // TODO(afiore): multiple load } // TODO(afiore): MacroUnload TEST_F(CommonRepoFiles, PluginLoad) { ASSERT_THROW( ::dfi::plugin::load("repo/should-not/exist.cc"), std::runtime_error); gInterpreter->ProcessLine( "dfi::plugin::my_plugin_namespace::example2();", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_NE(*ecode, EErrorCode::kNoError); ASSERT_NO_THROW(::dfi::plugin::load("repo/example.cc")); gInterpreter->ProcessLine( "dfi::plugin::my_plugin_namespace::example2();", ecode.get()); ASSERT_NE(ecode, nullptr); EXPECT_EQ(*ecode, EErrorCode::kNoError); // TODO(afiore): multiple load } // TODO(afiore): PluginUnload //! \brief Common fixture (free functions) //! \note Not a 'common' fixture but rather a fixture for 'common' //! \since docker-finance 1.1.0 struct CommonFree : public ::testing::Test, public ::dfi::tests::CommonFixture { }; TEST_F(CommonFree, env) { ASSERT_THROW(::dfi::common::get_env("should-not-exist"), std::runtime_error); ASSERT_NO_THROW(::dfi::common::get_env("DOCKER_FINANCE_VERSION")); } TEST_F(CommonFree, exec) { ASSERT_NE(::dfi::common::exec("should-not-exist"), 0); ASSERT_EQ(::dfi::common::exec("pwd"), 0); } TEST_F(CommonFree, make_timestamp) { ASSERT_EQ(::dfi::common::make_timestamp().size(), 20); } } // namespace unit } // namespace tests } // namespace dfi #endif // CONTAINER_SRC_ROOT_TEST_UNIT_UTILITY_HH_ // # vim: sw=2 sts=2 si ai et