|
@@ -0,0 +1,342 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright (c) 2021 Stefan Strobel <stefan.strobel@shimatta.net>
|
|
|
|
+ *
|
|
|
|
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @file test_integration_optLong.cpp
|
|
|
|
+ * @brief integration test implementation for the history buffer of the shellmatta
|
|
|
|
+ * @author Stefan Strobel <stefan.strobel@shimatta.net>
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include "test/framework/catch.hpp"
|
|
|
|
+extern "C" {
|
|
|
|
+#include "test/framework/fff.h"
|
|
|
|
+#include "shellmatta.h"
|
|
|
|
+}
|
|
|
|
+#include <string.h>
|
|
|
|
+
|
|
|
|
+FAKE_VALUE_FUNC(shellmatta_retCode_t, writeFct, const char *, uint32_t)
|
|
|
|
+FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct1, shellmatta_handle_t, const char *, uint32_t)
|
|
|
|
+FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct2, shellmatta_handle_t, const char *, uint32_t)
|
|
|
|
+FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct3, shellmatta_handle_t, const char *, uint32_t)
|
|
|
|
+FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct4, shellmatta_handle_t, const char *, uint32_t)
|
|
|
|
+
|
|
|
|
+/* List of fakes */
|
|
|
|
+#define FFF_FAKES_LIST(FAKE) \
|
|
|
|
+ FAKE(writeFct) \
|
|
|
|
+ FAKE(cmdFct1) \
|
|
|
|
+ FAKE(cmdFct2) \
|
|
|
|
+ FAKE(cmdFct3) \
|
|
|
|
+ FAKE(cmdFct4)
|
|
|
|
+
|
|
|
|
+#define CHECK_FOR_COMMAND(hist, idx) \
|
|
|
|
+ CHECK(writeFct_fake.call_count == ((hist) + 1u)); \
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[(hist)], commandSequence[(idx)], strlen(commandSequence[(idx)]) - 1)); \
|
|
|
|
+ CHECK((strlen(commandSequence[(idx)]) - 1) == writeFct_fake.arg1_history[(hist)]);
|
|
|
|
+
|
|
|
|
+#define UP "\x1b" "[A"
|
|
|
|
+#define DOWN "\x1b" "[B"
|
|
|
|
+#define PRESS_BUTTON(button) \
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_processData(handle, (char*)(button), 3u));
|
|
|
|
+
|
|
|
|
+shellmatta_cmd_t cmd1 = {(char*)"cmd1", (char*)"1", NULL, NULL, cmdFct1, NULL};
|
|
|
|
+shellmatta_cmd_t cmd2 = {(char*)"cmd2", (char*)"2", NULL, NULL, cmdFct2, NULL};
|
|
|
|
+shellmatta_cmd_t cmd3 = {(char*)"cmd3", (char*)"3", NULL, NULL, cmdFct3, NULL};
|
|
|
|
+shellmatta_cmd_t cmd4 = {(char*)"cmd4", (char*)"4", NULL, NULL, cmdFct4, NULL};
|
|
|
|
+
|
|
|
|
+char *commandSequence[] =
|
|
|
|
+{
|
|
|
|
+ (char*)"foo\r",
|
|
|
|
+ (char*)"bar\r",
|
|
|
|
+ (char*)"cmd1\r",
|
|
|
|
+ (char*)"2\r",
|
|
|
|
+ (char*)"4\r",
|
|
|
|
+ (char*)"cmd3\r"
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#define CMD_SEQ_LEN (sizeof(commandSequence) / sizeof(commandSequence[0]))
|
|
|
|
+
|
|
|
|
+SCENARIO("Test the history buffer with a fixed sequence of commands in there")
|
|
|
|
+{
|
|
|
|
+ GIVEN("An initialized Shellmatte instance with some commands already in the history buffer")
|
|
|
|
+ {
|
|
|
|
+ shellmatta_instance_t inst;
|
|
|
|
+ shellmatta_handle_t handle;
|
|
|
|
+ char buffer[1024u];
|
|
|
|
+ char historyBuffer[1024u];
|
|
|
|
+
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst,
|
|
|
|
+ &handle,
|
|
|
|
+ buffer,
|
|
|
|
+ sizeof(buffer),
|
|
|
|
+ historyBuffer,
|
|
|
|
+ sizeof(historyBuffer),
|
|
|
|
+ "shellmatta->",
|
|
|
|
+ NULL,
|
|
|
|
+ writeFct));
|
|
|
|
+
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd1));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd2));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd3));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd4));
|
|
|
|
+
|
|
|
|
+ for(uint32_t i = 0u; i < CMD_SEQ_LEN; i++)
|
|
|
|
+ {
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_processData(handle, commandSequence[i], strlen(commandSequence[i])));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WHEN("The up button is pressed")
|
|
|
|
+ {
|
|
|
|
+ THEN("The shellmatta prints the most recent command")
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+
|
|
|
|
+ CHECK(writeFct_fake.call_count == 2);
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[0], "\x1b" "[K", 3));
|
|
|
|
+ CHECK(3 == writeFct_fake.arg1_history[0]);
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[1], commandSequence[CMD_SEQ_LEN - 1], strlen(commandSequence[CMD_SEQ_LEN - 1]) - 1));
|
|
|
|
+ CHECK((strlen(commandSequence[CMD_SEQ_LEN - 1]) - 1) == writeFct_fake.arg1_history[1]);
|
|
|
|
+
|
|
|
|
+ for(uint32_t i = CMD_SEQ_LEN - 1; i > 0; i--)
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+
|
|
|
|
+ CHECK(writeFct_fake.call_count == 3);
|
|
|
|
+
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[1], "\x1b" "[K", 3));
|
|
|
|
+ CHECK(3 == writeFct_fake.arg1_history[1]);
|
|
|
|
+
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[2], commandSequence[i - 1u], strlen(commandSequence[i - 1u]) - 1));
|
|
|
|
+ CHECK((strlen(commandSequence[i - 1u]) - 1) == writeFct_fake.arg1_history[2]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WHEN("The history buffer it at the oldest command yet")
|
|
|
|
+ {
|
|
|
|
+ for(uint32_t i = CMD_SEQ_LEN; i > 0; i--)
|
|
|
|
+ {
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ AND_WHEN("The up button is pressed again")
|
|
|
|
+ {
|
|
|
|
+ THEN("The output is deleted and the oldest command is printed again")
|
|
|
|
+ {
|
|
|
|
+ for(uint32_t i = 0u; i < 64; i++)
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, 0u)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ AND_WHEN("The down button is pressed")
|
|
|
|
+ {
|
|
|
|
+ THEN("On each button press one newer command is printed")
|
|
|
|
+ {
|
|
|
|
+ for(uint32_t i = 1; i < CMD_SEQ_LEN; i++)
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK(0 == memcmp(writeFct_fake.arg0_history[1], "\x1b" "[K", 3));
|
|
|
|
+ CHECK(3 == writeFct_fake.arg1_history[1]);
|
|
|
|
+ CHECK_FOR_COMMAND(2u, i)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WHEN("The user pushes the up and down button alternatingly")
|
|
|
|
+ {
|
|
|
|
+ THEN("The output shall be updated with the correct command or not updated at all when at the end")
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(1u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 5u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 6u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 6u)
|
|
|
|
+
|
|
|
|
+ /* back down again */
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 5u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ /* end of the buffer - shellmatta shall not update */
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(DOWN)
|
|
|
|
+ CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ /* up once mothe history buffer with a fixed sequence of commands in therere */
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+SCENARIO("Test how the history buffer handles more commands than fits inside the buffer")
|
|
|
|
+{
|
|
|
|
+ GIVEN("An initialized Shellmatte instance with some commands already in the history buffer")
|
|
|
|
+ {
|
|
|
|
+ shellmatta_instance_t inst;
|
|
|
|
+ shellmatta_handle_t handle;
|
|
|
|
+ char buffer[1024u];
|
|
|
|
+ char historyBuffer[16u];
|
|
|
|
+
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst,
|
|
|
|
+ &handle,
|
|
|
|
+ buffer,
|
|
|
|
+ sizeof(buffer),
|
|
|
|
+ historyBuffer,
|
|
|
|
+ sizeof(historyBuffer),
|
|
|
|
+ "shellmatta->",
|
|
|
|
+ NULL,
|
|
|
|
+ writeFct));
|
|
|
|
+
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd1));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd2));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd3));
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_addCmd(handle, &cmd4));
|
|
|
|
+
|
|
|
|
+ for(uint32_t i = 0u; i < CMD_SEQ_LEN; i++)
|
|
|
|
+ {
|
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_processData(handle, commandSequence[i], strlen(commandSequence[i])));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WHEN("The user pushes the up and down button alternatingly")
|
|
|
|
+ {
|
|
|
|
+ THEN("The output shall be updated with the correct commands that did fit into the buffer")
|
|
|
|
+ {
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(1u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ PRESS_BUTTON(UP)
|
|
|
|
+ CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(UP)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(UP)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(UP)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(UP)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 4u)
|
|
|
|
+
|
|
|
|
+ // /* back down again */
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 3u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 1u)
|
|
|
|
+
|
|
|
|
+ // /* end of the buffer - shellmatta shall not update */
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(DOWN)
|
|
|
|
+ // CHECK(writeFct_fake.call_count == 0u);
|
|
|
|
+
|
|
|
|
+ // /* up once mothe history buffer with a fixed sequence of commands in therere */
|
|
|
|
+ // FFF_FAKES_LIST(RESET_FAKE)
|
|
|
|
+ // PRESS_BUTTON(UP)
|
|
|
|
+ // CHECK_FOR_COMMAND(2u, CMD_SEQ_LEN - 2u)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|