Files
XYParser/XYParser/XYParserTests/Tests.cpp

146 lines
4.2 KiB
C++
Raw Normal View History

2026-06-06 14:13:35 +08:00
#include <gtest/gtest.h>
#include "../XYParserApi.h"
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace {
class ParserGuard {
public:
explicit ParserGuard(XYParserHandle handle) : handle_(handle) {}
~ParserGuard()
{
if (handle_ != nullptr) {
XYParser_DestroyParser(handle_);
}
}
XYParserHandle get() const
{
return handle_;
}
private:
XYParserHandle handle_;
};
std::vector<std::uint8_t> BuildMinimalFrame(std::uint8_t channel_count)
{
constexpr std::size_t kSamplesPerFrame = 5;
constexpr std::uint8_t kHeader = 0xAA;
constexpr std::uint8_t kTail = 0x55;
constexpr std::size_t kTagLen = 25;
const std::size_t sample_bytes = static_cast<std::size_t>(channel_count) * 3 + 2;
const std::uint16_t payload_length = static_cast<std::uint16_t>(sample_bytes * kSamplesPerFrame);
const std::size_t frame_size = 1 + kTagLen + payload_length + 2;
std::vector<std::uint8_t> frame(frame_size, 0);
std::size_t offset = 0;
frame[offset++] = kHeader;
frame[offset++] = 0x01;
frame[offset++] = 0x00;
frame[offset++] = 0x00;
frame[offset++] = 0x00;
frame[offset++] = static_cast<std::uint8_t>((payload_length >> 8) & 0xFF);
frame[offset++] = static_cast<std::uint8_t>(payload_length & 0xFF);
frame[offset++] = 95;
frame[offset++] = channel_count;
offset += 2 + 2 + 2 + 2 + 2 + 6;
for (std::size_t sample = 0; sample < kSamplesPerFrame; ++sample) {
for (std::size_t channel = 0; channel < channel_count; ++channel) {
frame[offset++] = 0x00;
frame[offset++] = 0x00;
frame[offset++] = static_cast<std::uint8_t>(sample + channel + 1);
}
frame[offset++] = 0x00;
frame[offset++] = 0x00;
}
frame[offset++] = 0x00;
frame[offset++] = kTail;
frame[offset++] = kTail;
return frame;
}
} // namespace
TEST(XYParserApiTests, CreateParserRejectsUnsupportedChannelCount)
{
EXPECT_EQ(XYParser_CreateParser(7), nullptr);
}
TEST(XYParserApiTests, GetLastErrorReturnsMessageForNullParser)
{
EXPECT_EQ(std::string(XYParser_GetLastError(nullptr)), std::string("invalid parser handle"));
}
TEST(XYParserApiTests, FeedParsesAComplete8ChannelFrame)
{
ParserGuard parser(XYParser_CreateParser(8));
ASSERT_NE(parser.get(), nullptr);
XYParser_SetAdcParams(parser.get(), 4.5, 6.0);
XYParser_SetBypassChecksum(parser.get(), 1);
const std::vector<std::uint8_t> bytes = BuildMinimalFrame(8);
std::array<XYParserFrameSummary, 1> summaries{};
const int frame_count = XYParser_Feed(
parser.get(),
bytes.data(),
bytes.size(),
summaries.data(),
static_cast<int>(summaries.size()));
ASSERT_EQ(frame_count, 1);
EXPECT_EQ(summaries[0].frame_index, static_cast<std::uint32_t>(1));
EXPECT_EQ(summaries[0].channel_count, static_cast<std::uint8_t>(8));
EXPECT_EQ(summaries[0].battery, static_cast<std::uint8_t>(95));
EXPECT_EQ(summaries[0].sample_count, static_cast<std::uint8_t>(5));
EXPECT_GT(summaries[0].channel_values_uv[0][0], 0.0);
EXPECT_EQ(summaries[0].trigger_types[0], static_cast<std::uint8_t>(0));
EXPECT_EQ(summaries[0].trigger_indices[0], static_cast<std::uint8_t>(0));
}
TEST(XYParserApiTests, FeedBuffersPartialDataUntilAFullFrameIsAvailable)
{
ParserGuard parser(XYParser_CreateParser(8));
ASSERT_NE(parser.get(), nullptr);
XYParser_SetBypassChecksum(parser.get(), 1);
const std::vector<std::uint8_t> bytes = BuildMinimalFrame(8);
const std::size_t split_index = bytes.size() / 2;
std::array<XYParserFrameSummary, 1> summaries{};
const int first_result = XYParser_Feed(
parser.get(),
bytes.data(),
split_index,
summaries.data(),
static_cast<int>(summaries.size()));
EXPECT_EQ(first_result, 0);
const int second_result = XYParser_Feed(
parser.get(),
bytes.data() + split_index,
bytes.size() - split_index,
summaries.data(),
static_cast<int>(summaries.size()));
ASSERT_EQ(second_result, 1);
EXPECT_EQ(summaries[0].frame_index, static_cast<std::uint32_t>(1));
}