diff --git a/container/src/root/macro/test.C b/container/src/root/macro/test.C index d2dc03e..8a7f8d2 100644 --- a/container/src/root/macro/test.C +++ b/container/src/root/macro/test.C @@ -63,8 +63,9 @@ class Unit { static bool loaded{false}; static const std::initializer_list paths{ - {"../test/unit/random.hh"}, {"../test/unit/hash.hh"}, + {"../test/unit/random.hh"}, + {"../test/unit/type.hh"}, {"../test/unit/utility.hh"}}; if (!loaded) diff --git a/container/src/root/test/common/type.hh b/container/src/root/test/common/type.hh new file mode 100644 index 0000000..bc5ef9f --- /dev/null +++ b/container/src/root/test/common/type.hh @@ -0,0 +1,62 @@ +// docker-finance | modern accounting for the power-user +// +// Copyright (C) 2021-2024 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_COMMON_TYPE_HH_ +#define CONTAINER_SRC_ROOT_TEST_COMMON_TYPE_HH_ + +#include + +#include + +#include "../../src/internal/type.hh" + +//! \namespace docker_finance +//! \since docker-finance 1.0.0 +namespace docker_finance +{ +//! \namespace docker_finance::tests +//! \brief docker-finance common test framework +//! \ingroup cpp_tests +//! \since docker-finance 1.0.0 +namespace tests +{ +//! \namespace docker_finance::tests::unit +//! \brief docker-finance unit test cases +//! \ingroup cpp_tests +//! \since docker-finance 1.0.0 +namespace unit +{ +//! \brief Exception fixture (base) +//! \since docker-finance 1.0.0 +struct Exception : public ::testing::Test +{ + protected: + std::string_view what = "better to be caught than thrown"; + using t_type = type::Exception::kType; +}; +} // namespace unit +} // namespace tests +} // namespace docker_finance + +#endif // CONTAINER_SRC_ROOT_TEST_COMMON_TYPE_HH_ + +// # vim: sw=2 sts=2 si ai et diff --git a/container/src/root/test/unit/type.hh b/container/src/root/test/unit/type.hh new file mode 100644 index 0000000..831bbae --- /dev/null +++ b/container/src/root/test/unit/type.hh @@ -0,0 +1,243 @@ +// docker-finance | modern accounting for the power-user +// +// Copyright (C) 2021-2024 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_TYPE_HH_ +#define CONTAINER_SRC_ROOT_TEST_UNIT_TYPE_HH_ + +#include + +#include + +#include "../common/type.hh" + +//! \namespace docker_finance +//! \since docker-finance 1.0.0 +namespace docker_finance +{ +//! \namespace docker_finance::tests +//! \brief docker-finance common test framework +//! \ingroup cpp_tests +//! \since docker-finance 1.0.0 +namespace tests +{ +//! \namespace docker_finance::tests::unit +//! \brief docker-finance unit test cases +//! \ingroup cpp_tests +//! \since docker-finance 1.0.0 +namespace unit +{ + +// +// RuntimeError +// + +//! \brief Exception fixture (RuntimeError) +//! \since docker-finance 1.0.0 +struct RuntimeError : public Exception +{ +}; + +TEST_F(RuntimeError, macro_THROW_IF) // cppcheck-suppress syntaxError +{ + try + { + THROW_IF(false, type::RuntimeError, message); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::RuntimeError); + ASSERT_EQ(ex.what(), what); + } +} + +TEST_F(RuntimeError, macro_THROW) +{ + try + { + THROW(type::RuntimeError, message); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::RuntimeError); + // NOTE: no case for ex.what() because message is formatted within macro + } +} + +TEST_F(RuntimeError, rethrow) +{ + ASSERT_THROW( + { + try + { + throw type::RuntimeError(what); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::RuntimeError); + ASSERT_EQ(ex.what(), what); + throw; + } + }, + type::Exception); +} + +TEST_F(RuntimeError, copy_assignment) +{ + type::RuntimeError one(what); + type::RuntimeError two; + + two = one; + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(RuntimeError, copy_ctor) +{ + type::RuntimeError one(what); + type::RuntimeError two(one); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(RuntimeError, move_assignment) +{ + type::RuntimeError one(what); + type::RuntimeError two; + + two = std::move(one); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(RuntimeError, move_ctor) +{ + type::RuntimeError one(what); + type::RuntimeError two(std::move(one)); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +// +// InvalidArgument +// + +//! \brief Exception fixture (InvalidArgument) +//! \since docker-finance 1.0.0 +struct InvalidArgument : public Exception +{ +}; + +TEST_F(InvalidArgument, macro_THROW_IF) // cppcheck-suppress syntaxError +{ + try + { + THROW_IF(false, type::InvalidArgument, message); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::InvalidArgument); + ASSERT_EQ(ex.what(), what); + } +} + +TEST_F(InvalidArgument, macro_THROW) +{ + try + { + THROW(type::InvalidArgument, message); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::InvalidArgument); + // NOTE: no case for ex.what() because message is formatted within macro + } +} + +TEST_F(InvalidArgument, rethrow) +{ + ASSERT_THROW( + { + try + { + throw type::InvalidArgument(what); + } + catch (const type::Exception& ex) + { + ASSERT_EQ(ex.type(), t_type::InvalidArgument); + ASSERT_EQ(ex.what(), what); + throw; + } + }, + type::Exception); +} + +TEST_F(InvalidArgument, copy_assignment) +{ + type::InvalidArgument one(what); + type::InvalidArgument two; + + two = one; + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(InvalidArgument, copy_ctor) +{ + type::InvalidArgument one(what); + type::InvalidArgument two(one); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(InvalidArgument, move_assignment) +{ + type::InvalidArgument one(what); + type::InvalidArgument two; + + two = std::move(one); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +TEST_F(InvalidArgument, move_ctor) +{ + type::InvalidArgument one(what); + type::InvalidArgument two(std::move(one)); + + ASSERT_EQ(one.type(), two.type()); + ASSERT_EQ(one.what(), two.what()); +} + +} // namespace unit +} // namespace tests +} // namespace docker_finance + +#endif // CONTAINER_SRC_ROOT_TEST_UNIT_TYPE_HH_ + +// # vim: sw=2 sts=2 si ai et