/**
 * @file TestCount.cpp
 * @date Aug 5, 2008
 * @author Ronald Kluth
 *
 * @brief Tests for ODEMx class Count
 */

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

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

	/**
	 * @struct CountFixture
	 * @brief Helper struct providing set-up/tear-down of Count tests
	 *
	 * @copydetails EventFixture
	 */
	struct CountFixture
	{
		SuiteBase::SimulationTest sim;
		SuiteData::ReportTest reporter;
		Count count;

		CountFixture()
		:	sim( "CountTestSim" ),
			reporter(),
			count( sim, "CountTest")
			{}
	};

	/**
	 * @test odemx::Count construction
	 *
	 * Expected effects:
	 * @li label is set correctly
	 * @li statistics manager (Simulation) is set correctly
	 * @li counter value is 0
	 * @li last reset time is current SimTime
	 */
	TEST_FIXTURE( CountFixture, ConstructionDestruction )
	{
		data::Label label = "TestCountConstructionUserSim";
		std::auto_ptr< Count > count( new Count( sim, label ) );
		CHECK_EQUAL( label, count->getLabel() );
		CHECK_EQUAL( (int) 0, count->getValue() );
		CHECK_EQUAL( sim.getTime(), count->getResetTime() );
	}

	/**
	 * @test odemx::Count::update()
	 *
	 * Expected function call effects:
	 * @li usage counter is increased by one
	 */
	TEST_FIXTURE( CountFixture, Update )
	{
		count.update();
		CHECK_EQUAL( 1, count.getValue() );

		int increase = 32;
		count.update( increase );
		CHECK_EQUAL( 1 + increase, count.getValue() );
	}

	/**
	 * @test odemx::Count::reset()
	 *
	 * Expected function call effects:
	 * @li the counter value is set to 0
	 * @li the last reset time is set to the sim's time
	 */
	TEST_FIXTURE( CountFixture, Reset )
	{
		base::SimTime simTime = 25;

		count.update( 16 );
		count.update( 11 );
		CHECK( count.getValue() > 0 );

		count.reset( simTime );
		CHECK_EQUAL( (int) 0, count.getValue() );
		CHECK_EQUAL( simTime, count.getResetTime() );
	}

	/**
	 * @test odemx::Count::report(Report*)
	 *
	 * Expected function call effects:
	 * @li the report table contains correct values for label, reset time,
	 * number of uses, and the counter value
	 */
	TEST_FIXTURE( CountFixture, Report )
	{
		base::SimTime simTime = 25;

		unsigned int inc = 13;
		count.reset( simTime ); // non-0 reset time
		count.update( inc ); // two updates
		count.update( inc ); // result in value inc * 2

		reporter.addReportProducer( count );
		reporter.generateReport();
		CHECK( reporter.processedTables );

		// check the table line
		CHECK_EQUAL( count.getLabel(), reporter.allTableContent[0][0] );
		CHECK_EQUAL( toString( count.getResetTime() ), reporter.allTableContent[0][1] );
		CHECK_EQUAL( toString( count.getUpdateCount() ), reporter.allTableContent[0][2] );
		CHECK_EQUAL( toString( count.getValue() ), reporter.allTableContent[0][3] );
	}


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