ESPSomfy-RTS/test/test_rollingcode/test_rollingcode.cpp
cjkas 1962778912 test: cover the radio queue rules, shade TX state, rolling codes and web command hold
Move the pieces of the radio TX path that don't need FreeRTOS or NVS out of
Somfy.cpp and Web.cpp so they build in the native test env: the TX job and
event types and job encoding (TxBuffer), the queue rules (TxQueuePolicy.h),
a shade's pending radio jobs (ShadeTxState), the next rolling code
(RollingCode.h) and the web command queue types (WebCommand.h).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:26:33 +02:00

59 lines
1.9 KiB
C++

#include <unity.h>
#include "RollingCode.h"
// Stands in for NVS and counts how often it is read.
struct FakeStore {
uint16_t code = 0;
int reads = 0;
uint16_t operator()() { this->reads++; return this->code; }
};
// Passes the store by reference so the test sees the read count.
static uint16_t next(bool synced, uint16_t last, FakeStore &store) {
return nextRollingCode(synced, last, [&store]() { return store(); });
}
void setUp() {}
void tearDown() {}
static void test_unsynced_reads_the_store() {
FakeStore store;
store.code = 41;
TEST_ASSERT_EQUAL_UINT16(42, next(false, 7, store));
TEST_ASSERT_EQUAL_INT(1, store.reads);
}
static void test_synced_never_reads_the_store() {
FakeStore store;
store.code = 41;
TEST_ASSERT_EQUAL_UINT16(8, next(true, 7, store));
TEST_ASSERT_EQUAL_INT(0, store.reads);
}
static void test_reading_does_not_use_up_a_code() {
// A command the radio refuses must leave the remote on the same code.
FakeStore store;
store.code = 41;
TEST_ASSERT_EQUAL_UINT16(42, next(false, 0, store));
TEST_ASSERT_EQUAL_UINT16(42, next(false, 0, store));
TEST_ASSERT_EQUAL_UINT16(8, next(true, 7, store));
TEST_ASSERT_EQUAL_UINT16(8, next(true, 7, store));
}
static void test_wraps_to_zero_after_0xFFFF() {
// Current behaviour, kept on purpose for now: the code after 0xFFFF is 0.
// Our own decoder rejects a zero rolling code (see
// test_rejects_zero_rolling_code_except_sensor in test_frame), so a remote
// that gets this far sends one frame other receivers may ignore.
FakeStore store;
store.code = 0xFFFF;
TEST_ASSERT_EQUAL_UINT16(0, next(false, 0, store));
TEST_ASSERT_EQUAL_UINT16(0, next(true, 0xFFFF, store));
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
UNITY_BEGIN();
RUN_TEST(test_unsynced_reads_the_store);
RUN_TEST(test_synced_never_reads_the_store);
RUN_TEST(test_reading_does_not_use_up_a_code);
RUN_TEST(test_wraps_to_zero_after_0xFFFF);
return UNITY_END();
}