import junit.framework.TestCase;
import java.util.Random;

/**
 * Testet LogApproximator mit JUnit
 */
public class LogApproximatorTest extends TestCase{

    private LogApproximator[] dieLogger;
    private double[] dieEingaben;
    private Random generator;    
    private static final long STARTWERT = 12345678L;
    private static final int ANZAHL = 20;
    private static final double EPSILON = 1E-12 ;

    // die ausgedachten Eingabewerte:
    private static final double EINGABE1 = 1.2; // normal
    private static final double EINGABE2 = 3.0E23; // sehr groß
    private static final double EINGABE3 = 0.01; // sehr klein


    /**
     * Array der LogApproximator-Objekte wird gefüllt
     */
    //protected ist Standard
    protected void setUp(){
	generator = new Random(STARTWERT);
	dieEingaben = new double[ANZAHL];
	dieLogger = new LogApproximator[ANZAHL];
	
	dieEingaben[ANZAHL - 3] = EINGABE1;
	dieEingaben[ANZAHL - 2] = EINGABE2;
	dieEingaben[ANZAHL - 1] = EINGABE3;
	for (int i = 0; i< ANZAHL-3; i++)
	    // zufälliger Wert von 0 bis 2
	    dieEingaben[i]= 2.0 * generator.nextDouble();

 	for (int i = 0; i<ANZAHL; i++)
	    dieLogger[i]= new LogApproximator(dieEingaben[i]);
    }

    // folgende Methode nur aus formalen Gründen:
    /**
     * Array der LogApproximator-Objekte wird geleert
     */
    //protected ist Standard
    protected void tearDown(){
	for (int i = 0; i<ANZAHL; i++) dieLogger[i]=null;
    }


    private String testident(int i){
	return "Im " + i +"ten Test mit Eingabe " + dieEingaben[i] +":";
    }

    /**
     * testet, ob der Konstruktor Argument und Faktor richtig berechnet
     */
    // muß public sein
    public void testLogApproximator(){
	for (int i = 0; i<ANZAHL; i++)
	    assertEquals(testident(i),
			 dieEingaben[i],
			 eingaberekonstruktion(dieLogger[i]),
			 EPSILON*dieEingaben[i]);
    }	
    
    private static double eingaberekonstruktion(LogApproximator la){
	return la.getArgument()*Math.exp(la.getFaktor());
    }
    

    // muß public sein
    public void testGetLog(){
	for (int i = 0; i<ANZAHL; i++)
	assertEquals(testident(i),
		     dieEingaben[i],
		     exponentiationsprobe(dieLogger[i]),
		     EPSILON*dieEingaben[i]);
    }


    private static double exponentiationsprobe(LogApproximator la){
	return Math.exp(la.getLog());
    }

    // muß public sein
    public void testGetLog2(){
	for (int i = 0; i<ANZAHL; i++)
	assertEquals(testident(i),
		     Math.log(dieEingaben[i]),
		     dieLogger[i].getLog(),
		     EPSILON);
    }


    // muß public sein
    public void testNochUngenau(){	
	for (int i = 0; i<ANZAHL; i++){
	    dieLogger[i].getLog();
	    assertFalse(testident(i),dieLogger[i].nochUngenau());
	}
	
    }



    public static void main(String[] args){
	// bemühe den Reflektionsmechanismus
	Class testklasse = LogApproximatorTest.class;
	junit.textui.TestRunner.run(testklasse);
	// für grafische Ausgabe: junit.awtui.TestRunner oder
	// junit.swingui.TestRunner
    }
}
