From a5bd5c57aba2e9294b6c68f5b9f120eae8da445f Mon Sep 17 00:00:00 2001 From: prozessorkern Date: Sun, 24 Jan 2021 19:46:12 +0100 Subject: [PATCH] added detailed help function --- api/shellmatta.h | 2 +- makefile | 3 +- src/shellmatta_utils.c | 172 +++++++--- src/shellmatta_utils.h | 20 +- test/integrationtest/test_integration.cpp | 105 ++----- .../integrationtest/test_integration_help.cpp | 296 ++++++++++++++++++ .../test_integration_history.cpp | 14 +- 7 files changed, 470 insertions(+), 142 deletions(-) create mode 100644 test/integrationtest/test_integration_help.cpp diff --git a/api/shellmatta.h b/api/shellmatta.h index 1b3b936..dbabf05 100644 --- a/api/shellmatta.h +++ b/api/shellmatta.h @@ -109,7 +109,7 @@ typedef struct shellmatta_cmd char *cmd; /**< command name */ char *cmdAlias; /**< command alias */ char *helpText; /**< help text to print in "help" command */ - char *usageText; /**< usage text to print on parameter error */ + char *usageText; /**< usage text - printed on "help cmd" */ shellmatta_cmdFct_t cmdFct; /**< pointer to the cmd callack function */ struct shellmatta_cmd *next; /**< pointer to next command or NULL */ } shellmatta_cmd_t; diff --git a/makefile b/makefile index ddb6078..6afd7bb 100644 --- a/makefile +++ b/makefile @@ -49,7 +49,8 @@ INTEGRATIONTEST_SOURCES := test/integrationtest/test_main.cpp test/integrationtest/test_integration_optLong.cpp \ test/integrationtest/test_integration_continue.cpp \ test/integrationtest/test_integration_busy.cpp \ - test/integrationtest/test_integration_history.cpp + test/integrationtest/test_integration_history.cpp \ + test/integrationtest/test_integration_help.cpp UNITTEST_CPPOBJ := $(patsubst %.cpp,$(UNITTEST_OBJ_DIR)%.o,$(UNITTEST_SOURCES)) diff --git a/src/shellmatta_utils.c b/src/shellmatta_utils.c index ce22476..a0beb31 100644 --- a/src/shellmatta_utils.c +++ b/src/shellmatta_utils.c @@ -267,11 +267,48 @@ void utils_clearInput(shellmatta_instance_t *inst) inst->dirty = false; } +/** + * @brief prints the usage information of one passed command + * @param[in] inst handle shellmatta instance handle + * @param[in] cmd pointer to a command structure to print + * @return #SHELLMATTA_OK + * #SHELLMATTA_ERROR + */ +static shellmatta_retCode_t printUsage(const shellmatta_instance_t *inst, const shellmatta_cmd_t *cmd) +{ + shellmatta_retCode_t ret = SHELLMATTA_OK; + + /** -# write the command and alias if configured */ + SHELLMATTA_RET(ret, inst->write("Help for command: ", 18u)); + SHELLMATTA_RET(ret, inst->write(cmd->cmd, strlen(cmd->cmd))); + if((NULL != cmd->cmdAlias) && (0u != strlen(cmd->cmdAlias))) + { + SHELLMATTA_RET(ret, inst->write(" (", 2u)); + SHELLMATTA_RET(ret, inst->write(cmd->cmdAlias, strlen(cmd->cmdAlias))); + SHELLMATTA_RET(ret, inst->write(")", 1u)); + } + /** -# write the help text if configured */ + if((NULL != cmd->helpText) && (0u != strlen(cmd->helpText))) + { + SHELLMATTA_RET(ret, inst->write("\r\n\r\n", 4u)); + SHELLMATTA_RET(ret, inst->write(cmd->helpText, strlen(cmd->helpText))); + } + /** -# write the usage text if configured */ + if((NULL != cmd->usageText) && (0u != strlen(cmd->usageText))) + { + SHELLMATTA_RET(ret, inst->write("\r\n\r\nUsage: \r\n", 13u)); + SHELLMATTA_RET(ret, inst->write(cmd->usageText, strlen(cmd->usageText))); + } + SHELLMATTA_RET(ret, inst->write("\r\n", 2u)); + + return ret; +} + /** * @brief prints all possible commands with description and usage * @param[in] handle handle shellmatta instance handle - * @param[in] arguments not used here - * @param[in] length not used here + * @param[in] arguments arguments containing a command name or alias + * @param[in] length length of the arguments * @return #SHELLMATTA_OK * #SHELLMATTA_ERROR (buffer overflow) */ @@ -279,72 +316,113 @@ static shellmatta_retCode_t helpCmdFct(const shellmatta_handle_t handle, const c { shellmatta_retCode_t ret = SHELLMATTA_OK; const shellmatta_instance_t *inst = (const shellmatta_instance_t*) handle; - shellmatta_cmd_t *cmd = inst->cmdList; + shellmatta_cmd_t *cmd = NULL; size_t maxCmdLen = 0u; size_t maxCmdAliasLen = 0u; - size_t maxCmdHelpLen = 0u; - size_t cmdLen; + size_t cmdLen = 0u; + const char *subCmd = NULL; size_t cmdAliasLen; - size_t cmdHelpLen; uint32_t tabCnt; + uint32_t i; static const char tabBuffer[] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; - /** -# loop through all commands to determine the lengths of each cmd */ - while(NULL != cmd) + /** -# check if help is called with a command - find first space */ + for(i = 1u; i < length; i ++) { - maxCmdLen = SHELLMATTA_MAX(maxCmdLen, strlen(cmd->cmd)); - if(NULL != cmd->cmdAlias) + if(' ' == arguments[i - 1]) { - maxCmdAliasLen = SHELLMATTA_MAX(maxCmdAliasLen, strlen(cmd->cmdAlias)); + subCmd = &(arguments[i]); + + /** -# determine subcommand length*/ + cmdLen = 0u; + while( ((i + cmdLen) < length) + && (' ' != arguments[i + cmdLen]) + && ('\r' != arguments[i + cmdLen]) + && ('\n' != arguments[i + cmdLen]) + && ('\0' != arguments[i + cmdLen])) + { + cmdLen ++; + } + break; } - if(NULL != cmd->helpText) - { - maxCmdHelpLen = SHELLMATTA_MAX(maxCmdHelpLen, strlen(cmd->helpText)); - } - cmd = cmd->next; } - /** -# loop through all commands and print all possible information */ - cmd = inst->cmdList; - while(NULL != cmd) + /* print detailled help */ + if(NULL != subCmd) { - /** -# determine the length of each field to add padding */ - cmdLen = strlen(cmd->cmd); - cmdAliasLen = (NULL != cmd->cmdAlias) ? strlen(cmd->cmdAlias) : 0u; - cmdHelpLen = (NULL != cmd->helpText) ? strlen(cmd->helpText) : 0u; + cmd = inst->cmdList; - inst->write(cmd->cmd, strlen(cmd->cmd)); - tabCnt = (maxCmdLen - cmdLen) + 2u; - SHELLMATTA_PRINT_BUFFER(tabBuffer, tabCnt, inst->write); - - if(NULL != cmd->cmdAlias) + /** -# search for a matching command */ + while (NULL != cmd) { - inst->write(cmd->cmdAlias, cmdAliasLen); - } - tabCnt = (maxCmdAliasLen - cmdAliasLen) + 2u; - SHELLMATTA_PRINT_BUFFER(tabBuffer, tabCnt, inst->write); + /** -# compare command and alias string and length */ + if ( ((cmdLen == strlen(cmd->cmd)) + && (0 == strncmp(subCmd, cmd->cmd, cmdLen))) + || ((NULL != cmd->cmdAlias) + && (cmdLen == strlen(cmd->cmdAlias)) + && (0 == strncmp(subCmd, cmd->cmdAlias, cmdLen)))) + { + SHELLMATTA_RET(ret, printUsage(inst, cmd)); + break; + } - if(NULL != cmd->helpText) - { - inst->write(cmd->helpText, cmdHelpLen); + cmd = cmd->next; } - tabCnt = (maxCmdHelpLen - cmdHelpLen) + 2u; - SHELLMATTA_PRINT_BUFFER(tabBuffer, tabCnt, inst->write); - - if(NULL != cmd->usageText) - { - inst->write(cmd->usageText, strlen(cmd->usageText)); - } - inst->write("\r\n", 2u); - - cmd = cmd->next; } - (void)arguments; - (void)length; + /** -# print help list if no sub cmd was found */ + if(NULL == cmd) + { + /** -# loop through all commands to determine the lengths of each cmd */ + cmd = inst->cmdList; + while(NULL != cmd) + { + maxCmdLen = SHELLMATTA_MAX(maxCmdLen, strlen(cmd->cmd)); + if(NULL != cmd->cmdAlias) + { + maxCmdAliasLen = SHELLMATTA_MAX(maxCmdAliasLen, strlen(cmd->cmdAlias)); + } + cmd = cmd->next; + } + + /** -# loop through all commands and print all possible information */ + cmd = inst->cmdList; + while(NULL != cmd) + { + /** -# determine the length of each field to add padding */ + cmdLen = strlen(cmd->cmd); + cmdAliasLen = (NULL != cmd->cmdAlias) ? strlen(cmd->cmdAlias) : 0u; + + SHELLMATTA_RET(ret, inst->write(cmd->cmd, strlen(cmd->cmd))); + tabCnt = (maxCmdLen - cmdLen) + 2u; + + /** -# add padding if there is anything to be printed afterwards */ + if( ((NULL != cmd->cmdAlias) && (0u != strlen(cmd->cmdAlias))) + || ((NULL != cmd->helpText) && (0u != strlen(cmd->helpText)))) + { + SHELLMATTA_PRINT_BUFFER(tabBuffer, tabCnt, inst->write); + } + + if((NULL != cmd->cmdAlias) && (0u != strlen(cmd->cmdAlias))) + { + SHELLMATTA_RET(ret, inst->write(cmd->cmdAlias, cmdAliasLen)); + } + tabCnt = (maxCmdAliasLen - cmdAliasLen) + 2u; + + if((NULL != cmd->helpText) && (0u != strlen(cmd->helpText))) + { + SHELLMATTA_PRINT_BUFFER(tabBuffer, tabCnt, inst->write); + SHELLMATTA_RET(ret, inst->write(cmd->helpText, strlen(cmd->helpText))); + } + + SHELLMATTA_RET(ret, inst->write("\r\n", 2u)); + + cmd = cmd->next; + } + } return ret; } diff --git a/src/shellmatta_utils.h b/src/shellmatta_utils.h index 917356e..9749f36 100644 --- a/src/shellmatta_utils.h +++ b/src/shellmatta_utils.h @@ -36,6 +36,13 @@ */ #define SHELLMATTA_MAX(a,b) (((a) < (b)) ? (b) : (a)) +/** + * @brief sums up #shellmatta_retCode_t + * @param[in] ret return variable + * @param[in] expression expression with the return value + */ +#define SHELLMATTA_RET(ret, expression) (ret) = (SHELLMATTA_OK != (expression)) ? SHELLMATTA_ERROR : (ret) + /** * @brief calls fct with cnt bytes from buffer (to print cnt same bytes) * @param[in] buffer buffer to send (shall contain the same char) @@ -76,16 +83,21 @@ extern const shellmatta_cmd_t helpCmd; * e.g. use _-DSHELLMATTA_HELP_ALIAS=\"?\"_ as compile option to change the alias to ? */ #ifndef SHELLMATTA_HELP_COMMAND -#define SHELLMATTA_HELP_COMMAND (char*)"help" /**< help command */ +/** \brief help command */ +#define SHELLMATTA_HELP_COMMAND (char*)"help" #endif #ifndef SHELLMATTA_HELP_ALIAS -#define SHELLMATTA_HELP_ALIAS (char*)"h" /**< help command alias */ +/** \brief help command alias */ +#define SHELLMATTA_HELP_ALIAS (char*)"h" #endif #ifndef SHELLMATTA_HELP_HELP_TEXT -#define SHELLMATTA_HELP_HELP_TEXT (char*)"Print this help text" /**< help command help text */ +/** \brief help command help text */ +#define SHELLMATTA_HELP_HELP_TEXT (char*)"help [command] - print help or usage information" #endif #ifndef SHELLMATTA_HELP_USAGE_TEXT -#define SHELLMATTA_HELP_USAGE_TEXT (char*)"help" /**< help command usage text */ +/** \brief help command usage text */ +#define SHELLMATTA_HELP_USAGE_TEXT (char*) "help [command]\r\n" \ + "\tcommand: optional command name or alias to print detailled help for" #endif /** * @} diff --git a/test/integrationtest/test_integration.cpp b/test/integrationtest/test_integration.cpp index 8514704..e7a72e0 100644 --- a/test/integrationtest/test_integration.cpp +++ b/test/integrationtest/test_integration.cpp @@ -88,71 +88,6 @@ TEST_CASE( "shellmatta empty function" ) { } -TEST_CASE( "shellmatta help function" ) { - - shellmatta_instance_t inst; - shellmatta_handle_t handle; - char buffer[1024]; - char historyBuffer[1024]; - char *dummyData = (char*)"?\r\n" - "doSomething do Function does something use me, please\r\n" - "empty \r\n" - "help ? Print this help text help\r\n" - "\r\nshellmatta->"; - - shellmatta_doInit( &inst, - &handle, - buffer, - sizeof(buffer), - historyBuffer, - sizeof(historyBuffer), - "shellmatta->", - NULL, - writeFct); - shellmatta_addCmd(handle, &emptyCmd); - shellmatta_addCmd(handle, &doSomethingCmd); - - write_callCnt = 0u; - memset(write_data, 0, sizeof(write_data)); - write_length = 0u; - - shellmatta_processData(handle, (char*)"?\r", 2); - - CHECK( write_length == strlen(dummyData)); - CHECK( strcmp(dummyData, write_data) == 0); - - write_callCnt = 0u; - memset(write_data, 0, sizeof(write_data)); - write_length = 0u; - - dummyData = (char*)"? 564 321 56 465 46\r\n" - "doSomething do Function does something use me, please\r\n" - "empty \r\n" - "help ? Print this help text help\r\n" - "\r\nshellmatta->"; - - shellmatta_processData(handle, (char*)"? 564 321 56 465 46\r", 20); - - CHECK( write_length == strlen(dummyData)); - CHECK( strcmp(dummyData, write_data) == 0); - - - write_callCnt = 0u; - memset(write_data, 0, sizeof(write_data)); - write_length = 0u; - - dummyData = (char*)"?r\r\n" - "Command: ?r not found" - "\r\nshellmatta->"; - - shellmatta_processData(handle, (char*)"?r\r", 3); - - CHECK( write_length == 39u); - REQUIRE( strcmp(dummyData, write_data) == 0); -} - - - TEST_CASE( "shellmatta heredoc test" ) { shellmatta_instance_t inst; @@ -228,8 +163,8 @@ TEST_CASE( "shellmatta remove function" ) { char buffer[1024]; char historyBuffer[1024]; char *dummyData = (char*)"?\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, @@ -249,7 +184,7 @@ TEST_CASE( "shellmatta remove function" ) { shellmatta_processData(handle, (char*)"?\r", 2); - CHECK( write_length == 123u); + CHECK( write_length == strlen(dummyData)); CHECK( strcmp(dummyData, write_data) == 0); @@ -258,13 +193,13 @@ TEST_CASE( "shellmatta remove function" ) { write_length = 0u; dummyData = (char*)"? 564 321 56 465 46\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_processData(handle, (char*)"? 564 321 56 465 46\r", 20); - CHECK( write_length == 141u); + CHECK( write_length == strlen(dummyData)); CHECK( strcmp(dummyData, write_data) == 0); write_callCnt = 0u; @@ -275,10 +210,10 @@ TEST_CASE( "shellmatta remove function" ) { shellmatta_processData(handle, (char*)"? 564 321 56 465 46\r", 20); dummyData = (char*)"? 564 321 56 465 46\r\n" - "help ? Print this help text help\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; - CHECK( write_length == 72u); + CHECK( write_length == strlen(dummyData)); REQUIRE( strcmp(dummyData, write_data) == 0); } @@ -289,8 +224,8 @@ TEST_CASE( "shellmatta reset no prompt" ) { char buffer[1024]; char historyBuffer[1024]; char *dummyData = (char*)"dkfg hdlsfkgh ldksfjhg lkdjfsh glkd?\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, @@ -324,8 +259,8 @@ TEST_CASE( "shellmatta reset with prompt" ) { char historyBuffer[1024]; char *dummyData = (char*)"dkfg hdlsfkgh ldksfjhg lkdjfsh glkd" "\r\nshellmatta->?\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, @@ -358,8 +293,8 @@ TEST_CASE( "shellmatta reset no prompt history buffer" ) { char buffer[1024]; char historyBuffer[1024]; char *dummyData = (char*)"?\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, @@ -398,8 +333,8 @@ TEST_CASE( "shellmatta reset no prompt heredoc" ) { char buffer[1024]; char historyBuffer[1024]; char *dummyData = (char*)"?\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, @@ -439,12 +374,12 @@ TEST_CASE( "shellmatta configure disable echo" ) { char buffer[1024]; char historyBuffer[1024]; char *dummyData = (char*)"help this is some dummy Text\r\n" - "doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + "doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; - char *dummyData2 = (char*)"doSomething do Function does something use me, please\r\n" - "help ? Print this help text help\r\n" + char *dummyData2 = (char*)"doSomething do Function does something\r\n" + "help ? help [command] - print help or usage information\r\n" "\r\nshellmatta->"; shellmatta_doInit( &inst, diff --git a/test/integrationtest/test_integration_help.cpp b/test/integrationtest/test_integration_help.cpp new file mode 100644 index 0000000..e120ffc --- /dev/null +++ b/test/integrationtest/test_integration_help.cpp @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2021 Stefan Strobel + * + * 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_help.cpp + * @brief integration test implementation for the help command of the shellmatta + * @author Stefan Strobel + */ + +#include "test/framework/catch.hpp" +extern "C" { +#include "test/framework/fff.h" +#include "shellmatta.h" +} +#include + +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) + +static char fakeWriteData[1024]; +static uint32_t fakeWriteLength; +static shellmatta_retCode_t writeFct_customFake(const char* data, uint32_t length) +{ + while((length > 0) && (fakeWriteLength < sizeof(fakeWriteData))) + { + fakeWriteData[fakeWriteLength] = *data; + data ++; + length --; + fakeWriteLength ++; + } + + return SHELLMATTA_OK; +} + +/* List of fakes */ +#define FFF_FAKES_LIST(FAKE) \ + FAKE(writeFct) \ + FAKE(cmdFct1) \ + FAKE(cmdFct2) \ + FAKE(cmdFct3) + +#define PROCESS_INPUT(input) \ + CHECK(SHELLMATTA_OK == shellmatta_processData(handle, (char*)(input), sizeof((input)) - 1u)); + +static shellmatta_cmd_t cmd1 = {(char*)"cmd1", (char*)"1", (char*)"cmd1 [options]", (char*)"cmd1 usage\r\n--option, -o: option", cmdFct1, NULL}; +static shellmatta_cmd_t cmd2 = {(char*)"cmd2", NULL, NULL, NULL, cmdFct2, NULL}; +static shellmatta_cmd_t cmd3 = {(char*)"cmd3", (char*)"", (char*)"", (char*)"", cmdFct3, NULL}; + +SCENARIO("Test the help function") +{ + GIVEN("An initialized and empty Shellmatte instance") + { + 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)); + + WHEN("The user hits help") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help\r\n") + + THEN("The shellmatta prints the help text") + { + static const char * response = (char*) "help\r\n" + "cmd1 1 cmd1 [options]\r\n" + "cmd2\r\n" + "cmd3\r\n" + "help ? help [command] - print help or usage information\r\n\r\n" + "shellmatta->"; + CHECK(writeFct_fake.call_count == 23); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + WHEN("The user hits ?") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("?\r\n") + + THEN("The shellmatta prints the help text") + { + static const char * response = (char*) "?\r\n" + "cmd1 1 cmd1 [options]\r\n" + "cmd2\r\n" + "cmd3\r\n" + "help ? help [command] - print help or usage information\r\n\r\n" + "shellmatta->"; + CHECK(writeFct_fake.call_count == 20); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + } +} + +SCENARIO("Test if the help command prints the usage correctly") +{ + GIVEN("An initialized and empty Shellmatte instance") + { + 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)); + + WHEN("The user requests usage information from a valid command") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help cmd1\r\n") + + THEN("The shellmatta prints the help text") + { + static const char * response = (char*) "help cmd1\r\n" + "Help for command: cmd1 (1)\r\n\r\n" + "cmd1 [options]\r\n\r\n" + "Usage: \r\n" + "cmd1 usage\r\n--option, -o: option\r\n" + "\r\nshellmatta->"; + CHECK(writeFct_fake.call_count == 22); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + WHEN("The user requests usage information from a valid command using its alias") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help 1\r\n") + + THEN("The shellmatta prints the help text") + { + static const char * response = (char*) "help 1\r\n" + "Help for command: cmd1 (1)\r\n\r\n" + "cmd1 [options]\r\n\r\n" + "Usage: \r\n" + "cmd1 usage\r\n--option, -o: option\r\n" + "\r\nshellmatta->"; + CHECK(writeFct_fake.call_count == 19); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + WHEN("The user requests usage information from an empty command") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help cmd2\r\n") + + THEN("The shellmatta prints the help text - without alias, help and usage text") + { + static const char * response = (char*) "help cmd2\r\n" + "Help for command: cmd2\r\n" + "\r\nshellmatta->"; + CHECK(writeFct_fake.call_count == 15); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + + WHEN("The user requests usage information from an empty stringed command") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help cmd3\r\n") + + THEN("The shellmatta prints the help text - without alias, help and usage text") + { + static const char * response = (char*) "help cmd3\r\n" + "Help for command: cmd3\r\n" + "\r\nshellmatta->"; + CHECK(writeFct_fake.call_count == 15); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + WHEN("The user adds additional arguments to the help command") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help cmd2 foo bar meow this is nonsense\r\n") + + THEN("The shellmatta ignores the superflous arguments") + { + static const char * response = (char*) "help cmd2 foo bar meow this is nonsense\r\n" + "Help for command: cmd2\r\n" + "\r\nshellmatta->"; + CHECK(writeFct_fake.call_count == 45); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + + WHEN("The user requests help of a nonexisting command") + { + FFF_FAKES_LIST(RESET_FAKE) + fakeWriteLength = 0u; + memset(fakeWriteData, 0, sizeof(fakeWriteData)); + + shellmatta_write_t writeCustomFakeSeq[1] = {writeFct_customFake}; + SET_CUSTOM_FAKE_SEQ(writeFct, writeCustomFakeSeq, 1) + + PROCESS_INPUT("help cmd4\r\n") + + THEN("The shellmatta prints the help list") + { + static const char * response = (char*) "help cmd4\r\n" + "cmd1 1 cmd1 [options]\r\n" + "cmd2\r\n" + "cmd3\r\n" + "help ? help [command] - print help or usage information\r\n\r\n" + "shellmatta->"; + CHECK(writeFct_fake.call_count == 28); + CHECK(strlen(response) == fakeWriteLength); + CHECK(0 == strcmp(response, fakeWriteData)); + } + } + } +} diff --git a/test/integrationtest/test_integration_history.cpp b/test/integrationtest/test_integration_history.cpp index 3b13b19..9f167c2 100644 --- a/test/integrationtest/test_integration_history.cpp +++ b/test/integrationtest/test_integration_history.cpp @@ -43,10 +43,10 @@ FAKE_VALUE_FUNC(shellmatta_retCode_t, cmdFct4, shellmatta_handle_t, const char * #define PROCESS_INPUT(input) \ CHECK(SHELLMATTA_OK == shellmatta_processData(handle, (char*)(input), sizeof((input)) - 1u)); -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}; +static shellmatta_cmd_t cmd1 = {(char*)"cmd1", (char*)"1", NULL, NULL, cmdFct1, NULL}; +static shellmatta_cmd_t cmd2 = {(char*)"cmd2", (char*)"2", NULL, NULL, cmdFct2, NULL}; +static shellmatta_cmd_t cmd3 = {(char*)"cmd3", (char*)"3", NULL, NULL, cmdFct3, NULL}; +static shellmatta_cmd_t cmd4 = {(char*)"cmd4", (char*)"4", NULL, NULL, cmdFct4, NULL}; char *commandSequence[] = { @@ -69,6 +69,8 @@ SCENARIO("Test the history buffer with a fixed sequence of commands in there") char buffer[1024u]; char historyBuffer[1024u]; + FFF_FAKES_LIST(RESET_FAKE) + CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst, &handle, buffer, @@ -249,6 +251,8 @@ SCENARIO("Test how the history buffer handles more commands than fits inside the char buffer[1024u]; char historyBuffer[16u] = {0}; + FFF_FAKES_LIST(RESET_FAKE) + CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst, &handle, buffer, @@ -355,6 +359,8 @@ SCENARIO("Test if the history buffer stores changes done during navigating") char buffer[1024u]; char historyBuffer[16u] = {0}; + FFF_FAKES_LIST(RESET_FAKE) + CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst, &handle, buffer,