@@ -39,9 +39,10 @@ template <class T>
3939class GTestAutoRegister {
4040 struct TestInfo {
4141 std::string type;
42+ std::string name;
4243 std::string file;
4344 unsigned long long line;
44- std::string name ;
45+ std::string should ;
4546 };
4647
4748 auto parse (const std::string& line) {
@@ -53,6 +54,13 @@ class GTestAutoRegister {
5354 std::getline (stream, token, ' <' );
5455 std::getline (stream, token, ' >' );
5556
57+ std::istringstream nameStream (token);
58+ while (std::getline (nameStream, token, ' ,' )) {
59+ const auto begin = token.find (' )' );
60+ ti.name += static_cast <char >(std::atoi (token.substr (begin + 1 ).c_str ()));
61+ }
62+ std::getline (stream, token, ' ,' );
63+
5664 std::istringstream fileStream (token);
5765 while (std::getline (fileStream, token, ' ,' )) {
5866 const auto begin = token.find (' )' );
@@ -65,10 +73,10 @@ class GTestAutoRegister {
6573
6674 std::getline (stream, token, ' <' );
6775 std::getline (stream, token, ' >' );
68- std::istringstream nameStream (token);
69- while (std::getline (nameStream , token, ' ,' )) {
76+ std::istringstream shouldStream (token);
77+ while (std::getline (shouldStream , token, ' ,' )) {
7078 const auto begin = token.find (' )' );
71- ti.name += static_cast <char >(std::atoi (token.substr (begin + 1 ).c_str ()));
79+ ti.should += static_cast <char >(std::atoi (token.substr (begin + 1 ).c_str ()));
7280 }
7381
7482 return ti;
@@ -78,16 +86,15 @@ class GTestAutoRegister {
7886 GTestAutoRegister () {
7987 for (const auto & testInfo : getSymbols ()) {
8088 const auto test = parse (testInfo);
81- if (get_type_name<typename T::TEST_TYPE>() == test.type ) {
89+ if (get_type_name<typename T::TEST_TYPE>() == test.type && T::TEST_NAME::c_str () == test. name ) {
8290 ::testing::internal::MakeAndRegisterTestInfo (
83- test.type. c_str(), (std::string{" should " } + test.name ).c_str(), nullptr, nullptr,
91+ ( test.type + test.name). c_str(), (std::string{" should " } + test.should ).c_str(), nullptr, nullptr,
8492 ::testing::internal::CodeLocation(test.file.c_str(), test.line), ::testing::internal::GetTestTypeId(),
8593 ::testing::Test::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing::detail::GTestFactoryImpl<T>{});
8694 }
8795 }
8896 }
8997};
90-
9198template <class T , class = detail::is_complete<T>>
9299class GTest {
93100 protected:
@@ -108,35 +115,55 @@ class GTest {
108115 SUT sut; // has to be after mocks
109116};
110117
111- template <class T , class File , unsigned long long Line, class Name >
118+ template <class T >
119+ class GTest <T, std::false_type> {};
120+
121+ template <class T , class Name , class File , unsigned long long Line, class Should >
112122void SHOULD_REGISTER_GTEST () {
113123 static auto once = true ;
114124 once = false ;
115125 (void )once;
116126}
117-
118- template <class T >
119- class GTest <T, std::false_type> {};
120127} // detail
121128
122129template <class T = detail::none_t >
123130class GTest : public detail ::GTest<T>, public Test {};
124-
125131} // v1
126132} // testing
127133
128- #define GTEST (TYPE ) \
129- template <class > \
134+ #define GTEST (...) __GUNIT_CAT(GTEST_IMPL_, __GUNIT_SIZE(__VA_ARGS__))(__VA_ARGS__)
135+
136+ #define GTEST_IMPL_1 (TYPE ) \
137+ template <class ...> \
130138 struct GTEST ; \
131139 template <> \
132140 struct GTEST <TYPE> : ::testing::detail::GTest<TYPE> { \
133141 using TEST_TYPE = TYPE; \
142+ using TEST_NAME = ::testing::detail::string<>; \
134143 void test (); \
135144 }; \
136145 ::testing::detail::GTestAutoRegister<GTEST<TYPE>> __GUNIT_CAT (ar, __LINE__){}; \
137146 void GTEST<TYPE>::test()
138147
139- #define SHOULD (NAME ) \
140- using namespace ::testing::detail; \
141- SHOULD_REGISTER_GTEST<TEST_TYPE, decltype (__GUNIT_CAT(__FILE__, _s)), __LINE__, decltype (__GUNIT_CAT(NAME, _s))>(); \
148+ #define GTEST_IMPL_2 (TYPE, NAME ) \
149+ auto __GUNIT_CAT (GTESET_IMPL_TEST_NAME, __LINE__)() { \
150+ using namespace ::testing::detail; \
151+ return __GUNIT_CAT (NAME, _s); \
152+ } \
153+ template <class ...> \
154+ struct GTEST ; \
155+ template <> \
156+ struct GTEST <TYPE, decltype (__GUNIT_CAT(GTESET_IMPL_TEST_NAME, __LINE__))> : ::testing::detail::GTest<TYPE> { \
157+ using TEST_TYPE = TYPE; \
158+ using TEST_NAME = decltype (__GUNIT_CAT(GTESET_IMPL_TEST_NAME, __LINE__)()); \
159+ void test (); \
160+ }; \
161+ ::testing::detail::GTestAutoRegister<GTEST<TYPE, decltype (__GUNIT_CAT(GTESET_IMPL_TEST_NAME, __LINE__))>> __GUNIT_CAT ( \
162+ ar, __LINE__){}; \
163+ void GTEST<TYPE, decltype (__GUNIT_CAT(GTESET_IMPL_TEST_NAME, __LINE__))>::test()
164+
165+ #define SHOULD (NAME ) \
166+ using namespace ::testing::detail; \
167+ SHOULD_REGISTER_GTEST<TEST_TYPE, TEST_NAME, decltype (__GUNIT_CAT(__FILE__, _s)), __LINE__, \
168+ decltype (__GUNIT_CAT(NAME, _s))>(); \
142169 if (std::string{" should " } + NAME == ::testing::UnitTest::GetInstance()->current_test_info ()->name())
0 commit comments