/**
 * @file TestDraw.cpp
 * @date Aug 9, 2008
 * @author Ronald Kluth
 *
 * @brief Tests for ODEMx class Draw
 */

#include "TestRandom.h"
#include "../TestBase/TestBase.h"

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

	/**
	 * @struct DrawFixture
	 * @brief Helper struct providing set-up/tear-down of Draw tests
	 *
	 * @copydetails EventFixture
	 */
	struct DrawFixture
	{
		SuiteBase::SimulationTest sim;
		TestLogConsumer::Ptr log;
		double probability;
		int cells;
		Draw draw;
		statistics::Histogram histogram;
		data::TypeInfo type;

		DrawFixture()
		:	sim( "DrawTestSim" ),
			log( TestLogConsumer::create() ),
			probability( double(2) / 3 ),
			cells( 1 ),
			draw( sim, "DrawTest", probability ),
			histogram( sim, "DrawTestHistogram", 0, 1, cells ),
			type( typeid(Draw) )
			{
				sim.addConsumer( log );
			}
	};

	/**
	 * @test odemx::Draw construction
	 *
	 * Expected function call effects:
	 * @li label is set
	 * @li dist context (simulation) is set
	 * @li probability for drawing a \c 1 is set
	 */
	TEST_FIXTURE( DrawFixture, ConstructionDestruction )
	{
		data::Label l = "DrawTestUserSimConstruction";
		{
			Draw draw2( sim, l, probability );
			CHECK( log->getTraceRecord( "create", type ) );
			CHECK( log->getStatisticsRecord( "parameter", "seed", type ) );
			CHECK( log->getStatisticsRecord( "parameter", "probability", type ) );
			CHECK_EQUAL( l, draw2.getLabel() );
			CHECK_EQUAL( probability, draw2.getProbability() );
		}
		CHECK( log->getTraceRecord( "destroy", type ) );
	}

	/**
	 * @test odemx::Draw::sample()
	 *
	 * Expected function call effects:
	 * @li samples are always within the interval [0, 1]
	 * @li the probability is close to the mean value
	 */
	TEST_FIXTURE( DrawFixture, Sample )
	{
		draw.sample();
		CHECK( log->getTraceRecord( "sample", type ) );
		CHECK( log->getStatisticsRecord( "count", "uses", type ) );

		for( int i = 0; i < 1000000; ++i )
		{
			int value = draw.sample();
			CHECK( 0 <= value );
			CHECK( 1 >= value );
			histogram.update( value );
		}

		CHECK_CLOSE( draw.getProbability(), histogram.getMean(), 0.0005  );
	}

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