Skip to content

Commit

Permalink
feat: added custom fixture option for steps
Browse files Browse the repository at this point in the history
example:
```cpp
struct MyFixture : cucumber_cpp::Step{
  using cucumber_cpp::Step::Step;
};

GIVEN_F(MyFixture, "I have a custom fixture"){}
```
  • Loading branch information
daantimmer committed Jan 11, 2024
1 parent 60f598c commit d061a52
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 47 deletions.
37 changes: 19 additions & 18 deletions cucumber-cpp/BodyMacro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,25 @@

#define BODY_STRUCT CONCAT(BodyImpl, __LINE__)

#define BODY(matcher, type, args, registration, base) \
namespace \
{ \
struct BODY_STRUCT : cucumber_cpp::Body \
, cucumber_cpp::base \
{ \
using cucumber_cpp::base::base; \
void Execute(const nlohmann::json& parameters = {}) override \
{ \
InvokeWithArg(this, parameters, &BODY_STRUCT::ExecuteWithArgs); \
} \
\
private: \
void ExecuteWithArgs args; \
static std::size_t ID; \
}; \
} \
std::size_t BODY_STRUCT::ID = cucumber_cpp::registration<BODY_STRUCT>(matcher, type); \
#define BODY(matcher, type, args, registration, base) \
namespace \
{ \
struct BODY_STRUCT : cucumber_cpp::Body \
, base \
{ \
using myBase = base; \
using myBase::myBase; \
void Execute(const nlohmann::json& parameters = {}) override \
{ \
InvokeWithArg(this, parameters, &BODY_STRUCT::ExecuteWithArgs); \
} \
\
private: \
void ExecuteWithArgs args; \
static const std::size_t ID; \
}; \
} \
const std::size_t BODY_STRUCT::ID = cucumber_cpp::registration<BODY_STRUCT>(matcher, type); \
void BODY_STRUCT::ExecuteWithArgs args

#endif
2 changes: 1 addition & 1 deletion cucumber-cpp/Hooks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "cucumber-cpp/BodyMacro.hpp"
#include "cucumber-cpp/HookRegistry.hpp"

#define HOOK_(matcher, type) BODY(matcher, type, (), HookRegistry::Register, HookBase)
#define HOOK_(matcher, type) BODY(matcher, type, (), HookRegistry::Register, cucumber_cpp::HookBase)

#define HOOK_BEFORE_ALL() \
HOOK_( \
Expand Down
4 changes: 2 additions & 2 deletions cucumber-cpp/StepRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace cucumber_cpp
};
}

StepBase::StepBase(Context& context, const nlohmann::json& table)
Step::Step(Context& context, const nlohmann::json& table)
: context{ context }
, table{ table }
{}
Expand Down Expand Up @@ -126,7 +126,7 @@ namespace cucumber_cpp

if (matches.size() == 0)
{
throw std::out_of_range{ "Step: \"" + expression + "\" not found" };
throw StepNotFound{ "Step: \"" + expression + "\" not found" };
}

return matches;
Expand Down
9 changes: 7 additions & 2 deletions cucumber-cpp/StepRegistry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ namespace cucumber_cpp
any
};

struct StepBase
struct Step
{
StepBase(Context& context, const nlohmann::json& table);
Step(Context& context, const nlohmann::json& table);

protected:
Context& context;
Expand Down Expand Up @@ -63,6 +63,11 @@ namespace cucumber_cpp

struct StepRegistryBase
{
struct StepNotFound : std::out_of_range
{
using std::out_of_range::out_of_range;
};

struct Entry
{
StepType type;
Expand Down
6 changes: 4 additions & 2 deletions cucumber-cpp/StepRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ namespace cucumber_cpp

void StepRunner::Run(nlohmann::json& json, nlohmann::json& scenarioTags)
{
BeforeAfterStepHookScope stepHookScope{ context, JsonTagsToSet(scenarioTags) };
testing::internal::CaptureStdout();
testing::internal::CaptureStderr();

Expand All @@ -67,6 +66,9 @@ namespace cucumber_cpp
if (const auto& step = stepMatches.front(); stepMatches.size() == 1)
{
TraceTime traceTime{ json };

BeforeAfterStepHookScope stepHookScope{ context, JsonTagsToSet(scenarioTags) };

step.factory(context, json["argument"]["dataTable"])->Execute(step.regexMatch->Matches());
}

Expand All @@ -79,7 +81,7 @@ namespace cucumber_cpp
json["result"] = result::failed;
}
}
catch ([[maybe_unused]] const std::out_of_range& e)
catch ([[maybe_unused]] const StepRegistry::StepNotFound& e)
{
json["result"] = result::undefined;
}
Expand Down
37 changes: 15 additions & 22 deletions cucumber-cpp/Steps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,23 @@
#include "cucumber-cpp/BodyMacro.hpp"
#include "cucumber-cpp/StepRegistry.hpp"

#define STEP_(matcher, type, args) BODY(matcher, type, args, StepRegistry::Register, StepBase)
#define STEP_(matcher, type, args, fixture) BODY(matcher, type, args, StepRegistry::Register, fixture)

#define GIVEN(...) \
STEP_( \
BODY_MATCHER(__VA_ARGS__, ""), \
cucumber_cpp::StepType::given, \
BODY_ARGS(__VA_ARGS__, (), ()))
#define STEP_TYPE_(fixture, type, ...) \
STEP_( \
BODY_MATCHER(__VA_ARGS__, ""), \
type, \
BODY_ARGS(__VA_ARGS__, (), ()), \
fixture)

#define WHEN(...) \
STEP_( \
BODY_MATCHER(__VA_ARGS__, ""), \
cucumber_cpp::StepType::when, \
BODY_ARGS(__VA_ARGS__, (), ()))
#define GIVEN_F(fixture, ...) STEP_TYPE_(fixture, cucumber_cpp::StepType::given, __VA_ARGS__)
#define WHEN_F(fixture, ...) STEP_TYPE_(fixture, cucumber_cpp::StepType::when, __VA_ARGS__)
#define THEN_F(fixture, ...) STEP_TYPE_(fixture, cucumber_cpp::StepType::then, __VA_ARGS__)
#define STEP_F(fixture, ...) STEP_TYPE_(fixture, cucumber_cpp::StepType::any, __VA_ARGS__)

#define THEN(...) \
STEP_( \
BODY_MATCHER(__VA_ARGS__, ""), \
cucumber_cpp::StepType::then, \
BODY_ARGS(__VA_ARGS__, (), ()))

#define STEP(...) \
STEP_( \
BODY_MATCHER(__VA_ARGS__, ""), \
cucumber_cpp::StepType::any, \
BODY_ARGS(__VA_ARGS__, (), ()))
#define GIVEN(...) GIVEN_F(cucumber_cpp::Step, __VA_ARGS__)
#define WHEN(...) WHEN_F(cucumber_cpp::Step, __VA_ARGS__)
#define THEN(...) THEN_F(cucumber_cpp::Step, __VA_ARGS__)
#define STEP(...) STEP_F(cucumber_cpp::Step, __VA_ARGS__)

#endif

0 comments on commit d061a52

Please sign in to comment.