Skip to content

Commit d60c6d2

Browse files
committed
should
1 parent 47f70d5 commit d60c6d2

File tree

5 files changed

+142
-272
lines changed

5 files changed

+142
-272
lines changed

include/GUnit/Detail/Utility.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -196,27 +196,6 @@ inline auto &progname() {
196196
return self;
197197
}
198198

199-
template <class TParser>
200-
inline auto symbols(const std::string &symbol) {
201-
std::set<typename TParser::type> result;
202-
std::stringstream cmd;
203-
cmd << "nm -gpP " << progname();
204-
auto fp = popen(cmd.str().c_str(), "r");
205-
if (fp) {
206-
char buf[8192] = {};
207-
while (fgets(buf, sizeof(buf), fp)) {
208-
if (!strncmp(buf, symbol.c_str(), symbol.length())) {
209-
auto i = symbol.length() + 1;
210-
while (buf[i] != ' ' && buf[i]) ++i;
211-
buf[i] = 0;
212-
result.emplace(TParser::parse(demangle(buf)));
213-
}
214-
}
215-
}
216-
pclose(fp);
217-
return result;
218-
}
219-
220199
inline std::pair<std::string, int> addr2line(void *addr) {
221200
std::stringstream cmd;
222201
cmd << "addr2line -Cpe " << progname() << " " << addr;

include/GUnit/GTest-Lite.h

Whitespace-only changes.

include/GUnit/GTest.h

Lines changed: 136 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -16,109 +16,117 @@
1616
#include "GUnit/GMake.h"
1717
#include "GUnit/GMock.h"
1818

19-
#if !defined(GUNIT_SHOULD_PREFIX)
20-
#define GUNIT_SHOULD_PREFIX "should "
21-
#endif
22-
2319
namespace testing {
2420
inline namespace v1 {
2521
namespace detail {
2622

27-
struct TestCaseInfo {
28-
bool disabled = false;
29-
std::string symbol;
30-
std::string type;
31-
std::string name;
32-
std::string file;
33-
int line = 0;
34-
std::string should;
35-
36-
bool operator==(const TestCaseInfo& ti) const { return symbol == ti.symbol; }
37-
bool operator!=(const TestCaseInfo& ti) const { return symbol != ti.symbol; }
38-
bool operator<(const TestCaseInfo& ti) const { return symbol < ti.symbol; }
39-
bool operator>(const TestCaseInfo& ti) const { return symbol > ti.symbol; }
40-
};
23+
bool PatternMatchesString(const char *pattern,
24+
const char *str) {
25+
switch (*pattern) {
26+
case '\0':
27+
case ':': // Either ':' or '\0' marks the end of the pattern.
28+
return *str == '\0';
29+
case '?': // Matches any single character.
30+
return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
31+
case '*': // Matches any string (possibly empty) of characters.
32+
return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
33+
PatternMatchesString(pattern + 1, str);
34+
default: // Non-special character. Matches itself.
35+
return *pattern == *str &&
36+
PatternMatchesString(pattern + 1, str + 1);
37+
}
38+
}
4139

42-
struct TestCaseInfoParser {
43-
using type = TestCaseInfo;
44-
45-
static auto parse(const std::string& line) {
46-
TestCaseInfo ti;
47-
ti.symbol = line;
48-
const auto str = std::string{">()::shouldRegister"};
49-
ti.symbol.replace(ti.symbol.find(str), str.length(), "|");
50-
std::string token;
51-
std::istringstream stream(ti.symbol);
52-
53-
const auto parseString = [&](std::string& result, char end = '>') {
54-
std::getline(stream, token, end);
55-
if (token.find("::detail::string") != std::string::npos) {
56-
if (token.find(")") != std::string::npos) {
57-
std::istringstream istream(token);
58-
while (std::getline(istream, token, ',')) {
59-
const auto begin = token.find(')');
60-
result += static_cast<char>(std::atoi(token.substr(begin + 1).c_str()));
61-
}
62-
}
63-
} else {
64-
detail::trim(token);
65-
result = token;
66-
}
67-
std::getline(stream, token, ',');
68-
};
69-
70-
std::getline(stream, token, '<');
71-
std::getline(stream, token, ',');
72-
ti.disabled = token == "true";
73-
parseString(ti.name);
74-
parseString(ti.file);
75-
std::getline(stream, token, ',');
76-
ti.line = std::atoi(token.c_str());
77-
parseString(ti.should);
78-
parseString(ti.type, '|');
79-
if (!ti.type.empty() && ti.type[0] == '"' && ti.type[ti.type.length() - 2] == '"') {
80-
ti.type = ti.type.substr(1, ti.type.length() - 3);
40+
bool MatchesFilter( const std::string& name, const char* filter) {
41+
const char *cur_pattern = filter;
42+
for (;;) {
43+
if (PatternMatchesString(cur_pattern, name.c_str())) {
44+
return true;
8145
}
82-
return ti;
46+
47+
// Finds the next pattern in the filter.
48+
cur_pattern = strchr(cur_pattern, ':');
49+
50+
// Returns if no more pattern can be found.
51+
if (cur_pattern == NULL) {
52+
return false;
53+
}
54+
55+
// Skips the pattern separater (the ':' character).
56+
cur_pattern++;
8357
}
84-
};
58+
}
8559

86-
inline auto& tests() {
87-
static auto ts = symbols<TestCaseInfoParser>("_ZZN7testing2v16detail21SHOULD_REGISTER_GTEST");
88-
return ts;
60+
bool FilterMatchesShould(const std::string& name, const std::string &should) {
61+
// Split --gtest_filter at '-', if there is one, to separate into
62+
// positive filter and negative filter portions
63+
const char* const p = should.c_str();
64+
const char* const dash = strchr(p, '-');
65+
std::string positive;
66+
std::string negative;
67+
if (dash == NULL) {
68+
positive = should.c_str(); // Whole string is a positive filter
69+
negative = "";
70+
} else {
71+
positive = std::string(p, dash); // Everything up to the dash
72+
negative = std::string(dash + 1); // Everything after the dash
73+
if (positive.empty()) {
74+
// Treat '-test1' as the same as '*-test1'
75+
positive = "*";
76+
}
77+
}
78+
79+
return (MatchesFilter(name, positive.c_str()) && !MatchesFilter(name, negative.c_str()));
8980
}
9081

82+
struct TestRun {
83+
std::string should = GetShouldParam();
84+
bool once = false;
85+
86+
static std::string GetShouldParam() {
87+
const std::string filter = "--should=";
88+
for (auto i = 0u; i < internal::GetArgvs().size(); ++i) {
89+
if (internal::GetArgvs()[i].find(filter) != std::string::npos) {
90+
return internal::GetArgvs()[i].substr(filter.length());
91+
}
92+
}
93+
return "*";
94+
}
95+
96+
bool run(const std::string& name, int line) {
97+
if (once) {
98+
return false;
99+
}
100+
const auto result = line > test_line && FilterMatchesShould(name, should);
101+
if (result) {
102+
std::cout << "[ SHOULD ] " << name << std::endl;
103+
}
104+
test_line = line;
105+
once = true;
106+
return result;
107+
}
108+
109+
int test_line = 0;
110+
};
111+
91112
template <bool DISABLED, class T>
92113
class GTestAutoRegister {
93114
static auto IsDisabled(bool disabled) { return DISABLED || disabled ? "DISABLED_" : ""; }
94115

95-
void MakeAndRegisterTestInfo(const TestCaseInfo& ti,
116+
void MakeAndRegisterTestInfo(bool disabled, const std::string& type, const std::string& name, const std::string& /*file*/, int /*line*/,
96117
detail::type<TestInfo*(const char*, const char*, const char*, const char*, const void*,
97118
void (*)(), void (*)(), internal::TestFactoryBase*)>) {
98-
if (ti.should.empty()) {
99-
internal::MakeAndRegisterTestInfo((IsDisabled(ti.disabled) + ti.type).c_str(), ti.name.c_str(), nullptr, nullptr,
100-
internal::GetTestTypeId(), Test::SetUpTestCase, Test::TearDownTestCase,
101-
new internal::TestFactoryImpl<T>{});
102-
} else {
103-
internal::MakeAndRegisterTestInfo((IsDisabled(ti.disabled) + ti.type + ti.name).c_str(),
104-
(std::string{GUNIT_SHOULD_PREFIX} + ti.should).c_str(), nullptr, nullptr,
119+
internal::MakeAndRegisterTestInfo((IsDisabled(disabled) + type).c_str(), name.c_str(), nullptr, nullptr,
105120
internal::GetTestTypeId(), Test::SetUpTestCase, Test::TearDownTestCase,
106121
new internal::TestFactoryImpl<T>{});
107-
}
108122
}
109123

110124
template <class... Ts>
111-
void MakeAndRegisterTestInfo(const TestCaseInfo& ti, detail::type<TestInfo*(Ts...)>) {
112-
if (ti.should.empty()) {
113-
internal::MakeAndRegisterTestInfo((IsDisabled(ti.disabled) + ti.type).c_str(), ti.name.c_str(), nullptr, nullptr,
114-
{ti.file.c_str(), ti.line}, internal::GetTestTypeId(), Test::SetUpTestCase,
115-
Test::TearDownTestCase, new internal::TestFactoryImpl<T>{});
116-
} else {
117-
internal::MakeAndRegisterTestInfo((IsDisabled(ti.disabled) + ti.type + ti.name).c_str(),
118-
(std::string{GUNIT_SHOULD_PREFIX} + ti.should).c_str(), nullptr, nullptr,
119-
{ti.file.c_str(), ti.line}, internal::GetTestTypeId(), Test::SetUpTestCase,
120-
Test::TearDownTestCase, new internal::TestFactoryImpl<T>{});
121-
}
125+
void MakeAndRegisterTestInfo(bool disabled, const std::string& type, const std::string& name, const std::string& file, int line, detail::type<TestInfo*(Ts...)>) {
126+
internal::MakeAndRegisterTestInfo((IsDisabled(disabled) + type).c_str(), name.c_str(), nullptr, nullptr,
127+
{file.c_str(), line},
128+
internal::GetTestTypeId(), Test::SetUpTestCase, Test::TearDownTestCase,
129+
new internal::TestFactoryImpl<T>{});
122130
}
123131

124132
template <class TestType>
@@ -133,61 +141,48 @@ class GTestAutoRegister {
133141
return str;
134142
}
135143

136-
bool RegisterShouldTestCase() {
137-
auto registered = false;
138-
for (const auto& ti : tests()) {
139-
if (GetTypeName(detail::type<typename T::TEST_TYPE>{}) == ti.type && T::TEST_NAME::c_str() == ti.name) {
140-
MakeAndRegisterTestInfo(ti, detail::type<decltype(internal::MakeAndRegisterTestInfo)>{});
141-
registered = true;
142-
}
143-
}
144-
return registered;
145-
}
146-
147-
bool RegisterShouldParamTestCase() {
148-
auto registered = false;
149-
for (const auto& ti : tests()) {
150-
if (GetTypeName(detail::type<typename T::TEST_TYPE>{}) == ti.type && T::TEST_NAME::c_str() == ti.name) {
151-
UnitTest::GetInstance()
152-
->parameterized_test_registry()
153-
.GetTestCasePatternHolder<T>(ti.type.c_str(), {ti.file, ti.line})
154-
->AddTestPattern((IsDisabled(ti.disabled) + ti.type).c_str(), std::string{GUNIT_SHOULD_PREFIX + ti.should}.c_str(),
155-
new internal::TestMetaFactory<T>());
156-
registered = true;
157-
}
158-
}
159-
return registered;
160-
}
144+
//bool RegisterShouldParamTestCase() {
145+
//auto registered = false;
146+
//for (const auto& ti : tests()) {
147+
//if (GetTypeName(detail::type<typename T::TEST_TYPE>{}) == ti.type && T::TEST_NAME::c_str() == ti.name) {
148+
//UnitTest::GetInstance()
149+
//->parameterized_test_registry()
150+
//.GetTestCasePatternHolder<T>(ti.type.c_str(), {ti.file, ti.line})
151+
//->AddTestPattern((IsDisabled(ti.disabled) + ti.type).c_str(), std::string{GUNIT_SHOULD_PREFIX + ti.should}.c_str(),
152+
//new internal::TestMetaFactory<T>());
153+
//registered = true;
154+
//}
155+
//}
156+
//return registered;
157+
//}
161158

162159
public:
163160
GTestAutoRegister() {
164-
if (!RegisterShouldTestCase()) {
165-
MakeAndRegisterTestInfo({DISABLED,
166-
{},
167-
GetTypeName(detail::type<typename T::TEST_TYPE>{}),
168-
T::TEST_NAME::c_str(),
169-
T::TEST_FILE,
170-
T::TEST_LINE,
171-
{}},
161+
MakeAndRegisterTestInfo(DISABLED,
162+
GetTypeName(detail::type<typename T::TEST_TYPE>{}),
163+
T::TEST_NAME::c_str(),
164+
T::TEST_FILE,
165+
T::TEST_LINE,
172166
detail::type<decltype(internal::MakeAndRegisterTestInfo)>{});
173-
}
174167
}
175168

176169
template <class TEval, class TGenerateNames>
177-
explicit GTestAutoRegister(const TEval& eval, const TGenerateNames& genNames) {
178-
if (!RegisterShouldParamTestCase()) {
179-
UnitTest::GetInstance()
180-
->parameterized_test_registry()
181-
.GetTestCasePatternHolder<T>(GetTypeName(detail::type<typename T::TEST_TYPE>{}), {T::TEST_FILE, T::TEST_LINE})
182-
->AddTestPattern(GetTypeName(detail::type<typename T::TEST_TYPE>{}),
183-
GetTypeName(detail::type<typename T::TEST_TYPE>{}), new internal::TestMetaFactory<T>());
184-
}
185-
186-
UnitTest::GetInstance()
187-
->parameterized_test_registry()
188-
.GetTestCasePatternHolder<T>(GetTypeName(detail::type<typename T::TEST_TYPE>{}), {T::TEST_FILE, T::TEST_LINE})
189-
->AddTestCaseInstantiation((std::string{IsDisabled(DISABLED)} + T::TEST_NAME::c_str()).c_str(), eval, genNames,
190-
T::TEST_FILE, T::TEST_LINE);
170+
GTestAutoRegister(const TEval& eval, const TGenerateNames& genNames) {
171+
(void)eval;
172+
(void)genNames;
173+
//if (!RegisterShouldParamTestCase()) {
174+
//UnitTest::GetInstance()
175+
//->parameterized_test_registry()
176+
//.GetTestCasePatternHolder<T>(GetTypeName(detail::type<typename T::TEST_TYPE>{}), {T::TEST_FILE, T::TEST_LINE})
177+
//->AddTestPattern(GetTypeName(detail::type<typename T::TEST_TYPE>{}),
178+
//GetTypeName(detail::type<typename T::TEST_TYPE>{}), new internal::TestMetaFactory<T>());
179+
//}
180+
181+
//UnitTest::GetInstance()
182+
//->parameterized_test_registry()
183+
//.GetTestCasePatternHolder<T>(GetTypeName(detail::type<typename T::TEST_TYPE>{}), {T::TEST_FILE, T::TEST_LINE})
184+
//->AddTestCaseInstantiation((std::string{IsDisabled(DISABLED)} + T::TEST_NAME::c_str()).c_str(), eval, genNames,
185+
//T::TEST_FILE, T::TEST_LINE);
191186
}
192187
};
193188

@@ -224,11 +219,6 @@ class GTest<T, TParamType, std::false_type, TAny> : public Test {
224219
template <class T, class TParamType>
225220
class GTest<T, TParamType, std::true_type, std::true_type> : public T {};
226221

227-
template <bool Disabled, class Name, class File, int Line, class Should, class T>
228-
bool SHOULD_REGISTER_GTEST() {
229-
static auto shouldRegister = true;
230-
return shouldRegister;
231-
}
232222
} // detail
233223

234224
template <class T = detail::none_t, class TParamType = void>
@@ -253,14 +243,20 @@ class GTest : public detail::GTest<T, TParamType> {};
253243
::testing::detail::apply_t<std::common_type_t, decltype(PARAMS)>> { \
254244
using TEST_TYPE = __GUNIT_CAT(GTEST_TYPE_, __LINE__); \
255245
using TEST_NAME = NAME; \
256-
\
257246
static constexpr auto TEST_FILE = __FILE__; \
258247
static constexpr auto TEST_LINE = __LINE__; \
259-
void TestBody(); \
248+
void TestBodyImpl(::testing::detail::TestRun&); \
249+
void TestBody() {\
250+
::testing::detail::TestRun tr; \
251+
while(tr.once) {\
252+
tr.once = false; \
253+
TestBodyImpl(tr);\
254+
}; \
255+
} \
260256
}; \
261257
static ::testing::detail::GTestAutoRegister<DISABLED, GTEST<__GUNIT_CAT(GTEST_TYPE_, __LINE__), NAME>> __GUNIT_CAT( \
262258
ar, __LINE__){__VA_ARGS__}; \
263-
void GTEST<__GUNIT_CAT(GTEST_TYPE_, __LINE__), NAME>::TestBody()
259+
void GTEST<__GUNIT_CAT(GTEST_TYPE_, __LINE__), NAME>::TestBodyImpl(::testing::detail::TestRun& __attribute__((unused)) tr_gtest)
264260

265261
#define __GTEST_IMPL_1(DISABLED, TYPE) \
266262
__GTEST_IMPL(DISABLED, TYPE, ::testing::detail::string<>, ::testing::detail::type<void>{}, )
@@ -285,13 +281,7 @@ class GTest : public detail::GTest<T, TParamType> {};
285281
#define DISABLED_GTEST(...) __GUNIT_CAT(__GTEST_IMPL_, __GUNIT_SIZE(__VA_ARGS__))(true, __VA_ARGS__)
286282

287283
#define SHOULD(NAME) \
288-
if (::testing::detail::SHOULD_REGISTER_GTEST<false, TEST_NAME, decltype(__GUNIT_CAT(__FILE__, _gtest_string)), __LINE__, \
289-
decltype(__GUNIT_CAT(NAME, _gtest_string)), TEST_TYPE>() && \
290-
std::string{::testing::UnitTest::GetInstance()->current_test_info()->name()}.find(std::string{GUNIT_SHOULD_PREFIX} + \
291-
NAME) != std::string::npos)
284+
if (tr_gtest.run(NAME, __LINE__))
292285

293286
#define DISABLED_SHOULD(NAME) \
294-
if (::testing::detail::SHOULD_REGISTER_GTEST<true, TEST_NAME, decltype(__GUNIT_CAT(__FILE__, _gtest_string)), __LINE__, \
295-
decltype(__GUNIT_CAT(NAME, _gtest_string)), TEST_TYPE>() && \
296-
std::string{::testing::UnitTest::GetInstance()->current_test_info()->name()}.find(std::string{GUNIT_SHOULD_PREFIX} + \
297-
NAME) != std::string::npos)
287+
if (false)

0 commit comments

Comments
 (0)