/* * 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 #include #include #include #include #include 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 expected, const std::basic_string actual, const char* expectedExpr, const char* actualExpr, int lineno); #endif template 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 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 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 TestList; TestList test_funcs; std::string filename; bool disabled; }; typedef std::vector< std::pair > SuiteList; SuiteList& getAllSuites(); template class RegisterSuite { public: RegisterSuite() { T::populateSuite(); TestSuite* suite = T::getSuite(); LogUnit::getAllSuites().push_back(SuiteList::value_type(suite->getName(), suite)); } }; template 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(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(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 registration; #define LOGUNIT_TEST_SUITE_REGISTRATION_DISABLED(TF) \ static LogUnit::RegisterDisabledSuite 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