/**
 * @file TestXmlReport.cpp
 * @date Aug 15, 2008
 * @author Ronald Kluth
 *
 * @brief Tests for ODEMx class XmlReport
 */

#include "../TestData.h"
#include "../../TestBase/TestBase.h"

/// @cond DOXYGEN_SKIP
SUITE( Data )
{
/// @endcond

	/**
	 * @struct XmlReportFixture
	 * @brief Helper struct providing set-up/tear-down of XmlReport tests
	 *
	 * @copydetails EventFixture
	 */
	struct XmlReportFixture
	{
		SuiteBase::SimulationTest sim;
		std::string fileName;
		XmlReport fileReporter;
		odemx::statistics::Count count;

		XmlReportFixture()
		:	sim( "XmlReportTestSim" ),
			fileName( "XmlReportTest.xml" ),
			fileReporter( fileName ),
			count( sim, "CountTest" )
			{}
	};

	/**
	 * @test odemx::XmlReport construction
	 *
	 * Expected effects:
	 * @li the file exists after report destruction
	 */
	TEST_FIXTURE( XmlReportFixture, ConstructionDestruction )
	{
		CHECK_THROW( XmlReport report1( "" ), odemx::DataOutputException );
		std::string fileName = "XmlReportTestConstruction.xml";
		Poco::File file( fileName );
		if( file.exists() )
		{
			file.remove();
		}
		CHECK( ! Poco::File( fileName ).exists() );
		{
			XmlReport report( fileName );
		}
		CHECK( Poco::File( fileName ).exists() );
	}

	/**
	 * @test odemx::XmlReport file output
	 *
	 * Expected function call effects:
	 * @li the file contains the expected xml output
	 */
	TEST_FIXTURE( XmlReportFixture, GenerateReport )
	{
		unsigned int inc = 13;
		count.reset( base::SimTime(23) ); // non-0 reset time
		count.update( inc ); // two updates
		count.update( inc ); // result in value inc * 2

		fileReporter.addReportProducer( count );
		fileReporter.generateReport();
		CHECK( Poco::File( "XmlReport.xsl" ).exists() );

		std::ostringstream fileStream;
		std::ifstream inFile( fileName.c_str() );
		std::string tmp;
		while( inFile )
		{
			std::getline( inFile, tmp );
			fileStream << tmp << std::endl;
		}

		CHECK( fileStream.str().find( "<odemxreport>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<table columns=\"4\" label=\"Count Statistics\" lines=\"1\">" ) != std::string::npos );
		CHECK( fileStream.str().find( "<column label=\"Name\" number=\"1\" type=\"STRING\"/>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<column label=\"Reset at\" number=\"2\" type=\"SIMTIME\"/>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<column label=\"Uses\" number=\"3\" type=\"INTEGER\"/>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<column label=\"Value\" number=\"4\" type=\"INTEGER\"/>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<line number=\"1\">" ) != std::string::npos );
		CHECK( fileStream.str().find( "<cell col=\"1\">CountTest</cell>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<cell col=\"2\">23</cell>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<cell col=\"3\">2</cell>" ) != std::string::npos );
		CHECK( fileStream.str().find( "<cell col=\"4\">26</cell>" ) != std::string::npos );
		CHECK( fileStream.str().find( "</line>" ) != std::string::npos );
		CHECK( fileStream.str().find( "</table>" ) != std::string::npos );
		CHECK( fileStream.str().find( "</odemxreport>" ) != std::string::npos );
	}

/// @cond DOXYGEN_SKIP
}
/// @endcond
