Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature and stability updates #7

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ SCENARIO_P_VERBOSE(ExplicitTestName, "This is my scenario description", MyFixtur
}
```

Both of these macros deal with `INSTANTIATE_TEST_CASE_P` so that it is not required in your tests.
Both of these macros deal with `INSTANTIATE_TEST_SUITE_P` so that it is not required in your tests.
The difference between them is just what appears in the test output. `SCENARIO_P` will by default prefix test output with
`TEST_P` and presumes the fixture name and description are sufficient enough to give meaningful test output.
Where this is not the case, you can substitute additional test information for the `ExplicitTestName` placeholder.
Expand All @@ -138,6 +138,15 @@ SCENARIO_P("User updates their email address", UniqueFixtureName, emails) {
}
```

### Typed SCENARIO

Typed scenarios require a fixture and can be achieved with

```cpp
SCENARIO_T("This is my scenario description", MyUniqueFixture, Types()) {
}
```

### DISABLED tests

To disable a `SCENARIO`, just prefix the scenario string with `"DISABLED_"` as you would for a regular TEST
Expand Down
141 changes: 129 additions & 12 deletions include/cppbdd/gtestbdd.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@

namespace gtestbdd
{
class ExpectString
{
public:
template<typename... Args>
explicit ExpectString(Args&&... args)
: mString(std::forward<Args>(args)...)
{}

std::string GetString() &&
{
return std::move(mString);
}

std::string mString;
};

class Scenario
{
public:
Expand All @@ -18,7 +34,7 @@ namespace gtestbdd

virtual ~Scenario()
{
if (!mGiven && !mWhen && !mThen)
if(!mGiven && !mWhen && !mThen)
{
return;
}
Expand All @@ -44,13 +60,41 @@ namespace gtestbdd

void given(const std::string &description)
{
if (mGiven)
{
printError("GIVEN clause is duplicated. AND should be used for additional statements.");
assert(false);
}
mGiven = true;
printGiven(description);
}

void then(ExpectString description)
{
if(!mThenExpects.empty())
{
printError("THEN(EXPECT()) clause is duplicated. AND should be used for additional statements.");
assert(false);
}
else if(mGiven)
{
mThenExpects.push_back(std::move(description).GetString());
}
else
{
printError("GIVEN clause missing.");
assert(false);
}
}

void when(const std::string &description)
{
if(mGiven)
if(mWhen)
{
printError("WHEN clause is duplicated. AND should be used for additional statements.");
assert(false);
}
else if(mGiven)
{
mWhen = true;
printWhen(description);
Expand All @@ -64,10 +108,27 @@ namespace gtestbdd

void then(const std::string &description)
{
if(mWhen)
if(mThen)
{
printError("THEN clause is duplicated. AND should be used for additional statements.");
assert(false);
}
else if(mWhen)
{
mThen = true;
printThen(description);

if(!mThenExpects.empty())
{
printThen(mThenExpects[0]);
for (size_t i = 1; i < mThenExpects.size(); ++i)
printAnd(mThenExpects[i]);
mThenExpects.clear();
printAnd(description);
}
else
{
printThen(description);
}
}
else
{
Expand All @@ -80,7 +141,10 @@ namespace gtestbdd
{
if(mGiven || mWhen || mThen)
{
printAnd(description);
if(!mWhen && !mThenExpects.empty())
mThenExpects.push_back(description);
else
printAnd(description);
}
else
{
Expand Down Expand Up @@ -121,6 +185,7 @@ namespace gtestbdd
}

const std::string mDescription;
std::vector<std::string> mThenExpects;
bool mGiven = false;
bool mWhen = false;
bool mThen = false;
Expand Down Expand Up @@ -154,7 +219,8 @@ namespace gtestbdd
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestClass);\
TestClass(const TestClass&) = delete;\
TestClass& operator=(const TestClass&) = delete;\
};\
\
::testing::TestInfo* const TestClass\
Expand Down Expand Up @@ -184,19 +250,24 @@ namespace gtestbdd
static int AddToRegistry() {\
::testing::UnitTest::GetInstance()->parameterized_test_registry().\
GetTestCasePatternHolder<FixtureClass>(\
#FixtureClass, __FILE__, __LINE__)->AddTestPattern(\
#FixtureClass,\
Description,\
new ::testing::internal::TestMetaFactory<TestClass>());\
GTEST_STRINGIFY_(FixtureClass),\
::testing::internal::CodeLocation(\
__FILE__, __LINE__))->AddTestPattern(\
GTEST_STRINGIFY_(FixtureClass),\
Description,\
new ::testing::internal::TestMetaFactory<TestClass>(),\
::testing::internal::CodeLocation(\
__FILE__, __LINE__));\
return 0;\
}\
static int gtest_registering_dummy_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestClass);\
TestClass(const TestClass&) = delete;\
TestClass& operator=(const TestClass&) = delete;\
};\
\
int TestClass::gtest_registering_dummy_ =\
TestClass::AddToRegistry();\
INSTANTIATE_TEST_CASE_P(TestName, FixtureClass, Values);\
INSTANTIATE_TEST_SUITE_P(TestName, FixtureClass, Values);\
void TestClass::TestBody()

#define SCENARIO_P_VERBOSE(testname, description, fixture, values) \
Expand All @@ -214,6 +285,49 @@ namespace gtestbdd
fixture, \
values)



#define MAKE_SCENARIO_T(TestName, Description, FixtureClass, Types) \
TYPED_TEST_SUITE(FixtureClass, Types); \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(FixtureClass, TestName) \
: public gtestbdd::Scenario, public FixtureClass<gtest_TypeParam_> \
{ \
public: \
GTEST_TEST_CLASS_NAME_(FixtureClass, TestName)() : \
gtestbdd::Scenario(Description) \
{ \
} \
private: \
typedef FixtureClass<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##FixtureClass##_registered_ \
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
FixtureClass, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(FixtureClass, \
TestName)>, \
GTEST_TYPE_PARAMS_( \
FixtureClass)>::Register("", \
::testing::internal::CodeLocation( \
__FILE__, __LINE__), \
GTEST_STRINGIFY_(FixtureClass), \
GTEST_STRINGIFY_(TestName), 0, \
::testing::internal::GenerateNames< \
GTEST_NAME_GENERATOR_(FixtureClass), \
GTEST_TYPE_PARAMS_(FixtureClass)>()); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(FixtureClass, \
TestName)<gtest_TypeParam_>::TestBody()

#define SCENARIO_T(description, fixture, types) \
MAKE_SCENARIO_T(\
MAKE_UNIQUE(Scenario_##fixture##_Line), \
description, \
fixture, \
types)

#define SCENARIO_F(description, fixture) MAKE_SCENARIO(MAKE_UNIQUE(Scenario_##fixture##_Line), description, fixture)

#define SCENARIO(description) MAKE_SCENARIO(MAKE_UNIQUE(Scenario_Fixture_Line), description, ::testing::Test)
Expand All @@ -225,6 +339,9 @@ namespace gtestbdd
#define WHEN(description)\
when(description);

#define EXPECT(description)\
gtestbdd::ExpectString(description)

#define THEN(description)\
then(description);

Expand Down
18 changes: 15 additions & 3 deletions include/cppbdd/qtestbdd.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace qtestbdd

virtual ~Scenario()
{
if (!mGiven && !mWhen && !mThen)
if(!mGiven && !mWhen && !mThen)
{
return;
}
Expand All @@ -40,13 +40,21 @@ namespace qtestbdd

void given(const QString &description)
{
if (mGiven)
{
QFAIL("GIVEN clause is duplicated. AND should be used for additional statements.");
}
mGiven = true;
printGiven(description);
}

void when(const QString &description)
{
if(mGiven)
if(mWhen)
{
QFAIL("WHEN clause is duplicated. AND should be used for additional statements.");
}
else if(mGiven)
{
mWhen = true;
printWhen(description);
Expand All @@ -59,7 +67,11 @@ namespace qtestbdd

void then(const QString &description)
{
if(mWhen)
if(mThen)
{
QFAIL("THEN clause is duplicated. AND should be used for additional statements.");
}
else if(mWhen)
{
mThen = true;
printThen(description);
Expand Down