From ddf1866d6eccdc623de9051a317ee266a5e4a4de Mon Sep 17 00:00:00 2001 From: magenoxx Date: Mon, 20 Dec 2010 00:59:11 +0300 Subject: [PATCH 1/3] Removed using bdd tests because of weird behaeve framework. --- Mage.Server/pom.xml | 5 - .../java/mage/server/bdd/MageEmbedder.java | 73 --------- .../test/java/mage/server/bdd/MageSteps.java | 38 ----- .../java/mage/server/bdd/MageStoryRunner.java | 21 --- .../java/mage/server/bdd/StoryRunPOC.java | 152 ------------------ Mage.Server/src/test/java/stories/land.story | 7 - 6 files changed, 296 deletions(-) delete mode 100644 Mage.Server/src/test/java/mage/server/bdd/MageEmbedder.java delete mode 100644 Mage.Server/src/test/java/mage/server/bdd/MageSteps.java delete mode 100644 Mage.Server/src/test/java/mage/server/bdd/MageStoryRunner.java delete mode 100644 Mage.Server/src/test/java/mage/server/bdd/StoryRunPOC.java delete mode 100644 Mage.Server/src/test/java/stories/land.story diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index d746dea46a3..0146a43de4f 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -88,11 +88,6 @@ ${project.version} runtime - - org.jbehave - jbehave-core - 3.2-beta-1 - diff --git a/Mage.Server/src/test/java/mage/server/bdd/MageEmbedder.java b/Mage.Server/src/test/java/mage/server/bdd/MageEmbedder.java deleted file mode 100644 index 4e27d6791d9..00000000000 --- a/Mage.Server/src/test/java/mage/server/bdd/MageEmbedder.java +++ /dev/null @@ -1,73 +0,0 @@ -package mage.server.bdd; - -import org.jbehave.core.configuration.Configuration; -import org.jbehave.core.configuration.MostUsefulConfiguration; -import org.jbehave.core.embedder.Embedder; -import org.jbehave.core.io.CodeLocations; -import org.jbehave.core.io.LoadFromRelativeFile; -import org.jbehave.core.io.StoryResourceNotFound; -import org.jbehave.core.reporters.StoryReporterBuilder; -import org.jbehave.core.steps.CandidateSteps; -import org.jbehave.core.steps.InstanceStepsFactory; - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -/** - * Contains configuration for working with steps and stories in Mage. - * - * @author nantuko - */ -public class MageEmbedder extends Embedder { - - /** - * We meed to extend LoadFromRelativeFile because of bug in replacing slashes - * - * @author nantuko - */ - private class MageStoryFilePath extends LoadFromRelativeFile { - - private final StoryFilePath[] traversals; - private final URL location; - - public MageStoryFilePath(URL location, StoryFilePath... traversals) { - super(location, traversals); - this.location = location; - this.traversals = traversals; - } - - @Override - public String loadResourceAsText(String resourcePath) { - List traversalPaths = new ArrayList(); - String locationPath = new File(location.getFile()).getAbsolutePath(); - - String filePath = locationPath.replace("target\\test-classes", "src/test/java") + "/" + resourcePath; - File file = new File(filePath); - if (file.exists()) { - return loadContent(filePath); - } - - throw new StoryResourceNotFound(resourcePath, traversalPaths); - } - - } - - @Override - public Configuration configuration() { - Class embedderClass = this.getClass(); - URL codeLocation = CodeLocations.codeLocationFromClass(embedderClass); - Configuration configuration = new MostUsefulConfiguration() - .useStoryLoader(new MageStoryFilePath(codeLocation, LoadFromRelativeFile.mavenModuleTestStoryFilePath("src/test/java") )) - .useStoryReporterBuilder(new StoryReporterBuilder() - .withCodeLocation(codeLocation) - .withDefaultFormats()); - return configuration; - } - - @Override - public List candidateSteps() { - return new InstanceStepsFactory(configuration(), new MageSteps()).createCandidateSteps(); - } -} \ No newline at end of file diff --git a/Mage.Server/src/test/java/mage/server/bdd/MageSteps.java b/Mage.Server/src/test/java/mage/server/bdd/MageSteps.java deleted file mode 100644 index 7c59f3c5321..00000000000 --- a/Mage.Server/src/test/java/mage/server/bdd/MageSteps.java +++ /dev/null @@ -1,38 +0,0 @@ -package mage.server.bdd; - -import org.jbehave.core.annotations.Given; -import org.jbehave.core.annotations.Then; -import org.jbehave.core.annotations.When; - -/** - * Defines Mage BDD steps. - * - * @author nantuko - */ -public class MageSteps { - - @Given("I'm in the game") - public void inTheGame() { - System.out.println("In the game"); - } - - @Given("I have an \"$card\" card") - public void hasACard(String card) { - System.out.println("card: " + card); - } - - @Given("phase is $own \"$phase\"") - public void hasPhase(String own, String phase) { - System.out.println("phase is: " + own + " -> " + phase); - } - - @When("I splay \"$card\"") - public void playCard(String card) { - System.out.println("play a card: " + card); - } - - @Then("there is an \"$card\" on $zone") - public void playCard(String card, String zone) { - System.out.println("checking: " + card + ", zone=" + zone); - } -} diff --git a/Mage.Server/src/test/java/mage/server/bdd/MageStoryRunner.java b/Mage.Server/src/test/java/mage/server/bdd/MageStoryRunner.java deleted file mode 100644 index f8c142aa1de..00000000000 --- a/Mage.Server/src/test/java/mage/server/bdd/MageStoryRunner.java +++ /dev/null @@ -1,21 +0,0 @@ -package mage.server.bdd; - -import org.jbehave.core.io.StoryFinder; - -import java.util.List; - -import static java.util.Arrays.asList; - -/** - * Runs Mage stories (tests) - * - * @author nantuko - */ -public class MageStoryRunner { - public static void main(String[] argv) throws Throwable { - MageEmbedder embedder = new MageEmbedder(); - List storyPaths = (new StoryFinder()).findPaths("src/test/java", asList("stories/land.story"), null); - System.out.println("Found stories count: " + storyPaths.size()); - embedder.runStoriesAsPaths(storyPaths); - } -} diff --git a/Mage.Server/src/test/java/mage/server/bdd/StoryRunPOC.java b/Mage.Server/src/test/java/mage/server/bdd/StoryRunPOC.java deleted file mode 100644 index 96f2f1fd373..00000000000 --- a/Mage.Server/src/test/java/mage/server/bdd/StoryRunPOC.java +++ /dev/null @@ -1,152 +0,0 @@ -package mage.server.bdd; - -import mage.interfaces.MageException; -import mage.interfaces.Server; -import mage.interfaces.ServerState; -import mage.interfaces.callback.CallbackClient; -import mage.interfaces.callback.CallbackClientDaemon; -import mage.interfaces.callback.ClientCallback; -import mage.server.Main; -import mage.sets.Sets; -import mage.util.Logging; -import mage.view.*; -import org.junit.Test; - -import java.rmi.NotBoundException; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Proof of concept of running game from tests.\ - * Will be removed later when BDD is finished. - * - * @author nantuko - */ -public class StoryRunPOC { - - private static Logger logger = Logging.getLogger(StoryRunPOC.class.getName()); - - private static UUID sessionId; - private static Server server; - private static String userName; - private static ServerState serverState; - private static CallbackClientDaemon callbackDaemon; - private static UUID gameId; - private static UUID playerId; - private static CardView cardPlayed; - - @Test - public void testEmpty() { - - } - - public static void main(String[] argv) throws Exception { - String[] args = new String[] {"-testMode=true"}; - Main.main(args); - connect("player", "localhost", 17171); - UUID roomId = server.getMainRoomId(); - - List playerTypes = new ArrayList(); - playerTypes.add("Human"); - playerTypes.add("Computer - default"); - TableView table = server.createTable(sessionId, roomId, "Two Player Duel", "Limited", playerTypes, null, null); - System.out.println("Cards in the deck: " + Sets.loadDeck("UW Control.dck").getCards().size()); - server.joinTable(sessionId, roomId, table.getTableId(), "Human", Sets.loadDeck("UW Control.dck")); - server.joinTable(sessionId, roomId, table.getTableId(), "Computer", Sets.loadDeck("UW Control.dck")); - server.startGame(sessionId, roomId, table.getTableId()); - } - - public static void connect(String userName, String serverName, int port) { - try { - System.setSecurityManager(null); - Registry reg = LocateRegistry.getRegistry(serverName, port); - server = (Server) reg.lookup("mage-server"); - sessionId = server.registerClient(userName, UUID.randomUUID()); - CallbackClient client = new CallbackClient(){ - @Override - public void processCallback(ClientCallback callback) { - logger.info("IN >> " + callback.getMessageId() + " - " + callback.getMethod()); - try { - if (callback.getMethod().equals("startGame")) { - UUID[] data = (UUID[]) callback.getData(); - gameId = data[0]; - playerId = data[1]; - server.joinGame(gameId, sessionId); - } else if (callback.getMethod().equals("gameInit")) { - server.ack("gameInit", sessionId); - } else if (callback.getMethod().equals("gameAsk")) { - GameClientMessage message = (GameClientMessage) callback.getData(); - logger.info("ASK >> " + message.getMessage()); - if (message.getMessage().equals("Do you want to take a mulligan?")) { - server.sendPlayerBoolean(gameId, sessionId, false); - } - } else if (callback.getMethod().equals("gameTarget")) { - GameClientMessage message = (GameClientMessage) callback.getData(); - logger.info("TARGET >> " + message.getMessage() + " >> " + message.getTargets()); - if (message.getMessage().equals("Select a starting player")) { - logger.info(" Sending >> " + playerId); - server.sendPlayerUUID(gameId, sessionId, playerId); - } - } else if (callback.getMethod().equals("gameSelect")) { - GameClientMessage message = (GameClientMessage) callback.getData(); - logger.info("SELECT >> " + message.getMessage()); - if (!message.getMessage().startsWith("Precombat Main - play spells and sorceries.")) { - server.sendPlayerBoolean(gameId, sessionId, false); - } else { - if (cardPlayed == null) { - CardsView cards = message.getGameView().getHand(); - CardView landToPlay = null; - for (CardView card : cards.values()) { - //System.out.println(card.getName()); - if (card.getName().equals("Plains") || card.getName().equals("Island")) { - landToPlay = card; - } - } - if (landToPlay != null) { - logger.info("Playing " + landToPlay); - server.sendPlayerUUID(gameId, sessionId, landToPlay.getId()); - cardPlayed = landToPlay; - } else { - logger.warning("Couldn't find land to play"); - } - } else { - logger.info("Checking battlefield..."); - boolean foundPlayer = false; - boolean foundLand = false; - for (PlayerView player: message.getGameView().getPlayers()) { - if (player.getPlayerId().equals(playerId)) { - foundPlayer = true; - for (PermanentView permanent : player.getBattlefield().values()) { - if (permanent.getId().equals(cardPlayed.getId())) { - foundLand = true; - } - } - break; - } - } - logger.info(" found player: " + foundPlayer); - logger.info(" found land: " + foundLand); - System.exit(0); - } - } - } - } catch (Exception e) { - logger.info(e.getMessage()); - } - } - }; - callbackDaemon = new CallbackClientDaemon(sessionId, client, server); - serverState = server.getServerState(); - } catch (MageException ex) { - logger.log(Level.SEVERE, null, ex); - } catch (RemoteException ex) { - logger.log(Level.SEVERE, "Unable to connect to server - ", ex); - } catch (NotBoundException ex) { - logger.log(Level.SEVERE, "Unable to connect to server - ", ex); - } - } -} diff --git a/Mage.Server/src/test/java/stories/land.story b/Mage.Server/src/test/java/stories/land.story deleted file mode 100644 index af024677a26..00000000000 --- a/Mage.Server/src/test/java/stories/land.story +++ /dev/null @@ -1,7 +0,0 @@ -Scenario: player plays Land on his main phase - -Given I'm in the game -And I have an "Island" card -And phase is my "Precombat Main" -When I play "Island" -Then there is an "Island" on battlefield \ No newline at end of file From 1b6722f9b2375bdae460761e0ca24a6c2766b3e7 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Mon, 20 Dec 2010 01:03:12 +0300 Subject: [PATCH 2/3] Added Mage.Tests project. Update server for test operations. Implemented bdd classes. --- Mage.Common/src/mage/interfaces/Server.java | 4 +- .../src/main/java/mage/server/ServerImpl.java | 23 ++ .../java/mage/server/game/GameController.java | 13 +- .../java/mage/server/game/GameManager.java | 8 + Mage.Tests/UW Control.dck | 29 +++ Mage.Tests/pom.xml | 75 ++++++ .../test/java/org/mage/test/base/MageAPI.java | 53 ++++ .../java/org/mage/test/base/MageBase.java | 245 ++++++++++++++++++ .../test/java/org/mage/test/bdd/and/And.java | 6 + .../org/mage/test/bdd/and/Graveyards.java | 11 + .../java/org/mage/test/bdd/and/Phase.java | 20 ++ .../test/java/org/mage/test/bdd/given/A.java | 13 + .../java/org/mage/test/bdd/given/Given.java | 8 + .../java/org/mage/test/bdd/given/Have.java | 5 + .../test/java/org/mage/test/bdd/given/I.java | 5 + .../org/mage/test/bdd/then/Battlefield.java | 9 + .../java/org/mage/test/bdd/then/Then.java | 5 + .../test/java/org/mage/test/bdd/when/I.java | 10 + .../java/org/mage/test/bdd/when/When.java | 5 + pom.xml | 1 + 20 files changed, 546 insertions(+), 2 deletions(-) create mode 100644 Mage.Tests/UW Control.dck create mode 100644 Mage.Tests/pom.xml create mode 100644 Mage.Tests/src/test/java/org/mage/test/base/MageAPI.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/base/MageBase.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/and/And.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/and/Graveyards.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/and/Phase.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/given/A.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/given/Given.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/given/Have.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/given/I.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/then/Battlefield.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/then/Then.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/when/I.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/bdd/when/When.java diff --git a/Mage.Common/src/mage/interfaces/Server.java b/Mage.Common/src/mage/interfaces/Server.java index a6d3b7f3956..7cc8ade3c6e 100644 --- a/Mage.Common/src/mage/interfaces/Server.java +++ b/Mage.Common/src/mage/interfaces/Server.java @@ -39,6 +39,7 @@ import mage.game.GameException; import mage.interfaces.callback.CallbackServer; import mage.view.GameTypeView; import mage.view.TableView; +import mage.view.GameView; /** * @@ -94,5 +95,6 @@ public interface Server extends Remote, CallbackServer { //test methods public void cheat(UUID gameId, UUID sessionId, UUID playerId, DeckCardLists deckList) throws RemoteException, MageException; - + public void cheat(UUID gameId, UUID sessionId, UUID playerId, String cardName) throws RemoteException, MageException; + public GameView getGameView(UUID gameId, UUID sessionId, UUID playerId) throws RemoteException, MageException; } diff --git a/Mage.Server/src/main/java/mage/server/ServerImpl.java b/Mage.Server/src/main/java/mage/server/ServerImpl.java index d0a7abbf145..59bc37a5f29 100644 --- a/Mage.Server/src/main/java/mage/server/ServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/ServerImpl.java @@ -57,6 +57,7 @@ import mage.server.game.TableManager; import mage.server.util.ThreadExecutor; import mage.util.Logging; import mage.view.ChatMessage.MessageColor; +import mage.view.GameView; import mage.view.TableView; /** @@ -615,9 +616,31 @@ public class ServerImpl extends RemoteServer implements Server { } } + @Override + public void cheat(final UUID gameId, final UUID sessionId, final UUID playerId, final String cardName) throws MageException { + try { + rmiExecutor.execute( + new Runnable() { + @Override + public void run() { + if (testMode) + GameManager.getInstance().cheat(gameId, sessionId, playerId, cardName); + } + } + ); + } + catch (Exception ex) { + handleException(ex); + } + } + public void handleException(Exception ex) throws MageException { logger.log(Level.SEVERE, "", ex); throw new MageException("Server error"); } + public GameView getGameView(final UUID gameId, final UUID sessionId, final UUID playerId) { + return GameManager.getInstance().getGameView(gameId, sessionId, playerId); + } + } diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 7739f94f110..9f4484ed46d 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -235,6 +235,17 @@ public class GameController implements GameCallback { updateGame(); } + public void cheat(UUID sessionId, UUID playerId, String cardName) { + String clazz = Sets.findCard(cardName); + if (clazz != null) { + Card card = CardImpl.createCard(clazz); + Set cards = new HashSet(); + cards.add(card); + game.loadCards(cards, playerId); + updateGame(); + } + } + public void kill(UUID sessionId) { if (sessionPlayerMap.containsKey(sessionId)) { gameSessions.get(sessionPlayerMap.get(sessionId)).setKilled(); @@ -384,7 +395,7 @@ public class GameController implements GameCallback { return new GameView(game.getState(), game); } - private GameView getGameView(UUID playerId) { + public GameView getGameView(UUID playerId) { GameView gameView = new GameView(game.getState(), game); gameView.setHand(new CardsView(game.getPlayer(playerId).getHand().getCards(game))); return gameView; diff --git a/Mage.Server/src/main/java/mage/server/game/GameManager.java b/Mage.Server/src/main/java/mage/server/game/GameManager.java index 77da7725e4a..a28983c5f7a 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameManager.java +++ b/Mage.Server/src/main/java/mage/server/game/GameManager.java @@ -32,6 +32,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import mage.cards.decks.DeckCardLists; import mage.game.Game; +import mage.view.GameView; /** * @@ -112,6 +113,10 @@ public class GameManager { gameControllers.get(gameId).cheat(sessionId, playerId, deckList); } + public void cheat(UUID gameId, UUID sessionId, UUID playerId, String cardName) { + gameControllers.get(gameId).cheat(sessionId, playerId, cardName); + } + void timeout(UUID gameId, UUID sessionId) { gameControllers.get(gameId).timeout(sessionId); } @@ -120,4 +125,7 @@ public class GameManager { gameControllers.remove(gameId); } + public GameView getGameView(UUID gameId, UUID sessionId, UUID playerId) { + return gameControllers.get(gameId).getGameView(playerId); + } } diff --git a/Mage.Tests/UW Control.dck b/Mage.Tests/UW Control.dck new file mode 100644 index 00000000000..3033c885668 --- /dev/null +++ b/Mage.Tests/UW Control.dck @@ -0,0 +1,29 @@ +NAME:UW Control +2 [ROE:236] Island +1 [ROE:235] Island +1 [ROE:234] Island +2 [ROE:233] Island +2 [CON:15] Path to Exile +3 [ROE:21] Gideon Jura +1 [CON:11] Martial Coup +2 [ZEN:9] Day of Judgment +1 [ZEN:216] Kabira Crossroads +4 [WWK:31] Jace, the Mind Sculptor +3 [M10:64] Mind Spring +3 [WWK:123] Everflowing Chalice +1 [ROE:232] Plains +4 [ROE:53] Wall of Omens +1 [ROE:229] Plains +1 [ROE:230] Plains +1 [ROE:231] Plains +3 [ALA:20] Oblivion Ring +4 [ZEN:70] Spreading Seas +4 [WWK:145] Tectonic Edge +1 [ALA:9] Elspeth, Knight-Errant +2 [ROE:59] Deprive +1 [ZEN:220] Misty Rainforest +4 [WWK:133] Celestial Colonnade +1 [ZEN:211] Arid Mesa +4 [M10:226] Glacial Fortress +1 [WWK:142] Sejiri Steppe +2 [M10:65] Negate diff --git a/Mage.Tests/pom.xml b/Mage.Tests/pom.xml new file mode 100644 index 00000000000..f3d31fd2e62 --- /dev/null +++ b/Mage.Tests/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + org.mage + mage-root + 0.5 + + + Mage-Tests + jar + Mage Tests + + + + ${project.groupId} + Mage + ${mage-version} + + + ${project.groupId} + Mage-Common + ${mage-version} + + + ${project.groupId} + Mage-Sets + ${mage-version} + + + ${project.groupId} + Mage-Server + ${mage-version} + + + junit + junit + 4.8.2 + + + + log4j + log4j + 1.2.14 + jar + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + maven-resources-plugin + + UTF-8 + + + + + mage-tests + + + + + diff --git a/Mage.Tests/src/test/java/org/mage/test/base/MageAPI.java b/Mage.Tests/src/test/java/org/mage/test/base/MageAPI.java new file mode 100644 index 00000000000..0b88f85fab7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/base/MageAPI.java @@ -0,0 +1,53 @@ +package org.mage.test.base; + +import mage.game.turn.Phase; +import org.junit.BeforeClass; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/** + * Parent class for all Mage tests. + * Provides basic actions in mage game and assert functions to check game state. + */ +public class MageAPI { + + public enum Owner { + mine, + me, + ai + } + + @BeforeClass + public static void startServer() throws Exception { + MageBase.getInstance().start(); + Thread.sleep(3000); + } + + public void giveme(String card) throws Exception { + MageBase.getInstance().giveme(card); + } + + public boolean checkIhave(String card) throws Exception { + return MageBase.getInstance().checkIhave(card); + } + + public void goToPhase(String phase, Owner owner) { + if ("Precombat Main".equals(phase) && (owner.equals(Owner.mine) || owner.equals(Owner.me))) { + MageBase.getInstance().goToPhase("Precombat Main - play spells and sorceries."); + return; + } + System.err.println("waitForPhase not implemented for phase="+phase+", owner="+owner.name()); + throw new NotImplementedException(); + } + + public void playCard(String cardName) throws Exception { + MageBase.getInstance().playCard(cardName); + } + + public boolean checkBattlefield(String cardName) throws Exception { + return MageBase.getInstance().checkBattlefield(cardName); + } + + public boolean checkGraveyardsEmpty() throws Exception { + return MageBase.getInstance().checkGraveyardsEmpty(); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java b/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java new file mode 100644 index 00000000000..e00b5144451 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/base/MageBase.java @@ -0,0 +1,245 @@ +package org.mage.test.base; + +import mage.interfaces.MageException; +import mage.interfaces.Server; +import mage.interfaces.ServerState; +import mage.interfaces.callback.CallbackClient; +import mage.interfaces.callback.CallbackClientDaemon; +import mage.interfaces.callback.ClientCallback; +import mage.server.Main; +import mage.sets.Sets; +import mage.util.Logging; +import mage.view.*; + +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Base for starting Mage server. + * Controls interactions between MageAPI and Mage Server. + * + * @author nantuko + */ +public class MageBase { + /** + * MageBase single instance + */ + private static MageBase fInstance = new MageBase(); + + /** + * Default logger + */ + private static Logger logger = Logging.getLogger(MageBase.class.getName()); + + public static MageBase getInstance() { + return fInstance; + } + + private static UUID sessionId; + public static Server server; + private static String userName; + private static ServerState serverState; + private static CallbackClientDaemon callbackDaemon; + private static UUID gameId; + private static UUID playerId; + private static CardView cardPlayed; + + private static GameView gameView; + private static String phaseToWait; + private static Object sync = new Object(); + + public void start() throws Exception { + if (server == null) { + String[] args = new String[]{"-testMode=true"}; + Main.main(args); + connect("player", "localhost", 17171); + UUID roomId = server.getMainRoomId(); + + List playerTypes = new ArrayList(); + playerTypes.add("Human"); + playerTypes.add("Computer - default"); + TableView table = server.createTable(sessionId, roomId, "Two Player Duel", "Limited", playerTypes, null, null); + System.out.println("Cards in the deck: " + Sets.loadDeck("UW Control.dck").getCards().size()); + server.joinTable(sessionId, roomId, table.getTableId(), "Human", Sets.loadDeck("UW Control.dck")); + server.joinTable(sessionId, roomId, table.getTableId(), "Computer", Sets.loadDeck("UW Control.dck")); + server.startGame(sessionId, roomId, table.getTableId()); + } + } + + public static void connect(String userName, String serverName, int port) { + try { + System.setSecurityManager(null); + Registry reg = LocateRegistry.getRegistry(serverName, port); + server = (Server) reg.lookup("mage-server"); + sessionId = server.registerClient(userName, UUID.randomUUID()); + CallbackClient client = new CallbackClient(){ + @Override + public void processCallback(ClientCallback callback) { + logger.info("IN >> " + callback.getMessageId() + " - " + callback.getMethod()); + try { + if (callback.getMethod().equals("startGame")) { + UUID[] data = (UUID[]) callback.getData(); + gameId = data[0]; + playerId = data[1]; + server.joinGame(gameId, sessionId); + } else if (callback.getMethod().equals("gameInit")) { + server.ack("gameInit", sessionId); + } else if (callback.getMethod().equals("gameAsk")) { + GameClientMessage message = (GameClientMessage) callback.getData(); + logger.info("ASK >> " + message.getMessage()); + if (message.getMessage().equals("Do you want to take a mulligan?")) { + server.sendPlayerBoolean(gameId, sessionId, false); + } + } else if (callback.getMethod().equals("gameTarget")) { + GameClientMessage message = (GameClientMessage) callback.getData(); + logger.info("TARGET >> " + message.getMessage() + " >> " + message.getTargets()); + if (message.getMessage().equals("Select a starting player")) { + logger.info(" Sending >> " + playerId); + server.sendPlayerUUID(gameId, sessionId, playerId); + } + } else if (callback.getMethod().equals("gameSelect")) { + GameClientMessage message = (GameClientMessage) callback.getData(); + logger.info("SELECT >> " + message.getMessage()); + if (phaseToWait == null) { + synchronized (sync) { + sync.wait(); + } + } + if (!message.getMessage().startsWith(phaseToWait)) { + server.sendPlayerBoolean(gameId, sessionId, false); + } else { + phaseToWait = null; + } + + /*if (!message.getMessage().startsWith("Precombat Main - play spells and sorceries.")) { + server.sendPlayerBoolean(gameId, sessionId, false); + } else { + if (cardPlayed == null) { + CardsView cards = message.getGameView().getHand(); + CardView landToPlay = null; + for (CardView card : cards.values()) { + //System.out.println(card.getName()); + if (card.getName().equals("Plains") || card.getName().equals("Island")) { + landToPlay = card; + } + } + if (landToPlay != null) { + logger.info("Playing " + landToPlay); + server.sendPlayerUUID(gameId, sessionId, landToPlay.getId()); + cardPlayed = landToPlay; + } else { + logger.warning("Couldn't find land to play"); + } + } else { + logger.info("Checking battlefield..."); + boolean foundPlayer = false; + boolean foundLand = false; + for (PlayerView player: message.getGameView().getPlayers()) { + if (player.getPlayerId().equals(playerId)) { + foundPlayer = true; + for (PermanentView permanent : player.getBattlefield().values()) { + if (permanent.getId().equals(cardPlayed.getId())) { + foundLand = true; + } + } + break; + } + } + logger.info(" found player: " + foundPlayer); + logger.info(" found land: " + foundLand); + System.exit(0); + } + + } */ + } + } catch (Exception e) { + logger.info(e.getMessage()); + } + } + }; + callbackDaemon = new CallbackClientDaemon(sessionId, client, server); + serverState = server.getServerState(); + } catch (MageException ex) { + logger.log(Level.SEVERE, null, ex); + } catch (RemoteException ex) { + logger.log(Level.SEVERE, "Unable to connect to server - ", ex); + } catch (NotBoundException ex) { + logger.log(Level.SEVERE, "Unable to connect to server - ", ex); + } + } + + + public void giveme(String cardName) throws Exception { + server.cheat(gameId, sessionId, playerId, cardName); + } + + public boolean checkIhave(String cardName) throws Exception { + if (cardName == null) { + return false; + } + gameView = server.getGameView(gameId, sessionId, playerId); + for (CardView card : gameView.getHand().values()) { + if (card.getName().equals(cardName)) { + return true; + } + } + return false; + } + + public void goToPhase(String phase) { + phaseToWait = phase; + synchronized (sync) { + sync.notify(); + } + } + + public void playCard(String cardName) throws Exception { + gameView = server.getGameView(gameId, sessionId, playerId); + CardsView cards = gameView.getHand(); + CardView cardToPlay = null; + for (CardView card : cards.values()) { + if (card.getName().equals(cardName)) { + cardToPlay = card; + } + } + if (cardToPlay == null) { + throw new IllegalArgumentException("Couldn't find " + cardName + " in the hand."); + } + if (cardToPlay != null) { + logger.info("Playing " + cardToPlay); + server.sendPlayerUUID(gameId, sessionId, cardToPlay.getId()); + cardPlayed = cardToPlay; + } + } + + public boolean checkBattlefield(String cardName) throws Exception { + gameView = server.getGameView(gameId, sessionId, playerId); + for (PlayerView player: gameView.getPlayers()) { + if (player.getPlayerId().equals(playerId)) { + for (PermanentView permanent : player.getBattlefield().values()) { + if (permanent.getName().equals(cardName)) { + return true; + } + } + } + } + return false; + } + + public boolean checkGraveyardsEmpty() throws Exception { + gameView = server.getGameView(gameId, sessionId, playerId); + for (PlayerView player: gameView.getPlayers()) { + if (player.getGraveyard().size() > 0) { + return false; + } + } + return true; + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/and/And.java b/Mage.Tests/src/test/java/org/mage/test/bdd/and/And.java new file mode 100644 index 00000000000..3243bd7ea00 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/and/And.java @@ -0,0 +1,6 @@ +package org.mage.test.bdd.and; + +public class And { + public static Phase phase; + public static Graveyards graveyards; +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/and/Graveyards.java b/Mage.Tests/src/test/java/org/mage/test/bdd/and/Graveyards.java new file mode 100644 index 00000000000..2411d87f7b5 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/and/Graveyards.java @@ -0,0 +1,11 @@ +package org.mage.test.bdd.and; + +import org.mage.test.base.MageBase; + +public class Graveyards { + public static boolean empty() throws Exception { + boolean empty = MageBase.getInstance().checkGraveyardsEmpty(); + System.out.println("empty: " + empty); + return empty; + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/and/Phase.java b/Mage.Tests/src/test/java/org/mage/test/bdd/and/Phase.java new file mode 100644 index 00000000000..53a5a6fbeeb --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/and/Phase.java @@ -0,0 +1,20 @@ +package org.mage.test.bdd.and; + +import org.mage.test.base.MageAPI; +import org.mage.test.base.MageBase; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +import static org.mage.test.base.MageAPI.*; +import static org.mage.test.base.MageAPI.Owner.*; + +public class Phase { + public static void is(String phase, MageAPI.Owner owner) throws Exception { + if ("Precombat Main".equals(phase) && (owner.equals(mine) || owner.equals(me))) { + MageBase.getInstance().goToPhase("Precombat Main - play spells and sorceries."); + Thread.sleep(3000); + return; + } + System.err.println("waitForPhase not implemented for phase="+phase+", owner="+owner.name()); + throw new NotImplementedException(); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/given/A.java b/Mage.Tests/src/test/java/org/mage/test/bdd/given/A.java new file mode 100644 index 00000000000..325891ab54c --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/given/A.java @@ -0,0 +1,13 @@ +package org.mage.test.bdd.given; + +import org.mage.test.base.MageBase; + +public class A { + public static void card(String cardName) throws Exception { + MageBase.getInstance().giveme(cardName); + Thread.sleep(4000); + if (!MageBase.getInstance().checkIhave(cardName)) { + throw new IllegalStateException("Couldn't find a card in hand: " + cardName); + } + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/given/Given.java b/Mage.Tests/src/test/java/org/mage/test/bdd/given/Given.java new file mode 100644 index 00000000000..dd8c89e04c1 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/given/Given.java @@ -0,0 +1,8 @@ +package org.mage.test.bdd.given; + +import org.mage.test.bdd.and.Phase; + +public class Given { + public static I I; + public static Phase phase; +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/given/Have.java b/Mage.Tests/src/test/java/org/mage/test/bdd/given/Have.java new file mode 100644 index 00000000000..e49750c26a3 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/given/Have.java @@ -0,0 +1,5 @@ +package org.mage.test.bdd.given; + +public class Have { + public static A a; +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/given/I.java b/Mage.Tests/src/test/java/org/mage/test/bdd/given/I.java new file mode 100644 index 00000000000..034626aefcc --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/given/I.java @@ -0,0 +1,5 @@ +package org.mage.test.bdd.given; + +public class I { + public static Have have; +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/then/Battlefield.java b/Mage.Tests/src/test/java/org/mage/test/bdd/then/Battlefield.java new file mode 100644 index 00000000000..fe59b119235 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/then/Battlefield.java @@ -0,0 +1,9 @@ +package org.mage.test.bdd.then; + +import org.mage.test.base.MageBase; + +public class Battlefield { + public static boolean has(String cardName) throws Exception { + return MageBase.getInstance().checkBattlefield(cardName); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/then/Then.java b/Mage.Tests/src/test/java/org/mage/test/bdd/then/Then.java new file mode 100644 index 00000000000..6307c6b5cbc --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/then/Then.java @@ -0,0 +1,5 @@ +package org.mage.test.bdd.then; + +public class Then { + public static Battlefield battlefield; +} diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/when/I.java b/Mage.Tests/src/test/java/org/mage/test/bdd/when/I.java new file mode 100644 index 00000000000..053c5b69138 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/when/I.java @@ -0,0 +1,10 @@ +package org.mage.test.bdd.when; + +import org.mage.test.base.MageBase; + +public class I { + public static void play(String cardName) throws Exception { + MageBase.getInstance().playCard(cardName); + Thread.sleep(3000); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/bdd/when/When.java b/Mage.Tests/src/test/java/org/mage/test/bdd/when/When.java new file mode 100644 index 00000000000..bb995327306 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/bdd/when/When.java @@ -0,0 +1,5 @@ +package org.mage.test.bdd.when; + +public class When { + public static I I; +} diff --git a/pom.xml b/pom.xml index 76614ae0df1..e2e3a09f68a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ Mage.Client Mage.Plugins Mage.Server.Plugins + Mage.Tests From a2577c677f2368e8ad6ba0961873990f525acf88 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Mon, 20 Dec 2010 01:04:08 +0300 Subject: [PATCH 3/3] Land test. --- .../src/test/java/org/mage/test/LandTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/LandTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/LandTest.java b/Mage.Tests/src/test/java/org/mage/test/LandTest.java new file mode 100644 index 00000000000..9535a2d0c42 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/LandTest.java @@ -0,0 +1,36 @@ +package org.mage.test; + +import org.junit.Test; +import org.mage.test.base.MageAPI; +import org.mage.test.bdd.and.And; +import org.mage.test.bdd.given.Given; +import org.mage.test.bdd.then.Then; +import org.mage.test.bdd.when.When; + +import static org.mage.test.base.MageAPI.Owner.*; + +public class LandTest extends MageAPI { + + @Test + public void testPlayingLandInMainPhase() throws Exception { + //TODO: add test framework callback for synchronization and removing Thread.sleep calls + Given.I.have.a.card("Island"); + And.phase.is("Precombat Main", mine); + When.I.play("Island"); + Then.battlefield.has("Island"); + And.graveyards.empty(); + } + + /*@Test + public void testLightningHelix() throws Exception { + Given.I.have.a.card("Lightning Helix"); + And.battlefield.has("Mountain","Plains"); + And.phase.is("End of Turn", ai); + And.lifes(20,20); + When.I.play("Lightning Helix"); + Then.my.life(23); + And.ai.life(17); + And.my.graveyard.has("Lightning Helix"); + And.ai.graveyard.empty(); + }*/ +}