Skip to content

Commit

Permalink
adds unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: MarzellT <tobias.marzell@pionix.de>
  • Loading branch information
MarzellT committed Apr 23, 2024
1 parent bc9f5e2 commit baa23b8
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 34 deletions.
1 change: 0 additions & 1 deletion modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion modules/EvManager/EvManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct Conf {
int dc_discharge_max_power_limit;

Check notice on line 41 in modules/EvManager/EvManager.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvManager/EvManager.hpp#L41

struct member 'Conf::dc_discharge_max_power_limit' is never used.
int dc_discharge_target_current;
int dc_discharge_v2g_minimal_soc;
double max_curent;
double max_current;

Check notice on line 44 in modules/EvManager/EvManager.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvManager/EvManager.hpp#L44

struct member 'Conf::max_current' is never used.
bool three_phases;

Check notice on line 45 in modules/EvManager/EvManager.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvManager/EvManager.hpp#L45

struct member 'Conf::three_phases' is never used.
};

Expand Down
22 changes: 12 additions & 10 deletions modules/EvManager/main/RegisteredCommand.hpp
Original file line number Diff line number Diff line change
@@ -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 <cstddef>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <string>
#include <unordered_map>
Expand All @@ -19,7 +17,7 @@ template <typename Func> class RegisteredCommand;
class RegisteredCommandBase {
public:
RegisteredCommandBase() = default;
virtual ~RegisteredCommandBase(){};
virtual ~RegisteredCommandBase() = default;
RegisteredCommandBase(const RegisteredCommandBase&) = default;
RegisteredCommandBase& operator=(const RegisteredCommandBase&) = default;
RegisteredCommandBase(RegisteredCommandBase&&) = default;
Expand All @@ -34,8 +32,14 @@ class RegisteredCommandBase {
commandName, argumentCount, std::forward<FunctionT>(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:
Expand All @@ -51,7 +55,7 @@ template <typename FunctionT> class RegisteredCommand : public RegisteredCommand
~RegisteredCommand() override = default;

bool operator()(const std::vector<std::string>& arguments) const override {
if (!arguments.empty() && arguments.size() != argumentCount) {
if (arguments.size() != argumentCount) {
throw std::invalid_argument{"Invalid number of arguments"};
}
return function(arguments);
Expand All @@ -62,6 +66,4 @@ template <typename FunctionT> class RegisteredCommand : public RegisteredCommand
std::size_t argumentCount;
FunctionT function;
};
} // namespace module::main

#endif
} // namespace module::main
11 changes: 8 additions & 3 deletions modules/EvManager/main/SimCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
// Copyright Pionix GmbH and Contributors to EVerest

#include "SimCommand.hpp"
#include "RegisteredCommand.hpp"
#include <string>
#include <utility>
#include <vector>
namespace module::main {

SimCommand::SimCommand(std::string commandName, std::vector<std::string> arguments) :
SimCommand::SimCommand(std::string&& commandName, std::vector<std::string>&& arguments) :
arguments{std::move(arguments)}, registeredCommand{RegisteredCommandBase::getRegisteredCommand(commandName)} {
}

bool SimCommand::execute() {
return registeredCommand(arguments);
SimCommand::SimCommand(const std::string& commandName, const std::vector<std::string>& arguments) :
arguments{arguments}, registeredCommand{RegisteredCommandBase::getRegisteredCommand(commandName)} {
}

bool SimCommand::execute() const {
return (*registeredCommand)(arguments);
}

} // namespace module::main
15 changes: 6 additions & 9 deletions modules/EvManager/main/SimCommand.hpp
Original file line number Diff line number Diff line change
@@ -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 <cstddef>
#include <memory>
#include <mutex>
Expand All @@ -15,20 +15,17 @@

namespace module::main {

class RegisteredCommandBase;

class SimCommand {
public:
SimCommand(std::string commandName, std::vector<std::string> arguments);
SimCommand(std::string&& commandName, std::vector<std::string>&& arguments);
SimCommand(const std::string& commandName, const std::vector<std::string>& arguments);

bool execute();
bool execute() const;

private:
std::vector<std::string> arguments;

Check notice on line 26 in modules/EvManager/main/SimCommand.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvManager/main/SimCommand.hpp#L26

class member 'SimCommand::arguments' is never used.

const RegisteredCommandBase& registeredCommand;
const RegisteredCommandBase* registeredCommand;
};

} // namespace module::main

#endif // TMP_CLION_CLANG_TIDY_SIMCOMMAND_HPP
7 changes: 1 addition & 6 deletions modules/EvManager/main/SimData.hpp
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -55,8 +54,6 @@ struct SimData {

types::board_support_common::Event actualBspEvent{};



std::queue<SimCommand> commandQueue;

Check notice on line 57 in modules/EvManager/main/SimData.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/EvManager/main/SimData.hpp#L57

struct member 'SimData::commandQueue' is never used.
};

Expand All @@ -73,5 +70,3 @@ std::queue<SimCommand>
compileCommands(std::vector<std::pair<std::string, std::vector<std::string>>>& commandsWithArguments);

} // namespace module::main

#endif // EVEREST_CORE_SIMDATA_HPP
2 changes: 1 addition & 1 deletion modules/EvManager/main/car_simulatorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion modules/EvManager/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 26 additions & 2 deletions modules/EvManager/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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}
Expand All @@ -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 ()
83 changes: 83 additions & 0 deletions modules/EvManager/tests/RegisteredCommand.test.cpp
Original file line number Diff line number Diff line change
@@ -1,2 +1,85 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#include "../main/RegisteredCommand.hpp"
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <string>
#include <vector>

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<std::string>& 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<std::string>& 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<std::string>& 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");
}
}
}
}
}
42 changes: 42 additions & 0 deletions modules/EvManager/tests/SimCommand.test.cpp
Original file line number Diff line number Diff line change
@@ -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 <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <string>
#include <vector>

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<std::string>& 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");
}
}
}

0 comments on commit baa23b8

Please sign in to comment.