import EnvironmentPluginAPI.Exceptions.TechnicalException;
import EnvironmentPluginAPI.Contract.IEnvironmentState;
import EnvironmentPluginAPI.Contract.TEnvironmentDescription;
import EnvironmentPluginAPI.Service.ICycleReplay;
import EnvironmentPluginAPI.Service.ICycleStatisticsSaver;
import ZeroTypes.Exceptions.GameReplayNotContainedInDatabaseException;
import GameStatistics.Implementation.ClientNameDao;
import GameStatistics.Implementation.CycleReplayDescriptionDao;
import GameStatistics.Implementation.CycleStatisticsComponent;
import GameStatistics.Implementation.Entities.ClientName;
import GameStatistics.Implementation.Entities.CycleReplayDescription;
import GameStatistics.Implementation.GameReplayDescriptionSaverHelper;
import ZeroTypes.RemoteInterface.ICycleStatistics;
import ZeroTypes.TransportTypes.TCycleReplayDescription;
import org.junit.*;
import org.junit.rules.ExpectedException;
import java.rmi.RemoteException;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* User: N3trunner
* Date: 13.05.12
* Time: 12:51
* To change this template use File | Settings | File Templates.
*/
public class GameStatisticsComponentTest {
// Test Data parameters
private static final int MinimumNumberOfTurns = 10;
private static final int MaximumNumberOfTurns = 1000;
private static final int NumberOfPlayers = 4;
private static final int NumberOfReplays = 10;
// The time when the first CycleReplayDescription happened.
// The time of the following GameReplays will be incremented by 1 minute for each new game replay.
private Calendar startingDateTime;
private static final TEnvironmentDescription ENVIRONMENT_DESCRIPTION = new TEnvironmentDescription("test", "test", "test");
static CycleStatisticsComponent gameStatisticsComponent;
static CycleReplayDescriptionDao cycleDescriptionDao;
static ClientNameDao clientNameDao;
static GameReplayDescriptionSaverHelper gameReplayDescriptionSaverHelper;
static ICycleStatistics iCycleStatistics;
static ICycleStatisticsSaver iCycleStatisticsSaver;
List<String> testPlayers;
List<playerCombination> allPossiblePlayerCombinations;
List<ICycleReplay> testGameReplays;
List<CycleReplayDescription> testReplayDescriptions;
@Rule
public ExpectedException exception = ExpectedException.none();
public GameStatisticsComponentTest() {
startingDateTime = startingDateTime();
}
@BeforeClass
public static void testClassSetup() {
}
private static Calendar startingDateTime() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 1);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR, 1);
calendar.set(Calendar.MINUTE, 1);
calendar.set(Calendar.SECOND, 1);
return calendar;
}
@Before
public void testSetup() throws TechnicalException {
cycleDescriptionDao = new CycleReplayDescriptionDao(CycleReplayDescription.class, ENVIRONMENT_DESCRIPTION, true);
clientNameDao = new ClientNameDao(ClientName.class, true);
gameReplayDescriptionSaverHelper = new GameReplayDescriptionSaverHelper();
// Cleanup
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
try {
cycleDescriptionDao.remove(replay);
} catch (TechnicalException e) {
e.printStackTrace();
}
}
for (ClientName name : clientNameDao.findAll()) {
clientNameDao.remove(name);
}
gameStatisticsComponent = new CycleStatisticsComponent();
iCycleStatistics = gameStatisticsComponent;
iCycleStatisticsSaver = gameStatisticsComponent;
// Setup the test data.
// Setup the players
testPlayers = new ArrayList<String>();
for (int i = 0; i < NumberOfPlayers; i++) {
testPlayers.add("Player" + i);
}
//Get all possible combinations of test players
allPossiblePlayerCombinations = new ArrayList<playerCombination>();
for (String player : testPlayers) {
for (String opponent : testPlayers) {
if (!player.equals(opponent)) {
allPossiblePlayerCombinations.add(new playerCombination(player, opponent));
allPossiblePlayerCombinations.add(new playerCombination(opponent, player));
}
}
}
// Create game replays, and save them in the database
testReplayDescriptions = new LinkedList<CycleReplayDescription>();
testGameReplays = new LinkedList<ICycleReplay>();
Random random = new Random();
for (int i = 0; i < NumberOfReplays; i++) {
String player1;
String player2;
// Choose two different players to participate in the replay
int randomIndex1 = 0;
int randomIndex2 = 0;
while (randomIndex1 == randomIndex2) {
randomIndex1 = random.nextInt(testPlayers.size());
randomIndex2 = random.nextInt(testPlayers.size());
}
player1 = testPlayers.get(randomIndex1);
player2 = testPlayers.get(randomIndex2);
List<String> playersInReplay = new ArrayList<String>();
playersInReplay.add(player1);
playersInReplay.add(player2);
// Choose a random winning player
String winningPlayer = playersInReplay.get(random.nextInt(playersInReplay.size()));
// Choose a random number of turns
int numberOfTurns = random.nextInt(MaximumNumberOfTurns - MinimumNumberOfTurns) + MinimumNumberOfTurns;
Calendar tmp = startingDateTime();
tmp.add(Calendar.MINUTE, -i);
ICycleReplay replay = new TestReplay(UUID.randomUUID(), tmp.getTime(), playersInReplay, winningPlayer, numberOfTurns, new LinkedList<IEnvironmentState>());
tmp = startingDateTime();
tmp.add(Calendar.MINUTE, -i);
CycleReplayDescription description = new CycleReplayDescription(replay.getReplayId(), tmp.getTime(), playersInReplay, winningPlayer, numberOfTurns, ENVIRONMENT_DESCRIPTION);
// Create the GameStatistics.GameLogic.Entities.TestReplay and add it to the list.
testReplayDescriptions.add(description);
testGameReplays.add(replay);
}
// Save the created game replays in the database
for (int i = 0; i < testReplayDescriptions.size(); i++) {
gameReplayDescriptionSaverHelper.saveReplay(testReplayDescriptions.get(i), testGameReplays.get(i), ENVIRONMENT_DESCRIPTION);
}
}
@After
public void testTearDown() throws TechnicalException {
// Remove all replays from the database.
// Note that some tests create their own replays, that are not contained in the test replays.
// Some replay descriptions have no corresponding game replays on the harddrive.
// This may cause some "Cannot find the specified replay file at: " warnings on the console.
// These warnings can be savely ignored.
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
try {
cycleDescriptionDao.remove(replay);
} catch (TechnicalException e) {
e.printStackTrace();
}
}
for (ClientName name : clientNameDao.findAll()) {
clientNameDao.remove(name);
}
}
@Test
public void getGameReplayTest() throws GameReplayNotContainedInDatabaseException, RemoteException, TechnicalException {
Assert.assertEquals(testReplayDescriptions.size(), cycleDescriptionDao.findAll().size());
List<CycleReplayDescription> descriptions = cycleDescriptionDao.findAll();
List<CycleReplayDescription> expectedDescriptions = new ArrayList<CycleReplayDescription>(testReplayDescriptions);
for (CycleReplayDescription description : cycleDescriptionDao.findAll()) {
expectedDescriptions.remove(description);
}
Assert.assertTrue(expectedDescriptions.size() == 0);
/*for (CycleReplayDescription expected : testReplayDescriptions) {
boolean matchingReplayFound = false;
for (CycleReplayDescription actual : cycleDescriptionDao.findAll()) {
if (expected.equals(actual)) {
matchingReplayFound = true;
Assert.assertEquals(expected, actual);
Assert.assertEquals(expected.getGameReplay(), actual.getGameReplay());
break;
}
}
Assert.assertTrue(matchingReplayFound);
}*/
}
@Test
public void getGameReplayTestNegative() throws GameReplayNotContainedInDatabaseException, RemoteException, TechnicalException {
// Try to find a GameStatistics.GameLogic.Entities.TestReplay with a non existent id.
// A GameReplayNotContainedInDatabaseException should be thrown.
exception.expect(GameReplayNotContainedInDatabaseException.class);
iCycleStatistics.getCycleReplay(UUID.randomUUID(), ENVIRONMENT_DESCRIPTION);
}
@Test
public void getWinLooseRatioTest() throws RemoteException, TechnicalException {
for (playerCombination combination : allPossiblePlayerCombinations) {
float wins = 0;
float totalGames = 0;
for (CycleReplayDescription replay : testReplayDescriptions) {
if (replay.getPlayers().contains(combination.getPlayer()) && replay.getPlayers().contains(combination.getOpponent())) {
totalGames++;
if (replay.getWinningPlayer().equals(combination.player)) {
wins++;
}
}
}
float expectedWinLossRatio;
if (wins != 0 && totalGames != 0) {
expectedWinLossRatio = wins / totalGames;
} else {
expectedWinLossRatio = 0;
}
float returnedWinLossRatio = iCycleStatistics.getWinLoseRatio(combination.getPlayer(), combination.getOpponent(), ENVIRONMENT_DESCRIPTION);
Assert.assertTrue(Float.compare(expectedWinLossRatio, returnedWinLossRatio) == 0);
}
}
@Test
public void getGameReplayDescriptionsByDeltaTimeTest() throws RemoteException, TechnicalException {
// Test if all descriptions of all test replays are returned properly.
// Test if all descriptions are returned, if providing a time frame that covers all of them.
Calendar tmp = startingDateTime();
tmp.add(Calendar.MINUTE, testReplayDescriptions.size());
List<TCycleReplayDescription> allReplays = iCycleStatistics.getCycleReplayDescriptionsByDeltaTime(startingDateTime.getTime(), tmp.getTime(), ENVIRONMENT_DESCRIPTION);
Assert.assertTrue("checkGameDescriptions", checkGameDescriptions(allReplays, testReplayDescriptions));
// Test if no descriptions are returned, if providing a time frame that covers none of them.
tmp = startingDateTime();
tmp.add(Calendar.MINUTE, testReplayDescriptions.size());
Calendar tmp2 = startingDateTime();
tmp.add(Calendar.MINUTE, -1);
List<TCycleReplayDescription> descriptionRange1 = iCycleStatistics.getCycleReplayDescriptionsByDeltaTime(tmp.getTime(), tmp2.getTime(), ENVIRONMENT_DESCRIPTION);
Assert.assertTrue("descriptionRange1", descriptionRange1.size() == 0);
tmp = startingDateTime();
tmp.add(Calendar.MINUTE, testReplayDescriptions.size() + 1);
tmp2 = startingDateTime();
tmp2.add(Calendar.MINUTE, testReplayDescriptions.size() + 2);
List<TCycleReplayDescription> descriptionRange2 = iCycleStatistics.getCycleReplayDescriptionsByDeltaTime(tmp.getTime(), tmp2.getTime(), ENVIRONMENT_DESCRIPTION);
Assert.assertTrue("descriptionRange2", descriptionRange2.size() == 0);
// Test if single description is returned, if providing a timeframe that only covers one replay.
// List<TCycleReplayDescription> descriptionRange3 = iCycleStatistics.getCycleReplayDescriptionsByDeltaTime(startingDateTime.getTime(), startingDateTime.getTime(), ENVIRONMENT_DESCRIPTION);
// Assert.assertTrue("descriptionRange3 size wrong, was: " + descriptionRange3.size(), descriptionRange3.size() == 1);
// Assert.assertTrue("descriptionRange3 not equal", descriptionRange3.get(0).getReplayDate().equals(startingDateTime));
}
@Test
public void getCurrentGamesPerMinuteTest() throws RemoteException, TechnicalException {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -61);
cycleDescriptionDao.create(new CycleReplayDescription(UUID.randomUUID(), calendar.getTime(), new ArrayList<String>(), "", 0, ENVIRONMENT_DESCRIPTION));
calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -55);
cycleDescriptionDao.create(new CycleReplayDescription(UUID.randomUUID(), calendar.getTime(), new ArrayList<String>(), "", 0, ENVIRONMENT_DESCRIPTION));
calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -45);
cycleDescriptionDao.create(new CycleReplayDescription(UUID.randomUUID(), calendar.getTime(), new ArrayList<String>(), "", 0, ENVIRONMENT_DESCRIPTION));
calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -30);
cycleDescriptionDao.create(new CycleReplayDescription(UUID.randomUUID(), calendar.getTime(), new ArrayList<String>(), "", 0, ENVIRONMENT_DESCRIPTION));
calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -1);
cycleDescriptionDao.create(new CycleReplayDescription(UUID.randomUUID(), calendar.getTime(), new ArrayList<String>(), "", 0, ENVIRONMENT_DESCRIPTION));
float expectedGamesPerMinute = 4.0f;
float returnedGamesPerMinute = iCycleStatistics.getCurrentGamesPerMinute(ENVIRONMENT_DESCRIPTION);
Assert.assertTrue(Float.compare(returnedGamesPerMinute, expectedGamesPerMinute) == 0);
}
@Test
public void getTotalNumberOfPlayedGamesTest() throws RemoteException, TechnicalException {
HashMap<String, Integer> numberOfGamesPerPlayer = new HashMap<String, Integer>();
// Generate the expected number of games values for each player.
for (String player : testPlayers) {
int numberOfGamesForPlayer = 0;
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
if (replay.getPlayers().contains(player)) {
numberOfGamesForPlayer++;
}
}
numberOfGamesPerPlayer.put(player, numberOfGamesForPlayer);
}
// Test if the expected values match the values returned from the method.
for (String player : testPlayers) {
Assert.assertTrue(iCycleStatistics.getTotalNumberOfCycles(player, ENVIRONMENT_DESCRIPTION) == numberOfGamesPerPlayer.get(player));
}
}
@Test
public void getTotalNumberOfGamesWonTest() throws RemoteException, TechnicalException {
HashMap<String, Integer> numberOfGamesWonPerPlayer = new HashMap<String, Integer>();
// Generate the expected number of games values for each player.
for (String player : testPlayers) {
int numberOfGamesWonForPlayer = 0;
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
if (replay.getPlayers().contains(player) && replay.getWinningPlayer().equals(player)) {
numberOfGamesWonForPlayer++;
}
}
numberOfGamesWonPerPlayer.put(player, numberOfGamesWonForPlayer);
}
// Test if the expected values match the values returned from the method.
for (String player : testPlayers) {
Assert.assertTrue(iCycleStatistics.getTotalNumberOfCyclesWon(player, ENVIRONMENT_DESCRIPTION) == numberOfGamesWonPerPlayer.get(player));
}
}
@Test
public void getTotalNumberOfGamesLostTest() throws RemoteException, TechnicalException {
HashMap<String, Integer> numberOfGamesLostPerPlayer = new HashMap<String, Integer>();
// Generate the expected number of games values for each player.
for (String player : testPlayers) {
int numberOfGamesLostForPlayer = 0;
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
if (replay.getPlayers().contains(player) && !replay.getWinningPlayer().equals(player)) {
numberOfGamesLostForPlayer++;
}
}
numberOfGamesLostPerPlayer.put(player, numberOfGamesLostForPlayer);
}
// Test if the expected values match the values returned from the method.
for (String player : testPlayers) {
Assert.assertTrue(iCycleStatistics.getTotalNumberOfCyclesLost(player, ENVIRONMENT_DESCRIPTION) == numberOfGamesLostPerPlayer.get(player));
}
}
@Test
public void getAverageTurnsPerGameTest() throws RemoteException, TechnicalException {
// The maximum number of games that will be taken into account for the numberOfLastGames parameter
int maximumNumberOfGamesChecked = testReplayDescriptions.size() + 1;
for (String player : testPlayers) {
Assert.assertTrue(iCycleStatistics.getAverageTurnsPerCycle(player, 0, ENVIRONMENT_DESCRIPTION) == 0);
}
// Test the method for all players for all values of numberOfLastGames up to maximumNumberOfGamesChecked
for (int numberOfGamesChecked = 1; numberOfGamesChecked <= maximumNumberOfGamesChecked; numberOfGamesChecked++) {
for (String player : testPlayers) {
float numberOfGamesForPlayer = 0;
float numberOfTurnsForPlayer = 0;
int numberOfGamesFound = 0;
for (CycleReplayDescription replay : cycleDescriptionDao.findAll()) {
if (replay.getPlayers().contains(player)) {
numberOfGamesForPlayer++;
numberOfTurnsForPlayer += replay.getNumberOfTurns();
numberOfGamesFound++;
if (numberOfGamesFound >= numberOfGamesChecked) {
break;
}
}
}
float expectedValue;
if (numberOfGamesForPlayer != 0 && numberOfTurnsForPlayer != 0) {
expectedValue = numberOfTurnsForPlayer / numberOfGamesForPlayer;
} else {
expectedValue = 0;
}
Assert.assertTrue(Float.compare(iCycleStatistics.getAverageTurnsPerCycle(player, numberOfGamesChecked, ENVIRONMENT_DESCRIPTION), expectedValue) == 0);
}
}
}
@Test
public void saveReplayTest() throws RemoteException, TechnicalException {
List<String> players = new ArrayList<String>();
players.add("Batman");
players.add("Superman");
ICycleReplay testReplay = new TestReplay(UUID.randomUUID(), Calendar.getInstance().getTime(), new ArrayList<String>(), "Batman", 100000, new LinkedList<IEnvironmentState>());
CycleReplayDescription testDescription = new CycleReplayDescription(UUID.randomUUID(), testReplay.getReplayDate(), new ArrayList<String>(), "Batman", 100000, ENVIRONMENT_DESCRIPTION);
iCycleStatisticsSaver.SaveReplay(testReplay, ENVIRONMENT_DESCRIPTION);
for (CycleReplayDescription description : cycleDescriptionDao.findAll()) {
if (description.equals(testDescription)) {
// Assert that an equal replay is found.
Assert.assertTrue(true);
break;
}
}
}
@Test
public void getAllPlayerNamesTest() throws RemoteException, TechnicalException {
List<String> expected = testPlayers;
List<String> actual = iCycleStatistics.getClientNames(ENVIRONMENT_DESCRIPTION);
Assert.assertEquals(expected.size(), actual.size());
for (String s : expected) {
Assert.assertTrue(actual.contains(s));
}
for (CycleReplayDescription a : cycleDescriptionDao.findAll()) {
cycleDescriptionDao.remove(a);
}
iCycleStatistics.getClientNames(ENVIRONMENT_DESCRIPTION);
}
private boolean checkGameDescriptions(List<TCycleReplayDescription> descriptions, List<CycleReplayDescription> replays) {
/*if (descriptions.size() != replays.size()) {
return false;
}
// Extract all replays from the descriptions
List<CycleReplayDescription> replaysInDescription = new ArrayList<CycleReplayDescription>();
for (TGameDescription description : descriptions) {
replaysInDescription.add(new CycleReplayDescription(description.get_replay()));
}
// Check if all wanted replays are contained in the descriptions
for (CycleReplayDescription replay : replays) {
if (!replaysInDescription.contains(replay)) {
return false;
}
}*/
return true;
}
private class playerCombination {
private String player;
private String opponent;
public String getPlayer() {
return player;
}
public String getOpponent() {
return opponent;
}
public playerCombination(String player, String opponent) {
this.player = player;
this.opponent = opponent;
}
}
}