diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 907772e477..ea695f962a 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -18,7 +18,6 @@ ev_add_module(PacketSniffer) ev_add_module(PersistentStore) ev_add_module(PN532TokenProvider) ev_add_module(PyEvJosev) -ev_add_module(PySlacLoopback) ev_add_module(Setup) ev_add_module(SerialCommHub) ev_add_module(Store) diff --git a/modules/EvManager/EvManager.hpp b/modules/EvManager/EvManager.hpp index 46962e39bd..b92f4a0b98 100644 --- a/modules/EvManager/EvManager.hpp +++ b/modules/EvManager/EvManager.hpp @@ -41,7 +41,7 @@ struct Conf { int dc_discharge_max_power_limit; int dc_discharge_target_current; int dc_discharge_v2g_minimal_soc; - double max_curent; + double max_current; bool three_phases; }; diff --git a/modules/EvManager/main/RegisteredCommand.hpp b/modules/EvManager/main/RegisteredCommand.hpp index 5c46730e4a..2342e9a742 100644 --- a/modules/EvManager/main/RegisteredCommand.hpp +++ b/modules/EvManager/main/RegisteredCommand.hpp @@ -1,12 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest -#ifndef TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP -#define TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP +#pragma once #include #include -#include #include #include #include @@ -19,7 +17,7 @@ template class RegisteredCommand; class RegisteredCommandBase { public: RegisteredCommandBase() = default; - virtual ~RegisteredCommandBase(){}; + virtual ~RegisteredCommandBase() = default; RegisteredCommandBase(const RegisteredCommandBase&) = default; RegisteredCommandBase& operator=(const RegisteredCommandBase&) = default; RegisteredCommandBase(RegisteredCommandBase&&) = default; @@ -34,8 +32,14 @@ class RegisteredCommandBase { commandName, argumentCount, std::forward(function))); } - static const RegisteredCommandBase& getRegisteredCommand(const std::string& commandName) { - return *registeredCommands.at(commandName).get(); + static const RegisteredCommandBase* getRegisteredCommand(const std::string& commandName) { + + try { + const auto& registeredCommand = registeredCommands.at(commandName); + return registeredCommand.get(); + } catch (const std::out_of_range&) { + throw std::invalid_argument{"Command not found"}; + } } private: @@ -51,7 +55,7 @@ template class RegisteredCommand : public RegisteredCommand ~RegisteredCommand() override = default; bool operator()(const std::vector& arguments) const override { - if (!arguments.empty() && arguments.size() != argumentCount) { + if (arguments.size() != argumentCount) { throw std::invalid_argument{"Invalid number of arguments"}; } return function(arguments); @@ -62,6 +66,4 @@ template class RegisteredCommand : public RegisteredCommand std::size_t argumentCount; FunctionT function; }; -} // namespace module::main - -#endif \ No newline at end of file +} // namespace module::main \ No newline at end of file diff --git a/modules/EvManager/main/SimCommand.cpp b/modules/EvManager/main/SimCommand.cpp index fd54507343..cbbc8494be 100644 --- a/modules/EvManager/main/SimCommand.cpp +++ b/modules/EvManager/main/SimCommand.cpp @@ -2,17 +2,22 @@ // Copyright Pionix GmbH and Contributors to EVerest #include "SimCommand.hpp" +#include "RegisteredCommand.hpp" #include #include #include namespace module::main { -SimCommand::SimCommand(std::string commandName, std::vector arguments) : +SimCommand::SimCommand(std::string&& commandName, std::vector&& arguments) : arguments{std::move(arguments)}, registeredCommand{RegisteredCommandBase::getRegisteredCommand(commandName)} { } -bool SimCommand::execute() { - return registeredCommand(arguments); +SimCommand::SimCommand(const std::string& commandName, const std::vector& arguments) : + arguments{arguments}, registeredCommand{RegisteredCommandBase::getRegisteredCommand(commandName)} { +} + +bool SimCommand::execute() const { + return (*registeredCommand)(arguments); } } // namespace module::main diff --git a/modules/EvManager/main/SimCommand.hpp b/modules/EvManager/main/SimCommand.hpp index 17afaf1579..335e785261 100644 --- a/modules/EvManager/main/SimCommand.hpp +++ b/modules/EvManager/main/SimCommand.hpp @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest -#ifndef TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP -#define TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP +#pragma once +#include "RegisteredCommand.hpp" #include #include #include @@ -15,20 +15,17 @@ namespace module::main { -class RegisteredCommandBase; - class SimCommand { public: - SimCommand(std::string commandName, std::vector arguments); + SimCommand(std::string&& commandName, std::vector&& arguments); + SimCommand(const std::string& commandName, const std::vector& arguments); - bool execute(); + bool execute() const; private: std::vector arguments; - const RegisteredCommandBase& registeredCommand; + const RegisteredCommandBase* registeredCommand; }; } // namespace module::main - -#endif // TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP diff --git a/modules/EvManager/main/SimData.hpp b/modules/EvManager/main/SimData.hpp index 4471316061..b5a1f24e65 100644 --- a/modules/EvManager/main/SimData.hpp +++ b/modules/EvManager/main/SimData.hpp @@ -1,8 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest -#ifndef EVEREST_CORE_SIMDATA_HPP -#define EVEREST_CORE_SIMDATA_HPP +#pragma once #include "SimCommand.hpp" #include "generated/types/board_support_common.hpp" @@ -55,8 +54,6 @@ struct SimData { types::board_support_common::Event actualBspEvent{}; - - std::queue commandQueue; }; @@ -73,5 +70,3 @@ std::queue compileCommands(std::vector>>& commandsWithArguments); } // namespace module::main - -#endif // EVEREST_CORE_SIMDATA_HPP diff --git a/modules/EvManager/main/car_simulatorImpl.cpp b/modules/EvManager/main/car_simulatorImpl.cpp index 20884f8fb1..07b039d96b 100644 --- a/modules/EvManager/main/car_simulatorImpl.cpp +++ b/modules/EvManager/main/car_simulatorImpl.cpp @@ -529,7 +529,7 @@ void car_simulatorImpl::setupEVParameters() { void car_simulatorImpl::callEVBoardSupportFunctions() { mod->r_ev_board_support->call_allow_power_on(false); - mod->r_ev_board_support->call_set_ac_max_current(mod->config.max_curent); + mod->r_ev_board_support->call_set_ac_max_current(mod->config.max_current); mod->r_ev_board_support->call_set_three_phases(mod->config.three_phases); } void car_simulatorImpl::subscribeToExternalMQTT() { diff --git a/modules/EvManager/manifest.yaml b/modules/EvManager/manifest.yaml index f12e14cacc..979c9407cf 100644 --- a/modules/EvManager/manifest.yaml +++ b/modules/EvManager/manifest.yaml @@ -63,7 +63,7 @@ config: description: Discharge minimal soc at which the evse should shutdown type: integer default: 20 - max_curent: + max_current: description: Ac max current in Ampere type: number default: 16 diff --git a/modules/EvManager/tests/CMakeLists.txt b/modules/EvManager/tests/CMakeLists.txt index c2a3249328..2154d44048 100644 --- a/modules/EvManager/tests/CMakeLists.txt +++ b/modules/EvManager/tests/CMakeLists.txt @@ -1,4 +1,5 @@ -set(TARGET_NAME ${PROJECT_NAME}_module_ev_manager_tests) +# RegisteredCommand +set(TARGET_NAME test_${PROJECT_NAME}_RegisteredCommand) add_executable(${TARGET_NAME}) target_sources(${TARGET_NAME} @@ -12,10 +13,33 @@ target_link_libraries(${TARGET_NAME} everest::log Catch2::Catch2WithMain ) + if (NOT DISABLE_EDM) list(APPEND CMAKE_MODULE_PATH ${CPM_PACKAGE_catch2_SOURCE_DIR}/extras) include(Catch) catch_discover_tests(${TARGET_NAME}) endif () -catch_discover_tests(${TARGET_NAME}) + +# SimCommand +set(TARGET_NAME test_${PROJECT_NAME}_SimCommand) +add_executable(${TARGET_NAME}) + +target_sources(${TARGET_NAME} + PRIVATE + SimCommand.test.cpp + ../main/SimCommand.cpp +) + +target_link_libraries(${TARGET_NAME} + PRIVATE + everest::framework + everest::log + Catch2::Catch2WithMain +) + +if (NOT DISABLE_EDM) + list(APPEND CMAKE_MODULE_PATH ${CPM_PACKAGE_catch2_SOURCE_DIR}/extras) + include(Catch) + catch_discover_tests(${TARGET_NAME}) +endif () diff --git a/modules/EvManager/tests/RegisteredCommand.test.cpp b/modules/EvManager/tests/RegisteredCommand.test.cpp index 754962c51d..eb5c2815ff 100644 --- a/modules/EvManager/tests/RegisteredCommand.test.cpp +++ b/modules/EvManager/tests/RegisteredCommand.test.cpp @@ -1,2 +1,85 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest + +#include "../main/RegisteredCommand.hpp" +#include +#include +#include +#include + +using namespace module::main; + +SCENARIO("Commands can be registered", "[RegisteredCommand]") { + GIVEN("A command with 0 arguments") { + const auto commandName = std::string{"testCommand0"}; + const auto argumentCount = 0; + const auto testCommand0Function = [](const std::vector& arguments) { return arguments.empty(); }; + + WHEN("The command is registered") { + RegisteredCommandBase::registerCommand(commandName, testCommand0Function, argumentCount); + + THEN("The command can be retrieved") { + const auto* registeredCommand = RegisteredCommandBase::getRegisteredCommand(commandName); + REQUIRE(registeredCommand != nullptr); + THEN("The command can be executed") { + REQUIRE((*registeredCommand)({}) == true); + } + THEN("The command throws when the number of arguments is invalid") { + REQUIRE((*registeredCommand)({}) == true); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1"}), "Invalid number of arguments"); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1", "arg2"}), "Invalid number of arguments"); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1", "arg2", "arg3"}), "Invalid number of arguments"); + } + } + } + } + + GIVEN("A command with 1 argument") { + const auto commandName = std::string{"testCommand1"}; + const auto argumentCount = 1; + const auto testCommand1Function = [](const std::vector& arguments) { + return arguments.size() == 1; + }; + + WHEN("The command is registered") { + RegisteredCommandBase::registerCommand(commandName, testCommand1Function, argumentCount); + + THEN("The command can be retrieved") { + const auto* registeredCommand = RegisteredCommandBase::getRegisteredCommand(commandName); + REQUIRE(registeredCommand != nullptr); + THEN("The command can be executed") { + REQUIRE((*registeredCommand)({"arg1"}) == true); + } + THEN("The command throws when the number of arguments is invalid") { + REQUIRE_THROWS_WITH((*registeredCommand)({}), "Invalid number of arguments"); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1", "arg2"}), "Invalid number of arguments"); + } + } + } + } + + GIVEN("A command with 2 arguments") { + const auto commandName = std::string{"testCommand2"}; + const auto argumentCount = 2; + const auto testCommand2Function = [](const std::vector& arguments) { + return arguments.size() == 2; + }; + + WHEN("The command is registered") { + RegisteredCommandBase::registerCommand(commandName, testCommand2Function, argumentCount); + + THEN("The command can be retrieved") { + const auto* registeredCommand = RegisteredCommandBase::getRegisteredCommand(commandName); + REQUIRE(registeredCommand != nullptr); + THEN("The command can be executed") { + REQUIRE((*registeredCommand)({"arg1", "arg2"}) == true); + } + THEN("The command throws when the number of arguments is invalid") { + REQUIRE_THROWS_WITH((*registeredCommand)({}), "Invalid number of arguments"); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1"}), "Invalid number of arguments"); + REQUIRE_THROWS_WITH((*registeredCommand)({"arg1", "arg2", "arg3"}), "Invalid number of arguments"); + } + } + } + } +} diff --git a/modules/EvManager/tests/SimCommand.test.cpp b/modules/EvManager/tests/SimCommand.test.cpp new file mode 100644 index 0000000000..b8b3b4dcb7 --- /dev/null +++ b/modules/EvManager/tests/SimCommand.test.cpp @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest + +#include "../main/SimCommand.hpp" +#include "../main/RegisteredCommand.hpp" +#include +#include +#include +#include + +using namespace module::main; + +SCENARIO("SimCommands can be created", "[SimCommand]") { + GIVEN("A command with 0 arguments called testCommand is registered") { + const auto commandName = std::string{"testCommand"}; + const auto argumentCount = 0; + const auto testCommandFunction = [](const std::vector& arguments) { return arguments.empty(); }; + RegisteredCommandBase::registerCommand(commandName, testCommandFunction, argumentCount); + + WHEN("The SimCommand is created") { + const auto simCommand = SimCommand{commandName, {}}; + + THEN("The command can be executed") { + REQUIRE(simCommand.execute() == true); + } + } + + WHEN("The SimCommand is created with the wrong number of arguments") { + const auto simCommand = SimCommand{commandName, {"arg1"}}; + + THEN("The command throws") { + REQUIRE_THROWS_WITH(simCommand.execute(), "Invalid number of arguments"); + } + } + } + + WHEN("The SimCommand is created with the wrong commandName") { + THEN("The command throws") { + REQUIRE_THROWS_WITH(SimCommand("wrongCommand", {}), "Command not found"); + } + } +} \ No newline at end of file