CppUnit project page CppUnit home page

testinfo.h

Go to the documentation of this file.
00001 #ifndef CPPUT_TESTINFO_H_INCLUDED
00002 # define CPPUT_TESTINFO_H_INCLUDED
00003 
00004 # include <cpput/forwards.h>
00005 # include <cpput/message.h>
00006 # include <cpptl/intrusiveptr.h>
00007 # include <json/value.h>
00008 # include <stdexcept>
00009 
00010 namespace CppUT {
00011 
00012 
00017    class CPPUT_API AbortingAssertionException : public std::runtime_error
00018    {
00019    public:
00020       AbortingAssertionException( const std::string &message )
00021          : std::runtime_error( "AbortingAssertionException:\n" + message )
00022       {
00023       }
00024 
00025       virtual ~AbortingAssertionException() throw()
00026       {
00027       }
00028    };
00029 
00030 
00035    class CPPUT_API SkipTestException : public std::runtime_error
00036    {
00037    public:
00038       SkipTestException()
00039          : std::runtime_error( "SkipTestException" )
00040       {
00041       }
00042 
00043       virtual ~SkipTestException() throw()
00044       {
00045       }
00046    };
00047 
00048 
00053    class CPPUT_API UndeclaredResourceException : public std::runtime_error
00054    {
00055    public:
00056       UndeclaredResourceException( const std::string &resourceName )
00057          : std::runtime_error( "UndeclaredResourceException: " + resourceName )
00058       {
00059       }
00060 
00061       virtual ~UndeclaredResourceException() throw()
00062       {
00063       }
00064    };
00065 
00068    class SourceLocation
00069    {
00070    public:
00071       SourceLocation( const char *file = 0,
00072                       unsigned int line =0 )
00073          : file_( file )
00074          , line_( line )
00075       {
00076       }
00077 
00078       void clear()
00079       {
00080          file_ = 0;
00081          line_ = 0;
00082       }
00083 
00084       bool isValid() const
00085       {
00086          return file_ != 0;
00087       }
00088 
00089       const char *file_;
00090       unsigned int line_;
00091    };
00092 
00096    class CPPUT_API Assertion
00097    {
00098    public:
00099       enum Kind
00100       {
00101          fault = 1,
00102          assertion = 2
00103       };
00104 
00105       Assertion( Kind kind = assertion,
00106                  const SourceLocation &sourceLocation = SourceLocation() );
00107 
00108       void setLocation( const SourceLocation &location );
00109       const SourceLocation &location() const;
00110 
00111       void setKind( Kind kind_ );
00112       Kind kind() const;
00113 
00114       void setIgnoredFailure();
00115       bool isIgnoredFailure() const;
00116 
00117       void setMessages( const Message &messages );
00118       const Message &messages() const;
00119 
00120       void setTestDataType( const std::string &type );
00121       std::string testDataType() const;
00122 
00123       void setTestData( const std::string &name,
00124                         const Json::Value &value,
00125                         const std::string &type = "basic" );
00126 
00127       const Json::Value &testData() const;
00128 
00129       std::string toString() const;
00130 
00131    private:
00132       Message messages_;
00133       Json::Value testData_;
00134       CppTL::ConstString testDataType_;
00135       SourceLocation location_;
00136       Kind kind_;
00137       bool isIgnoredFailure_;
00138    };
00139 
00140 
00144    class CPPUT_API TestStatus
00145    {
00146    public:
00147       enum Status
00148       {
00149          passed = 1,
00150          skipped,
00151          failed
00152       };
00153 
00154       TestStatus( Status status = passed );
00155 
00156       void setStatus( Status status );
00157 
00158       Status status() const;
00159 
00160       bool hasFailed() const;
00161       bool hasPassed() const;
00162       bool wasSkipped() const;
00163 
00164       void setStatistics( const std::string &name,
00165                           const Json::Value &value );
00166       //Json::Value getStatistics( const std::string &name );
00167 
00168       void addSpecific( const std::string &type,
00169                         const Json::Value &value );
00170 
00171       int assertionCount() const;
00172       int failedAssertionCount() const;
00173       int ignoredFailureCount() const;
00174 
00175       void increaseAssertionCount( int delta = 1 );
00176       void increaseFailedAssertionCount( int delta = 1 );
00177       void increaseIgnoredFailureCount( int delta = 1 );
00178    private:
00179       Json::Value statistics_;
00180       Json::Value specifics_;
00181       Status status_;
00182       unsigned int assertionCount_;
00183       unsigned int failedAssertionCount_;
00184       unsigned int ignoredFailureCount_;
00185    };
00186 
00187 
00189    class CheckerResult
00190    {
00191    public:
00192       CheckerResult()
00193          : status_( TestStatus::passed )
00194          , message_( "" )
00195       {
00196       }
00197 
00198       void setFailed()
00199       {
00200          status_ = TestStatus::failed;
00201       }
00202 
00208       void compose( const CheckerResult &other )
00209       {
00210          switch ( status_ )
00211          {
00212          case TestStatus::failed:
00213          case TestStatus::passed:
00214             if ( other.status_ != TestStatus::passed )
00215                status_ = other.status_;
00216             break;
00217          case TestStatus::skipped:
00218             break;
00219          default:
00220             CPPTL_DEBUG_ASSERT_UNREACHABLE;
00221          }
00222          message_.extend( other.message_ );
00223       }
00224 
00225       TestStatus::Status status_;
00226       Message message_;
00227    };
00228    
00229    namespace Impl {
00230 
00232       class CheckerLineLocation
00233       {
00234       public:
00235          const CheckerResult *result_;
00236          unsigned long line_;
00237       };
00238 
00239       struct FileLocationMarker {};
00240 
00241 
00243       class CheckerFileLocation
00244       {
00245       public:
00246          const CheckerLineLocation *lineData_;
00247          const char *file_;
00248       };
00249 
00251       class AssertionTrigger
00252       {
00253       public:
00254          static AssertionTrigger aborting;
00255          static AssertionTrigger checking;
00256 
00257          AssertionTrigger &operator +=( const CheckerFileLocation &fileLocation );
00258       };
00259 
00260    } // end of namespace Impl
00261 
00262 
00317    # define CPPUT_BEGIN_ASSERTION_MACRO() \
00318       CppUT::Impl::AssertionTrigger::aborting += (const CppUT::Impl::FileLocationMarker *)__FILE__ + __LINE__ / 
00319 
00324    # define CPPUT_BEGIN_CHECKING_MACRO() \
00325       CppUT::Impl::AssertionTrigger::checking += (const CppUT::Impl::FileLocationMarker *)__FILE__ + __LINE__ / 
00326 
00327 
00328 
00331    class CPPUT_API TestResultUpdater : public CppTL::IntrusiveCount
00332    {
00333    public:
00334       virtual ~TestResultUpdater()
00335       {
00336       }
00337 
00338       virtual void addResultLog( const Json::Value &log ) = 0;
00339 
00340       virtual void addResultAssertion( const Assertion &assertion ) = 0;
00341    };
00342 
00346    enum AssertionType
00347    {
00348       abortingAssertion = 1,   
00349       checkingAssertion        
00350    };
00351 
00355    enum AbortingAssertionMode
00356    {
00357       fastAbortingAssertion = 1,
00358       richAbortingAssertion
00359    };
00360 
00365    class TestInfo : public CppTL::IntrusiveCount
00366       // @todo inherit CppTL::NonCopyable
00367    {
00368    public:
00369       class CPPUT_API ScopedContextOverride
00370       {
00371       public:
00372          ScopedContextOverride();
00373 
00374          ~ScopedContextOverride();
00375 
00376       protected:
00377          TestInfoPtr context_;
00378       };
00379 
00380       class CPPUT_API IgnoreFailureScopedContextOverride : public ScopedContextOverride
00381                                                          , private TestResultUpdater
00382       {
00383       public:
00384          IgnoreFailureScopedContextOverride( bool &assertionFailed );
00385 
00386          ~IgnoreFailureScopedContextOverride();
00387 
00388       private: // overridden from TestResultUpdater
00389          virtual void addResultLog( const Json::Value &log );
00390 
00391          virtual void addResultAssertion( const Assertion &assertion );
00392 
00393       private:
00394          Assertion *assertion_;
00395          bool &assertionFailed_;
00396       };
00397 
00398       friend class IgnoreFailureScopedContextOverride;
00399 
00400 
00405       static TestInfo &threadInstance();
00406 
00407       TestInfo();
00408 
00409       void setTestResultUpdater( TestResultUpdater &updater );
00410       void removeTestResultUpdater();
00411 
00415       void startNewTest();
00416 
00420       void addResource( const AcquiredResourceHandlePtr &resource );
00421 
00425       void discardTestResources();
00426 
00433       Resource &getResource( const ResourceName &name );
00434 
00435       TestStatus &testStatus();
00436 
00437       void handleAssertion( const char *file, 
00438                             unsigned int line, 
00439                             const CheckerResult &result,
00440                             bool isAbortingAssertion );
00441 
00442       void handleUnexpectedException( const Assertion &fault );
00443 
00444       void setAbortingAssertionMode( AbortingAssertionMode mode );
00445 
00446       void log( const Json::Value &log );
00447 
00448    private:
00449       typedef std::map<ResourceName,AcquiredResourceHandlePtr> Resources;
00450       Resources resources_;
00451       TestStatus testStatus_;
00452       Assertion currentAssertion_;
00453       AssertionType assertionType_;
00454       AbortingAssertionMode abortingAssertionMode_;
00455       TestResultUpdater *updater_;
00456    };
00457 
00465    Resource &CPPUT_API getResource( const ResourceName &name );
00466 
00470    void CPPUT_API log( const Json::Value &log );
00471 
00475    void CPPUT_API log( const std::string &log );
00476 
00480    void CPPUT_API log( const char *log );
00481 
00485    void CPPUT_API log( const CppTL::ConstString &log );
00486 
00487 } // namespace CppUT
00488 
00489 
00490 inline CppUT::Impl::CheckerLineLocation operator /( unsigned long line, const CppUT::CheckerResult &result )
00491 {
00492    CppUT::Impl::CheckerLineLocation lineData;
00493    lineData.result_ = &result;
00494    lineData.line_ = line;
00495    return lineData;
00496 }
00497 
00498 
00499 inline CppUT::Impl::CheckerFileLocation operator +( const CppUT::Impl::FileLocationMarker *file, const CppUT::Impl::CheckerLineLocation &lineData )
00500 {
00501    CppUT::Impl::CheckerFileLocation fileData;
00502    fileData.file_ = (const char *)file;
00503    fileData.lineData_ = &lineData;
00504    return fileData;
00505 }
00506 
00507 
00508 
00509 #endif // CPPUT_TESTINFO_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers