1 /* 2 * Copyright (C) 2005-2008 by Dr. Marc Boris Duerner 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * As a special exception, you may use this file as part of a free 10 * software library without restriction. Specifically, if other files 11 * instantiate templates or use macros or inline functions from this 12 * file, or you compile this file and link it with other files to 13 * produce an executable, this file does not by itself cause the 14 * resulting executable to be covered by the GNU General Public 15 * License. This exception does not however invalidate any other 16 * reasons why the executable file might be covered by the GNU Library 17 * General Public License. 18 * 19 * This library is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * Lesser General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public 25 * License along with this library; if not, write to the Free Software 26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 27 */ 28 #ifndef CXXTOOLS_ASSERTION_H 29 #define CXXTOOLS_ASSERTION_H 30 31 #include "cxxtools/sourceinfo.h" 32 #include <stdexcept> 33 #include <iostream> 34 #include <sstream> 35 36 namespace cxxtools { 37 38 namespace unit { 39 40 /** @brief %Test %Assertion exception 41 @ingroup UnitTests 42 43 Assertions are modeled as an exception type, which is thrown by Unit 44 tests when an assertion has failed. This class implements 45 std::exception and overrides std::exception::what() to return an 46 error message Besides the error message, Assertions can provide 47 information where the exception was raised in the source code through 48 a SourceInfo object. It is recommended to use the CXXTOOLS_UNIT_ASSERT 49 for easy creation from a source info object. 50 51 @code 52 void myTest() 53 { 54 int ten = 5 + 5; 55 CXXTOOLS_UNIT_ASSERT(ten == 10) 56 } 57 @endcode 58 */ 59 class Assertion 60 { 61 public: 62 /** @brief Construct from a message and source info. 63 64 Constructs a assertion exception from a message string 65 and a source info object that describes where the 66 assertion failed. Use the CXXTOOLS_UNIT_ASSERT macro instead 67 of this constructor. 68 69 @param what Error message 70 @param si Info where the assertion failed 71 */ 72 Assertion(const std::string& what, const SourceInfo& si); 73 74 const SourceInfo& sourceInfo() const; 75 what()76 const char* what() const { return _what.c_str(); } 77 78 private: 79 SourceInfo _sourceInfo; 80 std::string _what; 81 }; 82 83 #define CXXTOOLS_UNIT_ASSERT(cond) \ 84 do { \ 85 if( !(cond) ) \ 86 throw cxxtools::unit::Assertion(#cond, CXXTOOLS_SOURCEINFO); \ 87 } while (false) 88 89 #define CXXTOOLS_UNIT_ASSERT_MSG(cond, what) \ 90 do { \ 91 if( !(cond) ) \ 92 { \ 93 std::ostringstream _cxxtools_msg; \ 94 _cxxtools_msg << what; \ 95 throw cxxtools::unit::Assertion(_cxxtools_msg.str(), CXXTOOLS_SOURCEINFO); \ 96 } \ 97 } while (false) 98 99 #define CXXTOOLS_UNIT_ASSERT_EQUALS(value1, value2) \ 100 do { \ 101 if( ! ((value1) == (value2)) ) \ 102 { \ 103 std::ostringstream _cxxtools_msg; \ 104 _cxxtools_msg << "not equal:\n\tvalue1 (" #value1 ")=\n\t\t<" << value1 << ">\n\tvalue2 (" #value2 ")=\n\t\t<" << value2 << '>'; \ 105 throw cxxtools::unit::Assertion(_cxxtools_msg.str(), CXXTOOLS_SOURCEINFO); \ 106 } \ 107 } while (false) 108 109 #define CXXTOOLS_UNIT_ASSERT_THROW(cond, EX) \ 110 do { \ 111 struct _cxxtools_ex { }; \ 112 try \ 113 { \ 114 cond; \ 115 throw _cxxtools_ex(); \ 116 } \ 117 catch(const _cxxtools_ex &) \ 118 { \ 119 std::ostringstream _cxxtools_msg; \ 120 _cxxtools_msg << "exception of type " #EX " expected in " #cond; \ 121 throw cxxtools::unit::Assertion(_cxxtools_msg.str(), CXXTOOLS_SOURCEINFO); \ 122 } \ 123 catch(const EX &) \ 124 {} \ 125 } while (false) 126 127 #define CXXTOOLS_UNIT_ASSERT_NOTHROW(cond) \ 128 do { \ 129 try { \ 130 \ 131 cond; \ 132 } \ 133 catch(const std::exception& e) \ 134 { \ 135 throw cxxtools::unit::Assertion( \ 136 std::string("unexpected exception of type ") + typeid(e).name() + ": " + e.what(), \ 137 CXXTOOLS_SOURCEINFO); \ 138 } \ 139 catch(const cxxtools::unit::Assertion&) \ 140 { \ 141 throw; \ 142 } \ 143 catch(...) \ 144 { \ 145 throw cxxtools::unit::Assertion("unexpected exception." , CXXTOOLS_SOURCEINFO); \ 146 } \ 147 } while (false) 148 149 #define CXXTOOLS_UNIT_FAIL(what) \ 150 do { \ 151 std::ostringstream _cxxtools_msg; \ 152 _cxxtools_msg << what; \ 153 throw cxxtools::unit::Assertion(_cxxtools_msg.str(), CXXTOOLS_SOURCEINFO); \ 154 } while (false) 155 156 } // namespace unit 157 158 } // namespace cxxtools 159 160 #endif 161