container: root: rewrite throw handler, refactor using common types

- Refactor using common types that were once internal
- Removes ancient macro approaches to C++20 solutions
- Changes `Exception` message type to use std::string
  * std::string_view isn't worthwhile in this context
This commit is contained in:
2025-11-19 16:37:46 -08:00
parent fa91fd02e8
commit ca59169116
11 changed files with 134 additions and 121 deletions

View File

@@ -24,32 +24,7 @@
#define CONTAINER_SRC_ROOT_COMMON_TYPE_HH_ #define CONTAINER_SRC_ROOT_COMMON_TYPE_HH_
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string>
//! \brief Conditional throw handler
//! \ingroup cpp_type_exceptions
#define THROW_IF(condition, exception, message) \
if (condition) \
THROW(exception, message);
//! \brief Throw handler
//! \ingroup cpp_type_exceptions
#define THROW(exception, message) \
THROW_IMPL(exception, \
\n\tFILE = __FILE__ \
\n\tLINE = __LINE__ \
\n\tWHAT = message);
//! \brief Throw handler implementation
//! \warning Should not be called directly, use THROW handlers
//! \ingroup cpp_type_exceptions
#define THROW_IMPL(exception, message) \
throw exception(THROW_IMPL_EXPAND(message));
//! \brief Throw handler implementation (message)
//! \warning Should not be called directly, use THROW handlers
//! \ingroup cpp_type_exceptions
#define THROW_IMPL_EXPAND(message) #message
//! \namespace dfi //! \namespace dfi
//! \since docker-finance 1.0.0 //! \since docker-finance 1.0.0
@@ -70,15 +45,15 @@ namespace type
class Exception : virtual public std::exception class Exception : virtual public std::exception
{ {
public: public:
//! \brief Exception type //! \brief Exception type tag
enum struct kType : uint8_t enum struct kType : uint8_t
{ {
RuntimeError, RuntimeError,
InvalidArgument, InvalidArgument,
}; };
//! \brief Construct by type with given message //! \brief Construct by type tag with given message
Exception(const kType type, const std::string_view what) Exception(const kType type, const std::string& what)
: m_type(type), m_what(what) : m_type(type), m_what(what)
{ {
} }
@@ -91,32 +66,32 @@ class Exception : virtual public std::exception
Exception& operator=(Exception&&) = default; Exception& operator=(Exception&&) = default;
public: public:
//! \return Exeption type //! \return Exeption type tag
kType type() const noexcept { return m_type; } kType type() const noexcept { return m_type; }
//! \return Exception message //! \return Exception message
const char* what() const noexcept { return m_what.data(); } const char* what() const noexcept { return m_what.c_str(); }
private: private:
kType m_type; kType m_type;
std::string_view m_what; std::string m_what;
}; };
//! \brief Exception class for runtime errors //! \brief Exception type for runtime errors
//! \ingroup cpp_type_exceptions //! \ingroup cpp_type_exceptions
struct RuntimeError final : public Exception struct RuntimeError final : public Exception
{ {
explicit RuntimeError(const std::string_view what = {}) explicit RuntimeError(const std::string& what = {})
: Exception(Exception::kType::RuntimeError, what) : Exception(Exception::kType::RuntimeError, what)
{ {
} }
}; };
//! \brief Exception class for invalid arguments (logic error) //! \brief Exception type for invalid arguments (logic error)
//! \ingroup cpp_type_exceptions //! \ingroup cpp_type_exceptions
struct InvalidArgument final : public Exception struct InvalidArgument final : public Exception
{ {
explicit InvalidArgument(const std::string_view what = {}) explicit InvalidArgument(const std::string& what = {})
: Exception(Exception::kType::InvalidArgument, what) : Exception(Exception::kType::InvalidArgument, what)
{ {
} }

View File

@@ -30,6 +30,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "./type.hh"
//! \namespace dfi //! \namespace dfi
//! \since docker-finance 1.0.0 //! \since docker-finance 1.0.0
namespace dfi namespace dfi
@@ -39,6 +41,51 @@ namespace dfi
//! \since docker-finance 1.1.0 //! \since docker-finance 1.1.0
namespace common namespace common
{ {
//! \concept Exception
//! \brief Exception type concept for `dfi` exceptions
//! \ingroup cpp_common_impl
//! \since docker-finance 1.1.0
template <typename t_exception>
concept Exception = std::derived_from<t_exception, type::Exception>;
//! \brief Throw exception using `dfi` exception type
//! \param message Message to pass to exception type
//! \param location Source location of exception
//! \ingroup cpp_common_impl
//! \since docker-finance 1.1.0
template <Exception t_exception>
inline void throw_ex(
const std::string& message = {},
const std::source_location location = std::source_location::current())
{
// TODO(unassigned): when throwing because of heap allocation
std::string msg;
msg += std::string(" \n\tFILE = ") + location.file_name();
msg += std::string(" \n\tFUNC = ") + location.function_name();
msg += std::string(" \n\tLINE = ") + location.line();
msg += std::string(" \n\tWHAT = ") + message;
throw t_exception(msg);
}
//! \brief Throw exception using `dfi` exception type (but only on condition)
//! \param condition If boolean condition is true, throw
//! \param message Message to pass to exception type
//! \param location Source location of exception
//! \ingroup cpp_common_impl
//! \since docker-finance 1.1.0
template <Exception t_exception>
inline void throw_ex_if(
const bool condition,
const std::string& message = {},
const std::source_location location = std::source_location::current())
{
if (condition)
{
throw_ex<t_exception>(message, location);
}
}
//! \brief Wrapper to ROOT Cling commands //! \brief Wrapper to ROOT Cling commands
//! \ingroup cpp_common_impl //! \ingroup cpp_common_impl
//! \since docker-finance 1.0.0 //! \since docker-finance 1.0.0
@@ -69,16 +116,13 @@ class Command
static void load(const std::string& path) static void load(const std::string& path)
{ {
std::filesystem::path p(path); std::filesystem::path p(path);
if (!std::filesystem::exists(p))
{ throw_ex_if<type::RuntimeError>(
throw std::runtime_error( !std::filesystem::exists(p), "'" + path + "' does not exist!");
std::string{"'" + path + "' does not exist!"}.c_str());
} throw_ex_if<type::RuntimeError>(
if (!std::filesystem::is_regular_file(p)) !std::filesystem::is_regular_file(p),
{ "'" + path + "' is not a regular file!");
throw std::runtime_error(
std::string{"'" + path + "' is not a regular file!"}.c_str());
}
std::string cmd{".L " + path}; std::string cmd{".L " + path};
Command::cmd_handler({cmd}); Command::cmd_handler({cmd});
@@ -101,9 +145,10 @@ class Command
std::string get_env(const std::string& var) std::string get_env(const std::string& var)
{ {
const auto* env = gSystem->Getenv(var.c_str()); const auto* env = gSystem->Getenv(var.c_str());
if (!env)
throw std::runtime_error( throw_ex_if<type::RuntimeError>(
std::string{var + " is not set or is unavailable"}.c_str()); !env, "'" + var + "' is not set or is unavailable");
return std::string{env}; return std::string{env};
} }

View File

@@ -184,7 +184,7 @@ class Meta final
//! \param column Existing CSV metadata column //! \param column Existing CSV metadata column
static void meta_sample(const std::string& column) static void meta_sample(const std::string& column)
{ {
namespace common = ::dfi::macro::common; namespace common = ::dfi::common;
// Import meta file // Import meta file
const std::string path{common::get_env("global_conf_meta")}; const std::string path{common::get_env("global_conf_meta")};
@@ -197,14 +197,12 @@ class Meta final
available += "\n\t" + col; available += "\n\t" + col;
available += "\n"; available += "\n";
if (!csv->HasColumn(column)) common::throw_ex_if<common::type::RuntimeError>(
throw std::runtime_error( !csv->HasColumn(column), "\n\nAvailable columns: " + available);
std::string{"\n\nAvailable columns: " + available}.c_str());
// Aggregate all rows of given column // Aggregate all rows of given column
auto count = csv->Count(); auto count = csv->Count();
if (!*count) common::throw_ex_if<common::type::RuntimeError>(!*count, "Empty CSV");
throw std::runtime_error("Empty CSV");
// Prepare canvas data // Prepare canvas data
Meta::CanvasData data; Meta::CanvasData data;

View File

@@ -87,7 +87,7 @@ void load(const std::string& path)
} }
else else
{ {
throw std::runtime_error( ::dfi::common::throw_ex<::dfi::common::type::RuntimeError>(
"must be of type 'repo/<file>' or 'custom/<file>'"); "must be of type 'repo/<file>' or 'custom/<file>'");
} }

View File

@@ -429,10 +429,8 @@ class Hash : public common::HashImpl<libsodium::Hash>, public type::Hash
//! have any effects." //! have any effects."
Hash() Hash()
{ {
THROW_IF( ::dfi::common::throw_ex_if<::dfi::common::type::RuntimeError>(
::sodium_init() < 0, ::sodium_init() < 0, "sodium_init could not be initialized");
type::RuntimeError,
"sodium_init could not be initialized")
} }
~Hash() = default; ~Hash() = default;

View File

@@ -128,7 +128,8 @@ class Random : public common::RandomImpl<botan::Random>
|| std::is_same_v<t_random, uint32_t>, || std::is_same_v<t_random, uint32_t>,
"Invalid type (only uint16_t or uint32_t supported)"); "Invalid type (only uint16_t or uint32_t supported)");
THROW_IF(!m_csprng.is_seeded(), type::RuntimeError, "Botan is not seeded") ::dfi::common::throw_ex_if<type::RuntimeError>(
!m_csprng.is_seeded(), "Botan is not seeded");
// WARNING: DO *NOT* set_high_bit to true here! // WARNING: DO *NOT* set_high_bit to true here!
// Otherwise, [0..(~2150*10^6)] WILL NOT BE GENERATED! // Otherwise, [0..(~2150*10^6)] WILL NOT BE GENERATED!
@@ -222,10 +223,8 @@ class Random : public common::RandomImpl<libsodium::Random>
//! have any effects." //! have any effects."
Random() Random()
{ {
THROW_IF( ::dfi::common::throw_ex_if<::dfi::common::type::RuntimeError>(
::sodium_init() < 0, ::sodium_init() < 0, "sodium_init could not be initialized");
type::RuntimeError,
"sodium_init could not be initialized")
} }
~Random() = default; ~Random() = default;

View File

@@ -159,8 +159,8 @@ class Tools
std::vector<t_num> std::vector<t_num>
random_dist(const t_num min, const t_num max, const uint16_t precision = 8) random_dist(const t_num min, const t_num max, const uint16_t precision = 8)
{ {
THROW_IF( ::dfi::common::throw_ex_if<::dfi::common::type::InvalidArgument>(
min > max, type::InvalidArgument, "minimum is greater than maximum") min > max, "minimum is greater than maximum");
// Get first chunk // Get first chunk
std::vector<t_num> chunks; std::vector<t_num> chunks;
@@ -193,7 +193,8 @@ class Tools
std::cout.precision(precision); std::cout.precision(precision);
std::cout << "rounded = " << rounded << '\n' std::cout << "rounded = " << rounded << '\n'
<< "max = " << max << std::fixed << std::endl; << "max = " << max << std::fixed << std::endl;
THROW(type::RuntimeError, "random distribution not fulfilled") ::dfi::common::throw_ex<::dfi::common::type::RuntimeError>(
"random distribution not fulfilled");
} }
return chunks; return chunks;

View File

@@ -43,6 +43,7 @@ namespace dfi
namespace utility namespace utility
{ {
namespace common = ::dfi::common;
namespace type = dfi::internal::type; namespace type = dfi::internal::type;
//! \brief Misc utility tools //! \brief Misc utility tools
@@ -86,8 +87,8 @@ class Tools final : protected impl::Tools
void print_dist(t_num min, t_num max, const size_t precision = 8) void print_dist(t_num min, t_num max, const size_t precision = 8)
{ {
// Specific to this use-case // Specific to this use-case
THROW_IF( common::throw_ex_if<common::type::InvalidArgument>(
min < 0 || max < 0, type::InvalidArgument, "no negative values allowed") min < 0 || max < 0, "no negative values allowed");
if (min > max) if (min > max)
{ {

View File

@@ -25,7 +25,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <string_view> #include <string>
#include "../../src/internal/type.hh" #include "../../src/internal/type.hh"
@@ -50,8 +50,8 @@ namespace unit
struct Exception : public ::testing::Test struct Exception : public ::testing::Test
{ {
protected: protected:
std::string_view what = "better to be caught than thrown"; std::string what = "better to be caught than thrown";
using t_type = type::Exception::kType; using t_type = ::dfi::common::type::Exception::kType;
}; };
} // namespace unit } // namespace unit
} // namespace tests } // namespace tests

View File

@@ -46,6 +46,8 @@ namespace tests
namespace unit namespace unit
{ {
namespace common = ::dfi::common;
// //
// RuntimeError // RuntimeError
// //
@@ -56,11 +58,11 @@ struct RuntimeError : public Exception
{ {
}; };
TEST_F(RuntimeError, macro_THROW_IF) // cppcheck-suppress syntaxError TEST_F(RuntimeError, throw_ex_if) // cppcheck-suppress syntaxError
{ {
try try
{ {
THROW_IF(false, type::RuntimeError, message); common::throw_ex_if<common::type::RuntimeError>(false, what);
} }
catch (const type::Exception& ex) catch (const type::Exception& ex)
{ {
@@ -69,16 +71,16 @@ TEST_F(RuntimeError, macro_THROW_IF) // cppcheck-suppress syntaxError
} }
} }
TEST_F(RuntimeError, macro_THROW) TEST_F(RuntimeError, throw_ex)
{ {
try try
{ {
THROW(type::RuntimeError, message); common::throw_ex<common::type::RuntimeError>(what);
} }
catch (const type::Exception& ex) catch (const type::Exception& ex)
{ {
ASSERT_EQ(ex.type(), t_type::RuntimeError); ASSERT_EQ(ex.type(), t_type::RuntimeError);
// NOTE: no case for ex.what() because message is formatted within macro // NOTE: no case for ex.what() because message is formatted within function
} }
} }
@@ -108,7 +110,7 @@ TEST_F(RuntimeError, copy_assignment)
two = one; two = one;
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STREQ(one.what(), two.what());
} }
TEST_F(RuntimeError, copy_ctor) TEST_F(RuntimeError, copy_ctor)
@@ -117,7 +119,7 @@ TEST_F(RuntimeError, copy_ctor)
type::RuntimeError two(one); type::RuntimeError two(one);
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STREQ(one.what(), two.what());
} }
TEST_F(RuntimeError, move_assignment) TEST_F(RuntimeError, move_assignment)
@@ -128,7 +130,7 @@ TEST_F(RuntimeError, move_assignment)
two = std::move(one); two = std::move(one);
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STRNE(one.what(), two.what());
} }
TEST_F(RuntimeError, move_ctor) TEST_F(RuntimeError, move_ctor)
@@ -137,7 +139,7 @@ TEST_F(RuntimeError, move_ctor)
type::RuntimeError two(std::move(one)); type::RuntimeError two(std::move(one));
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STRNE(one.what(), two.what());
} }
// //
@@ -150,11 +152,11 @@ struct InvalidArgument : public Exception
{ {
}; };
TEST_F(InvalidArgument, macro_THROW_IF) // cppcheck-suppress syntaxError TEST_F(InvalidArgument, throw_ex_if)
{ {
try try
{ {
THROW_IF(false, type::InvalidArgument, message); common::throw_ex_if<common::type::InvalidArgument>(false, what);
} }
catch (const type::Exception& ex) catch (const type::Exception& ex)
{ {
@@ -163,16 +165,16 @@ TEST_F(InvalidArgument, macro_THROW_IF) // cppcheck-suppress syntaxError
} }
} }
TEST_F(InvalidArgument, macro_THROW) TEST_F(InvalidArgument, throw_ex)
{ {
try try
{ {
THROW(type::InvalidArgument, message); common::throw_ex<common::type::InvalidArgument>(what);
} }
catch (const type::Exception& ex) catch (const type::Exception& ex)
{ {
ASSERT_EQ(ex.type(), t_type::InvalidArgument); ASSERT_EQ(ex.type(), t_type::InvalidArgument);
// NOTE: no case for ex.what() because message is formatted within macro // NOTE: no case for ex.what() because message is formatted within function
} }
} }
@@ -202,7 +204,7 @@ TEST_F(InvalidArgument, copy_assignment)
two = one; two = one;
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STREQ(one.what(), two.what());
} }
TEST_F(InvalidArgument, copy_ctor) TEST_F(InvalidArgument, copy_ctor)
@@ -211,7 +213,7 @@ TEST_F(InvalidArgument, copy_ctor)
type::InvalidArgument two(one); type::InvalidArgument two(one);
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STREQ(one.what(), two.what());
} }
TEST_F(InvalidArgument, move_assignment) TEST_F(InvalidArgument, move_assignment)
@@ -222,7 +224,7 @@ TEST_F(InvalidArgument, move_assignment)
two = std::move(one); two = std::move(one);
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STRNE(one.what(), two.what());
} }
TEST_F(InvalidArgument, move_ctor) TEST_F(InvalidArgument, move_ctor)
@@ -231,7 +233,7 @@ TEST_F(InvalidArgument, move_ctor)
type::InvalidArgument two(std::move(one)); type::InvalidArgument two(std::move(one));
ASSERT_EQ(one.type(), two.type()); ASSERT_EQ(one.type(), two.type());
ASSERT_EQ(one.what(), two.what()); ASSERT_STRNE(one.what(), two.what());
} }
} // namespace unit } // namespace unit

