Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions test/test_asserts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ TEST(test_asserts, check_does_not_throw_if_condition_is_true) {
EXPECT_NO_THROW(rcpputils::check_true(true));
}

TEST(test_asserts, assertion_exception_what_message) {
const rcpputils::AssertionException ex("assertion failed");
EXPECT_STREQ("assertion failed", ex.what());
}

TEST(test_asserts, illegal_state_exception_what_message) {
const rcpputils::IllegalStateException ex("illegal state");
EXPECT_STREQ("illegal state", ex.what());
}

TEST(test_asserts, assertion_exception_empty_message) {
const rcpputils::AssertionException ex("");
EXPECT_STREQ("", ex.what());
}

TEST(test_asserts, illegal_state_exception_empty_message) {
const rcpputils::IllegalStateException ex("");
EXPECT_STREQ("", ex.what());
}

#ifndef NDEBUG
TEST(test_asserts, assert_true_throws_if_condition_is_false_and_ndebug_not_set) {
EXPECT_THROW(rcpputils::assert_true(false), rcpputils::AssertionException);
Expand Down
8 changes: 8 additions & 0 deletions test/test_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,11 @@ TEST(TestSetEnv, test_set_env) {
"",
rcpputils::get_env_var("NEW_ENV_VAR").c_str());
}

TEST(TestSetEnv, test_set_env_empty_value) {
// Setting to empty string is distinct from unsetting.
EXPECT_TRUE(rcpputils::set_env_var("EMPTY_VALUE_VAR", ""));
EXPECT_STREQ("", rcpputils::get_env_var("EMPTY_VALUE_VAR").c_str());
// Cleanup
EXPECT_TRUE(rcpputils::set_env_var("EMPTY_VALUE_VAR", nullptr));
}
39 changes: 39 additions & 0 deletions test/test_filesystem_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <fstream>
#include <string>
#include <vector>

#include "rcpputils/filesystem_helper.hpp"
#include "rcpputils/env.hpp"
Expand Down Expand Up @@ -99,3 +100,41 @@ TEST(TestFilesystemHelper, create_temporary_directory)
EXPECT_EQ(tmpdir_template_in_name.filename().string().rfind("base_", 0), 0u);
}
}

TEST(TestFilesystemHelper, create_temporary_directory_default_parent)
{
// When no parent_path is provided the function should use std::filesystem::temp_directory_path.
const auto tmpdir = rcpputils::fs::create_temporary_directory("default_parent_test");
EXPECT_TRUE(std::filesystem::exists(tmpdir));
EXPECT_TRUE(std::filesystem::is_directory(tmpdir));
// The parent must be the system temp directory.
// Normalize both sides to remove any trailing separator before comparing
// (std::filesystem::temp_directory_path() appends a trailing slash on Windows
// while path::parent_path() does not).
const std::filesystem::path expected_parent =
std::filesystem::path(std::filesystem::temp_directory_path().generic_string());
const std::filesystem::path actual_parent =
std::filesystem::path(tmpdir.parent_path().generic_string());
EXPECT_EQ(actual_parent, expected_parent);
EXPECT_TRUE(std::filesystem::remove_all(tmpdir));
}

TEST(TestFilesystemHelper, create_temporary_directory_unique_per_call)
{
// Multiple calls with the same base_name must produce different paths.
constexpr int kNumDirs = 5;
std::vector<std::filesystem::path> dirs;
dirs.reserve(kNumDirs);
for (int i = 0; i < kNumDirs; ++i) {
dirs.push_back(rcpputils::fs::create_temporary_directory("unique_test"));
}
// All paths must be distinct.
for (int i = 0; i < kNumDirs; ++i) {
for (int j = i + 1; j < kNumDirs; ++j) {
EXPECT_NE(dirs[i], dirs[j]);
}
}
for (const auto & d : dirs) {
std::filesystem::remove_all(d);
}
}
5 changes: 5 additions & 0 deletions test/test_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@
TEST(TestProcess, test_get_executable_name) {
EXPECT_EQ("test_process", rcpputils::get_executable_name());
}

TEST(TestProcess, test_get_executable_name_consistent) {
// Calling twice must return the same value.
EXPECT_EQ(rcpputils::get_executable_name(), rcpputils::get_executable_name());
}
41 changes: 41 additions & 0 deletions test/test_shared_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,47 @@ TEST(test_shared_library, failed_test) {
}
}

