hayai_test_descriptor.hpp
Go to the documentation of this file.
00001 #ifndef __HAYAI_TESTDESCRIPTOR
00002 #define __HAYAI_TESTDESCRIPTOR
00003 #include <cstring>
00004 #include <sstream>
00005 #include <string>
00006 #include <vector>
00007 
00008 #include "hayai/hayai_test.hpp"
00009 #include "hayai/hayai_test_factory.hpp"
00010 
00011 
00012 namespace hayai
00013 {
00015 
00017     class TestParameterDescriptor
00018     {
00019     public:
00020         TestParameterDescriptor(std::string declaration,
00021                                 std::string value)
00022             :   Declaration(declaration),
00023                 Value(value)
00024         {
00025 
00026         }
00027 
00028 
00030         std::string Declaration;
00031 
00032 
00034         std::string Value;
00035     };
00036 
00037 
00039     class TestParametersDescriptor
00040     {
00041     private:
00043         enum QuotingState
00044         {
00046             Unquoted,
00047 
00048 
00050             SingleQuoted,
00051 
00052 
00054             DoubleQuoted
00055         };
00056 
00057 
00059 
00062         inline static std::string TrimmedString(const char* start,
00063                                                 const char* end)
00064         {
00065             while (start < end)
00066             {
00067                 if ((*start == ' ') ||
00068                         (*start == '\r') ||
00069                         (*start == '\n') ||
00070                         (*start == '\t'))
00071                 {
00072                     ++start;
00073                 }
00074                 else
00075                 {
00076                     break;
00077                 }
00078             }
00079 
00080             while (end > start)
00081             {
00082                 const char c = *(end - 1);
00083 
00084                 if ((c != ' ') &&
00085                         (c != '\r') &&
00086                         (c != '\n') &&
00087                         (c != '\t'))
00088                 {
00089                     break;
00090                 }
00091 
00092                 --end;
00093             }
00094 
00095             return std::string(start, std::string::size_type(end - start));
00096         }
00097 
00098 
00100 
00103         static std::vector<std::string>
00104         ParseCommaSeparated(const char* separated)
00105         {
00106             std::vector<std::string> result;
00107 
00108             if (*separated)
00109             {
00110                 ++separated;
00111             }
00112 
00113             while ((*separated) && (*separated != ')'))
00114             {
00115                 std::size_t escapeCounter = 0;
00116                 const char* start = separated;
00117                 QuotingState state = Unquoted;
00118                 bool escaped = false;
00119 
00120                 while (*separated)
00121                 {
00122                     const char c = *separated++;
00123 
00124                     if (state == Unquoted)
00125                     {
00126                         if ((c == '"') || (c == '\''))
00127                         {
00128                             state = (c == '"' ? DoubleQuoted : SingleQuoted);
00129                             escaped = false;
00130                         }
00131                         else if ((c == '<') ||
00132                                  (c == '(') ||
00133                                  (c == '[') ||
00134                                  (c == '{'))
00135                         {
00136                             ++escapeCounter;
00137                         }
00138                         else if ((escapeCounter) &&
00139                                  ((c == '>') ||
00140                                   (c == ')') ||
00141                                   (c == ']') ||
00142                                   (c == '}')))
00143                         {
00144                             --escapeCounter;
00145                         }
00146                         else if ((!escapeCounter) &&
00147                                  ((c == ',') || (c == ')')))
00148                         {
00149                             result.push_back(TrimmedString(start,
00150                                                            separated - 1));
00151                             break;
00152                         }
00153                     }
00154                     else
00155                     {
00156                         if (escaped)
00157                         {
00158                             escaped = false;
00159                         }
00160                         else if (c == '\\')
00161                         {
00162                             escaped = true;
00163                         }
00164                         else if (c == (state == DoubleQuoted ? '"' : '\''))
00165                         {
00166                             state = Unquoted;
00167                         }
00168                     }
00169                 }
00170             }
00171 
00172             return result;
00173         }
00174 
00175 
00177 
00179         TestParameterDescriptor ParseDescriptor(const std::string& raw)
00180         {
00181             const char* position = raw.c_str();
00182 
00183             // Split the declaration into its declaration and its default
00184             // type.
00185             const char* equalPosition = NULL;
00186             std::size_t escapeCounter = 0;
00187             QuotingState state = Unquoted;
00188             bool escaped = false;
00189 
00190             while (*position)
00191             {
00192                 const char c = *position++;
00193 
00194                 if (state == Unquoted)
00195                 {
00196                     if ((c == '"') || (c == '\''))
00197                     {
00198                         state = (c == '"' ? DoubleQuoted : SingleQuoted);
00199                         escaped = false;
00200                     }
00201                     else if ((c == '<') ||
00202                              (c == '(') ||
00203                              (c == '[') ||
00204                              (c == '{'))
00205                     {
00206                         ++escapeCounter;
00207                     }
00208                     else if ((escapeCounter) &&
00209                              ((c == '>') ||
00210                               (c == ')') ||
00211                               (c == ']') ||
00212                               (c == '}')))
00213                     {
00214                         --escapeCounter;
00215                     }
00216                     else if ((!escapeCounter) &&
00217                              (c == '='))
00218                     {
00219                         equalPosition = position;
00220                         break;
00221                     }
00222                 }
00223                 else
00224                 {
00225                     if (escaped)
00226                     {
00227                         escaped = false;
00228                     }
00229                     else if (c == '\\')
00230                     {
00231                         escaped = true;
00232                     }
00233                     else if (c == (state == DoubleQuoted ? '"' : '\''))
00234                     {
00235                         state = Unquoted;
00236                     }
00237                 }
00238             }
00239 
00240             // Construct the parameter descriptor.
00241             if (equalPosition)
00242             {
00243                 const char* start = raw.c_str();
00244                 const char* end = start + raw.length();
00245 
00246                 return TestParameterDescriptor(
00247                            std::string(TrimmedString(start,
00248                                                      equalPosition - 1)),
00249                            std::string(TrimmedString(equalPosition,
00250                                                      end))
00251                        );
00252             }
00253             else
00254             {
00255                 return TestParameterDescriptor(raw, std::string());
00256             }
00257         }
00258     public:
00259         TestParametersDescriptor()
00260         {
00261 
00262         }
00263 
00264 
00265         TestParametersDescriptor(const char* rawDeclarations,
00266                                  const char* rawValues)
00267         {
00268             // Parse the declarations.
00269             std::vector<std::string> declarations =
00270                 ParseCommaSeparated(rawDeclarations);
00271 
00272             for (std::vector<std::string>::const_iterator it =
00273                         declarations.begin();
00274                     it != declarations.end();
00275                     ++it)
00276             {
00277                 _parameters.push_back(ParseDescriptor(*it));
00278             }
00279 
00280             // Parse the values.
00281             std::vector<std::string> values = ParseCommaSeparated(rawValues);
00282 
00283             std::size_t
00284             straightValues = (_parameters.size() > values.size() ?
00285                               values.size() :
00286                               _parameters.size()),
00287                              variadicValues = 0;
00288 
00289             if (values.size() > _parameters.size())
00290             {
00291                 if (straightValues > 0)
00292                 {
00293                     --straightValues;
00294                 }
00295 
00296                 variadicValues = values.size() - _parameters.size() + 1;
00297             }
00298 
00299             for (std::size_t i = 0; i < straightValues; ++i)
00300             {
00301                 _parameters[i].Value = values[i];
00302             }
00303 
00304             if (variadicValues)
00305             {
00306                 std::stringstream variadic;
00307 
00308                 for (std::size_t i = 0; i < variadicValues; ++i)
00309                 {
00310                     if (i)
00311                     {
00312                         variadic << ", ";
00313                     }
00314 
00315                     variadic << values[straightValues + i];
00316                 }
00317 
00318                 _parameters[_parameters.size() - 1].Value = variadic.str();
00319             }
00320         }
00321 
00322 
00323         inline const std::vector<TestParameterDescriptor>& Parameters() const
00324         {
00325             return _parameters;
00326         }
00327     private:
00328         std::vector<TestParameterDescriptor> _parameters;
00329     };
00330 
00331 
00333     class TestDescriptor
00334     {
00335     public:
00337 
00344         TestDescriptor(const char* fixtureName,
00345                        const char* testName,
00346                        std::size_t runs,
00347                        std::size_t iterations,
00348                        TestFactory* testFactory,
00349                        TestParametersDescriptor parameters,
00350                        bool isDisabled = false)
00351             :   FixtureName(fixtureName),
00352                 TestName(testName),
00353                 CanonicalName(std::string(fixtureName) + "." + testName),
00354                 Runs(runs),
00355                 Iterations(iterations),
00356                 Factory(testFactory),
00357                 Parameters(parameters),
00358                 IsDisabled(isDisabled)
00359         {
00360 
00361         }
00362 
00363 
00365         ~TestDescriptor()
00366         {
00367             delete this->Factory;
00368         }
00369 
00370 
00372         std::string FixtureName;
00373 
00374 
00376         std::string TestName;
00377 
00378 
00380 
00382         std::string CanonicalName;
00383 
00384 
00386         std::size_t Runs;
00387 
00388 
00390         std::size_t Iterations;
00391 
00392 
00394         TestFactory* Factory;
00395 
00396 
00398         TestParametersDescriptor Parameters;
00399 
00400 
00402         bool IsDisabled;
00403     };
00404 }
00405 #endif


hayai
Author(s): Nick Bruun
autogenerated on Thu Jun 6 2019 18:13:43