CPUnit 0.95 (beta)
The REAL C++ port of JUnit.
/Users/Shared/Development/cpp/sourceforge/cpunit_095/src/cpunit_ErrorReportFormat.cpp
Go to the documentation of this file.
00001 /*
00002    Copyright (c) 2011 Daniel Bakkelund.
00003    All rights reserved.
00004 
00005    Redistribution and use in source and binary forms, with or without
00006    modification, are permitted provided that the following conditions
00007    are met:
00008     1. Redistributions of source code must retain the above copyright
00009        notice, this list of conditions and the following disclaimer.
00010     2. Redistributions in binary form must reproduce the above copyright
00011        notice, this list of conditions and the following disclaimer in the
00012        documentation and/or other materials provided with the distribution.
00013     3. Neither the name of the copyright holders nor the names of its
00014        contributors may be used to endorse or promote products derived from
00015        this software without specific prior written permission.
00016 
00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00027    THE POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 
00031 
00032 #include "cpunit_WrongSetupException.hpp"
00033 #include "cpunit_ErrorReportFormat.hpp"
00034 #include "cpunit_ExecutionReport.hpp"
00035 #include "cpunit_TimeFormat.hpp"
00036 
00037 #include <sstream>
00038 
00039 cpunit::ErrorReportFormat::ErrorReportFormat()
00040 {}
00041 
00042 cpunit::ErrorReportFormat::ErrorReportFormat(const std::string &format) {
00043   parse(format);
00044 }
00045 
00046 cpunit::ErrorReportFormat::ErrorReportFormat(const ErrorReportFormat &o) :
00047   msg_parts(o.msg_parts),
00048   fragments(o.fragments)
00049 {}
00050 
00051 cpunit::ErrorReportFormat::~ErrorReportFormat()
00052 {}
00053 
00054 cpunit::ErrorReportFormat& 
00055 cpunit::ErrorReportFormat::operator = (const ErrorReportFormat &o) {
00056   if (&o != this) {
00057     msg_parts = o.msg_parts;
00058     fragments = o.fragments;
00059   }
00060   return *this;
00061 }
00062 
00063 std::string 
00064 cpunit::ErrorReportFormat::format(const ExecutionReport &r) const {
00065   std::ostringstream oss;
00066   for (std::size_t i=0; i<fragments.size(); i++) {
00067     oss<<msg_parts[i]<<format(r, fragments[i]);
00068   }
00069   oss<<msg_parts[fragments.size()];
00070   return oss.str();
00071 }
00072 
00073 std::string
00074 cpunit::ErrorReportFormat::format(const ExecutionReport &r, const Fragment f) const {
00075   switch (f) {
00076   case PATH:
00077     return r.get_test().get_path();
00078   case TEST_NAME:
00079     return r.get_test().get_name();
00080   case TEST_TIME:
00081     return TimeFormat(r.get_time_spent()).get_formatted_time();
00082   case FILE:
00083     return r.get_test().get_file();
00084   case LINE:
00085     return r.get_test().get_line();
00086   case MESSAGE:
00087     return r.get_message();
00088   case ERROR_TYPE:
00089     return ExecutionReport::translate(r.get_execution_result());
00090   case NEWLINE:
00091     return "\n";
00092   case TABULATOR:
00093     return "\t";
00094   default:
00095     throw "Unknown fragment type."; 
00096   }
00097 }
00098 
00099 void
00100 cpunit::ErrorReportFormat::parse(const std::string &format) {
00101   std::ostringstream oss;
00102   for (std::size_t i=0; i<format.length(); i++) {
00103     const char c = format[i];
00104     if (c == '%') {
00105       const char f = format[++i];
00106       if (f == '%') {
00107    oss<<f;
00108       } else {
00109    msg_parts.push_back(oss.str());
00110    oss.str("");
00111    handle_fragment_identifier(f);
00112       }
00113     } else {
00114       oss<<c;
00115     }
00116   }
00117   msg_parts.push_back(oss.str());
00118 }
00119 
00120 void 
00121 cpunit::ErrorReportFormat::handle_fragment_identifier(const char c) {
00122   switch (c) {
00123   case 'p':
00124     fragments.push_back(PATH);
00125     break;
00126   case 'n':
00127     fragments.push_back(TEST_NAME);
00128     break;
00129   case 't':
00130     fragments.push_back(TEST_TIME);
00131     break;
00132   case 'f':
00133     fragments.push_back(FILE);
00134     break;
00135   case 'l':
00136     fragments.push_back(LINE);
00137     break;
00138   case 'm':
00139     fragments.push_back(MESSAGE);
00140     break;
00141   case 'e':
00142     fragments.push_back(ERROR_TYPE);
00143     break;
00144   case 'N':
00145     fragments.push_back(NEWLINE);
00146     break;
00147   case 'T':
00148     fragments.push_back(TABULATOR);
00149     break;
00150   default:
00151     std::ostringstream oss;
00152     oss<<"Unknown flag in error format: '%"<<c<<"', must be one of [p n f l m e t N T].";
00153     throw WrongSetupException(oss.str());
00154   }
00155 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines