package com.shootoff.plugins;
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javafx.scene.Group;
import javafx.scene.Node;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import com.shootoff.camera.CamerasSupervisor;
import com.shootoff.camera.Shot;
import com.shootoff.camera.shot.ShotColor;
import com.shootoff.config.Configuration;
import com.shootoff.config.ConfigurationException;
import com.shootoff.gui.CanvasManager;
import com.shootoff.gui.JavaFXThreadingRule;
import com.shootoff.gui.pane.ProjectorArenaPane;
import com.shootoff.gui.targets.TargetView;
import com.shootoff.targets.Hit;
import com.shootoff.targets.MockHit;
import com.shootoff.targets.Target;
import com.shootoff.targets.TargetRegion;
import com.shootoff.targets.io.TargetIO;
import com.shootoff.targets.io.TargetIO.TargetComponents;
import ch.qos.logback.classic.Logger;
public class TestDuelingTree {
@Rule public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule();
private PrintStream originalOut;
private ByteArrayOutputStream stringOut = new ByteArrayOutputStream();
private PrintStream stringOutStream;
private List<Target> targets;
private List<Hit> leftPaddlesHits;
private List<Hit> rightPaddlesHits;
private DuelingTree dt;
@Before
public void setUp() throws ConfigurationException, NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException, IOException {
stringOutStream = new PrintStream(stringOut, false, "UTF-8");
System.setProperty("shootoff.home", System.getProperty("user.dir"));
TextToSpeech.silence(true);
TrainingExerciseBase.silence(true);
originalOut = System.out;
System.setOut(stringOutStream);
targets = new ArrayList<Target>();
TargetComponents tc = TargetIO.loadTarget(new File("targets" + File.separator + "Duel_Tree.target")).get();
TargetView duelTreeTarget = new TargetView(tc.getTargetGroup(), tc.getTargetTags(), new ArrayList<Target>());
targets.add(duelTreeTarget);
leftPaddlesHits = new ArrayList<Hit>();
rightPaddlesHits = new ArrayList<Hit>();
for (Node node : tc.getTargetGroup().getChildren()) {
TargetRegion region = (TargetRegion) node;
if (region.tagExists("subtarget") && region.getTag("subtarget").startsWith("left_paddle")) {
leftPaddlesHits.add(new MockHit(duelTreeTarget, region, 0, 0));
} else if (region.tagExists("subtarget") && region.getTag("subtarget").startsWith("right_paddle")) {
rightPaddlesHits.add(new MockHit(duelTreeTarget, region, 0, 0));
}
}
Configuration config = new Configuration(new String[0]);
config.setDebugMode(true);
dt = new DuelingTree(targets);
CanvasManager arenaCanvas = new CanvasManager(new Group(), null, "arena", null);
arenaCanvas.addTarget(duelTreeTarget);
dt.init(config, new CamerasSupervisor(config), null, null, new ProjectorArenaPane(config, arenaCanvas));
config.setExercise(dt);
// Set the wait to zero
Field delayConstant = dt.getClass().getDeclaredField("NEW_ROUND_DELAY");
delayConstant.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(delayConstant, delayConstant.getModifiers() & ~Modifier.FINAL);
delayConstant.setInt(dt, 0);
}
@After
public void tearDown() {
TextToSpeech.silence(false);
TrainingExerciseBase.silence(false);
System.setOut(originalOut);
Logger rootLogger = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
rootLogger.detachAndStopAllAppenders();
}
@Test
public void testNoTarget() throws IOException, ConfigurationException {
List<Target> targets = new ArrayList<Target>();
Configuration config = new Configuration(new String[0]);
config.setDebugMode(true);
DuelingTree dt = new DuelingTree(targets);
dt.init(config, new CamerasSupervisor(config), null, null, null);
assertEquals(String.format("sounds/voice/shootoff-duelingtree-warning.wav%n"),
stringOut.toString("UTF-8").replace(File.separatorChar, '/'));
stringOut.reset();
dt.reset(targets);
assertEquals(
String.format("left score: 0%n") + String.format("right score: 0%n")
+ String.format("sounds/voice/shootoff-duelingtree-warning.wav%n"),
stringOut.toString("UTF-8").replace(File.separatorChar, '/'));
stringOut.reset();
}
@Test
public void testOneRoundsLeftWins() throws UnsupportedEncodingException {
for (Hit leftPaddleHit : leftPaddlesHits) {
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(leftPaddleHit));
}
assertEquals(String.format("sounds/beep.wav%n").replace("/", File.separator) +
String.format("left score: 1%n") +
String.format("right score: 0%n"), stringOut.toString("UTF-8"));
stringOut.reset();
dt.destroy();
assertEquals("", stringOut.toString("UTF-8"));
stringOut.reset();
}
@Test
public void testTwoSeparateRoundsEachSideWinsOnce() throws UnsupportedEncodingException {
// Let right shoot two paddles then have left come in for the win
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(rightPaddlesHits.get(0)));
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(rightPaddlesHits.get(1)));
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(rightPaddlesHits.get(0)));
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(rightPaddlesHits.get(1)));
for (Hit leftPaddleHit : leftPaddlesHits) {
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(leftPaddleHit));
}
assertEquals(String.format("sounds/beep.wav%n").replace("/", File.separator) +
String.format("left score: 1%n") +
String.format("right score: 0%n"), stringOut.toString("UTF-8"));
stringOut.reset();
dt.reset(targets);
assertEquals(String.format("left score: 0%n") + String.format("right score: 0%n"), stringOut.toString("UTF-8"));
stringOut.reset();
// Right pulls out the win with no competition
for (Hit rightPaddleHit : rightPaddlesHits) {
dt.shotListener(new Shot(ShotColor.RED, 0, 0, 0, 2), Optional.of(rightPaddleHit));
}
assertEquals(String.format("sounds/beep.wav%n").replace("/", File.separator) +
String.format("left score: 0%n") +
String.format("right score: 1%n"), stringOut.toString("UTF-8"));
stringOut.reset();
dt.destroy();
assertEquals("", stringOut.toString("UTF-8"));
stringOut.reset();
}
}