Skip to content

Commit eed61b7

Browse files
committed
feat: expose parameter registration interface
1 parent 296d7d0 commit eed61b7

File tree

5 files changed

+60
-16
lines changed

5 files changed

+60
-16
lines changed

cucumber_cpp/library/Application.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "cucumber_cpp/library/Errors.hpp"
44
#include "cucumber_cpp/library/StepRegistry.hpp"
55
#include "cucumber_cpp/library/cucumber_expression/Errors.hpp"
6+
#include "cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp"
67
#include "cucumber_cpp/library/engine/ContextManager.hpp"
78
#include "cucumber_cpp/library/engine/FeatureFactory.hpp"
89
#include "cucumber_cpp/library/engine/FeatureInfo.hpp"
@@ -177,6 +178,11 @@ namespace cucumber_cpp::library
177178
return contextManager.ProgramContext();
178179
}
179180

181+
cucumber_expression::ParameterRegistration& Application::ParameterRegistration()
182+
{
183+
return parameterRegistry;
184+
}
185+
180186
void Application::AddReportHandler(const std::string& name, std::unique_ptr<report::ReportHandlerV2>&& reporter)
181187
{
182188
reporters.Add(name, std::move(reporter));

cucumber_cpp/library/Application.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace cucumber_cpp::library
4545

4646
CLI::App& CliParser();
4747
Context& ProgramContext();
48+
cucumber_expression::ParameterRegistration& ParameterRegistration();
4849

4950
void AddReportHandler(const std::string& name, std::unique_ptr<report::ReportHandlerV2>&& reporter);
5051

cucumber_cpp/library/cucumber_expression/ParameterRegistry.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,20 @@ namespace cucumber_cpp::library::cucumber_expression
6969
const static std::string stringSingleRegex{ R"__('([^'\\]*(\\.[^'\\]*)*)')__" };
7070
const static std::string wordRegex{ R"__([^\s]+)__" };
7171

72-
AddParameter("int", { integerNegativeRegex, integerPositiveRegex }, CreateStreamConverter<std::int32_t>());
73-
AddParameter("float", { floatRegex }, CreateStreamConverter<float>());
74-
AddParameter("word", { wordRegex }, CreateStreamConverter<std::string>());
75-
AddParameter("string", { stringDoubleRegex, stringSingleRegex }, CreateStringConverter());
76-
AddParameter("", { ".*" }, CreateStreamConverter<std::string>());
77-
AddParameter("bigdecimal", { floatRegex }, CreateStreamConverter<double>());
78-
AddParameter("biginteger", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int64_t>());
79-
AddParameter("byte", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int32_t>());
80-
AddParameter("short", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int32_t>());
81-
AddParameter("long", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int64_t>());
82-
AddParameter("double", { floatRegex }, CreateStreamConverter<double>());
72+
Add("int", { integerNegativeRegex, integerPositiveRegex }, CreateStreamConverter<std::int32_t>());
73+
Add("float", { floatRegex }, CreateStreamConverter<float>());
74+
Add("word", { wordRegex }, CreateStreamConverter<std::string>());
75+
Add("string", { stringDoubleRegex, stringSingleRegex }, CreateStringConverter());
76+
Add("", { ".*" }, CreateStreamConverter<std::string>());
77+
Add("bigdecimal", { floatRegex }, CreateStreamConverter<double>());
78+
Add("biginteger", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int64_t>());
79+
Add("byte", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int32_t>());
80+
Add("short", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int32_t>());
81+
Add("long", { { integerNegativeRegex, integerPositiveRegex } }, CreateStreamConverter<std::int64_t>());
82+
Add("double", { floatRegex }, CreateStreamConverter<double>());
8383

8484
// extension
85-
AddParameter("bool", { wordRegex }, CreateStreamConverter<bool>());
85+
Add("bool", { wordRegex }, CreateStreamConverter<bool>());
8686
}
8787

8888
Parameter ParameterRegistry::Lookup(const std::string& name) const
@@ -92,7 +92,7 @@ namespace cucumber_cpp::library::cucumber_expression
9292
return {};
9393
}
9494

95-
void ParameterRegistry::AddParameter(std::string name, std::vector<std::string> regex, std::function<std::any(MatchRange)> converter)
95+
void ParameterRegistry::Add(std::string name, std::vector<std::string> regex, std::function<std::any(MatchRange)> converter)
9696
{
9797
if (parameters.contains(name))
9898
{

cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,17 @@ namespace cucumber_cpp::library::cucumber_expression
120120
std::function<std::any(MatchRange)> converter;
121121
};
122122

123-
struct ParameterRegistry
123+
struct ParameterRegistration
124+
{
125+
virtual void Add(std::string name, std::vector<std::string> regex, std::function<std::any(MatchRange)> converter) = 0;
126+
};
127+
128+
struct ParameterRegistry : ParameterRegistration
124129
{
125130
ParameterRegistry();
126131

127132
Parameter Lookup(const std::string& name) const;
128-
void AddParameter(std::string name, std::vector<std::string> regex, std::function<std::any(MatchRange)> converter);
133+
void Add(std::string name, std::vector<std::string> regex, std::function<std::any(MatchRange)> converter) override;
129134

130135
private:
131136
std::map<std::string, Parameter, std::less<>> parameters{};

cucumber_cpp/library/cucumber_expression/test/TestExpression.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ namespace cucumber_cpp::library::cucumber_expression
155155
std::optional<std::int64_t> number;
156156
};
157157

158-
parameterRegistry.AddParameter("textAndOrNumber", { R"(([A-Z]+)?(?: )?([0-9]+)?)" }, [](MatchRange matches) -> std::any
158+
parameterRegistry.Add("textAndOrNumber", { R"(([A-Z]+)?(?: )?([0-9]+)?)" }, [](MatchRange matches) -> std::any
159159
{
160160
std::optional<std::string> text{ matches[1].matched ? StringTo<std::string>(matches[1].str()) : std::optional<std::string>{ std::nullopt } };
161161
std::optional<std::int64_t> number{ matches[2].matched ? StringTo<std::int64_t>(matches[2].str()) : std::optional<std::int64_t>{ std::nullopt } };
@@ -221,4 +221,36 @@ namespace cucumber_cpp::library::cucumber_expression
221221
"Please register a ParameterType for 'doesnotexist'\n"));
222222
}
223223
}
224+
225+
TEST_F(TestExpression, ThrowDuplicateAnonymousParameterError)
226+
{
227+
try
228+
{
229+
parameterRegistry.Add("", { ".*" }, [](const MatchRange& matches)
230+
{
231+
return StringTo<std::string>(matches.begin()->str());
232+
});
233+
FAIL() << "Expected CucumberExpressionError to be thrown";
234+
}
235+
catch (const CucumberExpressionError& e)
236+
{
237+
EXPECT_THAT(e.what(), testing::StrEq("The anonymous parameter type has already been defined"));
238+
}
239+
}
240+
241+
TEST_F(TestExpression, ThrowDuplicateParameterError)
242+
{
243+
try
244+
{
245+
parameterRegistry.Add("word", { wordRegex }, [](const MatchRange& matches)
246+
{
247+
return StringTo<std::string>(matches.begin()->str());
248+
});
249+
FAIL() << "Expected CucumberExpressionError to be thrown";
250+
}
251+
catch (const CucumberExpressionError& e)
252+
{
253+
EXPECT_THAT(e.what(), testing::StrEq("There is already a parameter with name word"));
254+
}
255+
}
224256
}

0 commit comments

Comments
 (0)