/* * Copyright (c) 2021 - 2024 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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(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_THAT(response, Catch::Matchers::Equals(fakeWriteData)); } } } }