/**
 * @file TestSum.cpp
 * @date Aug 6, 2008
 * @author Ronald Kluth
 *
 * @brief Tests for ODEMx class Sum
 */

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

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

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

		SumFixture()
		:	sim( "SumTestSim" ),
			reporter(),
			sum( sim, "SumTest" )
			{}
	};

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

	/**
	 * @test odemx::Sum::update()
	 *
	 * Expected function call effects:
	 * @li usage counter is increased by one
	 */
	TEST_FIXTURE( SumFixture, Update )
	{
		sum.update();
		CHECK_EQUAL( (unsigned int) 1, sum.getValue() );

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

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

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

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

	/**
	 * @test odemx::Sum::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( SumFixture, Report )
	{
		base::SimTime simTime = 25;

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

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

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

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