11// Copyright 2020-2025 Nestor Neto
22
33#include < gtest/gtest.h>
4+ #include < cstdlib>
5+ #include < cstring>
6+ #include < dirent.h>
7+ #include < unistd.h>
48#include < memory>
59#include < string>
610
7- // Include libserial headers
811#include " libserial/ports.hpp"
912#include " libserial/serial_exception.hpp"
1013
1114// Simple unit tests that don't require actual hardware
1215class PortsTest : public ::testing::Test {
1316protected:
1417void SetUp () override {
15- // Test setup if needed
18+ char temp_template[] = " /tmp/fake_serial_XXXXXX" ;
19+ ASSERT_NE (mkdtemp (temp_template), nullptr ) << " Failed to create temp directory" ;
20+ temp_dir_ = temp_template;
1621}
1722
1823void TearDown () override {
19- // Test cleanup if needed
24+ // Clean up all symlinks in temp_dir_
25+ DIR* dir = opendir (temp_dir_.c_str ());
26+ if (dir) {
27+ struct dirent * entry;
28+ while ((entry = readdir (dir)) != nullptr ) {
29+ if (entry->d_name [0 ] != ' .' ) {
30+ std::string path = temp_dir_ + " /" + entry->d_name ;
31+ unlink (path.c_str ());
32+ }
33+ }
34+ closedir (dir);
35+ }
36+ rmdir (temp_dir_.c_str ());
2037}
38+
39+ std::string temp_dir_;
2140};
2241
2342TEST_F (PortsTest, DefaultConstructor) {
@@ -32,17 +51,47 @@ TEST_F(PortsTest, ScanPortsThrowsWhenPathMissing) {
3251 libserial::Ports ports (missing_path);
3352
3453
35- try {
54+ try {
3655 (void )ports.scanPorts ();
56+ FAIL () << " Expected libserial::SerialException to be thrown" ;
3757 } catch (const libserial::SerialException& e) {
3858 std::cout << " Caught SerialException: " << e.what () << std::endl;
3959 // Optionally assert something about the message:
40- // EXPECT_NE(std::string(e.what()).find("Error while reading"), std::string::npos);
60+ EXPECT_NE (std::string (e.what ()).find (" Error while reading" ), std::string::npos);
61+ } catch (...) {
62+ FAIL () << " Expected libserial::SerialException, but got a different exception" ;
4163 }
64+ }
4265
43- EXPECT_THROW ({
44- (void )ports.scanPorts ();
45- }, libserial::PortNotFoundException);
66+ TEST_F (PortsTest, ScanPortsWithFakeDevices) {
67+
68+ // Create fake device symlinks
69+ std::string fake_device1 = std::string (temp_dir_) + " /usb-FTDI_FT232R_USB_UART_A1B2C3D4" ;
70+ std::string fake_device2 = std::string (temp_dir_) + " /usb-Arduino_Uno_12345678" ;
71+
72+ // Create symlinks pointing to fake /dev/ttyUSB* paths
73+ // The actual target doesn't need to exist for scanPorts to process it
74+ ASSERT_EQ (symlink (" ../../ttyUSB0" , fake_device1.c_str ()), 0 );
75+ ASSERT_EQ (symlink (" ../../ttyUSB1" , fake_device2.c_str ()), 0 );
76+
77+ // Test scanPorts with the fake directory
78+ libserial::Ports ports (temp_dir_.c_str ());
79+ uint16_t count = 0 ;
80+ EXPECT_NO_THROW ({
81+ count = ports.scanPorts ();
82+ });
83+
84+ EXPECT_EQ (count, 2 ) << " Should find 2 fake devices" ;
85+
86+ // Verify device details
87+ std::vector<libserial::Device> devices;
88+ ports.getDevices (devices);
89+ ASSERT_EQ (devices.size (), 2 );
90+
91+ EXPECT_EQ (devices[1 ].getName (), " usb-FTDI_FT232R_USB_UART_A1B2C3D4" );
92+ EXPECT_EQ (devices[1 ].getPortPath (), " /dev/ttyUSB0" );
93+ EXPECT_EQ (devices[0 ].getName (), " usb-Arduino_Uno_12345678" );
94+ EXPECT_EQ (devices[0 ].getPortPath (), " /dev/ttyUSB1" );
4695}
4796
4897
0 commit comments