TEST(test_shared_library, has_symbol_string_overload) {
const std::string library_name = rcpputils::get_platform_library_name("dummy_shared_library");
auto library = std::make_shared<rcpputils::SharedLibrary>(library_name);

// Positive: string overload delegates to const char* overload.
EXPECT_TRUE(library->has_symbol(std::string("print_name")));

// Negative: missing symbol via string overload.
EXPECT_FALSE(library->has_symbol(std::string("nonexistent_symbol_xyz")));
}

TEST(test_shared_library, get_symbol_string_overload_throws_on_missing) {
const std::string library_name = rcpputils::get_platform_library_name("dummy_shared_library");
auto library = std::make_shared<rcpputils::SharedLibrary>(library_name);

EXPECT_THROW(
library->get_symbol(std::string("nonexistent_symbol_xyz")),
std::runtime_error);
}

TEST(test_shared_library, get_library_path_non_empty) {
const std::string library_name = rcpputils::get_platform_library_name("dummy_shared_library");
auto library = std::make_shared<rcpputils::SharedLibrary>(library_name);
EXPECT_FALSE(library->get_library_path().empty());
}

TEST(test_get_platform_library_name, release_name_contains_library_name) {
const std::string name = rcpputils::get_platform_library_name("mylib", false);
EXPECT_NE(name.find("mylib"), std::string::npos);
EXPECT_FALSE(name.empty());
}

TEST(test_get_platform_library_name, debug_and_release_differ_or_equal) {
// On some platforms (e.g. Windows) debug builds append a 'd' suffix.
// We only verify both calls succeed and return non-empty strings.
const std::string release_name = rcpputils::get_platform_library_name("mylib", false);
const std::string debug_name = rcpputils::get_platform_library_name("mylib", true);
EXPECT_FALSE(release_name.empty());
EXPECT_FALSE(debug_name.empty());
}

TEST(test_get_platform_library_name, failed_test) {
// create a string bigger than the internal buffer
std::string str(2000, 'A');
Expand Down
41 changes: 41 additions & 0 deletions test/test_thread_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,33 @@ TEST(TestOsThread, set_thread_name) {
EXPECT_STREQ("test_thread", rcpputils::get_thread_name().c_str());
}

TEST(TestOsThread, set_thread_name_empty) {
// Setting an empty name must not throw and get_thread_name must return empty string.
EXPECT_NO_THROW(rcpputils::set_thread_name(""));
EXPECT_STREQ("", rcpputils::get_thread_name().c_str());
}

TEST(TestOsThread, get_thread_name_returns_string) {
rcpputils::set_thread_name("abc");
const std::string name = rcpputils::get_thread_name();
EXPECT_FALSE(name.empty());
EXPECT_STREQ("abc", name.c_str());
}

#if defined(_WIN32)
TEST(TestOsThread, no_truncation_on_windows) {
rcpputils::set_thread_name("0123456789abcdef");

// Should be unaffected by truncation
EXPECT_STREQ("0123456789abcdef", rcpputils::get_thread_name().c_str());
}

TEST(TestOsThread, exact_max_length_no_truncation_windows) {
// 15 chars is well within the Windows limit; no truncation expected.
const std::string name_15(15, 'x');
rcpputils::set_thread_name(name_15);
EXPECT_EQ(rcpputils::get_thread_name(), name_15);
}
#elif defined(__APPLE__)
TEST(TestOsThread, truncation_on_apple) {
rcpputils::set_thread_name(
Expand All @@ -38,11 +58,32 @@ TEST(TestOsThread, truncation_on_apple) {
EXPECT_STREQ("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde",
rcpputils::get_thread_name().c_str());
}

TEST(TestOsThread, exact_max_length_no_truncation_apple) {
// Exactly 63 chars (MAXTHREADNAMESIZE - 1): must not be truncated.
const std::string name_63(63, 'y');
rcpputils::set_thread_name(name_63);
EXPECT_EQ(rcpputils::get_thread_name(), name_63);
}
#else // posix
TEST(TestOsThread, truncation_on_posix) {
rcpputils::set_thread_name("0123456789abcdef");

// Should be 15 characters and then the null terminator
EXPECT_STREQ("0123456789abcde", rcpputils::get_thread_name().c_str());
}

TEST(TestOsThread, exact_max_length_no_truncation_posix) {
// Exactly 15 chars (MAXTHREADNAMESIZE - 1): must not be truncated.
const std::string name_15(15, 'z');
rcpputils::set_thread_name(name_15);
EXPECT_EQ(rcpputils::get_thread_name(), name_15);
}

TEST(TestOsThread, one_less_than_max_no_truncation_posix) {
// 14 chars is under the limit; returned name must be identical.
const std::string name_14(14, 'w');
rcpputils::set_thread_name(name_14);
EXPECT_EQ(rcpputils::get_thread_name(), name_14);
}
#endif