mirror of
https://github.com/esphome/esphome.git
synced 2025-10-30 06:33:51 +00:00
C++ components unit test framework (#9284)
Co-authored-by: J. Nick Koston <nick@home-assistant.io> Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
37
tests/components/uart/common.h
Normal file
37
tests/components/uart/common.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "esphome/components/uart/uart_component.h"
|
||||
|
||||
namespace esphome::uart::testing {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::SaveArg;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::SetArgPointee;
|
||||
|
||||
// Derive a mock from UARTComponent to test the wrapper implementations.
|
||||
class MockUARTComponent : public UARTComponent {
|
||||
public:
|
||||
using UARTComponent::write_array;
|
||||
using UARTComponent::write_byte;
|
||||
|
||||
// NOTE: std::vector is used here for test convenience. For production code,
|
||||
// consider using StaticVector or FixedVector from esphome/core/helpers.h instead.
|
||||
std::vector<uint8_t> written_data;
|
||||
|
||||
void write_array(const uint8_t *data, size_t len) override { written_data.assign(data, data + len); }
|
||||
|
||||
MOCK_METHOD(bool, read_array, (uint8_t * data, size_t len), (override));
|
||||
MOCK_METHOD(bool, peek_byte, (uint8_t * data), (override));
|
||||
MOCK_METHOD(int, available, (), (override));
|
||||
MOCK_METHOD(void, flush, (), (override));
|
||||
MOCK_METHOD(void, check_logger_conflict, (), (override));
|
||||
};
|
||||
|
||||
} // namespace esphome::uart::testing
|
||||
73
tests/components/uart/uart_component.cpp
Normal file
73
tests/components/uart/uart_component.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "common.h"
|
||||
|
||||
namespace esphome::uart::testing {
|
||||
|
||||
TEST(UARTComponentTest, SetGetBaudRate) {
|
||||
MockUARTComponent mock;
|
||||
mock.set_baud_rate(38400);
|
||||
EXPECT_EQ(mock.get_baud_rate(), 38400);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, SetGetStopBits) {
|
||||
MockUARTComponent mock;
|
||||
mock.set_stop_bits(2);
|
||||
EXPECT_EQ(mock.get_stop_bits(), 2);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, SetGetDataBits) {
|
||||
MockUARTComponent mock;
|
||||
mock.set_data_bits(7);
|
||||
EXPECT_EQ(mock.get_data_bits(), 7);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, SetGetParity) {
|
||||
MockUARTComponent mock;
|
||||
mock.set_parity(UARTParityOptions::UART_CONFIG_PARITY_EVEN);
|
||||
EXPECT_EQ(mock.get_parity(), UARTParityOptions::UART_CONFIG_PARITY_EVEN);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, SetGetRxBufferSize) {
|
||||
MockUARTComponent mock;
|
||||
mock.set_rx_buffer_size(128);
|
||||
EXPECT_EQ(mock.get_rx_buffer_size(), 128);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, WriteArrayVector) {
|
||||
MockUARTComponent mock;
|
||||
std::vector<uint8_t> data = {10, 20, 30};
|
||||
mock.write_array(data);
|
||||
EXPECT_EQ(mock.written_data, data);
|
||||
}
|
||||
TEST(UARTComponentTest, WriteByte) {
|
||||
MockUARTComponent mock;
|
||||
uint8_t byte = 0x79;
|
||||
mock.write_byte(byte);
|
||||
EXPECT_EQ(mock.written_data.size(), 1);
|
||||
EXPECT_EQ(mock.written_data[0], byte);
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, WriteStr) {
|
||||
MockUARTComponent mock;
|
||||
const char *str = "Hello";
|
||||
std::vector<uint8_t> captured;
|
||||
mock.write_str(str);
|
||||
EXPECT_EQ(mock.written_data.size(), strlen(str));
|
||||
EXPECT_EQ(0, strncmp(str, (const char *) mock.written_data.data(), mock.written_data.size()));
|
||||
}
|
||||
|
||||
// Tests for wrapper methods forwarding to pure virtual read_array
|
||||
TEST(UARTComponentTest, ReadByteSuccess) {
|
||||
MockUARTComponent mock;
|
||||
uint8_t value = 0;
|
||||
EXPECT_CALL(mock, read_array(&value, 1)).WillOnce(Return(true));
|
||||
EXPECT_TRUE(mock.read_byte(&value));
|
||||
}
|
||||
|
||||
TEST(UARTComponentTest, ReadByteFailure) {
|
||||
MockUARTComponent mock;
|
||||
uint8_t value = 0xFF;
|
||||
EXPECT_CALL(mock, read_array(&value, 1)).WillOnce(Return(false));
|
||||
EXPECT_FALSE(mock.read_byte(&value));
|
||||
}
|
||||
|
||||
} // namespace esphome::uart::testing
|
||||
108
tests/components/uart/uart_device.cpp
Normal file
108
tests/components/uart/uart_device.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "common.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
namespace esphome::uart::testing {
|
||||
|
||||
TEST(UARTDeviceTest, ReadByteSuccess) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
uint8_t value = 0;
|
||||
EXPECT_CALL(mock, read_array(_, 1)).WillOnce(DoAll(SetArgPointee<0>(0x5A), Return(true)));
|
||||
bool result = dev.read_byte(&value);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(value, 0x5A);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, ReadByteFailure) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
uint8_t value = 0xFF;
|
||||
EXPECT_CALL(mock, read_array(_, 1)).WillOnce(Return(false));
|
||||
bool result = dev.read_byte(&value);
|
||||
EXPECT_FALSE(result);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, PeekByteSuccess) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
uint8_t value = 0;
|
||||
EXPECT_CALL(mock, peek_byte(_)).WillOnce(DoAll(SetArgPointee<0>(0xA5), Return(true)));
|
||||
bool result = dev.peek_byte(&value);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(value, 0xA5);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, PeekByteFailure) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
uint8_t value = 0;
|
||||
EXPECT_CALL(mock, peek_byte(_)).WillOnce(Return(false));
|
||||
bool result = dev.peek_byte(&value);
|
||||
EXPECT_FALSE(result);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, Available) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
EXPECT_CALL(mock, available()).WillOnce(Return(5));
|
||||
EXPECT_EQ(dev.available(), 5);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, FlushCallsParent) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
EXPECT_CALL(mock, flush()).Times(1);
|
||||
dev.flush();
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, WriteByteForwardsToWriteArray) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
dev.write_byte(0xAB);
|
||||
EXPECT_EQ(mock.written_data.size(), 1);
|
||||
EXPECT_EQ(mock.written_data[0], 0xAB);
|
||||
}
|
||||
TEST(UARTDeviceTest, WriteArrayPointer) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
uint8_t data[3] = {1, 2, 3};
|
||||
dev.write_array(data, 3);
|
||||
EXPECT_EQ(mock.written_data.size(), 3);
|
||||
EXPECT_EQ(mock.written_data, std::vector(data, data + 3));
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, WriteArrayVector) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
std::vector<uint8_t> data = {4, 5, 6};
|
||||
dev.write_array(data);
|
||||
EXPECT_EQ(mock.written_data, data);
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, WriteArrayStdArray) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
std::array<uint8_t, 4> data = {7, 8, 9, 10};
|
||||
dev.write_array(data);
|
||||
EXPECT_EQ(mock.written_data.size(), data.size());
|
||||
EXPECT_EQ(mock.written_data, std::vector(data.begin(), data.end()));
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, WriteStrForwardsToWriteArray) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
const char *str = "ESPHome";
|
||||
dev.write_str(str);
|
||||
EXPECT_EQ(mock.written_data.size(), strlen(str));
|
||||
EXPECT_EQ(0, strncmp(str, (const char *) mock.written_data.data(), mock.written_data.size()));
|
||||
}
|
||||
|
||||
TEST(UARTDeviceTest, WriteStrEmptyString) {
|
||||
MockUARTComponent mock;
|
||||
UARTDevice dev(&mock);
|
||||
const char *str = "";
|
||||
dev.write_str(str);
|
||||
EXPECT_EQ(mock.written_data.size(), 0);
|
||||
}
|
||||
|
||||
} // namespace esphome::uart::testing
|
||||
Reference in New Issue
Block a user