/* =============================================================================
 *  scpp_unittest.cpp
 *  Copyright (c)  2003 - 2011  Nomura Kei
 *  LICENSE :
 *  LGPL (GNU Lesser General General Public License - Version 3,29 June 2007)
 *  http://www.gnu.org/copyleft/lesser.html
 * =============================================================================
 *
 * 単体試験用モジュール.
 *
 */
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

#include <scpp_unittest.hpp>


namespace scpp
{


////////////////////////////////////////////////////////////////////////////////
//
// TestCase
//

/**
 * テストケースクラスを生成します.
 * テスト実行時に一度だけ初期化が必要な処理を行います.
 */
TestCase::TestCase()
{
	// NOP
};


/**
 * テストケースクラスを破棄します.
 */
TestCase::~TestCase()
{
	// NOP
}


/**
 * 各テストを実行する前に実行される setUp 関数です.
 *
 * 各テストクラスは, 本メソッドをオーバーライドして,
 * 各テスト実行前に実施する処理を記述してください.
 */
void TestCase::setUp()
{
	// NOP
}


/**
 * 各テストを実行した後に実行される tearDown 関数です.
 *
 * 各テストクラスは, 本メソッドをオーバーライドして,
 * 各テスト実行後に実施する処理を記述してください.
 */
void TestCase::tearDown()
{
	// NOP
}



////////////////////////////////////////////////////////////////////////////////
//
// UnittestManager
//

/**
 * テスト管理.
 * 本クラスのインスタンスは, 一応複数生成できますが,
 * あらかじめインスタンス utManager が用意されています.
 */
UnittestManager::UnittestManager() : okCount(0), ngCount(0)
{
	// NOP
}

/**
 * テスト管理破棄.
 */
UnittestManager::~UnittestManager()
{
	// NOP
	printResult();
}


/**
 * テストの結果を追加します.
 *
 * @param file  ファイル
 * @param line   行番号
 * @param func   関数
 * @param result 結果
 * @param e      AssertError
 */
void UnittestManager::addTestResult(const char* file, int line, const char* func, bool result, const AssertError* e) throw()
{
	std::ostringstream msg;
	msg << file << ":" << line << " (" << func << ")";
	std::string msgStr(msg.str());

	std::cout << "[" << std::setw(5)  << std::setfill('0') << std::right << (okCount + ngCount + 1)  << "] ";
	std::cout << std::setw(64) << std::setfill(' ') << std::left  << msgStr;
	if (result)
	{
		std::cout << "  [   OK   ]" << std::endl;
		okCount++;
	}
	else
	{
		std::cout << "  [   NG   ]" << std::endl;
		if (e != 0)
		{
			std::cout << "AssertError: " << e->what() << std::endl;
			std::cout << "  at " << e->getFileName()
					  << ":"     << e->getLineNumber()
					  << " ("    << e->getFunctionName() << ")" << std::endl;
		}
		ngCount++;

	}
}


/**
 * 単体テストの結果を出力します.
 */
void UnittestManager::printResult()
{
	std::cout << "--------------------------------------------------------------------------------" << std::endl;
	std::cout << "  OK    : " << okCount << std::endl;
	std::cout << "  NG    : " << ngCount << std::endl;
	std::cout << "  Total : " << (okCount + ngCount) << std::endl;
	std::cout << std::endl;

}



UnittestManager utManager;

}	// namespace scpp

