Skip to content
Merged
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
19 changes: 10 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ CPMAddPackage(
"gtest_force_shared_crt ON"
)

file(
GLOB_RECURSE LIB_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
)
# Library sources: src/*.cpp only, exclude *.test.cpp and test_helpers/
file(GLOB_RECURSE LIB_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
list(FILTER LIB_SOURCES EXCLUDE REGEX ".*\\.test\\.cpp$")
list(FILTER LIB_SOURCES EXCLUDE REGEX ".*/test_helpers/.*")

add_library(cpp_bindings_linux SHARED ${LIB_SOURCES})

Expand Down Expand Up @@ -88,11 +88,11 @@ target_link_libraries(

target_compile_features(cpp_bindings_linux PUBLIC cxx_std_23)

# Collect all test source files
file(
GLOB_RECURSE TEST_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp"
)
# Test sources: src/*.test.cpp, tests/*.test.cpp, src/test_helpers/*.cpp (helpers excluded from lib)
file(GLOB SRC_UNIT_TESTS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.test.cpp")
file(GLOB TESTS_INTEGRATION "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.test.cpp")
file(GLOB TEST_HELPER_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/test_helpers/*.cpp")
set(TEST_SOURCES ${SRC_UNIT_TESTS} ${TESTS_INTEGRATION} ${TEST_HELPER_SOURCES})

if(TEST_SOURCES)
add_executable(cpp_bindings_linux_tests ${TEST_SOURCES})
Expand All @@ -101,6 +101,7 @@ if(TEST_SOURCES)
cpp_bindings_linux_tests
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/generated
)

Expand Down
81 changes: 81 additions & 0 deletions src/serial_close.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <cpp_core/interface/serial_close.h>
#include <cpp_core/status_codes.h>

#include <limits>

#include <gtest/gtest.h>

#include "test_helpers/error_capture.hpp"

class SerialCloseTest : public ::testing::Test
{
protected:
void SetUp() override
{
ErrorCapture::instance = &error_capture;
error_callback = &ErrorCapture::callback;
}

void TearDown() override
{
ErrorCapture::instance = nullptr;
}

ErrorCapture error_capture;
ErrorCallbackT error_callback = nullptr;
};

TEST_F(SerialCloseTest, CloseInvalidHandleZero)
{
int result = serialClose(0, error_callback);

EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kSuccess));
}

TEST_F(SerialCloseTest, CloseInvalidHandleNegative)
{
int result = serialClose(-1, error_callback);

EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kSuccess));
}

TEST_F(SerialCloseTest, CloseInvalidHandleNegativeLarge)
{
int result = serialClose(-12345, error_callback);

EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kSuccess));
}

TEST_F(SerialCloseTest, CloseInvalidHandleTooLarge)
{
auto too_large_handle = static_cast<int64_t>(std::numeric_limits<int>::max()) + 1;
int result = serialClose(too_large_handle, error_callback);

EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kInvalidHandleError));
}

TEST_F(SerialCloseTest, CloseInvalidHandleIntMaxBoundary)
{
auto handle = static_cast<int64_t>(std::numeric_limits<int>::max());
int result = serialClose(handle, error_callback);

// Should fail because this fd doesn't exist, but not with InvalidHandleError
EXPECT_NE(result, static_cast<int>(cpp_core::StatusCodes::kInvalidHandleError));
}

TEST_F(SerialCloseTest, CloseNoErrorCallback)
{
int result = serialClose(0, nullptr);

EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kSuccess));
}

TEST_F(SerialCloseTest, CloseInvalidHandle)
{
// Test closing a real invalid fd (one that never existed)
// We should get an error but not crash
int result = serialClose(9999, error_callback);

// This will fail because the fd doesn't exist
EXPECT_EQ(result, static_cast<int>(cpp_core::StatusCodes::kCloseHandleError));
}
209 changes: 209 additions & 0 deletions src/serial_open.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#include <cpp_core/interface/serial_open.h>
#include <cpp_core/status_codes.h>

#include <array>
#include <string>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "test_helpers/error_capture.hpp"

class SerialOpenTest : public ::testing::Test
{
protected:
void SetUp() override
{
ErrorCapture::instance = &error_capture;
error_callback = &ErrorCapture::callback;
}

void TearDown() override
{
ErrorCapture::instance = nullptr;
}

ErrorCapture error_capture;
ErrorCallbackT error_callback = nullptr;
};

TEST_F(SerialOpenTest, NullPortParameter)
{
intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kNotFoundError));
EXPECT_NE(error_capture.last_message.find("nullptr"), std::string::npos);
}

TEST_F(SerialOpenTest, BaudrateTooLow)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 100, 8, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
EXPECT_NE(error_capture.last_message.find("baudrate"), std::string::npos);
}

TEST_F(SerialOpenTest, BaudrateTooLowBoundary)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 299, 8, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, BaudrateBoundaryValid)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 300, 8, 0, 1, error_callback);

// /dev/null is not a real serial port, but should pass baudrate validation
EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, DataBitsTooLow)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 4, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
EXPECT_NE(error_capture.last_message.find("data bits"), std::string::npos);
}

TEST_F(SerialOpenTest, DataBitsTooHigh)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 9, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidDataBits5)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 5, 0, 1, error_callback);

// Should pass data bits validation
EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidDataBits6)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 6, 0, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidDataBits7)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 7, 0, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidDataBits8)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, InvalidParity)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 5, 1, error_callback);

// Invalid parity should return an error
EXPECT_LT(result, 0);
}

TEST_F(SerialOpenTest, ValidParityNone)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidParityEven)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 1, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidParityOdd)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 2, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, InvalidStopBits)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 3, error_callback);

// Invalid stop bits should return an error
EXPECT_LT(result, 0);
}

TEST_F(SerialOpenTest, ValidStopBits0)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 0, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidStopBits1)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 1, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, ValidStopBits2)
{
const char *port = "/dev/null";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 2, error_callback);

EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError));
}

TEST_F(SerialOpenTest, NonExistentPort)
{
const char *port = "/dev/ttyNONEXISTENT99999";
intptr_t result = serialOpen(const_cast<void *>(static_cast<const void *>(port)), 9600, 8, 0, 1, error_callback);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kNotFoundError));
}

TEST_F(SerialOpenTest, VariousBaudrates)
{
const char *port = "/dev/null";

// Test common baudrates
const std::array<int, 11> baudrates = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800};

for (int baudrate : baudrates)
{
intptr_t result =
serialOpen(const_cast<void *>(static_cast<const void *>(port)), baudrate, 8, 0, 1, error_callback);
EXPECT_NE(result, static_cast<intptr_t>(cpp_core::StatusCodes::kSetStateError))
<< "Baudrate " << baudrate << " should be valid";
}
}

TEST_F(SerialOpenTest, NoErrorCallbackNullPort)
{
intptr_t result = serialOpen(nullptr, 9600, 8, 0, 1, nullptr);

EXPECT_EQ(result, static_cast<intptr_t>(cpp_core::StatusCodes::kNotFoundError));
}
Loading