Add tests for initialization and teardown for all input methods.feature/data-structs
@@ -80,6 +80,7 @@ add_executable( | |||||
__mocks__/SDL_events.mock.h | __mocks__/SDL_events.mock.h | ||||
__mocks__/SDL_joystick.mock.h | __mocks__/SDL_joystick.mock.h | ||||
__mocks__/SDL_stdinc.mock.h | __mocks__/SDL_stdinc.mock.h | ||||
__mocks__/portmidi.mock.h | |||||
src/packages/game/IZ_config.h | src/packages/game/IZ_config.h | ||||
@@ -89,6 +90,9 @@ add_executable( | |||||
src/packages/game/input/IZ_joystick.h | src/packages/game/input/IZ_joystick.h | ||||
src/packages/game/input/IZ_joystick.c | src/packages/game/input/IZ_joystick.c | ||||
src/packages/game/input/IZ_midi.h | |||||
src/packages/game/input/IZ_midi.c | |||||
src/packages/game/input/input.test.c | src/packages/game/input/input.test.c | ||||
) | ) | ||||
@@ -6,13 +6,15 @@ | |||||
typedef struct _SDL_Joystick {} SDL_Joystick; | typedef struct _SDL_Joystick {} SDL_Joystick; | ||||
#define MOCK_OPEN_JOYSTICKS 1 | |||||
mock(SDL_JoystickOpen) SDL_Joystick* SDL_JoystickOpen(i32 device_index) { | mock(SDL_JoystickOpen) SDL_Joystick* SDL_JoystickOpen(i32 device_index) { | ||||
static SDL_Joystick joystick; | static SDL_Joystick joystick; | ||||
mock_return(SDL_JoystickOpen) &joystick; | mock_return(SDL_JoystickOpen) &joystick; | ||||
} | } | ||||
mock(SDL_NumJoysticks) i32 SDL_NumJoysticks(void) { | mock(SDL_NumJoysticks) i32 SDL_NumJoysticks(void) { | ||||
mock_return(SDL_NumJoysticks) 1; | |||||
mock_return(SDL_NumJoysticks) MOCK_OPEN_JOYSTICKS; | |||||
} | } | ||||
mock(SDL_JoystickInstanceID) i32 SDL_JoystickInstanceID(SDL_Joystick* joystick) { | mock(SDL_JoystickInstanceID) i32 SDL_JoystickInstanceID(SDL_Joystick* joystick) { | ||||
@@ -0,0 +1,69 @@ | |||||
#ifndef PORTMIDI_MOCK_H | |||||
#define PORTMIDI_MOCK_H | |||||
#define PORTMIDI_INCLUDED | |||||
#include "../src/packages/game/IZ_common.h" | |||||
typedef i32 PmDeviceID; | |||||
typedef void PortMidiStream; | |||||
typedef i32 PmTimestamp; | |||||
typedef PmTimestamp (*PmTimeProcPtr)(void *time_info); | |||||
typedef i32 PmMessage; | |||||
typedef struct { | |||||
PmMessage message; | |||||
PmTimestamp timestamp; | |||||
} PmEvent; | |||||
typedef struct { | |||||
int structVersion; /**< @brief this internal structure version */ | |||||
const char *interf; /**< @brief underlying MIDI API, e.g. | |||||
"MMSystem" or "DirectX" */ | |||||
char *name; /**< @brief device name, e.g. "USB MidiSport 1x1" */ | |||||
int input; /**< @brief true iff input is available */ | |||||
int output; /**< @brief true iff output is available */ | |||||
int opened; /**< @brief used by generic PortMidi for error checking */ | |||||
int is_virtual; /**< @brief true iff this is/was a virtual device */ | |||||
} PmDeviceInfo; | |||||
#define PmStream PortMidiStream | |||||
static PmDeviceInfo MOCK_DEVICE_INFO = { | |||||
.output = 1, | |||||
.input = 1, | |||||
.name = "Mock MIDI Device", | |||||
.interf = "MMSystem", | |||||
.is_virtual = 0, | |||||
.opened = 0, | |||||
.structVersion = 1, | |||||
}; | |||||
mock(Pm_Initialize) i32 Pm_Initialize(void) { | |||||
mock_return(Pm_Initialize) 0; | |||||
} | |||||
mock(Pm_GetDeviceInfo) const PmDeviceInfo* Pm_GetDeviceInfo(PmDeviceID id) { | |||||
mock_return(Pm_GetDeviceInfo) &MOCK_DEVICE_INFO; | |||||
} | |||||
mock(Pm_OpenInput) i32 Pm_OpenInput( | |||||
PortMidiStream** stream, | |||||
PmDeviceID inputDevice, | |||||
void* inputDriverInfo, | |||||
i32 bufferSize, | |||||
PmTimeProcPtr time_proc, | |||||
void* time_info | |||||
) { | |||||
mock_return(Pm_OpenInput) 0; | |||||
} | |||||
mock(Pm_Close) i32 Pm_Close(PortMidiStream* stream) { | |||||
mock_return(Pm_Close) 0; | |||||
} | |||||
#define MOCK_OPEN_MIDI_DEVICES 1 | |||||
mock(Pm_CountDevices) i32 Pm_CountDevices(void) { | |||||
mock_return(Pm_CountDevices) MOCK_OPEN_MIDI_DEVICES; | |||||
} | |||||
#endif |
@@ -19,7 +19,10 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) { | |||||
return 2; | return 2; | ||||
} | } | ||||
IZ_InputInitialize(config_path, &app->input_state); | |||||
if (IZ_InputInitialize(config_path, &app->input_state)) { | |||||
return 3; | |||||
} | |||||
IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE); | IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE); | ||||
// TODO put into its timer module | // TODO put into its timer module | ||||
@@ -84,7 +84,7 @@ spec("geometry") { | |||||
.up = 69.f, | .up = 69.f, | ||||
}; | }; | ||||
static IZ_GeoCoord s = 2.f; | |||||
static f32 s = 2.f; | |||||
static IZ_Vector2D expected = { | static IZ_Vector2D expected = { | ||||
.right = 840.f, | .right = 840.f, | ||||
@@ -9,7 +9,7 @@ void IZ_InputHandlePortMIDIEvents(PmEvent e, IZ_InputState* state) { | |||||
IZ_MIDIInputHandleEvents(e, &state->midi_input_state, &state->action); | IZ_MIDIInputHandleEvents(e, &state->midi_input_state, &state->action); | ||||
} | } | ||||
void IZ_InputInitialize(const char* config_path, IZ_InputState* state) { | |||||
IZ_ProcedureResult IZ_InputInitialize(const char* config_path, IZ_InputState* state) { | |||||
*state = (IZ_InputState) { | *state = (IZ_InputState) { | ||||
.action = {}, | .action = {}, | ||||
.joystick_state = {}, | .joystick_state = {}, | ||||
@@ -17,25 +17,29 @@ void IZ_InputInitialize(const char* config_path, IZ_InputState* state) { | |||||
.keyboard_state = {}, | .keyboard_state = {}, | ||||
}; | }; | ||||
IZ_ProcedureResult result = 0; | |||||
IZ_ProcedureResult joystick_result = IZ_JoystickInitialize(config_path, &state->joystick_state); | IZ_ProcedureResult joystick_result = IZ_JoystickInitialize(config_path, &state->joystick_state); | ||||
if (joystick_result) { | if (joystick_result) { | ||||
fprintf_s(stderr, "Error committing joystick config. Code: %u.\n", joystick_result); | |||||
result |= 1; | |||||
} | } | ||||
IZ_ProcedureResult keyboard_result = IZ_KeyboardInitialize(config_path, &state->keyboard_state); | IZ_ProcedureResult keyboard_result = IZ_KeyboardInitialize(config_path, &state->keyboard_state); | ||||
if (keyboard_result) { | if (keyboard_result) { | ||||
fprintf_s(stderr, "Error committing keyboard config. Code: %u.\n", keyboard_result); | |||||
result |= 2; | |||||
} | } | ||||
IZ_ProcedureResult midi_input_result = IZ_MIDIInputInitialize(config_path, &state->midi_input_state); | IZ_ProcedureResult midi_input_result = IZ_MIDIInputInitialize(config_path, &state->midi_input_state); | ||||
if (midi_input_result) { | if (midi_input_result) { | ||||
fprintf_s(stderr, "Error committing MIDI input config. Code: %u.\n", midi_input_result); | |||||
result |= 4; | |||||
} | } | ||||
u8 player_index; | u8 player_index; | ||||
for (player_index = 0; player_index < PLAYERS; player_index += 1) { | for (player_index = 0; player_index < PLAYERS; player_index += 1) { | ||||
state->action[player_index] = 0; | state->action[player_index] = 0; | ||||
} | } | ||||
return result; | |||||
} | } | ||||
void IZ_InputTeardown(IZ_InputState* state) { | void IZ_InputTeardown(IZ_InputState* state) { | ||||
@@ -17,7 +17,7 @@ void IZ_InputHandleSDLEvents(SDL_Event, IZ_InputState*); | |||||
void IZ_InputHandlePortMIDIEvents(PmEvent, IZ_InputState*); | void IZ_InputHandlePortMIDIEvents(PmEvent, IZ_InputState*); | ||||
void IZ_InputInitialize(const char*, IZ_InputState*); | |||||
IZ_ProcedureResult IZ_InputInitialize(const char*, IZ_InputState*); | |||||
void IZ_InputTeardown(IZ_InputState*); | void IZ_InputTeardown(IZ_InputState*); | ||||
@@ -172,6 +172,9 @@ IZ_ProcedureResult IZ_JoystickInitialize(const char* config_path, IZ_JoystickSta | |||||
u8 joysticks_count = SDL_NumJoysticks(); | u8 joysticks_count = SDL_NumJoysticks(); | ||||
u8 player_index; | u8 player_index; | ||||
for (player_index = 0; player_index < joysticks_count; player_index += 1) { | for (player_index = 0; player_index < joysticks_count; player_index += 1) { | ||||
if (player_index >= PLAYERS) { | |||||
break; | |||||
} | |||||
(*state)[player_index].device = SDL_JoystickOpen(state[player_index]->config.device_id); | (*state)[player_index].device = SDL_JoystickOpen(state[player_index]->config.device_id); | ||||
} | } | ||||
@@ -18,15 +18,15 @@ char* IZ_MIDIGetNoteName(u8 midi_note) { | |||||
const u8 pitch_class = midi_note % 12; | const u8 pitch_class = midi_note % 12; | ||||
const u8 octave = midi_note / 12; | const u8 octave = midi_note / 12; | ||||
static char note_name[4]; | |||||
sprintf_s(note_name, 4, "%s%u", pitch_names[pitch_class], octave); | |||||
static char note_name[8]; | |||||
sprintf_s(note_name, 8, "%s%u", pitch_names[pitch_class], octave); | |||||
return note_name; | return note_name; | ||||
} | } | ||||
u8 IZ_MIDIGetNoteFromName(char* name) { | u8 IZ_MIDIGetNoteFromName(char* name) { | ||||
char name_copy[4]; | |||||
memcpy_s(name_copy, 4, name, 4); | |||||
_strlwr_s(name_copy, 4); | |||||
char name_copy[8]; | |||||
memcpy_s(name_copy, 8, name, 8); | |||||
_strlwr_s(name_copy, 8); | |||||
u8 octave; | u8 octave; | ||||
const char base_pitch_name[] = "c d ef g a b"; | const char base_pitch_name[] = "c d ef g a b"; | ||||
@@ -181,7 +181,23 @@ IZ_ProcedureResult IZ_MIDIInputInitialize(const char* config_path, IZ_MIDIInputS | |||||
} | } | ||||
u8 player_index; | u8 player_index; | ||||
for (player_index = 0; player_index < PLAYERS; player_index += 1) { | |||||
// TODO Pm_CountDevices(), only filter input devices | |||||
u8 midi_devices_count = Pm_CountDevices(); | |||||
u8 input_midi_devices_count = 0; | |||||
u8 device_index; | |||||
for (device_index = 0; device_index < midi_devices_count; device_index += 1) { | |||||
if (!Pm_GetDeviceInfo(device_index)->output) { | |||||
continue; | |||||
} | |||||
// midi device can output messages for the app to receive | |||||
input_midi_devices_count += 1; | |||||
} | |||||
for (player_index = 0; player_index < input_midi_devices_count; player_index += 1) { | |||||
if (player_index >= PLAYERS) { | |||||
break; | |||||
} | |||||
(*state)[player_index].device_info = Pm_GetDeviceInfo((*state)[player_index].config.device_id); | (*state)[player_index].device_info = Pm_GetDeviceInfo((*state)[player_index].config.device_id); | ||||
(*state)[player_index].stream = NULL; | (*state)[player_index].stream = NULL; | ||||
Pm_OpenInput( | Pm_OpenInput( | ||||
@@ -3,7 +3,12 @@ | |||||
#include <SDL_stdinc.h> | #include <SDL_stdinc.h> | ||||
#include <string.h> | #include <string.h> | ||||
#ifndef PORTMIDI_INCLUDED | |||||
#define PORTMIDI_INCLUDED | |||||
#include <portmidi.h> | #include <portmidi.h> | ||||
#endif | |||||
#include <minIni.h> | #include <minIni.h> | ||||
#include "IZ_action.h" | #include "IZ_action.h" | ||||
@@ -77,8 +82,8 @@ static const IZ_MIDIInputState IZ_DEFAULT_MIDI_INPUT_STATE[PLAYERS] = { | |||||
56, | 56, | ||||
57, | 57, | ||||
}, | }, | ||||
.device_id = 0, | |||||
.channel = 0, | |||||
.device_id = 1, | |||||
.channel = 1, | |||||
}, | }, | ||||
.event_buffer = {}, | .event_buffer = {}, | ||||
.stream = NULL, | .stream = NULL, | ||||
@@ -2,8 +2,10 @@ | |||||
#include "../../../__mocks__/SDL_joystick.mock.h" | #include "../../../__mocks__/SDL_joystick.mock.h" | ||||
#include "../../../__mocks__/SDL_stdinc.mock.h" | #include "../../../__mocks__/SDL_stdinc.mock.h" | ||||
#include "../../../__mocks__/minIni.mock.h" | #include "../../../__mocks__/minIni.mock.h" | ||||
#include "../../../__mocks__/portmidi.mock.h" | |||||
#include "IZ_keyboard.h" | #include "IZ_keyboard.h" | ||||
#include "IZ_joystick.h" | #include "IZ_joystick.h" | ||||
#include "IZ_midi.h" | |||||
i16 GenerateAxisValueWithinThreshold(u16 threshold) { | i16 GenerateAxisValueWithinThreshold(u16 threshold) { | ||||
return rand() % threshold; | return rand() % threshold; | ||||
@@ -15,6 +17,76 @@ i16 GenerateAxisValueOutsideThreshold(u16 threshold) { | |||||
spec("input") { | spec("input") { | ||||
describe("joystick") { | describe("joystick") { | ||||
describe("Initialize") { | |||||
static IZ_JoystickState state[PLAYERS]; | |||||
after_each() { | |||||
mock_reset(SDL_memcpy); | |||||
} | |||||
after_each() { | |||||
mock_reset(SDL_NumJoysticks); | |||||
} | |||||
after_each() { | |||||
mock_reset(SDL_JoystickOpen); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_putl); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_getl); | |||||
} | |||||
it("sets initial state") { | |||||
IZ_JoystickInitialize("config.ini", &state); | |||||
check(mock_is_called(SDL_memcpy), "Initial state not loaded."); | |||||
check(mock_is_called(SDL_NumJoysticks), "Connected joysticks not checked."); | |||||
} | |||||
it("calls load method") { | |||||
mock_set_expected_calls(ini_getl, ((CONTROLS - 4) + 2) * PLAYERS); | |||||
IZ_JoystickInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
} | |||||
it("calls save method") { | |||||
mock_set_expected_calls(ini_putl, ((CONTROLS - 4) + 2) * PLAYERS); | |||||
IZ_JoystickInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
} | |||||
it("opens device handles") { | |||||
mock_set_expected_calls(SDL_JoystickOpen, MOCK_OPEN_JOYSTICKS); | |||||
IZ_JoystickInitialize("config.ini", &state); | |||||
check( | |||||
mock_get_expected_calls(SDL_JoystickOpen) == mock_get_actual_calls(SDL_JoystickOpen), | |||||
"Call count mismatch for SDL_JoystickOpen() (expected %u, received %u).", | |||||
mock_get_expected_calls(SDL_JoystickOpen), | |||||
mock_get_actual_calls(SDL_JoystickOpen) | |||||
); | |||||
} | |||||
} | |||||
describe("HandleEvents") { | describe("HandleEvents") { | ||||
static SDL_Event e; | static SDL_Event e; | ||||
static IZ_JoystickState state[PLAYERS] = {}; | static IZ_JoystickState state[PLAYERS] = {}; | ||||
@@ -289,9 +361,93 @@ spec("input") { | |||||
); | ); | ||||
} | } | ||||
} | } | ||||
describe("Teardown") { | |||||
static SDL_Joystick device; | |||||
static IZ_JoystickState state[PLAYERS] = {}; | |||||
before_each() { | |||||
for (u8 p = 0; p < PLAYERS; p += 1) { | |||||
state[p].device = &device; | |||||
} | |||||
} | |||||
after_each() { | |||||
mock_reset(SDL_JoystickClose); | |||||
} | |||||
it("closes opened devices") { | |||||
mock_set_expected_calls(SDL_JoystickClose, PLAYERS); | |||||
IZ_JoystickTeardown(&state); | |||||
check( | |||||
mock_get_expected_calls(SDL_JoystickClose) == mock_get_actual_calls(SDL_JoystickClose), | |||||
"Call count mismatch for SDL_JoystickClose() (expected %u, received %u).", | |||||
mock_get_expected_calls(SDL_JoystickClose), | |||||
mock_get_actual_calls(SDL_JoystickClose) | |||||
); | |||||
} | |||||
} | |||||
} | } | ||||
describe("keyboard") { | describe("keyboard") { | ||||
describe("Initialize") { | |||||
static IZ_KeyboardState state[PLAYERS] = {}; | |||||
after_each() { | |||||
mock_reset(SDL_memcpy); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_gets); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_puts); | |||||
} | |||||
before_each() { | |||||
for (u8 p = 0; p < PLAYERS; p += 1) { | |||||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||||
state[p].config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[p].config.control_mapping[i]; | |||||
} | |||||
} | |||||
} | |||||
it("sets initial state") { | |||||
IZ_KeyboardInitialize("config.ini", &state); | |||||
check(mock_is_called(SDL_memcpy), "Initial state not loaded."); | |||||
} | |||||
it("calls load method") { | |||||
mock_set_expected_calls(ini_gets, CONTROLS * PLAYERS); | |||||
IZ_KeyboardInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
} | |||||
it("calls save method") { | |||||
mock_set_expected_calls(ini_puts, CONTROLS * PLAYERS); | |||||
IZ_KeyboardInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
} | |||||
} | |||||
describe("HandleEvents") { | describe("HandleEvents") { | ||||
static SDL_Event e; | static SDL_Event e; | ||||
static IZ_KeyboardState state[PLAYERS] = {}; | static IZ_KeyboardState state[PLAYERS] = {}; | ||||
@@ -359,4 +515,197 @@ spec("input") { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
describe("midi") { | |||||
describe("Initialize") { | |||||
static IZ_MIDIInputState state[PLAYERS]; | |||||
after_each() { | |||||
mock_reset(SDL_memcpy); | |||||
} | |||||
after_each() { | |||||
mock_reset(Pm_CountDevices); | |||||
} | |||||
after_each() { | |||||
mock_reset(Pm_OpenInput); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_puts); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_gets); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_putl); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_getl); | |||||
} | |||||
it("sets initial state") { | |||||
IZ_MIDIInputInitialize("config.ini", &state); | |||||
check(mock_is_called(SDL_memcpy), "Initial state not loaded."); | |||||
check(mock_is_called(Pm_CountDevices), "Connected MIDI devices not checked."); | |||||
} | |||||
it("calls load method") { | |||||
mock_set_expected_calls(ini_gets, CONTROLS * PLAYERS); | |||||
mock_set_expected_calls(ini_getl, 2 * PLAYERS); | |||||
IZ_MIDIInputInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
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) | |||||
); | |||||
} | |||||
it("calls save method") { | |||||
mock_set_expected_calls(ini_puts, CONTROLS * PLAYERS); | |||||
mock_set_expected_calls(ini_putl, 2 * PLAYERS); | |||||
IZ_MIDIInputInitialize("config.ini", &state); | |||||
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) | |||||
); | |||||
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) | |||||
); | |||||
} | |||||
it("opens device handles") { | |||||
mock_set_expected_calls(Pm_OpenInput, MOCK_OPEN_JOYSTICKS); | |||||
IZ_MIDIInputInitialize("config.ini", &state); | |||||
check( | |||||
mock_get_expected_calls(Pm_OpenInput) == mock_get_actual_calls(Pm_OpenInput), | |||||
"Call count mismatch for Pm_OpenInput() (expected %u, received %u).", | |||||
mock_get_expected_calls(Pm_OpenInput), | |||||
mock_get_actual_calls(Pm_OpenInput) | |||||
); | |||||
} | |||||
} | |||||
describe("SaveConfig") { | |||||
static IZ_MIDIInputState state[PLAYERS]; | |||||
after_each() { | |||||
mock_reset(ini_puts); | |||||
} | |||||
after_each() { | |||||
mock_reset(ini_putl); | |||||
} | |||||
it("calls save method") { | |||||
mock_set_expected_calls(ini_puts, CONTROLS * PLAYERS); | |||||
mock_set_expected_calls(ini_putl, 2 * PLAYERS); | |||||
IZ_MIDIInputSaveConfig("config.ini", &state); | |||||
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) | |||||
); | |||||
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("HandleEvents") { | |||||
static PmEvent e; | |||||
static IZ_MIDIInputState state[PLAYERS] = {}; | |||||
static IZ_Action action[PLAYERS] = {}; | |||||
for (u8 p = 0; p < PLAYERS; p += 1) { | |||||
describe("on player %u", p) { | |||||
for (u8 i = 0; i < CONTROLS; i += 1) { | |||||
it("handles %s action activation", ACTION_NAMES[i]) { | |||||
e.message = IZ_MIDI_NOTE_ON | (IZ_DEFAULT_MIDI_INPUT_STATE[p].config.control_mapping[i] << 8); | |||||
state[p].config.control_mapping[i] = IZ_DEFAULT_MIDI_INPUT_STATE[p].config.control_mapping[i]; | |||||
action[p] = 0; | |||||
IZ_MIDIInputHandleEvents(e, &state, &action); | |||||
check( | |||||
action[p] == (0x1 << i), | |||||
"Action not set." | |||||
); | |||||
} | |||||
it("handles %s action deactivation", ACTION_NAMES[i]) { | |||||
e.message = IZ_MIDI_NOTE_OFF | (IZ_DEFAULT_MIDI_INPUT_STATE[p].config.control_mapping[i] << 8); | |||||
state[p].config.control_mapping[i] = IZ_DEFAULT_MIDI_INPUT_STATE[p].config.control_mapping[i]; | |||||
action[p] = ~0; | |||||
IZ_MIDIInputHandleEvents(e, &state, &action); | |||||
check( | |||||
!(action[p] & (0x1 << i)), | |||||
"Action not unset." | |||||
); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
describe("Teardown") { | |||||
static PmStream* stream; | |||||
static IZ_MIDIInputState state[PLAYERS] = {}; | |||||
before_each() { | |||||
for (u8 p = 0; p < PLAYERS; p += 1) { | |||||
state[p].stream = &stream; | |||||
} | |||||
} | |||||
after_each() { | |||||
mock_reset(Pm_Close); | |||||
} | |||||
it("closes opened devices") { | |||||
mock_set_expected_calls(Pm_Close, PLAYERS); | |||||
IZ_MIDIInputTeardown(&state); | |||||
check( | |||||
mock_get_expected_calls(Pm_Close) == mock_get_actual_calls(Pm_Close), | |||||
"Call count mismatch for Pm_Close() (expected %u, received %u).", | |||||
mock_get_expected_calls(Pm_Close), | |||||
mock_get_actual_calls(Pm_Close) | |||||
); | |||||
} | |||||
} | |||||
} | |||||
} | } |