/**
 * @file       kycppunit.hpp
 * @brief      簡易C++単体テスト用モジュール
 * @author     Nomura Kei
 * @copyright  2003 - 2017  Nomura Kei
 * License: New BSD License (3-cclause BSD license)
 */
#ifndef KYCPPUNIT_HPP
#define KYCPPUNIT_HPP

#include <kyassert.hpp>

namespace ky
{


/**
 * 指定されたテストメソッドを実行します.
 */
#define RUN_TEST(func) {                                               \
	setUp();                                                           \
	try {                                                              \
		func();                                                        \
		ky::utMgr.addTestResult(__FILE__, __LINE__, #func, true);      \
	} catch (ky::AssertError& e) {                                     \
		ky::utMgr.addTestResult(__FILE__, __LINE__, #func, false, &e); \
	} catch (...) {                                                    \
		ky::utMgr.addTestResult(__FILE__, __LINE__, #func, false);     \
	}                                                                  \
	tearDown();                                                        \
}



/**
 * テストケース.
 * 各テストクラスは, 本クラスを継承して作成してください.
 *
 * 如何に実装例を示します.
 *
 * @code
 * #include <kycppunit.hpp>
 *
 * using namespace ky;
 * class SampleTest : public TestCase
 * {
 *   public:
 *     SampleTest() {}
 *     ~SampleTest() {}
 *     void setUp() {
 *       // 各テストケースの実行前に実施する内容を記述する.
 *     }
 *     void tearDown()
 *     {
 *       // 各テストケースの実行後に実施する内容を記述する.
 *     }
 *     void testSample1()
 *     {
 *       // テスト内容を記述する.
 *       std::string tmp("ABC");
 *       Assertion::assertEquals("ABC", tmp);
 *     }
 *     void testSample2()
 *     {
 *        // 何らかのテスト
 *     }
 *     void suite()
 *     {
 *       RUN_TEST(testSample1);
 *       RUN_TEST(testSample2);
 *     }
 * };
 * @endcode
 */
class TestCase
{
	public:
		TestCase();
		virtual ~TestCase();
		virtual void setUp();
		virtual void tearDown();
		virtual void suite() = 0;

};


/**
 * 単体試験を管理するクラス.
 * 本クラスは単体テストにて使用されます.
 * 通常, 本クラスのインスタンスを生成する必要はなく,
 * ky::utMgr を利用してください.
 */
class UTManager
{
	public:
		UTManager();
		virtual ~UTManager();
		void addTestResult(const char* file, int line, const char* func,
			bool result, const AssertError* e = 0) throw();
		void printResult();
	private:
		int okCount;
		int ngCount;
};

extern UTManager utMgr;

}	// namespace ky

#endif	// KYCPPUNIT_HPP

