Files
stickshid/tests/test_stk.c
T
portersky 8276b7bad5 fix: map throttle to axis 3 (AETR layout)
Verified via hid_discover caps and live data dump. Throttle
responds on axis 3 (HID usage 0x33 = Rx), not axis 5 or 6.
2026-06-14 19:26:37 +02:00

157 lines
5.1 KiB
C

#include "unity.h"
#include "stk/stk.h"
void setUp(void) {}
void tearDown(void) {}
// ---------------------------------------------------------------------------
// stk_config_t
// ---------------------------------------------------------------------------
void test_config_has_correct_fields(void) {
stk_config_t cfg = {
.vendor_id = STK_DEFAULT_VID,
.product_id = STK_DEFAULT_PID,
};
TEST_ASSERT_EQUAL_UINT16(STK_DEFAULT_VID, cfg.vendor_id);
TEST_ASSERT_EQUAL_UINT16(STK_DEFAULT_PID, cfg.product_id);
}
void test_config_defaults_match_vid_pid(void) {
TEST_ASSERT_EQUAL_UINT16(0x1209, STK_DEFAULT_VID);
TEST_ASSERT_EQUAL_UINT16(0x4F54, STK_DEFAULT_PID);
}
// ---------------------------------------------------------------------------
// stk_state_t
// ---------------------------------------------------------------------------
void test_state_defaults_to_zero(void) {
stk_state_t state = { 0 };
for (int i = 0; i < STK_NUM_AXES; i++)
TEST_ASSERT_EQUAL_INT16(0, state.axes[i]);
TEST_ASSERT_EQUAL_UINT32(0, state.buttons);
}
void test_state_has_expected_size(void) {
// 8 axes * 2 bytes + 4 bytes buttons = 20 bytes
TEST_ASSERT_EQUAL_INT(20, (int)sizeof(stk_state_t));
}
// ---------------------------------------------------------------------------
// Axis range constants
// ---------------------------------------------------------------------------
void test_axis_range_is_valid(void) {
TEST_ASSERT_TRUE(STK_AXIS_MIN < STK_AXIS_MID);
TEST_ASSERT_TRUE(STK_AXIS_MID < STK_AXIS_MAX);
}
void test_axis_mid_is_center(void) {
TEST_ASSERT_EQUAL_INT(
(STK_AXIS_MIN + STK_AXIS_MAX + 1) / 2,
STK_AXIS_MID);
}
void test_axis_range_values(void) {
TEST_ASSERT_EQUAL_INT(0, STK_AXIS_MIN);
TEST_ASSERT_EQUAL_INT(2047, STK_AXIS_MAX);
TEST_ASSERT_EQUAL_INT(1024, STK_AXIS_MID);
}
void test_axis_count(void) {
TEST_ASSERT_EQUAL_INT(8, STK_NUM_AXES);
}
void test_button_count(void) {
TEST_ASSERT_EQUAL_INT(24, STK_NUM_BUTTONS);
}
// ---------------------------------------------------------------------------
// Named axis accessors
// ---------------------------------------------------------------------------
void test_named_accessors_map_correct_indices(void) {
stk_state_t state = { 0 };
state.axes[1] = 111;
state.axes[2] = 222;
state.axes[3] = 333;
state.axes[4] = 444;
TEST_ASSERT_EQUAL_INT16(111, stk_right_x(&state));
TEST_ASSERT_EQUAL_INT16(222, stk_right_y(&state));
TEST_ASSERT_EQUAL_INT16(333, stk_throttle(&state));
TEST_ASSERT_EQUAL_INT16(444, stk_left_x(&state));
}
// ---------------------------------------------------------------------------
// Button helper
// ---------------------------------------------------------------------------
void test_button_pressed_returns_false_for_unset_bits(void) {
stk_state_t state = { .buttons = 0 };
for (int i = 0; i < STK_NUM_BUTTONS; i++)
TEST_ASSERT_FALSE(stk_button_pressed(&state, (uint8_t)i));
}
void test_button_pressed_returns_true_for_set_bits(void) {
stk_state_t state = { .buttons = (1u << 3) | (1u << 17) };
TEST_ASSERT_TRUE(stk_button_pressed(&state, 3));
TEST_ASSERT_TRUE(stk_button_pressed(&state, 17));
TEST_ASSERT_FALSE(stk_button_pressed(&state, 0));
TEST_ASSERT_FALSE(stk_button_pressed(&state, 23));
}
void test_button_pressed_out_of_range_returns_false(void) {
stk_state_t state = { .buttons = 0xFFFFFFFFu };
TEST_ASSERT_FALSE(stk_button_pressed(&state, 24));
TEST_ASSERT_FALSE(stk_button_pressed(&state, 31));
}
// ---------------------------------------------------------------------------
// API error handling
// ---------------------------------------------------------------------------
void test_open_with_null_config_fails(void) {
TEST_ASSERT_NOT_EQUAL_INT(0, stk_open(NULL));
}
void test_read_with_null_state_fails(void) {
TEST_ASSERT_NOT_EQUAL_INT(0, stk_read(NULL));
}
void test_read_without_open_fails(void) {
stk_state_t state = { 0 };
TEST_ASSERT_NOT_EQUAL_INT(0, stk_read(&state));
}
void test_close_is_safe_without_open(void) {
stk_close(); // should not crash
}
// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_config_has_correct_fields);
RUN_TEST(test_config_defaults_match_vid_pid);
RUN_TEST(test_state_defaults_to_zero);
RUN_TEST(test_state_has_expected_size);
RUN_TEST(test_axis_range_is_valid);
RUN_TEST(test_axis_mid_is_center);
RUN_TEST(test_axis_range_values);
RUN_TEST(test_axis_count);
RUN_TEST(test_button_count);
RUN_TEST(test_named_accessors_map_correct_indices);
RUN_TEST(test_button_pressed_returns_false_for_unset_bits);
RUN_TEST(test_button_pressed_returns_true_for_set_bits);
RUN_TEST(test_button_pressed_out_of_range_returns_false);
RUN_TEST(test_open_with_null_config_fails);
RUN_TEST(test_read_with_null_state_fails);
RUN_TEST(test_read_without_open_fails);
RUN_TEST(test_close_is_safe_without_open);
return UNITY_END();
}