/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Pavel Savara
* - Initial implementation
*******************************************************************************/
package net.sf.robocode.test.helpers;
import net.sf.robocode.io.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import robocode.control.*;
import robocode.control.events.*;
import robocode.control.snapshot.IRobotSnapshot;
import robocode.util.Utils;
import java.io.File;
import java.io.IOException;
import java.util.Random;
/**
* @author Pavel Savara (original)
*/
public abstract class RobocodeTestBed extends BattleAdaptor {
protected static final IRobocodeEngine engine;
protected final BattlefieldSpecification battleFieldSpec = new BattlefieldSpecification();
protected static int errors = 0;
protected static StringBuilder errorText = new StringBuilder();
protected static int messages = 0;
protected static String robotsPath;
public static boolean isDumpingPositions = false;
public static boolean isDumpingTurns = false;
public static boolean isDumpingOutput = true;
public static boolean isDumpingErrors = true;
public static boolean isDumpingMessages = true;
static {
System.setProperty("EXPERIMENTAL", "true");
System.setProperty("TESTING", "true");
System.setProperty("WORKINGDIRECTORY", "target/test-classes");
try {
if (new File("").getAbsolutePath().endsWith("robocode.tests")) {
robotsPath = new File("../robocode.tests.robots").getCanonicalPath();
} else if (new File("").getAbsolutePath().endsWith("robocode.dotnet.tests")) {
robotsPath = new File("../../../robocode.tests.robots").getCanonicalPath();
} else {
throw new Error("Unknown directory");
}
} catch (IOException e) {
e.printStackTrace(Logger.realErr);
}
System.setProperty("ROBOTPATH", robotsPath + "/target/classes");
engine = new RobocodeEngine(new BattleAdaptor() {
public void onBattleMessage(BattleMessageEvent event) {
if (isDumpingMessages) {
Logger.realOut.println(event.getMessage());
}
messages++;
}
public void onBattleError(BattleErrorEvent event) {
if (isDumpingErrors) {
Logger.realErr.println(event.getError());
}
errorText.append("----------err #");
errorText.append(errors);
errorText.append("--------------------------------------------------\n");
errorText.append(event.getError());
errorText.append("\n");
errors++;
}
});
}
public RobocodeTestBed() {
// silent when running in maven
if (System.getProperty("surefire.test.class.path", null) != null) {
isDumpingOutput = false;
isDumpingErrors = false;
isDumpingMessages = false;
}
errors = 0;
messages = 0;
}
public void onTurnEnded(TurnEndedEvent event) {
if (isDumpingTurns) {
Logger.realOut.println("turn " + event.getTurnSnapshot().getTurn());
}
for (IRobotSnapshot robot : event.getTurnSnapshot().getRobots()) {
if (isDumpingPositions) {
Logger.realOut.print(robot.getVeryShortName());
Logger.realOut.print(" X:");
Logger.realOut.print(robot.getX());
Logger.realOut.print(" Y:");
Logger.realOut.print(robot.getY());
Logger.realOut.print(" V:");
Logger.realOut.print(robot.getVelocity());
Logger.realOut.println();
}
if (isDumpingOutput) {
Logger.realOut.print(robot.getOutputStreamSnapshot());
}
}
}
public void onBattleStarted(BattleStartedEvent event) {
if (isDeterministic() && isCheckOnBattleStart()) {
final Random random = Utils.getRandom();
if (event.getRobotsCount() == 2) {
Assert.assertNear(0.98484154, random.nextDouble());
}
}
}
public abstract String getRobotNames();
public int getNumRounds() {
return 1;
}
public String getInitialPositions() {
return null;
}
public int getExpectedRobotCount(String robotList) {
return robotList.split("[\\s,;]+").length;
}
public boolean isDeterministic() {
return true;
}
public boolean isCheckOnBattleStart() {
return false;
}
@Before
public void setup() {
engine.addBattleListener(this);
if (isDeterministic()) {
RandomFactory.resetDeterministic(0);
if (isCheckOnBattleStart()) {
Assert.assertNear(0.730967, RandomFactory.getRandom().nextDouble());
}
}
errors = 0;
errorText = new StringBuilder();
messages = 0;
}
@After
public void tearDown() {
engine.removeBattleListener(this);
}
@Test
public void run() {
runSetup();
runBattle(getRobotNames(), getNumRounds(), getInitialPositions());
runTeardown();
final int expectedErrors = getExpectedErrors();
if (errors != expectedErrors) {
throw new AssertionError(
"Number of errors " + errors + " is different than expected " + expectedErrors + "\n" + errorText
+ "======================================================================");
}
}
protected int getExpectedErrors() {
return 0;
}
protected void runSetup() {}
protected void runTeardown() {}
protected void runBattle(String robotList, int numRounds, String initialPositions) {
final RobotSpecification[] robotSpecifications = engine.getLocalRepository(robotList);
if (getExpectedRobotCount(robotList) > 0) {
Assert.assertNotNull("Robot were not loaded", robotSpecifications);
Assert.assertEquals("Robot were not loaded", getExpectedRobotCount(robotList), robotSpecifications.length);
engine.runBattle(new BattleSpecification(numRounds, battleFieldSpec, robotSpecifications), initialPositions,
true);
}
}
}