diff --git a/.vscode/settings.json b/.vscode/settings.json index e4581758..dc1809b9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,5 +24,24 @@ "sonarlint.connectedMode.project": { "connectionId": "philips-software", "projectKey": "philips-software_amp-cucumber-cpp-runner" + }, + { + "parameter": ")\"", + "value": "\"" } + ], + "C/C++ Include Guard.Macro Type": "Filepath", + "C/C++ Include Guard.Path Depth": 1, + "C/C++ Include Guard.Remove Extension": false, + "C/C++ Include Guard.Comment Style": "None", + "C/C++ Include Guard.Path Skip": 0, + "testMate.cpp.test.executables": "${workspaceFolder}/.build/**/*{test,Test,TEST}*", + "sonarlint.connectedMode.project": { + "connectionId": "philips-software", + "projectKey": "philips-software_amp-cucumber-cpp-runner" + }, + "cmake.postRunCoverageTarget": "generate-coverage-report", + "cmake.coverageInfoFiles": [ + "${workspaceFolder}/.build/${command:cmake.activeConfigurePresetName}/lcov.info" + ] } diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f5d7475..7ef12c5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,18 +21,29 @@ else() set(CCR_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL") endif() -option( - CCR_FETCH_DEPS - "Fetch dependencies via FetchContent." - On -) - -option(CCR_BUILD_TESTS "Enable building the tests" ${CCR_DEFAULTOPT}) +option(CCR_FETCH_DEPS "Fetch dependencies via FetchContent." On ) +option(CCR_BUILD_TESTS "Enable build of the tests" ${CCR_DEFAULTOPT}) +option(CCR_ENABLE_COVERAGE "Enable compiler flags for code coverage measurements" Off) if (CCR_BUILD_TESTS) ccr_enable_testing() endif() +if (CCR_ENABLE_COVERAGE) + find_program(GCOVR_PATH gcovr) + + if (NOT GCOVR_PATH) + message(FATAL_ERROR "Could not find gcovr, which is required for code coverage IDE integration") + endif() + + add_custom_target( + generate-coverage-report + COMMAND ${GCOVR_PATH} --delete --lcov ${CMAKE_CURRENT_BINARY_DIR}/lcov.info + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating code coverage report in LCOV format" + ) +endif() + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED On) set(CMAKE_CXX_EXTENSIONS Off) diff --git a/cucumber_cpp/library/Application.cpp b/cucumber_cpp/library/Application.cpp index b42cd4a9..5ddf5a93 100644 --- a/cucumber_cpp/library/Application.cpp +++ b/cucumber_cpp/library/Application.cpp @@ -3,6 +3,7 @@ #include "cucumber_cpp/library/Errors.hpp" #include "cucumber_cpp/library/StepRegistry.hpp" #include "cucumber_cpp/library/cucumber_expression/Errors.hpp" +#include "cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp" #include "cucumber_cpp/library/engine/ContextManager.hpp" #include "cucumber_cpp/library/engine/FeatureFactory.hpp" #include "cucumber_cpp/library/engine/FeatureInfo.hpp" @@ -177,6 +178,11 @@ namespace cucumber_cpp::library return contextManager.ProgramContext(); } + cucumber_expression::ParameterRegistration& Application::ParameterRegistration() + { + return parameterRegistry; + } + void Application::AddReportHandler(const std::string& name, std::unique_ptr&& reporter) { reporters.Add(name, std::move(reporter)); diff --git a/cucumber_cpp/library/Application.hpp b/cucumber_cpp/library/Application.hpp index e29c2294..5b762852 100644 --- a/cucumber_cpp/library/Application.hpp +++ b/cucumber_cpp/library/Application.hpp @@ -45,6 +45,7 @@ namespace cucumber_cpp::library CLI::App& CliParser(); Context& ProgramContext(); + cucumber_expression::ParameterRegistration& ParameterRegistration(); void AddReportHandler(const std::string& name, std::unique_ptr&& reporter); diff --git a/cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp b/cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp index 66a809c2..fcd2c44b 100644 --- a/cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp +++ b/cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp @@ -120,12 +120,23 @@ namespace cucumber_cpp::library::cucumber_expression std::function converter; }; - struct ParameterRegistry + struct ParameterRegistration + { + protected: + ~ParameterRegistration() = default; + + public: + virtual void AddParameter(std::string name, std::vector regex, std::function converter) = 0; + }; + + struct ParameterRegistry : ParameterRegistration { ParameterRegistry(); + virtual ~ParameterRegistry() = default; + Parameter Lookup(const std::string& name) const; - void AddParameter(std::string name, std::vector regex, std::function converter); + void AddParameter(std::string name, std::vector regex, std::function converter) override; private: std::map> parameters{}; diff --git a/cucumber_cpp/library/cucumber_expression/test/TestExpression.cpp b/cucumber_cpp/library/cucumber_expression/test/TestExpression.cpp index 9b4608a2..a13f0bb7 100644 --- a/cucumber_cpp/library/cucumber_expression/test/TestExpression.cpp +++ b/cucumber_cpp/library/cucumber_expression/test/TestExpression.cpp @@ -221,4 +221,36 @@ namespace cucumber_cpp::library::cucumber_expression "Please register a ParameterType for 'doesnotexist'\n")); } } + + TEST_F(TestExpression, ThrowDuplicateAnonymousParameterError) + { + try + { + parameterRegistry.AddParameter("", { ".*" }, [](const MatchRange& matches) + { + return StringTo(matches.begin()->str()); + }); + FAIL() << "Expected CucumberExpressionError to be thrown"; + } + catch (const CucumberExpressionError& e) + { + EXPECT_THAT(e.what(), testing::StrEq("The anonymous parameter type has already been defined")); + } + } + + TEST_F(TestExpression, ThrowDuplicateParameterError) + { + try + { + parameterRegistry.AddParameter("word", { ".*" }, [](const MatchRange& matches) + { + return StringTo(matches.begin()->str()); + }); + FAIL() << "Expected CucumberExpressionError to be thrown"; + } + catch (const CucumberExpressionError& e) + { + EXPECT_THAT(e.what(), testing::StrEq("There is already a parameter with name word")); + } + } } diff --git a/cucumber_cpp/library/test/TestApplication.cpp b/cucumber_cpp/library/test/TestApplication.cpp index b5a2b7ab..fa500b48 100644 --- a/cucumber_cpp/library/test/TestApplication.cpp +++ b/cucumber_cpp/library/test/TestApplication.cpp @@ -124,4 +124,9 @@ namespace cucumber_cpp::library EXPECT_THAT(stdoutString, testing::HasSubstr("1/2 passed")); } + + TEST_F(TestApplication, ExposeParameterRegistration) + { + EXPECT_THAT(&Application{}.ParameterRegistration(), testing::NotNull()); + } }