Files
IR-protocol/tests/test_rx_reason_contract.cpp

80 lines
2.6 KiB
C++

#include "IR_config.h"
#include "RingBuffer.h"
#include <cassert>
#include <cstdint>
#include <iostream>
#include <type_traits>
// Test-only visibility: exercise the private reason enum and logging bound without
// widening the production API. Dependencies are included first so this macro
// cannot rewrite access specifiers in the standard library.
#define private public
#include "IR_DecoderRaw.h"
#undef private
namespace {
constexpr const char kZeroStats[] =
"RXSTAT,MUTEB=0,MUTEE=0,QRAW=0,QFLT=0,HOLD=0,GLITCH=0,TIME=0,"
"PREAMB=0,SYNC=0,BUF=0,TIMEOUT=0,CRC=0,OK=0\n";
constexpr const char kOneEachStats[] =
"RXSTAT,MUTEB=1,MUTEE=1,QRAW=1,QFLT=1,HOLD=1,GLITCH=1,TIME=1,"
"PREAMB=1,SYNC=1,BUF=1,TIMEOUT=1,CRC=1,OK=1\n";
static_assert(IR_DecoderRaw::rxReasonCounterCount() > 0U,
"RX reason counter storage must not be empty");
static_assert(IR_DecoderRaw::rxReasonCounterCount() ==
static_cast<uint8_t>(IR_DecoderRaw::RxBriefReason::Count),
"public RX reason count must follow the enum sentinel");
static_assert(static_cast<uint8_t>(IR_DecoderRaw::RxBriefReason::Count) ==
static_cast<uint8_t>(IR_DecoderRaw::RxBriefReason::Ok) + 1U,
"RX reason Count must remain one past the final reason");
static_assert(std::extent<decltype(IR_DecoderRaw::rxReasonCnt)>::value ==
IR_DecoderRaw::rxReasonCounterCount(),
"RX reason counter array must follow the enum-derived count");
void testStatsWireFormatAndClearCoverage()
{
IR_DecoderRaw decoder(0U, 0U);
Print out;
decoder.printRxReasonStats(out);
assert(out.str() == kZeroStats);
const uint8_t first = static_cast<uint8_t>(IR_DecoderRaw::RxBriefReason::MuteBegin);
const uint8_t count = IR_DecoderRaw::rxReasonCounterCount();
for (uint8_t i = first; i < count; ++i)
decoder.rxBriefLog(static_cast<IR_DecoderRaw::RxBriefReason>(i));
// The sentinel is a bound, not a loggable reason.
decoder.rxBriefLog(IR_DecoderRaw::RxBriefReason::Count);
const uint16_t *const counters = decoder.rxReasonCounters();
assert(counters[0] == 0U);
for (uint8_t i = first; i < count; ++i)
assert(counters[i] == 1U);
out.clear();
decoder.printRxReasonStats(out);
assert(out.str() == kOneEachStats);
decoder.rxReasonCountersClear();
for (uint8_t i = 0U; i < count; ++i)
assert(counters[i] == 0U);
out.clear();
decoder.printRxReasonStats(out);
assert(out.str() == kZeroStats);
}
} // namespace
int main()
{
testStatsWireFormatAndClearCoverage();
std::cout << "RX reason counter/tag contract tests: OK\n";
return 0;
}