View File

@@ -60,6 +60,9 @@ namespace tests
//! \since docker-finance 1.0.0 //! \since docker-finance 1.0.0
namespace unit namespace unit
{ {
namespace common = ::dfi::common;
//! \brief Tools utility fixture //! \brief Tools utility fixture
//! \since docker-finance 1.0.0 //! \since docker-finance 1.0.0
struct Tools : public ::testing::Test, public tests::ToolsFixture struct Tools : public ::testing::Test, public tests::ToolsFixture
@@ -296,50 +299,41 @@ struct CommonRawFiles : public ::testing::Test,
} }
catch (...) catch (...)
{ {
THROW(std::runtime_error, "could not generate path"); common::throw_ex<common::type::RuntimeError>("could not generate path");
} }
std::ofstream file_1(path_1), file_2(path_2); std::ofstream file_1(path_1), file_2(path_2);
THROW_IF( common::throw_ex_if<common::type::RuntimeError>(
!file_1.is_open() || !file_2.is_open(), !file_1.is_open() || !file_2.is_open(), "could not create file");
std::runtime_error,
"could not create file");
file_1 << "using my_foo = int;\n"; file_1 << "using my_foo = int;\n";
file_1.close(); file_1.close();
file_2 << "using my_bar = char;\n"; file_2 << "using my_bar = char;\n";
file_2.close(); file_2.close();
THROW_IF( common::throw_ex_if<common::type::RuntimeError>(
file_1.bad() || file_2.bad(), file_1.bad() || file_2.bad(), "could not write to file");
std::runtime_error,
"could not write to file");
} }
void TearDown() override void TearDown() override
{ {
THROW_IF( common::throw_ex_if<common::type::RuntimeError>(
std::remove(path_1.c_str()), std::remove(path_1.c_str()), "could not remove file '" + path_1 + "'");
std::runtime_error,
"could not remove file '" + path_1 + "'");
THROW_IF( common::throw_ex_if<common::type::RuntimeError>(
std::remove(path_2.c_str()), std::remove(path_2.c_str()), "could not remove file '" + path_2 + "'");
std::runtime_error,
"could not remove file '" + path_2 + "'");
} }
}; };
TEST_F(CommonRawFiles, RawLoadSingle) TEST_F(CommonRawFiles, RawLoadSingle)
{ {
ASSERT_THROW( ASSERT_THROW(
::dfi::common::Command::load({path_1 + "should-not-exist"}), common::Command::load({path_1 + "should-not-exist"}), type::RuntimeError);
std::runtime_error);
gInterpreter->ProcessLine("my_foo foo;", ecode.get()); gInterpreter->ProcessLine("my_foo foo;", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
EXPECT_NE(*ecode, EErrorCode::kNoError); EXPECT_NE(*ecode, EErrorCode::kNoError);
ASSERT_NO_THROW(::dfi::common::Command::load(path_1)); ASSERT_NO_THROW(common::Command::load(path_1));
gInterpreter->ProcessLine("my_foo foo;", ecode.get()); gInterpreter->ProcessLine("my_foo foo;", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
EXPECT_EQ(*ecode, EErrorCode::kNoError); EXPECT_EQ(*ecode, EErrorCode::kNoError);
@@ -348,14 +342,14 @@ TEST_F(CommonRawFiles, RawLoadSingle)
TEST_F(CommonRawFiles, RawLoadMultiple) TEST_F(CommonRawFiles, RawLoadMultiple)
{ {
ASSERT_THROW( ASSERT_THROW(
::dfi::common::Command::load( common::Command::load(
{{path_1 + "should-not-exist"}, {path_2 + "nor-should-this"}}), {{path_1 + "should-not-exist"}, {path_2 + "nor-should-this"}}),
std::runtime_error); type::RuntimeError);
gInterpreter->ProcessLine("my_bar bar;", ecode.get()); gInterpreter->ProcessLine("my_bar bar;", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
EXPECT_NE(*ecode, EErrorCode::kNoError); EXPECT_NE(*ecode, EErrorCode::kNoError);
ASSERT_NO_THROW(::dfi::common::Command::load({path_1, path_2})); ASSERT_NO_THROW(common::Command::load({path_1, path_2}));
gInterpreter->ProcessLine("my_bar bar;", ecode.get()); gInterpreter->ProcessLine("my_bar bar;", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
EXPECT_EQ(*ecode, EErrorCode::kNoError); EXPECT_EQ(*ecode, EErrorCode::kNoError);
@@ -373,7 +367,7 @@ struct CommonRepoFiles : public ::testing::Test,
TEST_F(CommonRepoFiles, MacroLoad) TEST_F(CommonRepoFiles, MacroLoad)
{ {
ASSERT_THROW( ASSERT_THROW(
::dfi::macro::load("macro/should-not/exist.C"), std::runtime_error); ::dfi::macro::load("macro/should-not/exist.C"), type::RuntimeError);
gInterpreter->ProcessLine( gInterpreter->ProcessLine(
"dfi::macro::common::crypto::botan::Hash h;", ecode.get()); "dfi::macro::common::crypto::botan::Hash h;", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
@@ -391,7 +385,7 @@ TEST_F(CommonRepoFiles, MacroLoad)
TEST_F(CommonRepoFiles, PluginLoad) TEST_F(CommonRepoFiles, PluginLoad)
{ {
ASSERT_THROW( ASSERT_THROW(
::dfi::plugin::load("repo/should-not/exist.cc"), std::runtime_error); ::dfi::plugin::load("repo/should-not/exist.cc"), type::RuntimeError);
gInterpreter->ProcessLine( gInterpreter->ProcessLine(
"dfi::plugin::my_plugin_namespace::example2();", ecode.get()); "dfi::plugin::my_plugin_namespace::example2();", ecode.get());
ASSERT_NE(ecode, nullptr); ASSERT_NE(ecode, nullptr);
@@ -416,19 +410,19 @@ struct CommonFree : public ::testing::Test, public ::dfi::tests::CommonFixture
TEST_F(CommonFree, env) TEST_F(CommonFree, env)
{ {
ASSERT_THROW(::dfi::common::get_env("should-not-exist"), std::runtime_error); ASSERT_THROW(common::get_env("should-not-exist"), type::RuntimeError);
ASSERT_NO_THROW(::dfi::common::get_env("DOCKER_FINANCE_VERSION")); ASSERT_NO_THROW(common::get_env("DOCKER_FINANCE_VERSION"));
} }
TEST_F(CommonFree, exec) TEST_F(CommonFree, exec)
{ {
ASSERT_NE(::dfi::common::exec("should-not-exist"), 0); ASSERT_NE(common::exec("should-not-exist"), 0);
ASSERT_EQ(::dfi::common::exec("pwd"), 0); ASSERT_EQ(common::exec("pwd"), 0);
} }
TEST_F(CommonFree, make_timestamp) TEST_F(CommonFree, make_timestamp)
{ {
ASSERT_EQ(::dfi::common::make_timestamp().size(), 20); ASSERT_EQ(common::make_timestamp().size(), 20);
} }
} // namespace unit } // namespace unit