Go to the documentation of this file.00001 #ifndef __HAYAI_JSONOUTPUTTER
00002 #define __HAYAI_JSONOUTPUTTER
00003 #include <iomanip>
00004 #include <ostream>
00005
00006 #include "hayai/hayai_outputter.hpp"
00007
00008
00009 #define JSON_OBJECT_BEGIN "{"
00010 #define JSON_OBJECT_END "}"
00011 #define JSON_ARRAY_BEGIN "["
00012 #define JSON_ARRAY_END "]"
00013 #define JSON_STRING_BEGIN "\""
00014 #define JSON_STRING_END "\""
00015 #define JSON_NAME_SEPARATOR ":"
00016 #define JSON_VALUE_SEPARATOR ","
00017 #define JSON_TRUE "true"
00018 #define JSON_FALSE "false"
00019
00020 namespace hayai
00021 {
00023
00050 class JsonOutputter
00051 : public Outputter
00052 {
00053 public:
00055
00058 JsonOutputter(std::ostream& stream)
00059 : _stream(stream),
00060 _firstTest(true)
00061 {
00062
00063 }
00064
00065
00066 virtual void Begin(const std::size_t& enabledCount,
00067 const std::size_t& disabledCount)
00068 {
00069 (void)enabledCount;
00070 (void)disabledCount;
00071
00072 _stream <<
00073 JSON_OBJECT_BEGIN
00074
00075 JSON_STRING_BEGIN "format_version" JSON_STRING_END
00076 JSON_NAME_SEPARATOR
00077 "1"
00078
00079 JSON_VALUE_SEPARATOR
00080
00081 JSON_STRING_BEGIN "benchmarks" JSON_STRING_END
00082 JSON_NAME_SEPARATOR
00083 JSON_ARRAY_BEGIN;
00084 }
00085
00086
00087 virtual void End(const std::size_t& executedCount,
00088 const std::size_t& disabledCount)
00089 {
00090 (void)executedCount;
00091 (void)disabledCount;
00092
00093 _stream <<
00094 JSON_ARRAY_END
00095 JSON_OBJECT_END;
00096 }
00097
00098
00099 virtual void BeginTest(const std::string& fixtureName,
00100 const std::string& testName,
00101 const TestParametersDescriptor& parameters,
00102 const std::size_t& runsCount,
00103 const std::size_t& iterationsCount)
00104 {
00105 BeginTestObject(fixtureName,
00106 testName,
00107 parameters,
00108 runsCount,
00109 iterationsCount,
00110 false);
00111 }
00112
00113
00114 virtual void SkipDisabledTest(const std::string& fixtureName,
00115 const std::string& testName,
00116 const TestParametersDescriptor& parameters,
00117 const std::size_t& runsCount,
00118 const std::size_t& iterationsCount)
00119 {
00120 BeginTestObject(fixtureName,
00121 testName,
00122 parameters,
00123 runsCount,
00124 iterationsCount,
00125 true);
00126 EndTestObject();
00127 }
00128
00129
00130 virtual void EndTest(const std::string& fixtureName,
00131 const std::string& testName,
00132 const TestParametersDescriptor& parameters,
00133 const TestResult& result)
00134 {
00135 (void)fixtureName;
00136 (void)testName;
00137 (void)parameters;
00138
00139 _stream <<
00140 JSON_VALUE_SEPARATOR
00141
00142 JSON_STRING_BEGIN "runs" JSON_STRING_END
00143 JSON_NAME_SEPARATOR
00144 JSON_ARRAY_BEGIN;
00145
00146 const std::vector<uint64_t>& runTimes = result.RunTimes();
00147
00148 for (std::vector<uint64_t>::const_iterator it = runTimes.begin();
00149 it != runTimes.end();
00150 ++it)
00151 {
00152 if (it != runTimes.begin())
00153 {
00154 _stream << JSON_VALUE_SEPARATOR;
00155 }
00156
00157 _stream << JSON_OBJECT_BEGIN
00158
00159 JSON_STRING_BEGIN "duration" JSON_STRING_END
00160 JSON_NAME_SEPARATOR
00161 << std::fixed
00162 << std::setprecision(6)
00163 << (double(*it) / 1000000.0)
00164 << JSON_OBJECT_END;
00165 }
00166
00167 _stream <<
00168 JSON_ARRAY_END;
00169
00170 EndTestObject();
00171 }
00172 private:
00173 void BeginTestObject(const std::string& fixtureName,
00174 const std::string& testName,
00175 const TestParametersDescriptor& parameters,
00176 const std::size_t& runsCount,
00177 const std::size_t& iterationsCount,
00178 bool disabled)
00179 {
00180 (void)runsCount;
00181
00182 if (_firstTest)
00183 {
00184 _firstTest = false;
00185 }
00186 else
00187 {
00188 _stream << JSON_VALUE_SEPARATOR;
00189 }
00190
00191 _stream <<
00192 JSON_OBJECT_BEGIN
00193
00194 JSON_STRING_BEGIN "fixture" JSON_STRING_END
00195 JSON_NAME_SEPARATOR;
00196
00197 WriteString(fixtureName);
00198
00199 _stream <<
00200 JSON_VALUE_SEPARATOR
00201
00202 JSON_STRING_BEGIN "name" JSON_STRING_END
00203 JSON_NAME_SEPARATOR;
00204
00205 WriteString(testName);
00206
00207 _stream <<
00208 JSON_VALUE_SEPARATOR;
00209
00210 const std::vector<TestParameterDescriptor>& descs =
00211 parameters.Parameters();
00212
00213 if (!descs.empty())
00214 {
00215 _stream <<
00216 JSON_STRING_BEGIN "parameters" JSON_STRING_END
00217 JSON_NAME_SEPARATOR
00218 JSON_ARRAY_BEGIN;
00219
00220 for (std::size_t i = 0; i < descs.size(); ++i)
00221 {
00222 if (i)
00223 {
00224 _stream << JSON_VALUE_SEPARATOR;
00225 }
00226
00227 const TestParameterDescriptor& desc = descs[i];
00228
00229 _stream <<
00230 JSON_OBJECT_BEGIN
00231
00232 JSON_STRING_BEGIN "declaration" JSON_STRING_END
00233 JSON_NAME_SEPARATOR;
00234
00235 WriteString(desc.Declaration);
00236
00237 _stream <<
00238 JSON_VALUE_SEPARATOR
00239
00240 JSON_STRING_BEGIN "value" JSON_STRING_END
00241 JSON_NAME_SEPARATOR;
00242
00243 WriteString(desc.Value);
00244
00245 _stream <<
00246 JSON_OBJECT_END;
00247 }
00248
00249 _stream <<
00250 JSON_ARRAY_END
00251 JSON_VALUE_SEPARATOR;
00252 }
00253
00254 _stream <<
00255 JSON_STRING_BEGIN "iterations_per_run" JSON_STRING_END
00256 JSON_NAME_SEPARATOR << iterationsCount <<
00257
00258 JSON_VALUE_SEPARATOR
00259
00260 JSON_STRING_BEGIN "disabled" JSON_STRING_END
00261 JSON_NAME_SEPARATOR << (disabled ? JSON_TRUE : JSON_FALSE);
00262 }
00263
00264
00265 inline void EndTestObject()
00266 {
00267 _stream <<
00268 JSON_OBJECT_END;
00269 }
00270
00271
00273
00278 void WriteString(const std::string& str)
00279 {
00280 _stream << JSON_STRING_BEGIN;
00281
00282 std::string::const_iterator it = str.begin();
00283
00284 while (it != str.end())
00285 {
00286 char c = *it++;
00287
00288 switch (c)
00289 {
00290 case '\\':
00291 case '"':
00292 case '/':
00293 _stream << "\\" << c;
00294 break;
00295
00296 case '\b':
00297 _stream << "\\b";
00298 break;
00299
00300 case '\f':
00301 _stream << "\\f";
00302 break;
00303
00304 case '\n':
00305 _stream << "\\n";
00306 break;
00307
00308 case '\r':
00309 _stream << "\\r";
00310 break;
00311
00312 case '\t':
00313 _stream << "\\t";
00314 break;
00315
00316 default:
00317 _stream << c;
00318 break;
00319 }
00320 }
00321
00322 _stream << JSON_STRING_END;
00323 }
00324
00325
00326 std::ostream& _stream;
00327 bool _firstTest;
00328 };
00329 }
00330
00331 #undef JSON_OBJECT_BEGIN
00332 #undef JSON_OBJECT_END
00333 #undef JSON_ARRAY_BEGIN
00334 #undef JSON_ARRAY_END
00335 #undef JSON_STRING_BEGIN
00336 #undef JSON_STRING_END
00337 #undef JSON_NAME_SEPARATOR
00338 #undef JSON_VALUE_SEPARATOR
00339 #undef JSON_TRUE
00340 #undef JSON_FALSE
00341
00342 #endif