test_integration_history.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * Copyright (c) 2021 Stefan Strobel <stefan.strobel@shimatta.net>
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. /**
  9. * @file test_integration_optLong.cpp
  10. * @brief integration test implementation for the history buffer of the shellmatta
  11. * @author Stefan Strobel <stefan.strobel@shimatta.net>
  12. */
  13. #include "test/framework/catch.hpp"
  14. extern "C" {
  15. #include "test/framework/fff.h"
  16. #include "shellmatta.h"
  17. }
  18. #include <string.h>
  19. FAKE_VALUE_FUNC(shellmatta_retCode_t, writeFct, const char *, uint32_t)
  20. FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct1, shellmatta_handle_t, const char *, uint32_t)
  21. FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct2, shellmatta_handle_t, const char *, uint32_t)
  22. FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct3, shellmatta_handle_t, const char *, uint32_t)
  23. FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct4, shellmatta_handle_t, const char *, uint32_t)
  24. /* List of fakes */
  25. #define FFF_FAKES_LIST(FAKE) \
  26. FAKE(writeFct) \
  27. FAKE(cmdFct1) \
  28. FAKE(cmdFct2) \
  29. FAKE(cmdFct3) \
  30. FAKE(cmdFct4)
  31. #define CHECK_FOR_COMMAND(hist, idx) \
  32. CHECK(writeFct_fake.call_count == ((hist) + 1u)); \
  33. CHECK(0 == memcmp(writeFct_fake.arg0_history[(hist)], commandSequence[(idx)], strlen(commandSequence[(idx)]) - 1)); \
  34. CHECK((strlen(commandSequence[(idx)]) - 1) == writeFct_fake.arg1_history[(hist)]);
  35. #define UP "\x1b" "[A"
  36. #define DOWN "\x1b" "[B"
  37. #define PRESS_BUTTON(button) \
  38. CHECK(SHELLMATTA_OK == shellmatta_processData(handle, (char*)(button), 3u));
  39. shellmatta_cmd_t cmd1 = {(char*)"cmd1", (char*)"1", NULL, NULL, cmdFct1, NULL};
  40. shellmatta_cmd_t cmd2 = {(char*)"cmd2", (char*)"2", NULL, NULL, cmdFct2, NULL};
  41. shellmatta_cmd_t cmd3 = {(char*)"cmd3", (char*)"3", NULL, NULL, cmdFct3, NULL};
  42. shellmatta_cmd_t cmd4 = {(char*)"cmd4", (char*)"4", NULL, NULL, cmdFct4, NULL};
  43. char *commandSequence[] =
  44. {
  45. (char*)"foo\r",
  46. (char*)"bar\r",
  47. (char*)"cmd1\r",
  48. (char*)"2\r",
  49. (char*)"4\r",
  50. (char*)"cmd3\r"
  51. };
  52. #define CMD_SEQ_LEN (sizeof(commandSequence) / sizeof(commandSequence[0]))
  53. SCENARIO("Test the history buffer with a fixed sequence of commands in there")
  54. {
  55. GIVEN("An initialized Shellmatte instance with some commands already in the history buffer")
  56. {
  57. shellmatta_instance_t inst;
  58. shellmatta_handle_t handle;
  59. char buffer[1024u];
  60. char historyBuffer[1024u];
  61. CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst,
  62. &handle,
  63. buffer,
  64. sizeof(buffer),
  65. historyBuffer,
  66. sizeof(historyBuffer),
  67. "shellmatta->",
  68. NULL,
  69. writeFct));
  70. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd1));
  71. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd2));
  72. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd3));
  73. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd4));
  74. for(uint32_t i = 0u; i < CMD_SEQ_LEN; i++)
  75. {
  76. CHECK(SHELLMATTA_OK == shellmatta_processData(handle, commandSequence[i], strlen(commandSequence[i])));
  77. }
  78. WHEN("The up button is pressed")
  79. {
  80. THEN("The shellmatta prints the most recent command")
  81. {
  82. FFF_FAKES_LIST(RESET_FAKE)
  83. PRESS_BUTTON(UP)
  84. CHECK(writeFct_fake.call_count == 2);
  85. CHECK(0 == memcmp(writeFct_fake.arg0_history[0], "\x1b" "[K", 3));
  86. CHECK(3 == writeFct_fake.arg1_history[0]);
  87. CHECK(0 == memcmp(writeFct_fake.arg0_history[1], commandSequence[CMD_SEQ_LEN - 1], strlen(commandSequence[CMD_SEQ_LEN - 1]) - 1));
  88. CHECK((strlen(commandSequence[CMD_SEQ_LEN - 1]) - 1) == writeFct_fake.arg1_history[1]);
  89. for(uint32_t i = CMD_SEQ_LEN - 1; i > 0; i--)
  90. {
  91. FFF_FAKES_LIST(RESET_FAKE)
  92. PRESS_BUTTON(UP)
  93. CHECK(writeFct_fake.call_count == 3);
  94. CHECK(0 == memcmp(writeFct_fake.arg0_history[1], "\x1b" "[K", 3));
  95. CHECK(3 == writeFct_fake.arg1_history[1]);
  96. CHECK(0 == memcmp(writeFct_fake.arg0_history[2], commandSequence[i - 1u], strlen(commandSequence[i - 1u]) - 1));
  97. CHECK((strlen(commandSequence[i - 1u]) - 1) == writeFct_fake.arg1_history[2]);
  98. }
  99. }
  100. }
  101. WHEN("The history buffer it at the oldest command yet")
  102. {
  103. for(uint32_t i = CMD_SEQ_LEN; i > 0; i--)
  104. {
  105. PRESS_BUTTON(UP)
  106. }
  107. AND_WHEN("The up button is pressed again")
  108. {
  109. THEN("The output is deleted and the oldest command is printed again")
  110. {
  111. for(uint32_t i = 0u; i < 64; i++)
  112. {
  113. FFF_FAKES_LIST(RESET_FAKE)
  114. PRESS_BUTTON(UP)
  115. CHECK_FOR_COMMAND(2u, 0u)
  116. }
  117. }
  118. }
  119. AND_WHEN("The down button is pressed")
  120. {
  121. THEN("On each button press one newer command is printed")
  122. {
  123. for(uint32_t i = 1; i < CMD_SEQ_LEN; i++)
  124. {
  125. FFF_FAKES_LIST(RESET_FAKE)
  126. PRESS_BUTTON(DOWN)
  127. CHECK(0 == memcmp(writeFct_fake.arg0_history[1], "\x1b" "[K", 3));
  128. CHECK(3 == writeFct_fake.arg1_history[1]);
  129. CHECK_FOR_COMMAND(2u, i)
  130. }
  131. }
  132. }
  133. }
  134. WHEN("The user pushes the up and down button alternatingly")
  135. {
  136. THEN("The output shall be updated with the correct command or not updated at all when at the end")
  137. {
  138. FFF_FAKES_LIST(RESET_FAKE)
  139. PRESS_BUTTON(UP)
  140. CHECK_FOR_COMMAND(1u, CMD_SEQ_LEN - 1u)
  141. FFF_FAKES_LIST(RESET_FAKE)
  142. PRESS_BUTTON(UP)
  143. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  144. FFF_FAKES_LIST(RESET_FAKE)
  145. PRESS_BUTTON(DOWN)
  146. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
  147. FFF_FAKES_LIST(RESET_FAKE)
  148. PRESS_BUTTON(DOWN)
  149. CHECK(writeFct_fake.call_count == 0u);
  150. FFF_FAKES_LIST(RESET_FAKE)
  151. PRESS_BUTTON(DOWN)
  152. CHECK(writeFct_fake.call_count == 0u);
  153. FFF_FAKES_LIST(RESET_FAKE)
  154. PRESS_BUTTON(UP)
  155. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  156. FFF_FAKES_LIST(RESET_FAKE)
  157. PRESS_BUTTON(UP)
  158. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
  159. FFF_FAKES_LIST(RESET_FAKE)
  160. PRESS_BUTTON(UP)
  161. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
  162. FFF_FAKES_LIST(RESET_FAKE)
  163. PRESS_BUTTON(UP)
  164. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 5u)
  165. FFF_FAKES_LIST(RESET_FAKE)
  166. PRESS_BUTTON(UP)
  167. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 6u)
  168. FFF_FAKES_LIST(RESET_FAKE)
  169. PRESS_BUTTON(UP)
  170. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 6u)
  171. /* back down again */
  172. FFF_FAKES_LIST(RESET_FAKE)
  173. PRESS_BUTTON(DOWN)
  174. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 5u)
  175. FFF_FAKES_LIST(RESET_FAKE)
  176. PRESS_BUTTON(DOWN)
  177. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
  178. FFF_FAKES_LIST(RESET_FAKE)
  179. PRESS_BUTTON(DOWN)
  180. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
  181. FFF_FAKES_LIST(RESET_FAKE)
  182. PRESS_BUTTON(DOWN)
  183. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  184. FFF_FAKES_LIST(RESET_FAKE)
  185. PRESS_BUTTON(DOWN)
  186. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
  187. /* end of the buffer - shellmatta shall not update */
  188. FFF_FAKES_LIST(RESET_FAKE)
  189. PRESS_BUTTON(DOWN)
  190. CHECK(writeFct_fake.call_count == 0u);
  191. FFF_FAKES_LIST(RESET_FAKE)
  192. PRESS_BUTTON(DOWN)
  193. CHECK(writeFct_fake.call_count == 0u);
  194. /* up once mothe history buffer with a fixed sequence of commands in therere */
  195. FFF_FAKES_LIST(RESET_FAKE)
  196. PRESS_BUTTON(UP)
  197. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  198. }
  199. }
  200. }
  201. }
  202. SCENARIO("Test how the history buffer handles more commands than fits inside the buffer")
  203. {
  204. GIVEN("An initialized Shellmatte instance with some commands already in the history buffer")
  205. {
  206. shellmatta_instance_t inst;
  207. shellmatta_handle_t handle;
  208. char buffer[1024u];
  209. char historyBuffer[16u];
  210. CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst,
  211. &handle,
  212. buffer,
  213. sizeof(buffer),
  214. historyBuffer,
  215. sizeof(historyBuffer),
  216. "shellmatta->",
  217. NULL,
  218. writeFct));
  219. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd1));
  220. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd2));
  221. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd3));
  222. CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd4));
  223. for(uint32_t i = 0u; i < CMD_SEQ_LEN; i++)
  224. {
  225. CHECK(SHELLMATTA_OK == shellmatta_processData(handle, commandSequence[i], strlen(commandSequence[i])));
  226. }
  227. WHEN("The user pushes the up and down button alternatingly")
  228. {
  229. THEN("The output shall be updated with the correct commands that did fit into the buffer")
  230. {
  231. FFF_FAKES_LIST(RESET_FAKE)
  232. PRESS_BUTTON(UP)
  233. CHECK_FOR_COMMAND(1u, CMD_SEQ_LEN - 1u)
  234. FFF_FAKES_LIST(RESET_FAKE)
  235. PRESS_BUTTON(UP)
  236. CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  237. // FFF_FAKES_LIST(RESET_FAKE)
  238. // PRESS_BUTTON(DOWN)
  239. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
  240. // FFF_FAKES_LIST(RESET_FAKE)
  241. // PRESS_BUTTON(DOWN)
  242. // CHECK(writeFct_fake.call_count == 0u);
  243. // FFF_FAKES_LIST(RESET_FAKE)
  244. // PRESS_BUTTON(DOWN)
  245. // CHECK(writeFct_fake.call_count == 0u);
  246. // FFF_FAKES_LIST(RESET_FAKE)
  247. // PRESS_BUTTON(UP)
  248. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  249. // FFF_FAKES_LIST(RESET_FAKE)
  250. // PRESS_BUTTON(UP)
  251. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
  252. // FFF_FAKES_LIST(RESET_FAKE)
  253. // PRESS_BUTTON(UP)
  254. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
  255. // FFF_FAKES_LIST(RESET_FAKE)
  256. // PRESS_BUTTON(UP)
  257. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
  258. // /* back down again */
  259. // FFF_FAKES_LIST(RESET_FAKE)
  260. // PRESS_BUTTON(DOWN)
  261. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
  262. // FFF_FAKES_LIST(RESET_FAKE)
  263. // PRESS_BUTTON(DOWN)
  264. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  265. // FFF_FAKES_LIST(RESET_FAKE)
  266. // PRESS_BUTTON(DOWN)
  267. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
  268. // /* end of the buffer - shellmatta shall not update */
  269. // FFF_FAKES_LIST(RESET_FAKE)
  270. // PRESS_BUTTON(DOWN)
  271. // CHECK(writeFct_fake.call_count == 0u);
  272. // FFF_FAKES_LIST(RESET_FAKE)
  273. // PRESS_BUTTON(DOWN)
  274. // CHECK(writeFct_fake.call_count == 0u);
  275. // /* up once mothe history buffer with a fixed sequence of commands in therere */
  276. // FFF_FAKES_LIST(RESET_FAKE)
  277. // PRESS_BUTTON(UP)
  278. // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
  279. }
  280. }
  281. }
  282. }