Starter project for SDL2.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

418 lines
10 KiB

  1. #include "../../../__mocks__/SDL_keyboard.mock.h"
  2. #include "../../../__mocks__/SDL_joystick.mock.h"
  3. #include "../../../__mocks__/minIni.mock.h"
  4. #include "../__mocks__/IZ_config.mock.h"
  5. #include "IZ_keyboard.h"
  6. #include "IZ_joystick.h"
  7. short int GenerateAxisValueWithinThreshold(short int threshold) {
  8. return rand() % threshold;
  9. }
  10. short int GenerateAxisValueOutsideThreshold(short int threshold) {
  11. return threshold + (rand() % (RAND_MAX - threshold - 1)) + 1;
  12. }
  13. spec("input") {
  14. describe("joystick") {
  15. describe("HandleJoystickEvents") {
  16. static SDL_Event e;
  17. static IZ_JoystickState state;
  18. static IZ_Action action;
  19. describe("on axis motion events") {
  20. before_each() {
  21. e.type = SDL_JOYAXISMOTION;
  22. state.config.axis_threshold = 8000;
  23. }
  24. describe("on primary horizontal direction") {
  25. before_each() {
  26. e.jaxis.axis = IZ_JOYAXIS_DIRECTION_HORIZONTAL1;
  27. }
  28. it("handles positive motion") {
  29. e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  30. action = 0;
  31. printf("(axis value: %d) ", e.jaxis.value);
  32. IZ_HandleJoystickEvents(e, &state, &action);
  33. check(
  34. action == (0x1 << IZ_ACTION_INDEX_RIGHT),
  35. "Action not set."
  36. );
  37. }
  38. it("handles negative motion") {
  39. e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  40. action = 0;
  41. printf("(axis value: %d) ", e.jaxis.value);
  42. IZ_HandleJoystickEvents(e, &state, &action);
  43. check(
  44. action == (0x1 << IZ_ACTION_INDEX_LEFT),
  45. "Action not set."
  46. );
  47. }
  48. it("handles neutral motion") {
  49. e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);
  50. action = 0;
  51. printf("(axis value: %d) ", e.jaxis.value);
  52. IZ_HandleJoystickEvents(e, &state, &action);
  53. check(
  54. action == 0,
  55. "Action not set."
  56. );
  57. }
  58. }
  59. describe("on secondary horizontal direction") {
  60. before_each() {
  61. e.jaxis.axis = IZ_JOYAXIS_DIRECTION_HORIZONTAL2;
  62. }
  63. it("handles positive motion") {
  64. e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  65. action = 0;
  66. printf("(axis value: %d) ", e.jaxis.value);
  67. IZ_HandleJoystickEvents(e, &state, &action);
  68. check(
  69. action == (0x1 << IZ_ACTION_INDEX_RIGHT),
  70. "Action not set."
  71. );
  72. }
  73. it("handles negative motion") {
  74. e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  75. action = 0;
  76. printf("(axis value: %d) ", e.jaxis.value);
  77. IZ_HandleJoystickEvents(e, &state, &action);
  78. check(
  79. action == (0x1 << IZ_ACTION_INDEX_LEFT),
  80. "Action not set."
  81. );
  82. }
  83. it("handles neutral motion") {
  84. e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);;
  85. action = 0;
  86. printf("(axis value: %d) ", e.jaxis.value);
  87. IZ_HandleJoystickEvents(e, &state, &action);
  88. check(
  89. action == 0,
  90. "Action not set."
  91. );
  92. }
  93. }
  94. describe("on primary vertical direction") {
  95. before_each() {
  96. e.jaxis.axis = IZ_JOYAXIS_DIRECTION_VERTICAL1;
  97. }
  98. it("handles positive motion") {
  99. e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  100. action = 0;
  101. printf("(axis value: %d) ", e.jaxis.value);
  102. IZ_HandleJoystickEvents(e, &state, &action);
  103. check(
  104. action == (0x1 << IZ_ACTION_INDEX_DOWN),
  105. "Action not set."
  106. );
  107. }
  108. it("handles negative motion") {
  109. e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  110. action = 0;
  111. printf("(axis value: %d) ", e.jaxis.value);
  112. IZ_HandleJoystickEvents(e, &state, &action);
  113. check(
  114. action == (0x1 << IZ_ACTION_INDEX_UP),
  115. "Action not set."
  116. );
  117. }
  118. it("handles neutral motion") {
  119. e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);;
  120. action = 0;
  121. printf("(axis value: %d) ", e.jaxis.value);
  122. IZ_HandleJoystickEvents(e, &state, &action);
  123. check(
  124. action == 0,
  125. "Action not set."
  126. );
  127. }
  128. }
  129. describe("on secondary vertical direction") {
  130. before_each() {
  131. e.jaxis.axis = IZ_JOYAXIS_DIRECTION_VERTICAL2;
  132. }
  133. it("handles positive motion") {
  134. e.jaxis.value = GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  135. action = 0;
  136. printf("(axis value: %d) ", e.jaxis.value);
  137. IZ_HandleJoystickEvents(e, &state, &action);
  138. check(
  139. action == (0x1 << IZ_ACTION_INDEX_DOWN),
  140. "Action not set."
  141. );
  142. }
  143. it("handles negative motion") {
  144. e.jaxis.value = -GenerateAxisValueOutsideThreshold(state.config.axis_threshold);
  145. action = 0;
  146. printf("(axis value: %d) ", e.jaxis.value);
  147. IZ_HandleJoystickEvents(e, &state, &action);
  148. check(
  149. action == (0x1 << IZ_ACTION_INDEX_UP),
  150. "Action not set."
  151. );
  152. }
  153. it("handles neutral motion") {
  154. e.jaxis.value = GenerateAxisValueWithinThreshold(state.config.axis_threshold);;
  155. action = 0;
  156. printf("(axis value: %d) ", e.jaxis.value);
  157. IZ_HandleJoystickEvents(e, &state, &action);
  158. check(
  159. action == 0,
  160. "Action not set."
  161. );
  162. }
  163. }
  164. }
  165. describe("on hat motion events") {
  166. before_each() {
  167. e.type = SDL_JOYHATMOTION;
  168. }
  169. for (uint8_t i = 0; i < 4; i += 1) {
  170. it("handles motion for %s action", ACTION_NAMES[i]) {
  171. e.jhat.value = (0x1u << i);
  172. action = 0;
  173. IZ_HandleJoystickEvents(e, &state, &action);
  174. check(
  175. action == (0x1u << i),
  176. "Action not set."
  177. );
  178. }
  179. it("handles motion for %s deactivation", ACTION_NAMES[i]) {
  180. e.jhat.value = 0;
  181. action = ~0;
  182. IZ_HandleJoystickEvents(e, &state, &action);
  183. check(
  184. !(action & (0x1 << i)),
  185. "Action not unset."
  186. );
  187. }
  188. }
  189. }
  190. describe("on button events") {
  191. for (uint8_t i = 4; i < CONTROLS; i += 1) {
  192. it("handles %s action activation", ACTION_NAMES[i]) {
  193. e.type = SDL_JOYBUTTONDOWN;
  194. e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i];
  195. state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i];
  196. action = 0;
  197. IZ_HandleJoystickEvents(e, &state, &action);
  198. check(
  199. action == (0x1u << i),
  200. "Action not set."
  201. );
  202. }
  203. it("handles %s action deactivation", ACTION_NAMES[i]) {
  204. e.type = SDL_JOYBUTTONUP;
  205. e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i];
  206. state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i];
  207. action = ~0;
  208. IZ_HandleJoystickEvents(e, &state, &action);
  209. check(
  210. !(action & (0x1 << i)),
  211. "Action not unset."
  212. );
  213. }
  214. }
  215. }
  216. }
  217. describe("LoadJoystickConfig") {
  218. static IZ_JoystickConfig config;
  219. after_each() {
  220. mock_reset(IZ_GetConfigPath);
  221. }
  222. after_each() {
  223. mock_reset(ini_getl);
  224. }
  225. it("calls load method") {
  226. mock_set_expected_calls(ini_getl, CONTROLS - 4 + 1);
  227. IZ_LoadJoystickConfig(&config, 0);
  228. check(
  229. mock_is_called(IZ_GetConfigPath),
  230. "SDL_GetBasePath() not called."
  231. );
  232. check(
  233. mock_get_expected_calls(ini_getl) == mock_get_actual_calls(ini_getl),
  234. "Call count mismatch for ini_getl() (expected %u, received %u).",
  235. mock_get_expected_calls(ini_getl),
  236. mock_get_actual_calls(ini_getl)
  237. );
  238. }
  239. }
  240. describe("SaveJoystickConfig") {
  241. static IZ_JoystickConfig config;
  242. after_each() {
  243. mock_reset(IZ_GetConfigPath);
  244. }
  245. after_each() {
  246. mock_reset(ini_putl);
  247. }
  248. before_each() {
  249. for (uint8_t i = 0; i < CONTROLS; i += 1) {
  250. config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i];
  251. }
  252. }
  253. it("calls save method") {
  254. mock_set_expected_calls(ini_putl, CONTROLS - 4 + 1);
  255. IZ_SaveJoystickConfig(&config, 0);
  256. check(
  257. mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl),
  258. "Call count mismatch for ini_putl() (expected %u, received %u).",
  259. mock_get_expected_calls(ini_putl),
  260. mock_get_actual_calls(ini_putl)
  261. );
  262. }
  263. }
  264. }
  265. describe("keyboard") {
  266. describe("HandleKeyboardEvents") {
  267. static SDL_Event e;
  268. static IZ_KeyboardState state;
  269. static IZ_Action action;
  270. for (uint8_t i = 0; i < CONTROLS; i += 1) {
  271. it("handles %s action activation", ACTION_NAMES[i]) {
  272. e.type = SDL_KEYDOWN;
  273. e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i];
  274. state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i];
  275. action = 0;
  276. IZ_HandleKeyboardEvents(e, &state, &action);
  277. check(
  278. action == (0x1 << i),
  279. "Action not set."
  280. );
  281. }
  282. it("handles %s action deactivation", ACTION_NAMES[i]) {
  283. e.type = SDL_KEYUP;
  284. e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i];
  285. state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i];
  286. action = ~0;
  287. IZ_HandleKeyboardEvents(e, &state, &action);
  288. check(
  289. !(action & (0x1 << i)),
  290. "Action not unset."
  291. );
  292. }
  293. }
  294. }
  295. describe("LoadKeyboardConfig") {
  296. static IZ_KeyboardConfig config;
  297. after_each() {
  298. mock_reset(IZ_GetConfigPath);
  299. }
  300. after_each() {
  301. mock_reset(ini_gets);
  302. }
  303. it("calls load method") {
  304. mock_set_expected_calls(ini_gets, CONTROLS);
  305. IZ_LoadKeyboardConfig(&config, 0);
  306. check(
  307. mock_is_called(IZ_GetConfigPath),
  308. "SDL_GetBasePath() not called."
  309. );
  310. check(
  311. mock_get_expected_calls(ini_gets) == mock_get_actual_calls(ini_gets),
  312. "Call count mismatch for ini_gets() (expected %u, received %u).",
  313. mock_get_expected_calls(ini_gets),
  314. mock_get_actual_calls(ini_gets)
  315. );
  316. }
  317. }
  318. describe("SaveKeyboardConfig") {
  319. static IZ_KeyboardConfig config;
  320. after_each() {
  321. mock_reset(IZ_GetConfigPath);
  322. }
  323. after_each() {
  324. mock_reset(ini_puts);
  325. }
  326. before_each() {
  327. for (uint8_t i = 0; i < CONTROLS; i += 1) {
  328. config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i];
  329. }
  330. }
  331. it("calls save method") {
  332. mock_set_expected_calls(ini_puts, CONTROLS);
  333. IZ_SaveKeyboardConfig(&config, 0);
  334. check(
  335. mock_get_expected_calls(ini_puts) == mock_get_actual_calls(ini_puts),
  336. "Call count mismatch for ini_puts() (expected %u, received %u).",
  337. mock_get_expected_calls(ini_puts),
  338. mock_get_actual_calls(ini_puts)
  339. );
  340. }
  341. }
  342. }
  343. }