|
@@ -0,0 +1,417 @@ |
|
|
|
|
|
#include "../../../__mocks__/SDL_keyboard.mock.h" |
|
|
|
|
|
#include "../../../__mocks__/SDL_joystick.mock.h" |
|
|
|
|
|
#include "../../../__mocks__/minIni.mock.h" |
|
|
|
|
|
#include "../__mocks__/IZ_config.mock.h" |
|
|
|
|
|
#include "IZ_keyboard.h" |
|
|
|
|
|
#include "IZ_joystick.h" |
|
|
|
|
|
|
|
|
|
|
|
short int GenerateAxisValueWithinThreshold(short int threshold) { |
|
|
|
|
|
return rand() % threshold; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
short int GenerateAxisValueOutsideThreshold(short int threshold) { |
|
|
|
|
|
return threshold + (rand() % (RAND_MAX - threshold - 1)) + 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
spec("input") { |
|
|
|
|
|
describe("joystick") { |
|
|
|
|
|
describe("HandleJoystickEvents") { |
|
|
|
|
|
static SDL_Event e; |
|
|
|
|
|
static IZ_JoystickState state; |
|
|
|
|
|
static IZ_Action action; |
|
|
|
|
|
|
|
|
|
|
|
describe("on axis motion events") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.type = SDL_JOYAXISMOTION; |
|
|
|
|
|
state.config.axis_threshold = 8000; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on primary horizontal direction") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.jaxis.axis = IZ_JOYAXIS_DIRECTION_HORIZONTAL1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles positive motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_RIGHT), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles negative motion") { |
|
|
|
|
|
e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_LEFT), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles neutral motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == 0, |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on secondary horizontal direction") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.jaxis.axis = IZ_JOYAXIS_DIRECTION_HORIZONTAL2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles positive motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_RIGHT), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles negative motion") { |
|
|
|
|
|
e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_LEFT), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles neutral motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);; |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == 0, |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on primary vertical direction") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.jaxis.axis = IZ_JOYAXIS_DIRECTION_VERTICAL1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles positive motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_DOWN), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles negative motion") { |
|
|
|
|
|
e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_UP), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles neutral motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);; |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == 0, |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on secondary vertical direction") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.jaxis.axis = IZ_JOYAXIS_DIRECTION_VERTICAL2; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles positive motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_DOWN), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles negative motion") { |
|
|
|
|
|
e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << IZ_ACTION_INDEX_UP), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles neutral motion") { |
|
|
|
|
|
e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);; |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
printf("(axis value: %d) ", e.jaxis.value); |
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == 0, |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on hat motion events") { |
|
|
|
|
|
before_each() { |
|
|
|
|
|
e.type = SDL_JOYHATMOTION; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 4; i += 1) { |
|
|
|
|
|
it("handles motion for %s action", ACTION_NAMES[i]) { |
|
|
|
|
|
e.jhat.value = (0x1u << i); |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1u << i), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles motion for %s deactivation", ACTION_NAMES[i]) { |
|
|
|
|
|
e.jhat.value = 0; |
|
|
|
|
|
action = ~0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
!(action & (0x1 << i)), |
|
|
|
|
|
"Action not unset." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("on button events") { |
|
|
|
|
|
for (uint8_t i = 4; i < CONTROLS; i += 1) { |
|
|
|
|
|
it("handles %s action activation", ACTION_NAMES[i]) { |
|
|
|
|
|
e.type = SDL_JOYBUTTONDOWN; |
|
|
|
|
|
e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; |
|
|
|
|
|
state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1u << i), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles %s action deactivation", ACTION_NAMES[i]) { |
|
|
|
|
|
e.type = SDL_JOYBUTTONUP; |
|
|
|
|
|
e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; |
|
|
|
|
|
state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; |
|
|
|
|
|
action = ~0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleJoystickEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
!(action & (0x1 << i)), |
|
|
|
|
|
"Action not unset." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("LoadJoystickConfig") { |
|
|
|
|
|
static IZ_JoystickConfig config; |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(IZ_GetConfigPath); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(ini_getl); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("calls load method") { |
|
|
|
|
|
mock_set_expected_calls(ini_getl, CONTROLS - 4 + 1); |
|
|
|
|
|
|
|
|
|
|
|
IZ_LoadJoystickConfig(&config, 0); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_is_called(IZ_GetConfigPath), |
|
|
|
|
|
"SDL_GetBasePath() not called." |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_get_expected_calls(ini_getl) == mock_get_actual_calls(ini_getl), |
|
|
|
|
|
"Call count mismatch for ini_getl() (expected %u, received %u).", |
|
|
|
|
|
mock_get_expected_calls(ini_getl), |
|
|
|
|
|
mock_get_actual_calls(ini_getl) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("SaveJoystickConfig") { |
|
|
|
|
|
static IZ_JoystickConfig config; |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(IZ_GetConfigPath); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(ini_putl); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
before_each() { |
|
|
|
|
|
for (uint8_t i = 0; i < CONTROLS; i += 1) { |
|
|
|
|
|
config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("calls save method") { |
|
|
|
|
|
mock_set_expected_calls(ini_putl, CONTROLS - 4 + 1); |
|
|
|
|
|
|
|
|
|
|
|
IZ_SaveJoystickConfig(&config, 0); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl), |
|
|
|
|
|
"Call count mismatch for ini_putl() (expected %u, received %u).", |
|
|
|
|
|
mock_get_expected_calls(ini_putl), |
|
|
|
|
|
mock_get_actual_calls(ini_putl) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("keyboard") { |
|
|
|
|
|
describe("HandleKeyboardEvents") { |
|
|
|
|
|
static SDL_Event e; |
|
|
|
|
|
static IZ_KeyboardState state; |
|
|
|
|
|
static IZ_Action action; |
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < CONTROLS; i += 1) { |
|
|
|
|
|
it("handles %s action activation", ACTION_NAMES[i]) { |
|
|
|
|
|
e.type = SDL_KEYDOWN; |
|
|
|
|
|
e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; |
|
|
|
|
|
state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; |
|
|
|
|
|
action = 0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleKeyboardEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
action == (0x1 << i), |
|
|
|
|
|
"Action not set." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("handles %s action deactivation", ACTION_NAMES[i]) { |
|
|
|
|
|
e.type = SDL_KEYUP; |
|
|
|
|
|
e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; |
|
|
|
|
|
state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; |
|
|
|
|
|
action = ~0; |
|
|
|
|
|
|
|
|
|
|
|
IZ_HandleKeyboardEvents(e, &state, &action); |
|
|
|
|
|
check( |
|
|
|
|
|
!(action & (0x1 << i)), |
|
|
|
|
|
"Action not unset." |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("LoadKeyboardConfig") { |
|
|
|
|
|
static IZ_KeyboardConfig config; |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(IZ_GetConfigPath); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(ini_gets); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("calls load method") { |
|
|
|
|
|
mock_set_expected_calls(ini_gets, CONTROLS); |
|
|
|
|
|
|
|
|
|
|
|
IZ_LoadKeyboardConfig(&config, 0); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_is_called(IZ_GetConfigPath), |
|
|
|
|
|
"SDL_GetBasePath() not called." |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_get_expected_calls(ini_gets) == mock_get_actual_calls(ini_gets), |
|
|
|
|
|
"Call count mismatch for ini_gets() (expected %u, received %u).", |
|
|
|
|
|
mock_get_expected_calls(ini_gets), |
|
|
|
|
|
mock_get_actual_calls(ini_gets) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe("SaveKeyboardConfig") { |
|
|
|
|
|
static IZ_KeyboardConfig config; |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(IZ_GetConfigPath); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
after_each() { |
|
|
|
|
|
mock_reset(ini_puts); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
before_each() { |
|
|
|
|
|
for (uint8_t i = 0; i < CONTROLS; i += 1) { |
|
|
|
|
|
config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
it("calls save method") { |
|
|
|
|
|
mock_set_expected_calls(ini_puts, CONTROLS); |
|
|
|
|
|
|
|
|
|
|
|
IZ_SaveKeyboardConfig(&config, 0); |
|
|
|
|
|
|
|
|
|
|
|
check( |
|
|
|
|
|
mock_get_expected_calls(ini_puts) == mock_get_actual_calls(ini_puts), |
|
|
|
|
|
"Call count mismatch for ini_puts() (expected %u, received %u).", |
|
|
|
|
|
mock_get_expected_calls(ini_puts), |
|
|
|
|
|
mock_get_actual_calls(ini_puts) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |