| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #if !defined(_LOG4CXX_LOGUNIT_H) |
| #define _LOG4CXX_LOGUNIT_H |
| |
| |
| #if defined(_MSC_VER) |
| #pragma warning (push) |
| #pragma warning ( disable: 4231 4251 4275 4786 ) |
| #endif |
| |
| #include "abts.h" |
| #include <exception> |
| #include <map> |
| #include <sstream> |
| #include <string> |
| #include <vector> |
| |
| #include <log4cxx/logstring.h> |
| |
| namespace LogUnit { |
| class TestException : public std::exception { |
| public: |
| TestException(); |
| TestException(const TestException&); |
| TestException& operator=(const TestException&); |
| }; |
| class AssertException : public std::exception { |
| public: |
| AssertException(std::string msg, int lineno); |
| AssertException(bool expected, const char* actualExpr, int lineno); |
| AssertException(const AssertException&); |
| AssertException& operator=(const AssertException&); |
| virtual ~AssertException() throw(); |
| std::string getMessage() const; |
| int getLine() const; |
| private: |
| std::string msg; |
| int lineno; |
| }; |
| class TestFixture { |
| public: |
| TestFixture(); |
| virtual ~TestFixture(); |
| void setCase(abts_case* tc); |
| virtual void setUp(); |
| virtual void tearDown(); |
| |
| void assertEquals(const int expected, const int actual, int lineno); |
| void assertEquals(const std::string expected, |
| const std::string actual, |
| const char* expectedExpr, |
| const char* actualExpr, |
| int lineno); |
| void assertEquals(const char* expected, |
| const char* actual, |
| const char* expectedExpr, |
| const char* actualExpr, |
| int lineno); |
| #if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_WCHAR_T_API |
| void assertEquals(const std::wstring expected, |
| const std::wstring actual, |
| const char* expectedExpr, |
| const char* actualExpr, |
| int lineno); |
| #endif |
| #if LOG4CXX_LOGCHAR_IS_UNICHAR || LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API |
| void assertEquals(const std::basic_string<log4cxx::UniChar> expected, |
| const std::basic_string<log4cxx::UniChar> actual, |
| const char* expectedExpr, |
| const char* actualExpr, int lineno); |
| #endif |
| template<class T> |
| void assertEquals(const T& expected, |
| const T& actual, |
| const char* expectedExpr, |
| const char* actualExpr, |
| int lineno) { |
| if (expected != actual) { |
| std::string msg(expectedExpr); |
| msg.append(" != "); |
| msg.append(actualExpr); |
| abts_fail(tc, msg.c_str(), lineno); |
| } |
| } |
| private: |
| TestFixture(const TestFixture&); |
| TestFixture& operator=(const TestFixture&); |
| abts_case* tc; |
| }; |
| template<class T> |
| void runTest(abts_case* tc, void (T::*func)()) { |
| T ti; |
| ti.setCase(tc); |
| ti.setUp(); |
| try { |
| (ti.*func)(); |
| } catch(TestException&) { |
| } catch(AssertException& fx) { |
| abts_fail(tc, fx.getMessage().c_str(), fx.getLine()); |
| } catch(std::exception& e) { |
| const char* what = e.what(); |
| std::ostringstream oss; |
| oss << "Unexpected std::exception: " |
| << (what ? what : "what() == NULL"); |
| abts_fail(tc, oss.str().c_str(), -1); |
| } catch(...) { |
| abts_fail(tc, "Unexpected exception", -1); |
| } |
| ti.tearDown(); |
| } |
| template<class T, class X> |
| void runTestWithException(abts_case* tc, void (T::*func)()) { |
| T ti; |
| ti.setCase(tc); |
| ti.setUp(); |
| try { |
| (ti.*func)(); |
| } catch(TestException&) { |
| } catch(AssertException& fx) { |
| abts_fail(tc, fx.getMessage().c_str(), fx.getLine()); |
| } catch(X&) { |
| } catch(...) { |
| abts_fail(tc, "Unexpected exception", -1); |
| } |
| ti.tearDown(); |
| } |
| class TestSuite { |
| public: |
| TestSuite(const char* filename); |
| void addTest(const char* testName, test_func func); |
| abts_suite* run(abts_suite* suite) const; |
| std::string getName() const; |
| void setDisabled(bool newVal); |
| bool isDisabled() const; |
| private: |
| TestSuite(const TestSuite&); |
| TestSuite& operator=(const TestSuite&); |
| typedef std::vector<test_func> TestList; |
| TestList test_funcs; |
| std::string filename; |
| bool disabled; |
| }; |
| typedef std::vector< std::pair<std::string, const TestSuite*> > SuiteList; |
| SuiteList& getAllSuites(); |
| template<class T> |
| class RegisterSuite { |
| public: |
| RegisterSuite() { |
| T::populateSuite(); |
| TestSuite* suite = T::getSuite(); |
| LogUnit::getAllSuites().push_back(SuiteList::value_type(suite->getName(), suite)); |
| } |
| }; |
| template<class T> |
| class RegisterDisabledSuite { |
| public: |
| RegisterDisabledSuite() { |
| T::populateSuite(); |
| TestSuite* suite = T::getSuite(); |
| suite->setDisabled(true); |
| LogUnit::getAllSuites().push_back(SuiteList::value_type(suite->getName(), suite)); |
| } |
| }; |
| } |
| |
| #define LOGUNIT_CLASS(x) class x : public LogUnit::TestFixture |
| |
| |
| #define LOGUNIT_TEST_SUITE(TF) \ |
| public: \ |
| static LogUnit::TestSuite* getSuite() { \ |
| static LogUnit::TestSuite suite(__FILE__); \ |
| return &suite; \ |
| } \ |
| private: \ |
| class RegisterSuite { \ |
| public: \ |
| typedef TF ThisFixture |
| |
| #define LOGUNIT_TEST(testName) \ |
| class testName ## Registration { \ |
| public: \ |
| testName ## Registration() { \ |
| ThisFixture::getSuite()->addTest(#testName, &testName ## Registration :: run); \ |
| } \ |
| static void run(abts_case* tc, void*) { \ |
| LogUnit::runTest<ThisFixture>(tc, &ThisFixture::testName); \ |
| } \ |
| } register ## testName |
| |
| #define LOGUNIT_TEST_EXCEPTION(testName, Exception) \ |
| class testName ## Registration { \ |
| public: \ |
| testName ## Registration() { \ |
| ThisFixture::getSuite()->addTest(#testName, &testName ## Registration :: run); \ |
| } \ |
| static void run(abts_case* tc, void*) { \ |
| LogUnit::runTestWithException<ThisFixture, Exception>(tc, &ThisFixture::testName); \ |
| } \ |
| } register ## testName |
| |
| |
| #define LOGUNIT_TEST_SUITE_END() \ |
| }; \ |
| public: \ |
| static void populateSuite() { \ |
| static RegisterSuite registration; \ |
| } \ |
| private: \ |
| void nop() |
| |
| |
| #define LOGUNIT_TEST_SUITE_REGISTRATION(TF) \ |
| static LogUnit::RegisterSuite<TF> registration; |
| |
| #define LOGUNIT_TEST_SUITE_REGISTRATION_DISABLED(TF) \ |
| static LogUnit::RegisterDisabledSuite<TF> registration; |
| |
| |
| #define LOGUNIT_ASSERT( x) { if (!(x)) throw LogUnit::AssertException(true, #x, __LINE__); } |
| #define LOGUNIT_ASSERT_SRCL(x, srcLine) { if (!(x)) throw LogUnit::AssertException(true, #x, srcLine); } |
| #define LOGUNIT_ASSERT_EQUAL( expected, actual) assertEquals(expected, actual, #expected, #actual, __LINE__) |
| #define LOGUNIT_ASSERT_EQUAL_SRCL( expected, actual, srcLine) assertEquals(expected, actual, #expected, #actual, srcLine) |
| #define LOGUNIT_FAIL(msg) throw LogUnit::AssertException(msg, __LINE__) |
| |
| |
| #if defined(_MSC_VER) |
| #pragma warning (pop) |
| #endif |
| |
| #endif |
| |